TestSubscribeRelayMultipleReconnects verifies that the reconnect loop handles multiple consecutive relay drops, proving it is robust across repeated iterations — not just the single reconnect already covered by TestSubscribeRelayReconnectsOnDrop.
(t *testing.T)
| 1170 | // robust across repeated iterations — not just the single reconnect |
| 1171 | // already covered by TestSubscribeRelayReconnectsOnDrop. |
| 1172 | func TestSubscribeRelayMultipleReconnects(t *testing.T) { |
| 1173 | t.Parallel() |
| 1174 | |
| 1175 | db, ps := dbtestutil.NewDB(t) |
| 1176 | workerID := uuid.New() |
| 1177 | subscriberID := uuid.New() |
| 1178 | |
| 1179 | var callCount atomic.Int32 |
| 1180 | |
| 1181 | provider := func(_ context.Context, _ uuid.UUID, _ uuid.UUID, _ http.Header) ( |
| 1182 | []codersdk.ChatStreamEvent, <-chan codersdk.ChatStreamEvent, func(), error, |
| 1183 | ) { |
| 1184 | call := callCount.Add(1) |
| 1185 | ch := make(chan codersdk.ChatStreamEvent, 10) |
| 1186 | part := codersdk.ChatStreamEvent{ |
| 1187 | Type: codersdk.ChatStreamEventTypeMessagePart, |
| 1188 | MessagePart: &codersdk.ChatStreamMessagePart{ |
| 1189 | Role: "assistant", |
| 1190 | Part: codersdk.ChatMessagePart{ |
| 1191 | Type: codersdk.ChatMessagePartTypeText, |
| 1192 | Text: fmt.Sprintf("relay-%d", call), |
| 1193 | }, |
| 1194 | }, |
| 1195 | } |
| 1196 | ch <- part |
| 1197 | if call <= 2 { |
| 1198 | // First two dials: close channel to simulate relay |
| 1199 | // drop. This triggers scheduleRelayReconnect. |
| 1200 | close(ch) |
| 1201 | } |
| 1202 | // Third dial: keep channel open. |
| 1203 | return nil, ch, func() {}, nil |
| 1204 | } |
| 1205 | |
| 1206 | mclk := quartz.NewMock(t) |
| 1207 | // Trap the reconnect timer so we can fire both reconnects |
| 1208 | // deterministically. |
| 1209 | trapReconnect := mclk.Trap().NewTimer("reconnect") |
| 1210 | defer trapReconnect.Close() |
| 1211 | |
| 1212 | subscriber := newTestServer(t, db, ps, subscriberID, provider, mclk) |
| 1213 | |
| 1214 | ctx := testutil.Context(t, testutil.WaitLong) |
| 1215 | user, org, model := seedChatDependencies(t, db) |
| 1216 | |
| 1217 | chat := seedRemoteRunningChat( |
| 1218 | ctx, |
| 1219 | t, |
| 1220 | db, |
| 1221 | org.ID, |
| 1222 | user, |
| 1223 | model, |
| 1224 | workerID, |
| 1225 | "multiple-reconnects", |
| 1226 | ) |
| 1227 | |
| 1228 | _, events, cancel, ok := subscriber.Subscribe(ctx, chat.ID, nil, 0) |
| 1229 | require.True(t, ok) |
nothing calls this directly
no test coverage detected