aboutsummaryrefslogtreecommitdiff
path: root/internal/journal/read_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/journal/read_test.go')
-rw-r--r--internal/journal/read_test.go59
1 files changed, 44 insertions, 15 deletions
diff --git a/internal/journal/read_test.go b/internal/journal/read_test.go
index 2b46bfb..fb6f77f 100644
--- a/internal/journal/read_test.go
+++ b/internal/journal/read_test.go
@@ -303,15 +303,18 @@ func TestEntriesBothFailureModesReportsBadLineFirst(t *testing.T) {
t.Fatal(err)
}
+ // Since plan 10 a damaged line whose file is readable refuses only that
+ // file (a "damaged" entry); the run as a whole still fails closed here,
+ // on its missing run-start.
got, err := Entries(path, "A")
if err == nil {
- t.Fatal("Entries returned no error with both a bad line and a missing run-start present")
+ t.Fatal("Entries returned no error with a missing run-start")
}
- if !strings.Contains(err.Error(), "unparsable line 2") {
- t.Errorf("error = %q, want it to report the unparsable line (line 2), not the missing run-start", err)
+ if !strings.Contains(err.Error(), "no readable run-start") {
+ t.Errorf("error = %q, want it to name the missing run-start", err)
}
- if len(got) != 1 || got[0].Action != "run-end" {
- t.Errorf("entries = %+v, want just the surviving run-end", got)
+ if len(got) != 2 || got[0].Action != "damaged" || got[0].File != "x.pdf" || got[1].Action != "run-end" {
+ t.Errorf("entries = %+v, want x.pdf damaged, then run-end", got)
}
}
@@ -412,8 +415,10 @@ func TestEntriesAdjacentRunStartsOneCorrupted(t *testing.T) {
// TestEntriesReportsAMangledLine: a corrupt line that is not the log's
// final line must not be silently dropped by Entries the way Runs drops it
-// - PlanUndo needs to know a step went missing so it can refuse the whole
-// run rather than half-undo a file (spec ยง10).
+// - PlanUndo needs to know a step went missing. Since plan 10 (re-review
+// N1) a line whose directory and file columns are readable is returned as a
+// "damaged" entry for that file, so only that file is refused and the rest
+// of the run can still be undone.
func TestEntriesReportsAMangledLine(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -451,17 +456,41 @@ func TestEntriesReportsAMangledLine(t *testing.T) {
}
got, err := Entries(path, "A")
- if err == nil {
- t.Fatal("Entries did not report the mangled line")
+ if err != nil {
+ t.Fatalf("Entries = %v; a damaged line with a readable file must not refuse the run", err)
}
- if !strings.Contains(err.Error(), "line 2") {
- t.Errorf("error %q does not name line 2", err)
+ if len(got) != 3 || got[1].Action != "damaged" || got[1].Dir != "dl" || got[1].File != "x.pdf" || !strings.Contains(got[1].Detail, "line 2") {
+ t.Fatalf("entries = %+v; want run-start, x.pdf damaged (line 2), run-end", got)
}
- if len(got) != 2 {
- t.Fatalf("got %d entries, want the 2 surviving (run-start, run-end): %+v", len(got), got)
+}
+
+// TestEntriesIgnoresAnotherRunsDamagedLine: a damaged line whose run column
+// names another run - two directories' runs can interleave in one log - does
+// not refuse this run, even inside its window (re-review N1).
+func TestEntriesIgnoresAnotherRunsDamagedLine(t *testing.T) {
+ path := filepath.Join(t.TempDir(), "krino.log")
+ w, _ := Open(path)
+ at := time.Date(2026, 9, 11, 10, 2, 3, 0, time.UTC)
+ for _, e := range []Entry{
+ {Time: at, Run: "A", Action: "run-start", Status: "ok"},
+ {Time: at, Run: "A", Dir: "dl", File: "x.pdf", Step: 1, Action: "move", Status: "ok", Src: "/a/x.pdf", Dst: "/b/x.pdf"},
+ {Time: at, Run: "A", Action: "run-end", Status: "ok"},
+ } {
+ if err := w.Append(e); err != nil {
+ t.Fatal(err)
+ }
}
- if got[0].Action != "run-start" || got[1].Action != "run-end" {
- t.Errorf("entries = %+v", got)
+ w.Close()
+ raw, _ := os.ReadFile(path)
+ lines := strings.Split(strings.TrimRight(string(raw), "\n"), "\n")
+ cut := "2026-09-11T10:02:04Z\tB\tscans\ty.pdf\t1\tmo"
+ lines = append(lines[:2], append([]string{cut}, lines[2:]...)...)
+ if err := os.WriteFile(path, []byte(strings.Join(lines, "\n")+"\n"), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ got, err := Entries(path, "A")
+ if err != nil || len(got) != 3 {
+ t.Errorf("Entries(A) = %+v, %v; want A's three entries and no error", got, err)
}
}