MCPcopy Index your code
hub / github.com/coder/coder / TestHeartbeatClose

Function TestHeartbeatClose

coderd/httpapi/websocket_internal_test.go:56–185  ·  view source on GitHub ↗
(t *testing.T)

Source from the content-addressed store, hash-verified

54}
55
56func TestHeartbeatClose(t *testing.T) {
57 t.Parallel()
58
59 t.Run("ServerSideClose", func(t *testing.T) {
60 t.Parallel()
61 ctx := testutil.Context(t, testutil.WaitShort)
62
63 sink := testutil.NewFakeSink(t)
64 logger := sink.Logger()
65 mClock := quartz.NewMock(t)
66
67 // Trap ticker creation so we can synchronize startup.
68 trap := mClock.Trap().NewTicker("HeartbeatClose")
69 defer trap.Close()
70
71 serverConn := websocketPair(ctx, t)
72 exitCalled := make(chan struct{})
73
74 go heartbeatCloseWith(ctx, logger, func() {
75 close(exitCalled)
76 }, serverConn, mClock, time.Second)
77
78 // Wait for the ticker to be created, then release.
79 trap.MustWait(ctx).MustRelease(ctx)
80
81 // Close the server-side connection before the tick fires.
82 // The next ping will get net.ErrClosed.
83 _ = serverConn.Close(websocket.StatusGoingAway, "simulated teardown")
84
85 // Advance clock to trigger the tick.
86 mClock.Advance(time.Second).MustWait(ctx)
87
88 // Wait for heartbeatClose to call exit.
89 select {
90 case <-exitCalled:
91 case <-ctx.Done():
92 t.Fatal("timed out waiting for heartbeatClose to call exit")
93 }
94
95 // A closed connection is a normal shutdown condition. The
96 // error should be logged at Debug, not Error.
97 errorEntries := sink.Entries(func(e slog.SinkEntry) bool { return e.Level == slog.LevelError })
98 assert.Empty(t, errorEntries,
99 "closed connection should not produce error-level logs, got: %+v", errorEntries)
100 debugEntries := sink.Entries(func(e slog.SinkEntry) bool { return e.Level == slog.LevelDebug })
101 assert.NotEmpty(t, debugEntries,
102 "expected a debug-level log entry for the closed connection")
103 })
104
105 t.Run("ContextCanceled", func(t *testing.T) {
106 t.Parallel()
107 ctx := testutil.Context(t, testutil.WaitShort)
108
109 sink := testutil.NewFakeSink(t)
110 logger := sink.Logger()
111 mClock := quartz.NewMock(t)
112
113 trap := mClock.Trap().NewTicker("HeartbeatClose")

Callers

nothing calls this directly

Calls 13

LoggerMethod · 0.95
EntriesMethod · 0.95
ContextFunction · 0.92
NewFakeSinkFunction · 0.92
websocketPairFunction · 0.85
heartbeatCloseWithFunction · 0.85
FatalMethod · 0.80
NotEmptyMethod · 0.80
RunMethod · 0.65
CloseMethod · 0.65
DoneMethod · 0.45
EmptyMethod · 0.45

Tested by

no test coverage detected