@@ -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 code0 (background start successful)
374
- require .Equal (t ,0 ,result .ExitCode )
370
+ // Should have exit code124 (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 theactual 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"` , " Shouldnot containcommand output in backgroundmode" )
384
- require .NotContains (t ,result .Output ,`"completed"` , "Should not contain command output in background mode " )
376
+ // Should NOT contain thesecond echo (it never executed due to timeout)
377
+ require . NotContains ( t , result . Output , "completed" , "Should not contain output after timeout" )
378
+
379
+ // Should contain backgroundcontinuation 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 returnPID/log info, not the actual output
424
+ // Background mode shouldalso 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 :`sleep1 && echo "done" > /tmp/done` ,// Command thatwould 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" && sleep4 && echo "done" > /tmp/bg-test- done` ,// Command thatwill 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 errorand should not timeout
452
+ // Should not errorbut 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 havetimeout 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
- // ShouldNOT containtimeout message since backgroundmode ignores timeout
471
- require .NotContains (t ,result .Output ,"Commandcanceled due to timeout " )
463
+ // Should contain backgroundcontinuation message
464
+ require .Contains (t ,result .Output ,"Commandcontinues 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
}