github.com/metacubex/quic-go@v0.44.1-0.20240520163451-20b689a59136/integrationtests/self/tracer_test.go (about) 1 package self_test 2 3 import ( 4 "bufio" 5 "bytes" 6 "context" 7 "fmt" 8 "io" 9 mrand "math/rand" 10 "net" 11 12 "github.com/metacubex/quic-go" 13 "github.com/metacubex/quic-go/internal/protocol" 14 "github.com/metacubex/quic-go/internal/utils" 15 "github.com/metacubex/quic-go/logging" 16 "github.com/metacubex/quic-go/qlog" 17 18 . "github.com/onsi/ginkgo/v2" 19 . "github.com/onsi/gomega" 20 ) 21 22 var _ = Describe("Tracer tests", func() { 23 addTracers := func(pers protocol.Perspective, conf *quic.Config) *quic.Config { 24 enableQlog := mrand.Int()%3 != 0 25 enableCustomTracer := mrand.Int()%3 != 0 26 27 fmt.Fprintf(GinkgoWriter, "%s using qlog: %t, custom: %t\n", pers, enableQlog, enableCustomTracer) 28 29 var tracerConstructors []func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer 30 if enableQlog { 31 tracerConstructors = append(tracerConstructors, func(_ context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer { 32 if mrand.Int()%2 == 0 { // simulate that a qlog collector might only want to log some connections 33 fmt.Fprintf(GinkgoWriter, "%s qlog tracer deciding to not trace connection %s\n", p, connID) 34 return nil 35 } 36 fmt.Fprintf(GinkgoWriter, "%s qlog tracing connection %s\n", p, connID) 37 return qlog.NewConnectionTracer(utils.NewBufferedWriteCloser(bufio.NewWriter(&bytes.Buffer{}), io.NopCloser(nil)), p, connID) 38 }) 39 } 40 if enableCustomTracer { 41 tracerConstructors = append(tracerConstructors, func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer { 42 return &logging.ConnectionTracer{} 43 }) 44 } 45 c := conf.Clone() 46 c.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer { 47 tracers := make([]*logging.ConnectionTracer, 0, len(tracerConstructors)) 48 for _, c := range tracerConstructors { 49 if tr := c(ctx, p, connID); tr != nil { 50 tracers = append(tracers, tr) 51 } 52 } 53 return logging.NewMultiplexedConnectionTracer(tracers...) 54 } 55 return c 56 } 57 58 for i := 0; i < 3; i++ { 59 It("handshakes with a random combination of tracers", func() { 60 if enableQlog { 61 Skip("This test sets tracers and won't produce any qlogs.") 62 } 63 quicClientConf := addTracers(protocol.PerspectiveClient, getQuicConfig(nil)) 64 quicServerConf := addTracers(protocol.PerspectiveServer, getQuicConfig(nil)) 65 66 serverChan := make(chan *quic.Listener) 67 go func() { 68 defer GinkgoRecover() 69 ln, err := quic.ListenAddr("localhost:0", getTLSConfig(), quicServerConf) 70 Expect(err).ToNot(HaveOccurred()) 71 serverChan <- ln 72 conn, err := ln.Accept(context.Background()) 73 Expect(err).ToNot(HaveOccurred()) 74 str, err := conn.OpenUniStream() 75 Expect(err).ToNot(HaveOccurred()) 76 _, err = str.Write(PRData) 77 Expect(err).ToNot(HaveOccurred()) 78 Expect(str.Close()).To(Succeed()) 79 }() 80 81 ln := <-serverChan 82 defer ln.Close() 83 84 conn, err := quic.DialAddr( 85 context.Background(), 86 fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port), 87 getTLSClientConfig(), 88 quicClientConf, 89 ) 90 Expect(err).ToNot(HaveOccurred()) 91 defer conn.CloseWithError(0, "") 92 str, err := conn.AcceptUniStream(context.Background()) 93 Expect(err).ToNot(HaveOccurred()) 94 data, err := io.ReadAll(str) 95 Expect(err).ToNot(HaveOccurred()) 96 Expect(data).To(Equal(PRData)) 97 }) 98 } 99 })