package restic import ( "context" "fmt" "os" "path/filepath" "strings" "testing" ) // setupScriptBin writes a small shell script to a temp directory, // makes it executable, and returns its path. scriptBody is the // complete script content (without the shebang line — that's added // automatically). func setupScriptBin(t *testing.T, scriptBody string) string { t.Helper() dir := t.TempDir() p := filepath.Join(dir, "restic") content := "#!/bin/sh\n" + scriptBody + "\n" if err := os.WriteFile(p, []byte(content), 0o755); err != nil { t.Fatalf("setupScriptBin: %v", err) } return p } // captureLines returns a LineHandler that appends "stream:line" into // the returned slice pointer (safe for single-goroutine test use). func captureLines() (*[]string, LineHandler) { var lines []string h := func(stream, line string, _ any) { lines = append(lines, fmt.Sprintf("%s:%s", stream, line)) } return &lines, h } // --- B1: RunPrune + B2: RunCheck --- func TestRunPruneInvokesPrune(t *testing.T) { // Shell script that echoes its args; "prune" should appear in output. bin := setupScriptBin(t, `echo "$@"`) env := Env{Bin: bin} lines, h := captureLines() if err := env.RunPrune(context.Background(), h); err != nil { t.Fatalf("RunPrune returned error: %v", err) } for _, l := range *lines { if strings.Contains(l, "prune") { return } } t.Fatalf("expected 'prune' in captured output; got: %v", *lines) } // --- B2: RunCheck --- func TestRunCheckParsesLock(t *testing.T) { bin := setupScriptBin(t, `echo "Found stale lock" >&2`) env := Env{Bin: bin} res, err := env.RunCheck(context.Background(), 0, nil) if err != nil { t.Fatalf("RunCheck returned unexpected error: %v", err) } if !res.LockPresent { t.Fatal("expected LockPresent=true") } if res.ErrorsFound { t.Fatal("expected ErrorsFound=false") } } func TestRunCheckErrorsFoundOnExit1(t *testing.T) { bin := setupScriptBin(t, `exit 1`) env := Env{Bin: bin} res, err := env.RunCheck(context.Background(), 0, nil) if err != nil { t.Fatalf("RunCheck returned unexpected error (should have absorbed exit 1): %v", err) } if !res.ErrorsFound { t.Fatal("expected ErrorsFound=true for exit 1") } } func TestRunCheckSubsetArg(t *testing.T) { bin := setupScriptBin(t, `echo "$@"`) env := Env{Bin: bin} lines, h := captureLines() if _, err := env.RunCheck(context.Background(), 25, h); err != nil { t.Fatalf("RunCheck: %v", err) } want := "--read-data-subset 25%" for _, l := range *lines { if strings.Contains(l, want) { return } } t.Fatalf("expected %q in captured output; got: %v", want, *lines) }