mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(coderd): stabilize TestPatchChatMessage/ChangesModel flaky test (#25306)
Fixes coder/internal#1535 ## Problem `TestPatchChatMessage/ChangesModel` is flaky because it races with the chat daemon's background processing. `CreateChat` sets the chat to `pending` and the daemon picks it up asynchronously. The test immediately calls `EditChatMessage` (which changes the model to an override) while the first processing round is still running. The `InsertChatMessages` SQL CTE unconditionally updates `chats.last_model_config_id` to the model of the last inserted message. When the daemon's in-flight message insertions commit after the edit transaction, they overwrite `last_model_config_id` back to the default model. Similarly, after the edit sets the chat back to `pending`, the daemon re-processes it. The test's `GetChat` call could race with this second round. ## Fix Poll for the chat to reach `waiting` (or `error`) status: 1. **Before editing**: wait for the initial processing round to complete 2. **After editing**: wait for the second processing round (triggered by the edit) to complete Then assert `last_model_config_id`, which is now stable. > Generated with [Coder Agents](https://coder.com/agents) by @kylecarbs
This commit is contained in:
@@ -7792,6 +7792,20 @@ func TestPatchChatMessage(t *testing.T) {
|
||||
require.Equal(t, defaultModel.ID, chat.LastModelConfigID,
|
||||
"chat starts on the default model")
|
||||
|
||||
// Wait for the initial chat processing to complete before
|
||||
// editing. CreateChat sets the chat to pending and the daemon
|
||||
// processes it asynchronously; editing while that first round
|
||||
// is still running can race with message insertions that
|
||||
// overwrite last_model_config_id.
|
||||
testutil.Eventually(ctx, t, func(ctx context.Context) bool {
|
||||
c, getErr := client.GetChat(ctx, chat.ID)
|
||||
if getErr != nil {
|
||||
return false
|
||||
}
|
||||
return c.Status != codersdk.ChatStatusPending &&
|
||||
c.Status != codersdk.ChatStatusRunning
|
||||
}, testutil.IntervalFast, "initial chat processing did not finish")
|
||||
|
||||
messagesResult, err := client.GetChatMessages(ctx, chat.ID, nil)
|
||||
require.NoError(t, err)
|
||||
var userMessageID int64
|
||||
@@ -7816,6 +7830,19 @@ func TestPatchChatMessage(t *testing.T) {
|
||||
require.Equal(t, overrideModel.ID, *edited.Message.ModelConfigID,
|
||||
"replacement message must use the requested model")
|
||||
|
||||
// Wait for the second round of processing (triggered by the
|
||||
// edit) to complete, then verify last_model_config_id.
|
||||
// Reading immediately after EditChatMessage can race with the
|
||||
// daemon re-processing the now-pending chat.
|
||||
testutil.Eventually(ctx, t, func(ctx context.Context) bool {
|
||||
c, getErr := client.GetChat(ctx, chat.ID)
|
||||
if getErr != nil {
|
||||
return false
|
||||
}
|
||||
return c.Status != codersdk.ChatStatusPending &&
|
||||
c.Status != codersdk.ChatStatusRunning
|
||||
}, testutil.IntervalFast, "post-edit chat processing did not finish")
|
||||
|
||||
updatedChat, err := client.GetChat(ctx, chat.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, overrideModel.ID, updatedChat.LastModelConfigID,
|
||||
|
||||
Reference in New Issue
Block a user