package offsitekeys import ( "context" "strings" "testing" "time" ) type lsShell struct { out string cmds []string } func (s *lsShell) Run(_ context.Context, cmd string, _ []byte) ([]byte, error) { s.cmds = append(s.cmds, cmd) return []byte(s.out), nil } func (s *lsShell) Close() error { return nil } type lsDialer struct{ sh *lsShell } func (d lsDialer) Dial(context.Context, Target, string) (Shell, error) { return d.sh, nil } const id1 = "0a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9" const id2 = "ffeeddccbbaa99887766554433221100ffeeddccbbaa99887766554433221100" // R-895 measurement slice: the hub's own listing reads the snapshot files and their upload times from `ls -l`, counts // only restic snapshot ids, and issues exactly ONE read-only command. RED-PROOF // (audits/agent-allowlist-rotation-2026-10-17/P4/redproof-listing.txt): with parseLsL counting every line, Files is 3 // and this test fails. func TestListSnapshots_CountsTheBoxSnapshotFilesReadOnly(t *testing.T) { sh := &lsShell{out: "total 8\n" + "-rw------- 1 u1-sub4 u1-sub4 324 Oct 17 03:12 " + id1 + "\n" + "-rw------- 1 u1-sub4 u1-sub4 331 Mar 2 2026 " + id2 + "\n" + "-rw------- 1 u1-sub4 u1-sub4 12 Oct 17 03:13 .tmp-upload\n"} r := &Registrar{Dialer: lsDialer{sh}} now := time.Date(2026, 10, 17, 14, 0, 0, 0, time.UTC) l, err := r.ListSnapshots(context.Background(), tgt, "pw", now) if err != nil { t.Fatal(err) } if l.Files != 2 || l.Other != 1 { t.Fatalf("files=%d other=%d, want 2 and 1", l.Files, l.Other) } if !l.Newest.Equal(time.Date(2026, 10, 17, 3, 12, 0, 0, time.UTC)) || !l.Oldest.Equal(time.Date(2026, 3, 2, 0, 0, 0, 0, time.UTC)) { t.Fatalf("newest=%v oldest=%v", l.Newest, l.Oldest) } if len(sh.cmds) != 1 || sh.cmds[0] != "ls -l /home/felhom-repo/snapshots" { t.Fatalf("commands = %v — the listing must be one read-only ls", sh.cmds) } for _, c := range sh.cmds { for _, w := range []string{"rm", "mv", "dd", "chmod", "mkdir", "touch", "cp", "unlink"} { if strings.HasPrefix(c, w+" ") { t.Fatalf("a write verb in the listing: %q", c) } } } } // A December file read in January is last year's, not next year's. func TestLsTime_YearBoundary(t *testing.T) { ts, ok := lsTime("Dec", "30", "23:10", time.Date(2027, 1, 2, 0, 0, 0, 0, time.UTC)) if !ok || ts.Year() != 2026 { t.Fatalf("got %v %v", ts, ok) } }