MCPcopy
hub / github.com/jackc/pgx / TestConnectContextCancelHandlerRace

Function TestConnectContextCancelHandlerRace

pgconn/pgconn_test.go:4896–4948  ·  view source on GitHub ↗

TestConnectContextCancelHandlerRace reproduces the data race that occurred when the application-supplied BuildContextWatcherHandler was armed during the connect handshake. If the context was cancelled while connectOne was still running, a handler that reads *PgConn fields (such as CancelRequestConte

(t *testing.T)

Source from the content-addressed store, hash-verified

4894//
4895// Race originally reported in https://github.com/jackc/pgx/pull/2534.
4896func TestConnectContextCancelHandlerRace(t *testing.T) {
4897 t.Parallel()
4898
4899 for i := range 10 {
4900 t.Run(fmt.Sprintf("Stress %d", i), func(t *testing.T) {
4901 t.Parallel()
4902
4903 script := &pgmock.Script{
4904 Steps: []pgmock.Step{
4905 pgmock.ExpectAnyMessage(&pgproto3.StartupMessage{ProtocolVersion: pgproto3.ProtocolVersion30, Parameters: map[string]string{}}),
4906 pgmock.SendMessage(&pgproto3.AuthenticationOk{}),
4907 pgmock.SendMessage(&pgproto3.BackendKeyData{ProcessID: 12345, SecretKey: []byte{1, 2, 3, 4}}),
4908 pgmockWaitStep(200 * time.Millisecond),
4909 pgmock.SendMessage(&pgproto3.ReadyForQuery{TxStatus: 'I'}),
4910 },
4911 }
4912
4913 ln, err := net.Listen("tcp", "127.0.0.1:")
4914 require.NoError(t, err)
4915 defer ln.Close()
4916
4917 go func() {
4918 conn, err := ln.Accept()
4919 if err != nil {
4920 return
4921 }
4922 defer conn.Close()
4923 _ = conn.SetDeadline(time.Now().Add(5 * time.Second))
4924 _ = script.Run(pgproto3.NewBackend(conn, conn))
4925 }()
4926
4927 host, port, _ := strings.Cut(ln.Addr().String(), ":")
4928 connStr := fmt.Sprintf("sslmode=disable host=%s port=%s user=test database=test", host, port)
4929 config, err := pgconn.ParseConfig(connStr)
4930 require.NoError(t, err)
4931 config.BuildContextWatcherHandler = func(conn *pgconn.PgConn) ctxwatch.Handler {
4932 return &raceProbeHandler{conn: conn}
4933 }
4934 config.ConnectTimeout = 5 * time.Second
4935
4936 ctx, cancel := context.WithCancel(context.Background())
4937 // Cancel during the 200ms wait between BackendKeyData and ReadyForQuery,
4938 // after the auth loop has written pid/secretKey.
4939 time.AfterFunc(50*time.Millisecond, cancel)
4940 defer cancel()
4941
4942 pgConn, err := pgconn.ConnectConfig(ctx, config)
4943 if err == nil {
4944 closeConn(t, pgConn)
4945 }
4946 })
4947 }
4948}
4949
4950func TestConnectProtocolVersion32(t *testing.T) {
4951 t.Parallel()

Callers

nothing calls this directly

Calls 12

RunMethod · 0.95
ExpectAnyMessageFunction · 0.92
SendMessageFunction · 0.92
NewBackendFunction · 0.92
ParseConfigFunction · 0.92
ConnectConfigFunction · 0.92
pgmockWaitStepTypeAlias · 0.85
closeConnFunction · 0.70
CloseMethod · 0.65
RunMethod · 0.45
SetDeadlineMethod · 0.45
StringMethod · 0.45

Tested by

no test coverage detected