package tortoise_test import ( "testing" "time" "git.iamthefij.com/iamthefij/tortoise" ) func TestShellRunnerNoCallback(t *testing.T) { t.Parallel() cases := []struct { command string output string ReturnCode int }{ {"echo hello world", "hello world\n", 0}, {"echo hello world && exit 1", "hello world\n", 1}, } for _, c := range cases { c := c t.Run(c.command, func(t *testing.T) { t.Parallel() runner := tortoise.NewShellRunner() runner.Start() // Test command without callback if err := runner.AddCommand(c.command, nil); err != nil { t.Fatalf("unexpected error adding command: %v", err) } runner.Stop() result := runner.GetResults() if result == nil || result.Output != c.output || result.ReturnCode != c.ReturnCode { t.Fatalf("expected output '%s' and return code %d, got '%s' and %d", c.output, c.ReturnCode, result.Output, result.ReturnCode) } }) } } func TestShellRunnerCallback(t *testing.T) { t.Parallel() runner := tortoise.NewShellRunner() runner.Start() // Test command with callback done := make(chan struct{}) callbackReached := false if err := runner.AddCommand("echo callback test", func(result *tortoise.CommandResult) { callbackReached = true if result.Output != "callback test\n" { t.Fatalf("expected 'callback test', got '%s'", result.Output) } close(done) }); err != nil { t.Fatalf("unexpected error adding command: %v", err) } // Timeout waiting for callback select { case <-done: case <-time.After(2 * time.Second): t.Fatal("callback timed out") } if !callbackReached { t.Fatal("callback was not reached") } runner.Stop() // Make sure stop and kill both exit gracefully after the runner is stopped runner.Stop() runner.Kill() } func TestShellRunnerKillWithTimeout(t *testing.T) { t.Parallel() runner := tortoise.NewShellRunner() runner.Start() // Test command with callback callbackReached := false if err := runner.AddCommand("sleep 10 && echo callback test", func(result *tortoise.CommandResult) { callbackReached = true if result.Output != "callback test\n" { t.Fatalf("expected 'callback test', got '%s'", result.Output) } }); err != nil { t.Fatalf("unexpected error adding command: %v", err) } // Wait one second to make sure the command starts running time.Sleep(1 * time.Second) if err := runner.KillWithTimeout(1 * time.Second); err == nil { t.Fatal("expected error when killing commands, but got none") } if callbackReached { t.Fatal("callback was reached before kill") } } func TestStopPreventsNewCommands(t *testing.T) { runner := tortoise.NewShellRunner() runner.Start() runner.Stop() err := runner.AddCommand("echo should not run", nil) if err == nil { t.Fatal("expected error when adding command after stop, but got none") } } func TestAddingPriorToStart(t *testing.T) { runner := tortoise.NewShellRunner() err := runner.AddCommand("echo should not run", nil) if err == nil { t.Fatal("Should have failed to add prior to starting runner") } }