TestLoadCacheCorrupt verifies the binding constraint that LoadCache never errors: a corrupt cache file must yield an empty, usable cache (not nil, non-nil Entries map), and ScanFile must still work afterwards.
(t *testing.T)
| 60 | // errors: a corrupt cache file must yield an empty, usable cache (not nil, |
| 61 | // non-nil Entries map), and ScanFile must still work afterwards. |
| 62 | func TestLoadCacheCorrupt(t *testing.T) { |
| 63 | dir := t.TempDir() |
| 64 | cpath := filepath.Join(dir, "cache.json") |
| 65 | if err := os.WriteFile(cpath, []byte("{not valid json"), 0o644); err != nil { |
| 66 | t.Fatal(err) |
| 67 | } |
| 68 | |
| 69 | c := LoadCache(cpath) |
| 70 | if c == nil { |
| 71 | t.Fatal("LoadCache returned nil on corrupt file") |
| 72 | } |
| 73 | if c.Entries == nil { |
| 74 | t.Fatal("LoadCache left a nil Entries map on corrupt file") |
| 75 | } |
| 76 | if len(c.Entries) != 0 { |
| 77 | t.Fatalf("corrupt-cache load entries = %d, want 0", len(c.Entries)) |
| 78 | } |
| 79 | |
| 80 | // Cache is usable: a real scan succeeds and populates an entry. |
| 81 | jsonl := filepath.Join(dir, "s.jsonl") |
| 82 | line := `{"type":"assistant","timestamp":"2026-06-01T10:00:00.000Z","message":{"role":"assistant","content":[{"type":"tool_use","name":"Bash","input":{"command":"flow show task"}}]}}` |
| 83 | if err := os.WriteFile(jsonl, []byte(line), 0o644); err != nil { |
| 84 | t.Fatal(err) |
| 85 | } |
| 86 | r, err := c.ScanFile(jsonl, "mine") |
| 87 | if err != nil { |
| 88 | t.Fatalf("ScanFile on usable cache failed: %v", err) |
| 89 | } |
| 90 | if len(r.Lookups) != 1 { |
| 91 | t.Fatalf("scan after corrupt load lookups = %d, want 1", len(r.Lookups)) |
| 92 | } |
| 93 | if len(c.Entries) != 1 { |
| 94 | t.Fatalf("cache should have 1 entry after scan, got %d", len(c.Entries)) |
| 95 | } |
| 96 | } |