github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/integrationtests/self/rtt_test.go (about)

     1  package self_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"net"
     8  	"time"
     9  
    10  	"github.com/apernet/quic-go"
    11  	quicproxy "github.com/apernet/quic-go/integrationtests/tools/proxy"
    12  
    13  	. "github.com/onsi/ginkgo/v2"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("non-zero RTT", func() {
    18  	runServer := func() *quic.Listener {
    19  		ln, err := quic.ListenAddr(
    20  			"localhost:0",
    21  			getTLSConfig(),
    22  			getQuicConfig(nil),
    23  		)
    24  		Expect(err).ToNot(HaveOccurred())
    25  		go func() {
    26  			defer GinkgoRecover()
    27  			conn, err := ln.Accept(context.Background())
    28  			Expect(err).ToNot(HaveOccurred())
    29  			str, err := conn.OpenStream()
    30  			Expect(err).ToNot(HaveOccurred())
    31  			_, err = str.Write(PRData)
    32  			Expect(err).ToNot(HaveOccurred())
    33  			str.Close()
    34  		}()
    35  		return ln
    36  	}
    37  
    38  	downloadFile := func(port int) {
    39  		conn, err := quic.DialAddr(
    40  			context.Background(),
    41  			fmt.Sprintf("localhost:%d", port),
    42  			getTLSClientConfig(),
    43  			getQuicConfig(nil),
    44  		)
    45  		Expect(err).ToNot(HaveOccurred())
    46  		str, err := conn.AcceptStream(context.Background())
    47  		Expect(err).ToNot(HaveOccurred())
    48  		data, err := io.ReadAll(str)
    49  		Expect(err).ToNot(HaveOccurred())
    50  		Expect(data).To(Equal(PRData))
    51  		conn.CloseWithError(0, "")
    52  	}
    53  
    54  	for _, r := range [...]time.Duration{
    55  		10 * time.Millisecond,
    56  		50 * time.Millisecond,
    57  		100 * time.Millisecond,
    58  		200 * time.Millisecond,
    59  	} {
    60  		rtt := r
    61  
    62  		It(fmt.Sprintf("downloads a message with %s RTT", rtt), func() {
    63  			ln := runServer()
    64  			defer ln.Close()
    65  			serverPort := ln.Addr().(*net.UDPAddr).Port
    66  			proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{
    67  				RemoteAddr: fmt.Sprintf("localhost:%d", serverPort),
    68  				DelayPacket: func(quicproxy.Direction, []byte) time.Duration {
    69  					return rtt / 2
    70  				},
    71  			})
    72  			Expect(err).ToNot(HaveOccurred())
    73  			defer proxy.Close()
    74  
    75  			conn, err := quic.DialAddr(
    76  				context.Background(),
    77  				fmt.Sprintf("localhost:%d", proxy.LocalPort()),
    78  				getTLSClientConfig(),
    79  				getQuicConfig(nil),
    80  			)
    81  			Expect(err).ToNot(HaveOccurred())
    82  			str, err := conn.AcceptStream(context.Background())
    83  			Expect(err).ToNot(HaveOccurred())
    84  			data, err := io.ReadAll(str)
    85  			Expect(err).ToNot(HaveOccurred())
    86  			Expect(data).To(Equal(PRData))
    87  			conn.CloseWithError(0, "")
    88  		})
    89  	}
    90  
    91  	for _, r := range [...]time.Duration{
    92  		10 * time.Millisecond,
    93  		40 * time.Millisecond,
    94  	} {
    95  		rtt := r
    96  
    97  		It(fmt.Sprintf("downloads a message with %s RTT, with reordering", rtt), func() {
    98  			ln := runServer()
    99  			defer ln.Close()
   100  			serverPort := ln.Addr().(*net.UDPAddr).Port
   101  			proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{
   102  				RemoteAddr: fmt.Sprintf("localhost:%d", serverPort),
   103  				DelayPacket: func(quicproxy.Direction, []byte) time.Duration {
   104  					return randomDuration(rtt/2, rtt*3/2) / 2
   105  				},
   106  			})
   107  			Expect(err).ToNot(HaveOccurred())
   108  			defer proxy.Close()
   109  
   110  			downloadFile(proxy.LocalPort())
   111  		})
   112  	}
   113  })