返回 DeepSeek-Reasonix
recovered_source_test.go
根目录 / desktop / internal / workspacestate / recovered_source_test.go
1 package workspacestate
2
3 import (
4 "crypto/sha256"
5 "errors"
6 "fmt"
7 "path/filepath"
8 "reflect"
9 "testing"
10 )
11
12 func TestRecoveredSourceFencesCompetingOwnersAndGeneration(t *testing.T) {
13 for _, retired := range []bool{false, true} {
14 t.Run(fmt.Sprint(retired), func(t *testing.T) {
15 ctx := t.Context()
16 store := NewStore(filepath.Join(t.TempDir(), "state.json"))
17 if err := store.EnsureWorkspace(ctx, Workspace{ID: GlobalWorkspaceID}); err != nil {
18 t.Fatal(err)
19 }
20 for _, id := range []string{"old", "current"} {
21 if err := store.AttachSession(ctx, "", GlobalWorkspaceID, id, ""); err != nil {
22 t.Fatal(err)
23 }
24 }
25 path := filepath.Join(t.TempDir(), "source")
26 mapping := SourceMapping{SourceKey: "old-key", Path: path, Format: "canonical", Fingerprint: "proof", SessionID: "old", WorkspaceID: GlobalWorkspaceID}
27 if err := store.RecordSource(ctx, mapping, Presentation{}); err != nil {
28 t.Fatal(err)
29 }
30 if retired {
31 if err := store.ArchiveSession(ctx, "old"); err != nil {
32 t.Fatal(err)
33 }
34 state, err := store.Load(ctx)
35 if err != nil {
36 t.Fatal(err)
37 }
38 if err := store.BeginPurge(ctx, "old", state.Generation); err != nil {
39 t.Fatal(err)
40 }
41 }
42 before, err := store.Load(ctx)
43 if err != nil {
44 t.Fatal(err)
45 }
46 physical, err := sourcePathKey(path)
47 if err != nil {
48 t.Fatal(err)
49 }
50 mapping.SourceKey = fmt.Sprintf("%x", sha256.Sum256([]byte(physical+"\x00")))
51 mapping.SessionID = "current"
52 err = store.RecordRecoveredSource(ctx, mapping, before.Generation)
53 if !retired {
54 if !errors.Is(err, ErrMutationConflict) {
55 t.Fatalf("stole live source: %v", err)
56 }
57 return
58 }
59 if err != nil {
60 t.Fatal(err)
61 }
62 after, err := NewStore(store.Path()).Load(ctx)
63 if err != nil {
64 t.Fatal(err)
65 }
66 if !reflect.DeepEqual(before.SessionStates, after.SessionStates) || !reflect.DeepEqual(before.Workspaces, after.Workspaces) || !reflect.DeepEqual(before.Presentation, after.Presentation) {
67 t.Fatal("receipt repair changed target state")
68 }
69 if err := NewStore(store.Path()).ArchiveSession(ctx, "current"); err != nil {
70 t.Fatal(err)
71 }
72 if err := store.RecordRecoveredSource(ctx, mapping, after.Generation); !errors.Is(err, ErrMutationConflict) {
73 t.Fatalf("stale lifecycle proof accepted: %v", err)
74 }
75 })
76 }
77 }
78
78 lines GO