返回 DeepSeek-Reasonix
snapshot_conflict_diagnostic_test.go
根目录 / internal / control / snapshot_conflict_diagnostic_test.go
1 package control
2
3 import (
4 "bufio"
5 "encoding/json"
6 "os"
7 "path/filepath"
8 "strings"
9 "testing"
10
11 "reasonix/internal/agent"
12 "reasonix/internal/store"
13 )
14
15 func TestSnapshotConflictDiagnosticCountsLogicalTopicWithoutLeakingIdentity(t *testing.T) {
16 dir := t.TempDir()
17 first := filepath.Join(dir, "first.jsonl")
18 second := filepath.Join(dir, "second.jsonl")
19 for _, path := range []string{first, second} {
20 if err := agent.SaveBranchMeta(path, agent.BranchMeta{
21 ID: agent.BranchID(path), Scope: "project", WorkspaceRoot: "/private/workspace",
22 TopicID: "private-topic-id", TopicTitle: "private topic title", CustomTitle: "private version note",
23 }); err != nil {
24 t.Fatal(err)
25 }
26 }
27 appendSnapshotConflictDiagnostic(first, "save", "forked_recovery_branch", nil, "", false)
28 appendSnapshotConflictDiagnostic(second, "shutdown", "forked_file_lock_recovery", nil, "", false)
29
30 read := func(path string) snapshotConflictDiagnostic {
31 t.Helper()
32 file, err := os.Open(store.SessionConflictLog(path))
33 if err != nil {
34 t.Fatal(err)
35 }
36 defer file.Close()
37 scanner := bufio.NewScanner(file)
38 if !scanner.Scan() {
39 t.Fatalf("missing diagnostic for %s", agent.BranchID(path))
40 }
41 var record snapshotConflictDiagnostic
42 if err := json.Unmarshal(scanner.Bytes(), &record); err != nil {
43 t.Fatal(err)
44 }
45 for _, secret := range []string{dir, "/private/workspace", "private-topic-id", "private topic title", "private version note"} {
46 if strings.Contains(scanner.Text(), secret) {
47 t.Fatalf("diagnostic leaked %q: %s", secret, scanner.Text())
48 }
49 }
50 return record
51 }
52 firstRecord := read(first)
53 secondRecord := read(second)
54 if firstRecord.Occurrence != 1 || firstRecord.Repeated {
55 t.Fatalf("first occurrence = %+v", firstRecord)
56 }
57 if secondRecord.Occurrence != 2 || !secondRecord.Repeated {
58 t.Fatalf("second occurrence = %+v", secondRecord)
59 }
60 }
61
62 func TestSnapshotConflictDiagnosticKeepsFirstRepeatedSamePathRecovery(t *testing.T) {
63 dir := t.TempDir()
64 path := filepath.Join(dir, "same.jsonl")
65 if err := agent.SaveBranchMeta(path, agent.BranchMeta{
66 ID: agent.BranchID(path), Scope: "project", WorkspaceRoot: "/private/repeat-workspace",
67 TopicID: "private-repeat-topic", TopicTitle: "private repeat title",
68 }); err != nil {
69 t.Fatal(err)
70 }
71
72 appendSnapshotConflictDiagnostic(path, "save", "forked_recovery_branch", nil, "", false)
73 appendSnapshotConflictDiagnostic(path, "save", "forked_recovery_branch", nil, "", false)
74 appendSnapshotConflictDiagnostic(path, "save", "forked_recovery_branch", nil, "", false)
75
76 file, err := os.Open(store.SessionConflictLog(path))
77 if err != nil {
78 t.Fatal(err)
79 }
80 defer file.Close()
81 scanner := bufio.NewScanner(file)
82 records := []snapshotConflictDiagnostic{}
83 for scanner.Scan() {
84 for _, secret := range []string{dir, "/private/repeat-workspace", "private-repeat-topic", "private repeat title"} {
85 if strings.Contains(scanner.Text(), secret) {
86 t.Fatalf("diagnostic leaked %q: %s", secret, scanner.Text())
87 }
88 }
89 var record snapshotConflictDiagnostic
90 if err := json.Unmarshal(scanner.Bytes(), &record); err != nil {
91 t.Fatal(err)
92 }
93 records = append(records, record)
94 }
95 if err := scanner.Err(); err != nil {
96 t.Fatal(err)
97 }
98 if len(records) != 2 {
99 t.Fatalf("records = %+v, want first event plus one bounded repeat", records)
100 }
101 if records[0].Occurrence != 1 || records[0].Repeated || records[1].Occurrence != 2 || !records[1].Repeated {
102 t.Fatalf("occurrences = %+v, want 1 then repeated 2", records)
103 }
104 }
105
105 lines GO