forked from quic-go/quic-go
Move Chrome tests and test server setup to separate packages
This commit is contained in:
232
integrationtests/chrome/chrome_suite_test.go
Normal file
232
integrationtests/chrome/chrome_suite_test.go
Normal file
@@ -0,0 +1,232 @@
|
||||
package chrome_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/integrationtests/tools/testserver"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/gexec"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
nChromeRetries = 8
|
||||
|
||||
dataLen = 500 * 1024 // 500 KB
|
||||
dataLongLen = 50 * 1024 * 1024 // 50 MB
|
||||
)
|
||||
|
||||
var (
|
||||
nFilesUploaded int32
|
||||
testEndpointCalled bool
|
||||
doneCalled bool
|
||||
)
|
||||
|
||||
func TestChrome(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Chrome Suite")
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Requires the len & num GET parameters, e.g. /uploadtest?len=100&num=1
|
||||
http.HandleFunc("/uploadtest", func(w http.ResponseWriter, r *http.Request) {
|
||||
defer GinkgoRecover()
|
||||
response := uploadHTML
|
||||
response = strings.Replace(response, "LENGTH", r.URL.Query().Get("len"), -1)
|
||||
response = strings.Replace(response, "NUM", r.URL.Query().Get("num"), -1)
|
||||
_, err := io.WriteString(w, response)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
testEndpointCalled = true
|
||||
})
|
||||
|
||||
// Requires the len & num GET parameters, e.g. /downloadtest?len=100&num=1
|
||||
http.HandleFunc("/downloadtest", func(w http.ResponseWriter, r *http.Request) {
|
||||
defer GinkgoRecover()
|
||||
response := downloadHTML
|
||||
response = strings.Replace(response, "LENGTH", r.URL.Query().Get("len"), -1)
|
||||
response = strings.Replace(response, "NUM", r.URL.Query().Get("num"), -1)
|
||||
_, err := io.WriteString(w, response)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
testEndpointCalled = true
|
||||
})
|
||||
|
||||
http.HandleFunc("/uploadhandler", func(w http.ResponseWriter, r *http.Request) {
|
||||
defer GinkgoRecover()
|
||||
|
||||
l, err := strconv.Atoi(r.URL.Query().Get("len"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
defer r.Body.Close()
|
||||
actual, err := ioutil.ReadAll(r.Body)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(bytes.Equal(actual, testserver.GeneratePRData(l))).To(BeTrue())
|
||||
|
||||
atomic.AddInt32(&nFilesUploaded, 1)
|
||||
})
|
||||
|
||||
http.HandleFunc("/done", func(w http.ResponseWriter, r *http.Request) {
|
||||
doneCalled = true
|
||||
})
|
||||
}
|
||||
|
||||
var _ = JustBeforeEach(testserver.StartQuicServer)
|
||||
|
||||
var _ = AfterEach(func() {
|
||||
testserver.StopQuicServer()
|
||||
|
||||
nFilesUploaded = 0
|
||||
doneCalled = false
|
||||
testEndpointCalled = false
|
||||
})
|
||||
|
||||
func getChromePath() string {
|
||||
if runtime.GOOS == "darwin" {
|
||||
return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
}
|
||||
return "google-chrome"
|
||||
}
|
||||
|
||||
func chromeTest(version protocol.VersionNumber, url string, blockUntilDone func()) {
|
||||
// Chrome sometimes starts but doesn't send any HTTP requests for no apparent reason.
|
||||
// Retry starting it a couple of times.
|
||||
for i := 0; i < nChromeRetries; i++ {
|
||||
if chromeTestImpl(version, url, blockUntilDone) {
|
||||
return
|
||||
}
|
||||
}
|
||||
Fail("Chrome didn't hit the testing endpoints")
|
||||
}
|
||||
|
||||
func chromeTestImpl(version protocol.VersionNumber, url string, blockUntilDone func()) bool {
|
||||
userDataDir, err := ioutil.TempDir("", "quic-go-test-chrome-dir")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer os.RemoveAll(userDataDir)
|
||||
path := getChromePath()
|
||||
args := []string{
|
||||
"--disable-gpu",
|
||||
"--no-first-run=true",
|
||||
"--no-default-browser-check=true",
|
||||
"--user-data-dir=" + userDataDir,
|
||||
"--enable-quic=true",
|
||||
"--no-proxy-server=true",
|
||||
"--origin-to-force-quic-on=quic.clemente.io:443",
|
||||
fmt.Sprintf(`--host-resolver-rules=MAP quic.clemente.io:443 localhost:%s`, testserver.Port()),
|
||||
fmt.Sprintf("--quic-version=QUIC_VERSION_%d", version),
|
||||
url,
|
||||
}
|
||||
utils.Infof("Running chrome: %s '%s'", getChromePath(), strings.Join(args, "' '"))
|
||||
command := exec.Command(path, args...)
|
||||
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer session.Kill()
|
||||
const pollInterval = 100 * time.Millisecond
|
||||
const pollDuration = 10 * time.Second
|
||||
for i := 0; i < int(pollDuration/pollInterval); i++ {
|
||||
time.Sleep(pollInterval)
|
||||
if testEndpointCalled {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !testEndpointCalled {
|
||||
return false
|
||||
}
|
||||
blockUntilDone()
|
||||
return true
|
||||
}
|
||||
|
||||
func waitForDone() {
|
||||
Eventually(func() bool { return doneCalled }, 60).Should(BeTrue())
|
||||
}
|
||||
|
||||
func waitForNUploaded(expected int) func() {
|
||||
return func() {
|
||||
Eventually(func() int32 {
|
||||
return atomic.LoadInt32(&nFilesUploaded)
|
||||
}, 60).Should(BeEquivalentTo(expected))
|
||||
}
|
||||
}
|
||||
|
||||
const commonJS = `
|
||||
var buf = new ArrayBuffer(LENGTH);
|
||||
var prng = new Uint8Array(buf);
|
||||
var seed = 1;
|
||||
for (var i = 0; i < LENGTH; i++) {
|
||||
// https://en.wikipedia.org/wiki/Lehmer_random_number_generator
|
||||
seed = seed * 48271 % 2147483647;
|
||||
prng[i] = seed;
|
||||
}
|
||||
`
|
||||
|
||||
const uploadHTML = `
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
console.log("Running DL test...");
|
||||
|
||||
` + commonJS + `
|
||||
for (var i = 0; i < NUM; i++) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("POST", "/uploadhandler?len=" + LENGTH, true);
|
||||
req.send(buf);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
const downloadHTML = `
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
console.log("Running DL test...");
|
||||
` + commonJS + `
|
||||
|
||||
function verify(data) {
|
||||
if (data.length !== LENGTH) return false;
|
||||
for (var i = 0; i < LENGTH; i++) {
|
||||
if (data[i] !== prng[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var nOK = 0;
|
||||
for (var i = 0; i < NUM; i++) {
|
||||
let req = new XMLHttpRequest();
|
||||
req.responseType = "arraybuffer";
|
||||
req.open("POST", "/prdata?len=" + LENGTH, true);
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState === XMLHttpRequest.DONE && req.status === 200) {
|
||||
if (verify(new Uint8Array(req.response))) {
|
||||
nOK++;
|
||||
if (nOK === NUM) {
|
||||
console.log("Done :)");
|
||||
var reqDone = new XMLHttpRequest();
|
||||
reqDone.open("GET", "/done");
|
||||
reqDone.send();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
req.send();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
Reference in New Issue
Block a user