TestPromoteQueuedFallsThroughOnStaleHeartbeat asserts a stale heartbeat takes the synchronous path so the chat does not strand in Waiting waiting on a worker that will not return.
(t *testing.T)
| 10970 | // heartbeat takes the synchronous path so the chat does not strand |
| 10971 | // in Waiting waiting on a worker that will not return. |
| 10972 | func TestPromoteQueuedFallsThroughOnStaleHeartbeat(t *testing.T) { |
| 10973 | t.Parallel() |
| 10974 | |
| 10975 | db, ps := dbtestutil.NewDB(t) |
| 10976 | ctx := testutil.Context(t, testutil.WaitLong) |
| 10977 | |
| 10978 | staleAfter := 100 * time.Millisecond |
| 10979 | logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}) |
| 10980 | server := chatd.New(chatd.Config{ |
| 10981 | Logger: logger, |
| 10982 | Database: db, |
| 10983 | ReplicaID: uuid.New(), |
| 10984 | Pubsub: ps, |
| 10985 | PendingChatAcquireInterval: testutil.WaitLong, |
| 10986 | InFlightChatStaleAfter: staleAfter, |
| 10987 | }) |
| 10988 | t.Cleanup(func() { require.NoError(t, server.Close()) }) |
| 10989 | |
| 10990 | user, org, model := seedChatDependencies(t, db) |
| 10991 | |
| 10992 | chat, err := db.InsertChat(ctx, database.InsertChatParams{ |
| 10993 | OrganizationID: org.ID, |
| 10994 | Status: database.ChatStatusWaiting, |
| 10995 | ClientType: database.ChatClientTypeUi, |
| 10996 | OwnerID: user.ID, |
| 10997 | Title: "stale-heartbeat-promote-fallthrough", |
| 10998 | LastModelConfigID: model.ID, |
| 10999 | }) |
| 11000 | require.NoError(t, err) |
| 11001 | |
| 11002 | // Place the chat in Running with a stale heartbeat. We do not |
| 11003 | // start the server's run loop, so no worker will ever pick this |
| 11004 | // chat up; the test isolates the fall-through decision in |
| 11005 | // PromoteQueued. |
| 11006 | deadWorker := uuid.New() |
| 11007 | staleTime := time.Now().Add(-2 * staleAfter) |
| 11008 | _, err = db.UpdateChatStatus(ctx, database.UpdateChatStatusParams{ |
| 11009 | ID: chat.ID, |
| 11010 | Status: database.ChatStatusRunning, |
| 11011 | WorkerID: uuid.NullUUID{UUID: deadWorker, Valid: true}, |
| 11012 | StartedAt: sql.NullTime{Time: staleTime, Valid: true}, |
| 11013 | HeartbeatAt: sql.NullTime{Time: staleTime, Valid: true}, |
| 11014 | }) |
| 11015 | require.NoError(t, err) |
| 11016 | |
| 11017 | queued, err := server.SendMessage(ctx, chatd.SendMessageOptions{ |
| 11018 | ChatID: chat.ID, |
| 11019 | Content: []codersdk.ChatMessagePart{codersdk.ChatMessageText("promote me")}, |
| 11020 | BusyBehavior: chatd.SendMessageBusyBehaviorQueue, |
| 11021 | }) |
| 11022 | require.NoError(t, err) |
| 11023 | require.True(t, queued.Queued) |
| 11024 | require.NotNil(t, queued.QueuedMessage) |
| 11025 | |
| 11026 | result, err := server.PromoteQueued(ctx, chatd.PromoteQueuedOptions{ |
| 11027 | ChatID: chat.ID, |
| 11028 | QueuedMessageID: queued.QueuedMessage.ID, |
| 11029 | CreatedBy: user.ID, |
nothing calls this directly
no test coverage detected