add a set of integration tests with 10ms simulated RTT

This commit is contained in:
Lucas Clemente
2016-07-13 13:34:48 +02:00
parent 8413c00b48
commit 6449afe605
4 changed files with 86 additions and 19 deletions

View File

@@ -30,7 +30,7 @@ func runDropTest(incomingPacketDropper, outgoingPacketDropper dropCallback, vers
iPort, _ := strconv.Atoi(port)
var err error
proxy, err = NewUDPProxy(proxyPort, "localhost", iPort, incomingPacketDropper, outgoingPacketDropper)
proxy, err = NewUDPProxy(proxyPort, "localhost", iPort, incomingPacketDropper, outgoingPacketDropper, 0)
Expect(err).ToNot(HaveOccurred())
command := exec.Command(

View File

@@ -0,0 +1,66 @@
package integrationtests
import (
"bytes"
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"time"
_ "github.com/lucas-clemente/quic-clients" // download clients
"github.com/lucas-clemente/quic-go/protocol"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)
var _ = Describe("RTT", func() {
var rttProxy *UDPProxy
runRTTTest := func(rtt time.Duration, version protocol.VersionNumber) {
proxyPort := 12345
clientPath := fmt.Sprintf(
"%s/src/github.com/lucas-clemente/quic-clients/client-%s-debug",
os.Getenv("GOPATH"),
runtime.GOOS,
)
iPort, _ := strconv.Atoi(port)
var err error
rttProxy, err = NewUDPProxy(proxyPort, "localhost", iPort, nil, nil, rtt)
Expect(err).ToNot(HaveOccurred())
command := exec.Command(
clientPath,
"--quic-version="+strconv.Itoa(int(version)),
"--host=127.0.0.1",
"--port="+strconv.Itoa(proxyPort),
"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(), data)).To(BeTrue())
}
AfterEach(func() {
rttProxy.Stop()
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 with 10ms RTT", func() {
runRTTTest(10*time.Millisecond, version)
})
})
}
})

View File

@@ -4,6 +4,7 @@ import (
"net"
"strconv"
"sync"
"time"
)
// Connection is a UDP connection
@@ -26,13 +27,14 @@ type UDPProxy struct {
proxyConn *net.UDPConn
dropIncomingPacket dropCallback
dropOutgoingPacket dropCallback
rtt time.Duration
// Mapping from client addresses (as host:port) to connection
clientDict map[string]*connection
}
// NewUDPProxy creates a new UDP proxy
func NewUDPProxy(proxyPort int, serverAddress string, serverPort int, dropIncomingPacket, dropOutgoingPacket dropCallback) (*UDPProxy, error) {
func NewUDPProxy(proxyPort int, serverAddress string, serverPort int, dropIncomingPacket, dropOutgoingPacket dropCallback, rtt time.Duration) (*UDPProxy, error) {
dontDrop := func(p PacketNumber) bool {
return false
}
@@ -48,6 +50,7 @@ func NewUDPProxy(proxyPort int, serverAddress string, serverPort int, dropIncomi
clientDict: make(map[string]*connection),
dropIncomingPacket: dropIncomingPacket,
dropOutgoingPacket: dropOutgoingPacket,
rtt: rtt,
}
saddr, err := net.ResolveUDPAddr("udp", ":"+strconv.Itoa(proxyPort))
@@ -89,9 +92,8 @@ func (p *UDPProxy) newConnection(cliAddr *net.UDPAddr) (*connection, error) {
// runProxy handles inputs to Proxy port
func (p *UDPProxy) runProxy() error {
buffer := make([]byte, 1500)
for {
buffer := make([]byte, 1500)
n, cliaddr, err := p.proxyConn.ReadFromUDP(buffer[0:])
if err != nil {
return err
@@ -119,19 +121,18 @@ func (p *UDPProxy) runProxy() error {
if !p.dropIncomingPacket(conn.incomingPacketCounter) {
// Relay to server
_, err = conn.ServerConn.Write(buffer[0:n])
if err != nil {
return err
}
go func() {
time.Sleep(p.rtt / 2)
conn.ServerConn.Write(buffer[0:n])
}()
}
}
}
// runConnection handles packets from server to a single client
func (p *UDPProxy) runConnection(conn *connection) error {
buffer := make([]byte, 1500)
for {
buffer := make([]byte, 1500)
n, err := conn.ServerConn.Read(buffer[0:])
if err != nil {
return err
@@ -141,10 +142,10 @@ func (p *UDPProxy) runConnection(conn *connection) error {
if !p.dropOutgoingPacket(conn.outgoingPacketCounter) {
// Relay it to client
_, err = p.proxyConn.WriteToUDP(buffer[0:n], conn.ClientAddr)
if err != nil {
return err
}
go func() {
time.Sleep(p.rtt / 2)
p.proxyConn.WriteToUDP(buffer[0:n], conn.ClientAddr)
}()
}
}
}

View File

@@ -19,7 +19,7 @@ var _ = Describe("Integrationtests", func() {
})
It("sets up the UDPProxy", func() {
proxy, err := NewUDPProxy(13370, "localhost", serverPort, nil, nil)
proxy, err := NewUDPProxy(13370, "localhost", serverPort, nil, nil, 0)
Expect(err).ToNot(HaveOccurred())
Expect(proxy.clientDict).To(HaveLen(0))
@@ -34,7 +34,7 @@ var _ = Describe("Integrationtests", func() {
})
It("stops the UDPProxy", func() {
proxy, err := NewUDPProxy(13371, "localhost", serverPort, nil, nil)
proxy, err := NewUDPProxy(13371, "localhost", serverPort, nil, nil, 0)
Expect(err).ToNot(HaveOccurred())
proxy.Stop()
@@ -102,7 +102,7 @@ var _ = Describe("Integrationtests", func() {
BeforeEach(func() {
// setup the proxy
var err error
proxy, err = NewUDPProxy(10001, "localhost", serverPort, nil, nil)
proxy, err = NewUDPProxy(10001, "localhost", serverPort, nil, nil, 0)
Expect(err).ToNot(HaveOccurred())
})
@@ -175,7 +175,7 @@ var _ = Describe("Integrationtests", func() {
}
var err error
proxy, err = NewUDPProxy(10001, "localhost", serverPort, dropper, nil)
proxy, err = NewUDPProxy(10001, "localhost", serverPort, dropper, nil, 0)
Expect(err).ToNot(HaveOccurred())
for i := 1; i <= 6; i++ {
@@ -195,7 +195,7 @@ var _ = Describe("Integrationtests", func() {
}
var err error
proxy, err = NewUDPProxy(10001, "localhost", serverPort, nil, dropper)
proxy, err = NewUDPProxy(10001, "localhost", serverPort, nil, dropper, 0)
Expect(err).ToNot(HaveOccurred())
for i := 1; i <= 6; i++ {