@@ -25,8 +25,6 @@ import (
25
25
// Running them in parallel is prone to racy behavior.
26
26
// nolint:tparallel,paralleltest
27
27
func TestCoderTools (t * testing.T ) {
28
- t .Parallel ()
29
-
30
28
ctx := testutil .Context (t ,testutil .WaitLong )
31
29
// Given: a coder server, workspace, and agent.
32
30
client ,store := coderdtest .NewWithDatabase (t ,nil )
@@ -39,12 +37,20 @@ func TestCoderTools(t *testing.T) {
39
37
OwnerID :member .ID ,
40
38
}).WithAgent ().Do ()
41
39
42
- agt := agenttest .New (t ,client .URL ,r .AgentToken )
43
- t .Cleanup (func () {
44
- _ = agt .Close ()
45
- })
46
- // Given: the workspace agent is connected
47
- _ = coderdtest .NewWorkspaceAgentWaiter (t ,client ,r .Workspace .ID ).Wait ()
40
+ // Note: we want to test the list_workspaces tool before starting the
41
+ // workspace agent. Starting the workspace agent will modify the workspace
42
+ // state, which will affect the results of the list_workspaces tool.
43
+ listWorkspacesDone := make (chan struct {})
44
+ agentStarted := make (chan struct {})
45
+ go func () {
46
+ defer close (agentStarted )
47
+ <- listWorkspacesDone
48
+ agt := agenttest .New (t ,client .URL ,r .AgentToken )
49
+ t .Cleanup (func () {
50
+ _ = agt .Close ()
51
+ })
52
+ _ = coderdtest .NewWorkspaceAgentWaiter (t ,client ,r .Workspace .ID ).Wait ()
53
+ }()
48
54
49
55
// Given: a MCP server listening on a pty.
50
56
pty := ptytest .New (t )
@@ -118,6 +124,7 @@ func TestCoderTools(t *testing.T) {
118
124
})
119
125
120
126
t .Run ("coder_list_workspaces" ,func (t * testing.T ) {
127
+ defer close (listWorkspacesDone )
121
128
// When: the coder_list_workspaces tool is called
122
129
ctr := makeJSONRPCRequest (t ,"tools/call" ,"coder_list_workspaces" ,map [string ]any {
123
130
"coder_url" :client .URL .String (),
@@ -158,7 +165,11 @@ func TestCoderTools(t *testing.T) {
158
165
testutil .RequireJSONEq (t ,expected ,actual )
159
166
})
160
167
168
+ // NOTE: this test runs after the list_workspaces tool is called.
161
169
t .Run ("coder_workspace_exec" ,func (t * testing.T ) {
170
+ // Given: the workspace agent is connected
171
+ <- agentStarted
172
+
162
173
// When: the coder_workspace_exec tools is called with a command
163
174
randString := testutil .GetRandomName (t )
164
175
ctr := makeJSONRPCRequest (t ,"tools/call" ,"coder_workspace_exec" ,map [string ]any {
@@ -198,7 +209,11 @@ func TestCoderTools(t *testing.T) {
198
209
testutil .RequireJSONEq (t ,expected ,actual )
199
210
})
200
211
212
+ // NOTE: this test runs after the list_workspaces tool is called.
201
213
t .Run ("tool_and_command_restrictions" ,func (t * testing.T ) {
214
+ // Given: the workspace agent is connected
215
+ <- agentStarted
216
+
202
217
// Given: a restricted MCP server with only allowed tools and commands
203
218
restrictedPty := ptytest .New (t )
204
219
allowedTools := []string {"coder_workspace_exec" }