@@ -464,3 +464,109 @@ func TestDaemon_handlePorts_AllJobs(t *testing.T) {
464464 t .Error ("expected ports in response" )
465465 }
466466}
467+
468+ func TestDaemon_handleRemoveRun (t * testing.T ) {
469+ tmpDir := t .TempDir ()
470+ executor := NewFakeProcessExecutor ()
471+ jm := NewJobManagerWithExecutor (tmpDir , nil , executor , nil )
472+
473+ // Add a job (which creates a run)
474+ job , _ , _ := jm .AddJob ([]string {"echo" }, "/workdir" , "" , nil )
475+
476+ // Get the run ID
477+ runs , _ := jm .ListRunsForJob (job .ID )
478+ runID := runs [0 ].ID
479+
480+ // Stop the process first
481+ executor .LastHandle ().Stop ()
482+ time .Sleep (10 * time .Millisecond )
483+
484+ d := & Daemon {jobManager : jm }
485+ req := & Request {
486+ Type : RequestTypeRemoveRun ,
487+ Payload : map [string ]interface {}{
488+ "run_id" : runID ,
489+ },
490+ }
491+
492+ resp := d .handleRequest (req )
493+
494+ if ! resp .Success {
495+ t .Errorf ("expected success, got error: %s" , resp .Error )
496+ }
497+
498+ if resp .Data ["run_id" ] != runID {
499+ t .Errorf ("expected run_id %s in response, got %v" , runID , resp .Data ["run_id" ])
500+ }
501+
502+ // Verify run is actually removed
503+ runs , _ = jm .ListRunsForJob (job .ID )
504+ if len (runs ) != 0 {
505+ t .Errorf ("expected 0 runs after removal, got %d" , len (runs ))
506+ }
507+ }
508+
509+ func TestDaemon_handleRemoveRun_MissingRunID (t * testing.T ) {
510+ tmpDir := t .TempDir ()
511+ executor := NewFakeProcessExecutor ()
512+ jm := NewJobManagerWithExecutor (tmpDir , nil , executor , nil )
513+
514+ d := & Daemon {jobManager : jm }
515+ req := & Request {
516+ Type : RequestTypeRemoveRun ,
517+ Payload : map [string ]interface {}{},
518+ }
519+
520+ resp := d .handleRequest (req )
521+
522+ if resp .Success {
523+ t .Error ("expected error for missing run_id" )
524+ }
525+ }
526+
527+ func TestDaemon_handleRemoveRun_NotFound (t * testing.T ) {
528+ tmpDir := t .TempDir ()
529+ executor := NewFakeProcessExecutor ()
530+ jm := NewJobManagerWithExecutor (tmpDir , nil , executor , nil )
531+
532+ d := & Daemon {jobManager : jm }
533+ req := & Request {
534+ Type : RequestTypeRemoveRun ,
535+ Payload : map [string ]interface {}{
536+ "run_id" : "nonexistent-1" ,
537+ },
538+ }
539+
540+ resp := d .handleRequest (req )
541+
542+ if resp .Success {
543+ t .Error ("expected error for nonexistent run" )
544+ }
545+ }
546+
547+ func TestDaemon_handleRemoveRun_Running (t * testing.T ) {
548+ tmpDir := t .TempDir ()
549+ executor := NewFakeProcessExecutor ()
550+ jm := NewJobManagerWithExecutor (tmpDir , nil , executor , nil )
551+
552+ // Add a job (which creates a running run)
553+ job , _ , _ := jm .AddJob ([]string {"echo" }, "/workdir" , "" , nil )
554+
555+ // Get the run ID while it's still running
556+ runs , _ := jm .ListRunsForJob (job .ID )
557+ runID := runs [0 ].ID
558+
559+ d := & Daemon {jobManager : jm }
560+ req := & Request {
561+ Type : RequestTypeRemoveRun ,
562+ Payload : map [string ]interface {}{
563+ "run_id" : runID ,
564+ },
565+ }
566+
567+ resp := d .handleRequest (req )
568+
569+ if resp .Success {
570+ t .Error ("expected error for running run" )
571+ }
572+ }
0 commit comments