P2 redesign Phase 5 — prune/check/unlock + maintenance ticker + repo stats + pending-runs queue #3

Merged
steve merged 37 commits from p2r-phase5-maintenance into main 2026-05-04 10:25:02 +01:00
2 changed files with 46 additions and 12 deletions
Showing only changes of commit 7fd29427a0 - Show all commits
+1 -1
View File
@@ -367,7 +367,7 @@ func (e Env) RunCheck(ctx context.Context, subsetPct int, handle LineHandler) (C
var res CheckResult
sniff := func(stream, line string, ev any) {
if stream == "stderr" {
if strings.Contains(line, "Found stale lock") || strings.Contains(line, "locked") {
if strings.Contains(line, "stale lock") || strings.Contains(line, "already locked") {
res.LockPresent = true
}
}
+45 -11
View File
@@ -54,18 +54,34 @@ func TestRunPruneInvokesPrune(t *testing.T) {
// --- 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)
func TestRunCheckLockSniff(t *testing.T) {
cases := []struct {
name string
stderrLine string
wantLocked bool
}{
{"stale lock", "Found stale lock from PID 1234", true},
{"already locked", "repository is already locked exclusively", true},
{"benign mention", "subdir/locked-file ok", false},
{"empty", "", false},
}
if !res.LockPresent {
t.Fatal("expected LockPresent=true")
}
if res.ErrorsFound {
t.Fatal("expected ErrorsFound=false")
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
// Script emits the line on stderr, then exits 0.
script := fmt.Sprintf(`printf '%%s\n' %q >&2`, c.stderrLine)
bin := setupScriptBin(t, script)
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 != c.wantLocked {
t.Fatalf("LockPresent: got %v, want %v (line: %q)", res.LockPresent, c.wantLocked, c.stderrLine)
}
if res.ErrorsFound {
t.Fatal("expected ErrorsFound=false")
}
})
}
}
@@ -149,3 +165,21 @@ func TestRunStatsErrorsWithoutJSON(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
}
func TestRunStatsZeroSnapshots(t *testing.T) {
// Confirms RunStats succeeds and returns a valid *RepoStats when the
// repo has no snapshots (snapshots_count=0). A regression that
// re-added a "SnapshotsCount > 0" guard would return an error here.
bin := setupScriptBin(t, `echo '{"total_size":0,"total_uncompressed_size":0,"snapshots_count":0,"total_file_count":0,"total_blob_count":0}'`)
env := Env{Bin: bin}
stats, err := env.RunStats(context.Background(), nil)
if err != nil {
t.Fatalf("RunStats with zero snapshots returned unexpected error: %v", err)
}
if stats == nil {
t.Fatal("expected non-nil *RepoStats, got nil")
}
if stats.SnapshotsCount != 0 {
t.Fatalf("SnapshotsCount: got %d, want 0", stats.SnapshotsCount)
}
}