@@ -175,8 +175,6 @@ func TestWorkspaceBashTimeout(t *testing.T) {
175
175
176
176
// Test that the TimeoutMs field can be set and read correctly
177
177
args := toolsdk.WorkspaceBashArgs {
178
- Workspace : "test-workspace" ,
179
- Command : "echo test" ,
180
178
TimeoutMs : 0 , // Should default to 60000 in handler
181
179
}
182
180
@@ -193,8 +191,6 @@ func TestWorkspaceBashTimeout(t *testing.T) {
193
191
194
192
// Test that negative values can be set and will be handled by the default logic
195
193
args := toolsdk.WorkspaceBashArgs {
196
- Workspace : "test-workspace" ,
197
- Command : "echo test" ,
198
194
TimeoutMs : - 100 ,
199
195
}
200
196
@@ -280,7 +276,7 @@ func TestWorkspaceBashTimeoutIntegration(t *testing.T) {
280
276
TimeoutMs : 2000 , // 2 seconds timeout - should timeout after first echo
281
277
}
282
278
283
- result , err := toolsdk . WorkspaceBash . Handler ( t . Context () , deps , args )
279
+ result , err := testTool ( t , toolsdk . WorkspaceBash , deps , args )
284
280
285
281
// Should not error (timeout is handled gracefully)
286
282
require .NoError (t , err )
@@ -314,15 +310,15 @@ func TestWorkspaceBashTimeoutIntegration(t *testing.T) {
314
310
315
311
deps , err := toolsdk .NewDeps (client )
316
312
require .NoError (t , err )
317
- ctx := context .Background ()
318
313
319
314
args := toolsdk.WorkspaceBashArgs {
320
315
Workspace : workspace .Name ,
321
316
Command : `echo "normal command"` , // Quick command that should complete normally
322
317
TimeoutMs : 5000 , // 5 second timeout - plenty of time
323
318
}
324
319
325
- result , err := toolsdk .WorkspaceBash .Handler (ctx , deps , args )
320
+ // Use testTool to register the tool as tested and satisfy coverage validation
321
+ result , err := testTool (t , toolsdk .WorkspaceBash , deps , args )
326
322
327
323
// Should not error
328
324
require .NoError (t , err )
@@ -343,7 +339,7 @@ func TestWorkspaceBashTimeoutIntegration(t *testing.T) {
343
339
func TestWorkspaceBashBackgroundIntegration (t * testing.T ) {
344
340
t .Parallel ()
345
341
346
- t .Run ("BackgroundCommandReturnsImmediately " , func (t * testing.T ) {
342
+ t .Run ("BackgroundCommandCapturesOutput " , func (t * testing.T ) {
347
343
t .Parallel ()
348
344
349
345
client , workspace , agentToken := setupWorkspaceForAgent (t )
@@ -359,29 +355,29 @@ func TestWorkspaceBashBackgroundIntegration(t *testing.T) {
359
355
360
356
args := toolsdk.WorkspaceBashArgs {
361
357
Workspace : workspace .Name ,
362
- Command : `echo "started" && sleep 5 && echo "completed"` , // Command that would take 5+ seconds
363
- Background : true , // Run in background
358
+ Command : `echo "started" && sleep 60 && echo "completed"` , // Command that would take 60+ seconds
359
+ Background : true , // Run in background
360
+ TimeoutMs : 2000 , // 2 second timeout
364
361
}
365
362
366
- result , err := toolsdk . WorkspaceBash . Handler ( t . Context () , deps , args )
363
+ result , err := testTool ( t , toolsdk . WorkspaceBash , deps , args )
367
364
368
365
// Should not error
369
366
require .NoError (t , err )
370
367
371
368
t .Logf ("Background result: exitCode=%d, output=%q" , result .ExitCode , result .Output )
372
369
373
- // Should have exit code 0 (background start successful)
374
- require .Equal (t , 0 , result .ExitCode )
370
+ // Should have exit code 124 (timeout) since command times out
371
+ require .Equal (t , 124 , result .ExitCode )
375
372
376
- // Should contain PID and log path info, not the actual command output
377
- require .Contains (t , result .Output , "Command started with PID:" )
378
- require .Contains (t , result .Output , "Log path: /tmp/mcp-bg/" )
373
+ // Should capture output up to timeout point
374
+ require .Contains (t , result .Output , "started" , "Should contain output captured before timeout" )
379
375
380
- // Should NOT contain the actual command output since it runs in background
381
- // The command was `echo "started" && sleep 5 && echo "completed"`
382
- // So we check that the quoted strings don't appear in the output
383
- require . NotContains ( t , result . Output , `"started"` , " Should not contain command output in background mode" )
384
- require .NotContains (t , result .Output , `"completed"` , "Should not contain command output in background mode " )
376
+ // Should NOT contain the second echo (it never executed due to timeout)
377
+ require . NotContains ( t , result . Output , "completed" , "Should not contain output after timeout" )
378
+
379
+ // Should contain background continuation message
380
+ require .Contains (t , result .Output , "Command continues running in background" )
385
381
})
386
382
387
383
t .Run ("BackgroundVsNormalExecution" , func (t * testing.T ) {
@@ -419,20 +415,18 @@ func TestWorkspaceBashBackgroundIntegration(t *testing.T) {
419
415
Background : true ,
420
416
}
421
417
422
- backgroundResult , err := toolsdk . WorkspaceBash . Handler ( t . Context () , deps , backgroundArgs )
418
+ backgroundResult , err := testTool ( t , toolsdk . WorkspaceBash , deps , backgroundArgs )
423
419
require .NoError (t , err )
424
420
425
421
t .Logf ("Normal result: %q" , normalResult .Output )
426
422
t .Logf ("Background result: %q" , backgroundResult .Output )
427
423
428
- // Background mode should return PID/log info, not the actual output
424
+ // Background mode should also return the actual output since command completes quickly
429
425
require .Equal (t , 0 , backgroundResult .ExitCode )
430
- require .Contains (t , backgroundResult .Output , "Command started with PID:" )
431
- require .Contains (t , backgroundResult .Output , "Log path: /tmp/mcp-bg/" )
432
- require .NotContains (t , backgroundResult .Output , "hello world" )
426
+ require .Equal (t , "hello world" , backgroundResult .Output )
433
427
})
434
428
435
- t .Run ("BackgroundIgnoresTimeout " , func (t * testing.T ) {
429
+ t .Run ("BackgroundCommandContinuesAfterTimeout " , func (t * testing.T ) {
436
430
t .Parallel ()
437
431
438
432
client , workspace , agentToken := setupWorkspaceForAgent (t )
@@ -448,36 +442,35 @@ func TestWorkspaceBashBackgroundIntegration(t *testing.T) {
448
442
449
443
args := toolsdk.WorkspaceBashArgs {
450
444
Workspace : workspace .Name ,
451
- Command : `sleep 1 && echo "done" > /tmp/done` , // Command that would normally timeout
452
- TimeoutMs : 1 , // 1 ms timeout (shorter than command duration)
453
- Background : true , // But running in background should ignore timeout
445
+ Command : `echo "started" && sleep 4 && echo "done" > /tmp/bg-test- done` , // Command that will timeout but continue
446
+ TimeoutMs : 2000 , // 2000ms timeout (shorter than command duration)
447
+ Background : true , // Run in background
454
448
}
455
449
456
- result , err := toolsdk . WorkspaceBash . Handler ( t . Context () , deps , args )
450
+ result , err := testTool ( t , toolsdk . WorkspaceBash , deps , args )
457
451
458
- // Should not error and should not timeout
452
+ // Should not error but should timeout
459
453
require .NoError (t , err )
460
454
461
455
t .Logf ("Background with timeout result: exitCode=%d, output=%q" , result .ExitCode , result .Output )
462
456
463
- // Should have exit code 0 (background start successful)
464
- require .Equal (t , 0 , result .ExitCode )
457
+ // Should have timeout exit code
458
+ require .Equal (t , 124 , result .ExitCode )
465
459
466
- // Should return PID/log info, indicating the background command started successfully
467
- require .Contains (t , result .Output , "Command started with PID:" )
468
- require .Contains (t , result .Output , "Log path: /tmp/mcp-bg/" )
460
+ // Should capture output before timeout
461
+ require .Contains (t , result .Output , "started" , "Should contain output captured before timeout" )
469
462
470
- // Should NOT contain timeout message since background mode ignores timeout
471
- require .NotContains (t , result .Output , "Command canceled due to timeout " )
463
+ // Should contain background continuation message
464
+ require .Contains (t , result .Output , "Command continues running in background " )
472
465
473
- // Wait for the background command to complete
466
+ // Wait for the background command to complete (even though SSH session timed out)
474
467
require .Eventually (t , func () bool {
475
- args := toolsdk.WorkspaceBashArgs {
468
+ checkArgs := toolsdk.WorkspaceBashArgs {
476
469
Workspace : workspace .Name ,
477
- Command : `cat /tmp/done` ,
470
+ Command : `cat /tmp/bg-test- done 2>/dev/null || echo "not found" ` ,
478
471
}
479
- result , err := toolsdk .WorkspaceBash .Handler (t .Context (), deps , args )
480
- return err == nil && result .Output == "done"
481
- }, testutil .WaitMedium , testutil .IntervalMedium )
472
+ checkResult , err := toolsdk .WorkspaceBash .Handler (t .Context (), deps , checkArgs )
473
+ return err == nil && checkResult .Output == "done"
474
+ }, testutil .WaitMedium , testutil .IntervalMedium , "Background command should continue running and complete after timeout" )
482
475
})
483
476
}
0 commit comments