forked from quic-go/quic-go
The new QUIC proxy allows to listen on “:0”, which allows us to get rid of all “address already in use” errors. The constructor now takes an Opts struct, which makes configuring it easier.
102 lines
2.7 KiB
Go
102 lines
2.7 KiB
Go
package integrationtests
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"math/rand"
|
|
"os/exec"
|
|
"strconv"
|
|
"time"
|
|
|
|
_ "github.com/lucas-clemente/quic-clients" // download clients
|
|
"github.com/lucas-clemente/quic-go/integrationtests/proxy"
|
|
"github.com/lucas-clemente/quic-go/protocol"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
. "github.com/onsi/gomega/gexec"
|
|
)
|
|
|
|
// get a random duration between min and max
|
|
func getRandomDuration(min, max time.Duration) time.Duration {
|
|
return min + time.Duration(rand.Int63n(int64(max-min)))
|
|
}
|
|
|
|
var _ = Describe("Random Duration Generator", func() {
|
|
rand.Seed(time.Now().UnixNano())
|
|
It("gets a random RTT", func() {
|
|
var min time.Duration = time.Hour
|
|
var max time.Duration
|
|
|
|
var sum time.Duration
|
|
rep := 10000
|
|
for i := 0; i < rep; i++ {
|
|
val := getRandomDuration(100*time.Millisecond, 500*time.Millisecond)
|
|
sum += val
|
|
if val < min {
|
|
min = val
|
|
}
|
|
if val > max {
|
|
max = val
|
|
}
|
|
}
|
|
avg := sum / time.Duration(rep)
|
|
fmt.Println(avg)
|
|
Expect(avg).To(BeNumerically("~", 300*time.Millisecond, 5*time.Millisecond))
|
|
Expect(min).To(BeNumerically(">=", 100*time.Millisecond))
|
|
Expect(min).To(BeNumerically("<", 105*time.Millisecond))
|
|
Expect(max).To(BeNumerically(">", 495*time.Millisecond))
|
|
Expect(max).To(BeNumerically("<=", 500*time.Millisecond))
|
|
})
|
|
})
|
|
|
|
var _ = Describe("Random RTT", func() {
|
|
BeforeEach(func() {
|
|
dataMan.GenerateData(dataLen)
|
|
})
|
|
|
|
var proxy *quicproxy.QuicProxy
|
|
|
|
runRTTTest := func(minRtt, maxRtt time.Duration, version protocol.VersionNumber) {
|
|
rand.Seed(time.Now().UnixNano())
|
|
var err error
|
|
proxy, err = quicproxy.NewQuicProxy("localhost:", quicproxy.Opts{
|
|
RemoteAddr: "localhost:" + port,
|
|
DelayPacket: func(_ quicproxy.Direction, _ protocol.PacketNumber) time.Duration {
|
|
return getRandomDuration(minRtt, maxRtt)
|
|
},
|
|
})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
command := exec.Command(
|
|
clientPath,
|
|
"--quic-version="+strconv.Itoa(int(version)),
|
|
"--host=127.0.0.1",
|
|
"--port="+strconv.Itoa(proxy.LocalPort()),
|
|
"https://quic.clemente.io/data",
|
|
)
|
|
|
|
session, err := Start(command, nil, GinkgoWriter)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
defer session.Kill()
|
|
Eventually(session, 4).Should(Exit(0))
|
|
Expect(bytes.Contains(session.Out.Contents(), dataMan.GetData())).To(BeTrue())
|
|
}
|
|
|
|
AfterEach(func() {
|
|
err := proxy.Close()
|
|
Expect(err).ToNot(HaveOccurred())
|
|
time.Sleep(time.Millisecond)
|
|
})
|
|
|
|
for i := range protocol.SupportedVersions {
|
|
version := protocol.SupportedVersions[i]
|
|
|
|
Context(fmt.Sprintf("with quic version %d", version), func() {
|
|
It("gets a file a random RTT between 10ms and 30ms", func() {
|
|
runRTTTest(10*time.Millisecond, 30*time.Millisecond, version)
|
|
})
|
|
})
|
|
}
|
|
})
|