github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/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/apernet/quic-go"
    13  	"github.com/apernet/quic-go/internal/protocol"
    14  	"github.com/apernet/quic-go/internal/utils"
    15  	"github.com/apernet/quic-go/logging"
    16  	"github.com/apernet/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  })