test(coderd/x/chatd): stop waking acquireLoop in TestResolveExploreToolSnapshot (#25129)

Fixes [CODAGT-367](https://linear.app/codercom/issue/CODAGT-367).

`TestResolveExploreToolSnapshot/*` flaked on CI (Linux and Windows) with
`context deadline exceeded` on the `GetMCPServerConfigsByIDs` call
inside `resolveExploreToolSnapshot`.

Each test setup called `server.CreateChat` twice with `MCPServerIDs` set
to fake `.example.com` URLs. `CreateChat` marks the chat pending and
calls `signalWake`, which causes the chatd background `acquireLoop` to
pick the chat up. That goroutine then dialed the fake MCP URLs
(NXDOMAIN, slower on Windows) and made an OpenAI request with the dbgen
default test key (401). Under CI load, that activity racing the 4
parallel subtests' `GetMCPServerConfigsByIDs` calls was enough to exceed
the 25s test context deadline. The failure logs in the issue showed both
side effects firing in the same job.

`resolveExploreToolSnapshot` only reads `ID`, `MCPServerIDs`,
`PlanMode`, `ParentChatID`, and `Mode` off the parent argument, so the
chats do not need to be persisted. Build them as in-memory
`database.Chat` values instead. The MCP server configs remain in the DB
because the function still queries them via `GetMCPServerConfigsByIDs`.

Verified locally with `go test ./coderd/x/chatd -run
TestResolveExploreToolSnapshot -count=100 -race` (passes, ~5s total) and
the surrounding `TestResolve*` / `TestCreateChildSubagentChat*` /
`TestSpawnAgent_Explore*` tests.

---

_Made by Coder Agents on behalf of @ibetitsmike. [Linear
session](https://linear.app/codercom/issue/CODAGT-367/flake-testresolveexploretoolsnapshot#agent-session-0730f3fe)._
This commit is contained in:
Michael Suchacz
2026-05-11 19:46:59 +02:00
committed by GitHub
parent 19573e8aee
commit 60779ad2ec
+18 -28
View File
@@ -1429,8 +1429,7 @@ func TestResolveExploreToolSnapshot(t *testing.T) {
db, ps := dbtestutil.NewDB(t)
server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{})
ctx := chatdTestContext(t)
user, org, model := seedInternalChatDeps(t, db)
user, _, _ := seedInternalChatDeps(t, db)
approvedMCP := insertInternalMCPServerConfig(
t, db, user.ID, "approved-"+uuid.NewString(), true,
)
@@ -1438,42 +1437,33 @@ func TestResolveExploreToolSnapshot(t *testing.T) {
t, db, user.ID, "blocked-"+uuid.NewString(), false,
)
askParentRef, err := server.CreateChat(ctx, CreateOptions{
OrganizationID: org.ID,
OwnerID: user.ID,
Title: "ask-parent",
ModelConfigID: model.ID,
MCPServerIDs: []uuid.UUID{approvedMCP.ID, blockedMCP.ID},
InitialUserContent: []codersdk.ChatMessagePart{
codersdk.ChatMessageText("hello"),
},
})
require.NoError(t, err)
askParent, err := db.GetChatByID(ctx, askParentRef.ID)
require.NoError(t, err)
planParentRef, err := server.CreateChat(ctx, CreateOptions{
OrganizationID: org.ID,
OwnerID: user.ID,
Title: "plan-parent",
ModelConfigID: model.ID,
// Build parent chats in memory rather than via server.CreateChat.
// resolveExploreToolSnapshot only reads ID, MCPServerIDs, PlanMode,
// ParentChatID, and Mode from its parent argument, so persisting
// the chats is unnecessary. Skipping CreateChat avoids waking the
// background acquireLoop, which would otherwise try to dial the
// fake MCP URLs and call OpenAI with the dbgen test API key. Those
// side effects were the root cause of the flake tracked in
// CODAGT-367.
askParent := database.Chat{
ID: uuid.New(),
MCPServerIDs: []uuid.UUID{approvedMCP.ID, blockedMCP.ID},
}
planParent := database.Chat{
ID: uuid.New(),
PlanMode: database.NullChatPlanMode{
ChatPlanMode: database.ChatPlanModePlan,
Valid: true,
},
MCPServerIDs: []uuid.UUID{approvedMCP.ID, blockedMCP.ID},
InitialUserContent: []codersdk.ChatMessagePart{
codersdk.ChatMessageText("hello"),
},
})
require.NoError(t, err)
planParent, err := db.GetChatByID(ctx, planParentRef.ID)
require.NoError(t, err)
}
subagentPlanParent := planParent
subagentPlanParent.ID = uuid.New()
subagentPlanParent.ParentChatID = uuid.NullUUID{UUID: uuid.New(), Valid: true}
exploreParent := askParent
exploreParent.ID = uuid.New()
exploreParent.Mode = database.NullChatMode{ChatMode: database.ChatModeExplore, Valid: true}
exploreParent.ParentChatID = uuid.NullUUID{UUID: uuid.New(), Valid: true}
exploreParent.MCPServerIDs = []uuid.UUID{approvedMCP.ID}