返回 DeepSeek-Reasonix
read_cache_test.go
根目录 / desktop / internal / workspacestate / read_cache_test.go
1 package workspacestate
2
3 import (
4 "bytes"
5 "encoding/json"
6 "os"
7 "path/filepath"
8 "testing"
9 )
10
11 func TestReadProjectionDoesNotCopyOrDiscardJournals(t *testing.T) {
12 state := newState()
13 state.Generation = 7
14 state.Workspaces["w"] = Workspace{ID: "w", Title: "original", SessionIDs: []string{"s"}}
15 state.SessionStates["s"] = SessionState{Lifecycle: "active"}
16 state.PendingOperations["op"] = Operation{ID: "op", Lifecycle: "active", Kind: "import", Phase: "committed", Request: []byte(`{"large":"journal"}`)}
17 body, err := json.Marshal(state)
18 if err != nil {
19 t.Fatal(err)
20 }
21 path := filepath.Join(t.TempDir(), "state.json")
22 if err := os.WriteFile(path, body, 0600); err != nil {
23 t.Fatal(err)
24 }
25 store := NewStore(path)
26 projection, err := store.LoadProjection(t.Context())
27 if err != nil || projection.Generation != 7 || len(projection.PendingOperations) != 0 {
28 t.Fatalf("invalid display projection: %v", err)
29 }
30 projection.Workspaces["w"].SessionIDs[0] = "changed"
31 full, err := store.Load(t.Context())
32 if err != nil || full.Workspaces["w"].SessionIDs[0] != "s" || len(full.PendingOperations) != 1 {
33 t.Fatalf("projection changed authoritative state: %v", err)
34 }
35 }
36
37 func TestReadCacheObservesReplacementWithoutGenerationOrTimestampChange(t *testing.T) {
38 path := filepath.Join(t.TempDir(), "state.json")
39 body := []byte(`{"version":3,"generation":7,"workspaceIds":["global"],"workspaces":{"global":{"id":"global","title":"first","sessionIds":[]}},"sessionStates":{}}`)
40 if err := os.WriteFile(path, body, 0600); err != nil {
41 t.Fatal(err)
42 }
43 store := NewStore(path)
44 if _, err := store.Load(t.Context()); err != nil {
45 t.Fatal(err)
46 }
47 stat, err := os.Stat(path)
48 if err != nil {
49 t.Fatal(err)
50 }
51 body = bytes.Replace(body, []byte("first"), []byte("other"), 1)
52 if err := os.WriteFile(path, body, 0600); err != nil {
53 t.Fatal(err)
54 }
55 if err := os.Chtimes(path, stat.ModTime(), stat.ModTime()); err != nil {
56 t.Fatal(err)
57 }
58 state, err := store.Load(t.Context())
59 if err != nil || state.Workspaces["global"].Title != "other" {
60 t.Fatalf("stale cache: %v", err)
61 }
62 if err := os.WriteFile(path, []byte("{"), 0600); err != nil {
63 t.Fatal(err)
64 }
65 if _, err := store.Load(t.Context()); err == nil {
66 t.Fatal("cached state hid corruption")
67 }
68 if err := os.Remove(path); err != nil {
69 t.Fatal(err)
70 }
71 state, err = store.Load(t.Context())
72 if err != nil || len(state.Workspaces) != 0 {
73 t.Fatal("cached state survived deletion")
74 }
75 }
76
77 func TestReadCacheIsolatesOperationAndUnknownFields(t *testing.T) {
78 state := newState()
79 state.PendingOperations["op"] = Operation{ID: "op", Request: []byte(`{"value":1}`), Result: []byte(`{"value":2}`),
80 SessionIDs: []string{"s"}, Dependencies: []string{"dep"}, Mapping: &SourceMapping{RetainedArtifacts: []string{"artifact"}},
81 Presentation: &Presentation{Title: "title"}}
82 copy := cloneSnapshot(state)
83 operation := copy.PendingOperations["op"]
84 operation.Request[0], operation.Result[0] = '!', '!'
85 operation.SessionIDs[0], operation.Dependencies[0] = "changed", "changed"
86 operation.Mapping.RetainedArtifacts[0], operation.Presentation.Title = "changed", "changed"
87 original := state.PendingOperations["op"]
88 if original.Request[0] != '{' || original.Result[0] != '{' || original.SessionIDs[0] != "s" || original.Dependencies[0] != "dep" || original.Mapping.RetainedArtifacts[0] != "artifact" || original.Presentation.Title != "title" {
89 t.Fatal("snapshot aliases cached operation storage")
90 }
91 }
92
92 lines GO