MCPcopy
hub / github.com/redis/go-redis / TestInitConnNilMaintNotificationsConfig

Function TestInitConnNilMaintNotificationsConfig

internal_maint_notif_test.go:26–101  ·  view source on GitHub ↗

TestInitConnNilMaintNotificationsConfig is a regression test for https://github.com/redis/go-redis/issues/3675 initConn previously accessed MaintNotificationsConfig.EndpointType unconditionally, even though the preceding line correctly nil-checked MaintNotificationsConfig. This caused a nil pointer

(t *testing.T)

Source from the content-addressed store, hash-verified

24// MaintNotificationsConfig. This caused a nil pointer dereference panic
25// and left optLock.RLock held, leading to a subsequent deadlock.
26func TestInitConnNilMaintNotificationsConfig(t *testing.T) {
27 // Start a minimal TCP server that speaks enough RESP to let
28 // initConn get past the HELLO / AUTH / pipeline phases and reach
29 // the MaintNotificationsConfig code path.
30 ln, err := net.Listen("tcp", "127.0.0.1:0")
31 if err != nil {
32 t.Fatalf("failed to listen: %v", err)
33 }
34 defer ln.Close()
35
36 // mockRedis responds to every RESP command with a Redis-protocol
37 // error. This lets initConn fall through HELLO (Redis errors are
38 // not fatal when there is no password) and the empty pipeline
39 // succeeds trivially.
40 go func() {
41 for {
42 conn, err := ln.Accept()
43 if err != nil {
44 return
45 }
46 go func(c net.Conn) {
47 defer c.Close()
48 scanner := bufio.NewScanner(c)
49 for scanner.Scan() {
50 line := scanner.Text()
51 if strings.HasPrefix(line, "*") {
52 _, _ = c.Write([]byte("-ERR unknown command\r\n"))
53 }
54 }
55 }(conn)
56 }
57 }()
58
59 opt := &Options{
60 Addr: ln.Addr().String(),
61 }
62 opt.init()
63
64 // Force MaintNotificationsConfig to nil after init() to reproduce
65 // the scenario from issue #3675.
66 opt.MaintNotificationsConfig = nil
67
68 c := &baseClient{
69 opt: opt,
70 }
71 c.initHooks(hooks{
72 dial: c.dial,
73 process: c.process,
74 pipeline: c.processPipeline,
75 txPipeline: c.processTxPipeline,
76 })
77
78 // Dial a real connection to the mock server.
79 netConn, err := net.DialTimeout("tcp", ln.Addr().String(), 2*time.Second)
80 if err != nil {
81 t.Fatalf("failed to dial mock server: %v", err)
82 }
83 defer netConn.Close()

Callers

nothing calls this directly

Calls 13

CloseMethod · 0.95
initMethod · 0.95
GetStateMachineMethod · 0.95
initConnMethod · 0.95
NewConnFunction · 0.92
TextMethod · 0.80
initHooksMethod · 0.80
TransitionMethod · 0.80
CloseMethod · 0.65
ScanMethod · 0.65
StringMethod · 0.65
WriteMethod · 0.45

Tested by

no test coverage detected