f3eaf511be
Add CheckResult (LockPresent, ErrorsFound) and RunCheck. subsetPct>0 passes --read-data-subset N% to limit data reads. Stderr is sniffed for "Found stale lock"/"locked" to set LockPresent; a non-zero exit from restic is absorbed as ErrorsFound=true rather than an error so the caller can always persist last_check_status. Tests cover lock detection, exit-1 absorption, and subset-arg plumbing.
99 lines
2.6 KiB
Go
99 lines
2.6 KiB
Go
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)
|
|
}
|