diff --git a/coderd/exp_chats_chatstate_test.go b/coderd/exp_chats_chatstate_test.go index 5b78886e4d..e89be9a9d2 100644 --- a/coderd/exp_chats_chatstate_test.go +++ b/coderd/exp_chats_chatstate_test.go @@ -22,6 +22,15 @@ import ( "github.com/coder/coder/v2/testutil" ) +// withChatWorkerDisabled turns off the chat daemon's background worker +// so every test in this file observes synchronous chatstate endpoint +// behavior deterministically. Without it the worker races the tests: +// it can finish a turn (running -> waiting), promote queued messages, +// or commit steps concurrently with the driveChatTo* fixtures. +func withChatWorkerDisabled(o *coderdtest.Options) { + o.ChatWorkerDisabled = true +} + // driveChatToWaiting transitions the chat from `running` (its initial // state per the RFC) to `waiting` by running chatstate.FinishTurn. // Tests use this when they need to exercise endpoint behavior that @@ -88,7 +97,7 @@ func TestPostChatsStartsRunning(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, api := newChatClientWithAPI(t) + client, api := newChatClientWithAPI(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -122,7 +131,7 @@ func TestArchiveChatStateTransitions(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, api := newChatClientWithAPI(t) + client, api := newChatClientWithAPI(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -146,7 +155,7 @@ func TestArchiveChatStateTransitions(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -172,9 +181,7 @@ func TestPostChatMessagesBusyInterrupt(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t, func(o *coderdtest.Options) { - o.ChatWorkerDisabled = true - }) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -210,7 +217,7 @@ func TestDeleteChatQueuedMessageMissingReturns404(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -245,7 +252,7 @@ func TestDeleteChatQueuedMessageEmptyQueueReturnsConflict(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -273,7 +280,7 @@ func TestPromoteChatQueuedMessageMissingReturns404(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -307,7 +314,7 @@ func TestPromoteChatQueuedMessageEmptyQueueReturnsConflict(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -336,7 +343,7 @@ func TestInterruptChatIdleReturnsConflict(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, api := newChatClientWithAPI(t) + client, api := newChatClientWithAPI(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -358,7 +365,7 @@ func TestSubmitToolResultsWrongStateReturnsConflict(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -386,7 +393,7 @@ func TestSubmitToolResultsRequiresActionSucceeds(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, api := newChatClientWithAPI(t) + client, api := newChatClientWithAPI(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -438,7 +445,7 @@ func TestPatchChatArchiveChildRejected(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, db, api := newChatClientWithAPIAndDatabase(t) + client, db, api := newChatClientWithAPIAndDatabase(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) modelConfig := createChatModelConfig(t, client) @@ -488,7 +495,7 @@ func TestPatchChatUnarchiveChildRejected(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, db, api := newChatClientWithAPIAndDatabase(t) + client, db, api := newChatClientWithAPIAndDatabase(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) modelConfig := createChatModelConfig(t, client) @@ -547,7 +554,7 @@ func TestPatchChatArchiveRootRollsBackWhenChildCannotArchive(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, db, api := newChatClientWithAPIAndDatabase(t) + client, db, api := newChatClientWithAPIAndDatabase(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) modelConfig := createChatModelConfig(t, client) @@ -587,7 +594,7 @@ func TestPostChatMessagesInvalidStateReturnsSharedResponse(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, _, api := newChatClientWithAPIAndDatabase(t) + client, _, api := newChatClientWithAPIAndDatabase(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -620,7 +627,7 @@ func TestPostChatToolResultsInvalidStateReturnsSharedResponse(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, _, api := newChatClientWithAPIAndDatabase(t) + client, _, api := newChatClientWithAPIAndDatabase(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -654,7 +661,7 @@ func TestReconcileInvalidChatStateSucceeds(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client, db, api := newChatClientWithAPIAndDatabase(t) + client, db, api := newChatClientWithAPIAndDatabase(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -694,7 +701,7 @@ func TestReconcileInvalidChatStateNotInvalidReturnsConflict(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) firstUser := coderdtest.CreateFirstUser(t, client.Client) _ = createChatModelConfig(t, client) @@ -717,7 +724,7 @@ func TestReconcileInvalidChatStateNotFound(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) - client := newChatClient(t) + client := newChatClient(t, withChatWorkerDisabled) _ = coderdtest.CreateFirstUser(t, client.Client) _, err := client.ReconcileInvalidChatState(ctx, uuid.New())