From 0c26a6eaf26382c740bdf318a7e5bb93c27a1c92 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 11 Sep 2017 12:21:55 +0200 Subject: [PATCH] add an integration test for dropped packets during the handshake --- integrationtests/gquic/drop_test.go | 94 +++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/integrationtests/gquic/drop_test.go b/integrationtests/gquic/drop_test.go index 533edccc..cffa3fb4 100644 --- a/integrationtests/gquic/drop_test.go +++ b/integrationtests/gquic/drop_test.go @@ -14,6 +14,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gbytes" . "github.com/onsi/gomega/gexec" ) @@ -22,14 +23,16 @@ var directions = []quicproxy.Direction{quicproxy.DirectionIncoming, quicproxy.Di var _ = Describe("Drop tests", func() { var proxy *quicproxy.QuicProxy - runDropTest := func(dropCallback quicproxy.DropCallback, version protocol.VersionNumber) { + startProxy := func(dropCallback quicproxy.DropCallback, version protocol.VersionNumber) { var err error proxy, err = quicproxy.NewQuicProxy("localhost:0", version, &quicproxy.Opts{ RemoteAddr: "localhost:" + testserver.Port(), DropPacket: dropCallback, }) Expect(err).ToNot(HaveOccurred()) + } + downloadFile := func(version protocol.VersionNumber) { command := exec.Command( clientPath, "--quic-version="+strconv.Itoa(int(version)), @@ -37,7 +40,6 @@ var _ = Describe("Drop tests", func() { "--port="+strconv.Itoa(proxy.LocalPort()), "https://quic.clemente.io/prdata", ) - session, err := Start(command, nil, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) defer session.Kill() @@ -45,51 +47,91 @@ var _ = Describe("Drop tests", func() { Expect(bytes.Contains(session.Out.Contents(), testserver.PRData)).To(BeTrue()) } + downloadHello := func(version protocol.VersionNumber) { + command := exec.Command( + clientPath, + "--quic-version="+strconv.Itoa(int(version)), + "--host=127.0.0.1", + "--port="+strconv.Itoa(proxy.LocalPort()), + "https://quic.clemente.io/hello", + ) + session, err := Start(command, nil, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + defer session.Kill() + Eventually(session, 20).Should(Exit(0)) + Expect(session.Out).To(Say(":status 200")) + Expect(session.Out).To(Say("body: Hello, World!\n")) + } + + deterministicDropper := func(p, interval, dropInARow uint64) bool { + return (p % interval) < dropInARow + } + + stochasticDropper := func(freq int) bool { + return mrand.Int63n(int64(freq)) == 0 + } + AfterEach(func() { Expect(proxy.Close()).To(Succeed()) }) - Context("after the crypto handshake", func() { - deterministicDropper := func(p, interval, dropInARow uint64) bool { - if p <= 10 { // don't interfere with the crypto handshake - return false - } - return (p % interval) < dropInARow - } + for _, v := range protocol.SupportedVersions { + version := v - stochasticDropper := func(p protocol.PacketNumber, freq int) bool { - if p <= 10 { // don't interfere with the crypto handshake - return false - } - return mrand.Int63n(int64(freq)) == 0 - } + Context(fmt.Sprintf("with QUIC version %d", version), func() { + Context("during the crypto handshake", func() { + for _, d := range directions { + direction := d - for _, v := range protocol.SupportedVersions { - version := v + It(fmt.Sprintf("establishes a connection when the first packet is lost in %s direction", d), func() { + startProxy(func(d quicproxy.Direction, p uint64) bool { + return p == 1 && d.Is(direction) + }, version) + downloadHello(version) + }) - Context(fmt.Sprintf("with QUIC version %d", version), func() { + It(fmt.Sprintf("establishes a connection when the second packet is lost in %s direction", d), func() { + startProxy(func(d quicproxy.Direction, p uint64) bool { + return p == 2 && d.Is(direction) + }, version) + downloadHello(version) + }) + + It(fmt.Sprintf("establishes a connection when 1/5 of the packets are lost in %s direction", d), func() { + startProxy(func(d quicproxy.Direction, p uint64) bool { + return d.Is(direction) && stochasticDropper(5) + }, version) + downloadHello(version) + }) + } + }) + + Context("after the crypto handshake", func() { for _, d := range directions { direction := d It(fmt.Sprintf("downloads a file when every 5th packet is dropped in %s direction", d), func() { - runDropTest(func(d quicproxy.Direction, p uint64) bool { - return d.Is(direction) && deterministicDropper(p, 5, 1) + startProxy(func(d quicproxy.Direction, p uint64) bool { + return p >= 10 && d.Is(direction) && deterministicDropper(p, 5, 1) }, version) + downloadFile(version) }) It(fmt.Sprintf("downloads a file when 1/5th of all packet are dropped randomly in %s direction", d), func() { - runDropTest(func(d quicproxy.Direction, p protocol.PacketNumber) bool { - return d.Is(direction) && stochasticDropper(p, 5) + startProxy(func(d quicproxy.Direction, p uint64) bool { + return p >= 10 && d.Is(direction) && stochasticDropper(5) }, version) + downloadFile(version) }) It(fmt.Sprintf("downloads a file when 10 packets every 100 packet are dropped in %s direction", d), func() { - runDropTest(func(d quicproxy.Direction, p uint64) bool { - return d.Is(direction) && deterministicDropper(p, 100, 10) + startProxy(func(d quicproxy.Direction, p uint64) bool { + return p >= 10 && d.Is(direction) && deterministicDropper(p, 100, 10) }, version) + downloadFile(version) }) } }) - } - }) + }) + } })