返回 DeepSeek-Reasonix
session_display_pager_dag_test.go
根目录 / internal / agent / session_display_pager_dag_test.go
1 package agent
2
3 import (
4 "os"
5 "path/filepath"
6 "reflect"
7 "testing"
8 "time"
9
10 "reasonix/internal/provider"
11 "reasonix/internal/store"
12 )
13
14 func TestDisplayPagerDAGSelectedBranchMatchesNativeReplay(t *testing.T) {
15 path := dagTestSession(t)
16 if err := os.WriteFile(path, nil, 0600); err != nil {
17 t.Fatal(err)
18 }
19 _, at := dagLinearLog(t, path)
20 patch, err := encodeSessionDAGMessage(dagMsg(provider.RoleAssistant, "patched answer", "A1"))
21 if err != nil {
22 t.Fatal(err)
23 }
24 system, err := encodeSessionDAGMessage(dagMsg(provider.RoleSystem, "fork system", "override"))
25 if err != nil {
26 t.Fatal(err)
27 }
28 dagAppend(t, path,
29 sessionDAGEntry{Type: sessionDAGTypePatch, Target: "A1", Msgs: patch, At: at},
30 sessionDAGEntry{Type: sessionDAGTypeFork, Head: SessionMainHead, NewHead: "fork", From: "A1", At: at.Add(5 * time.Second)},
31 sessionDAGEntry{Type: sessionDAGTypeSystem, Head: "fork", Msgs: system, At: at},
32 dagMessageEntry(t, "fork", "A1", "t2", dagMsg(provider.RoleUser, "fork question", "F1"), at.Add(6*time.Second)),
33 sessionDAGEntry{Type: sessionDAGTypeSelect, Head: "fork", At: at},
34 )
35 original, err := os.ReadFile(store.SessionEventLog(path))
36 if err != nil {
37 t.Fatal(err)
38 }
39 for _, requested := range []string{"", SessionMainHead, "fork"} {
40 t.Run("head="+requested, func(t *testing.T) {
41 p, err := OpenDisplayPager(t.Context(), path, filepath.Join(t.TempDir(), "dag.sqlite"), requested)
42 if err != nil {
43 t.Fatal(err)
44 }
45 defer p.Close()
46 if !p.DAG || len(p.Header.Entries) != 0 {
47 t.Fatal("DAG was not disk paged")
48 }
49 got, err := p.DAGMessages(0, p.Header.MessageCount)
50 if err != nil {
51 t.Fatal(err)
52 }
53 st := dagReplay(t, path)
54 head := requested
55 if head == "" {
56 head = st.selectedHead()
57 }
58 want, _ := st.materialize(head)
59 for i := range got {
60 got[i].CreatedAt = want[i].CreatedAt
61 }
62 if !reflect.DeepEqual(got, want) {
63 t.Fatalf("DAG differs from native selected view: got=%+v want=%+v", got, want)
64 }
65 turns, err := p.TurnEntries(1, 1000)
66 if err != nil {
67 t.Fatal(err)
68 }
69 wantIndex := BuildSessionDisplayIndex(want, 0, false, [32]byte{})
70 var expected []DisplayIndexEntry
71 for _, entry := range wantIndex.Entries {
72 if entry.StartsTurn {
73 expected = append(expected, entry)
74 }
75 }
76 if len(turns) != len(expected) {
77 t.Fatalf("outline count %d != selected branch %d", len(turns), len(expected))
78 }
79 for i, entry := range turns {
80 if entry.Index != expected[i].Index || entry.AuthoredTurn != expected[i].AuthoredTurn {
81 t.Fatalf("outline disagrees with branch replay: %+v != %+v", entry, expected[i])
82 }
83 }
84 })
85 }
86 after, _ := os.ReadFile(store.SessionEventLog(path))
87 if !reflect.DeepEqual(original, after) {
88 t.Fatal("reading mutated the authoritative graph")
89 }
90 }
91
92 func TestDisplayPagerDAGDamageDoesNotPublishPrefix(t *testing.T) {
93 path := dagTestSession(t)
94 if err := os.WriteFile(path, nil, 0600); err != nil {
95 t.Fatal(err)
96 }
97 dagLinearLog(t, path)
98 f, err := os.OpenFile(store.SessionEventLog(path), os.O_APPEND|os.O_WRONLY, 0600)
99 if err != nil {
100 t.Fatal(err)
101 }
102 if _, err := f.WriteString("{\"schema_version\":2,"); err != nil {
103 t.Fatal(err)
104 }
105 if err := f.Close(); err != nil {
106 t.Fatal(err)
107 }
108 if p, err := OpenDisplayPager(t.Context(), path, filepath.Join(t.TempDir(), "dag.sqlite")); err == nil {
109 p.Close()
110 t.Fatal("damaged prefix published as complete")
111 }
112 }
113
113 lines GO