返回 DeepSeek-Reasonix
queue_mutations_test.go
根目录 / internal / sessioninbox / queue_mutations_test.go
1 package sessioninbox
2
3 import (
4 "errors"
5 "path/filepath"
6 "testing"
7 )
8
9 func TestPreparedQueueCrossWriterEditAndMove(t *testing.T) {
10 path := filepath.Join(t.TempDir(), "s.jsonl")
11 s, err := Open(path, Limits{})
12 if err != nil {
13 t.Fatal(err)
14 }
15 defer s.Close()
16 other, err := Open(path, Limits{})
17 if err != nil {
18 t.Fatal(err)
19 }
20 defer other.Close()
21 enqueue := func(text string, intent InboxIntent) string {
22 t.Helper()
23 r, err := s.Enqueue(EnqueueRequest{Intent: intent, Envelope: PromptEnvelope{SubmitText: text, DisplayText: text}})
24 if err != nil {
25 t.Fatal(err)
26 }
27 return r.ItemID
28 }
29 a, b := enqueue("first", IntentSteer), enqueue("second", IntentFollowup)
30 if head, _ := s.NextQueued(); head.ID != a {
31 t.Fatal("hidden intent priority reordered queue")
32 }
33 prepared, env, _ := s.ReadItem(a)
34 env.SubmitText, env.RawText, env.DisplayText = " edited\nbody ", " edited\nbody ", " edited\nbody "
35 updated, err := other.UpdateItemIfVersion(a, env, ContentVersion(prepared))
36 if err != nil {
37 t.Fatal(err)
38 }
39 if err := s.TransitionPrepared(a, ContentVersion(prepared), StateRunning, "", true); !errors.Is(err, ErrContentChanged) {
40 t.Fatalf("stale body claim: %v", err)
41 }
42 if _, err := s.UpdateItemIfVersion(a, env, ContentVersion(prepared)); !errors.Is(err, ErrContentChanged) {
43 t.Fatalf("stale save: %v", err)
44 }
45 if err := other.MoveItemBefore(b, &a, other.Snapshot().Revision); err != nil {
46 t.Fatal(err)
47 }
48 if err := s.TransitionPrepared(a, ContentVersion(updated), StateRunning, "", true); !errors.Is(err, ErrOrderChanged) {
49 t.Fatalf("stale head claim: %v", err)
50 }
51 if err := s.TransitionPrepared(a, ContentVersion(updated), StateBlocked, "stale failure", true); !errors.Is(err, ErrOrderChanged) {
52 t.Fatalf("stale preparation failure: %v", err)
53 }
54 metaB, _, _ := other.ReadItem(b)
55 if err := s.TransitionPrepared(b, ContentVersion(metaB), StateRunning, "", true); err != nil {
56 t.Fatal(err)
57 }
58 if _, err := other.UpdateItemIfVersion(b, env, ContentVersion(metaB)); !errors.Is(err, ErrInvalidState) {
59 t.Fatalf("edited running item: %v", err)
60 }
61 _, actual, _ := s.ReadItem(a)
62 if actual.SubmitText != env.SubmitText {
63 t.Fatalf("text was normalized: %q", actual.SubmitText)
64 }
65 }
66
67 func TestQueuePauseUncertainAndPersistentAnchors(t *testing.T) {
68 path := filepath.Join(t.TempDir(), "s.jsonl")
69 s, err := Open(path, Limits{})
70 if err != nil {
71 t.Fatal(err)
72 }
73 var ids []string
74 for _, text := range []string{"a", "b", "c"} {
75 r, err := s.Enqueue(EnqueueRequest{Envelope: PromptEnvelope{SubmitText: text}})
76 if err != nil {
77 t.Fatal(err)
78 }
79 ids = append(ids, r.ItemID)
80 }
81 if err := s.SetState(ids[0], StateUncertain, "unknown"); err != nil {
82 t.Fatal(err)
83 }
84 if _, found := s.NextQueued(); found {
85 t.Fatal("bypassed uncertain head")
86 }
87 if err := s.SetPaused(true); err != nil {
88 t.Fatal(err)
89 }
90 meta, env, _ := s.ReadItem(ids[0])
91 env.SubmitText = "edited uncertain"
92 if _, err := s.UpdateItemIfVersion(ids[0], env, ContentVersion(meta)); err != nil {
93 t.Fatal(err)
94 }
95 if snap := s.Snapshot(); !snap.Paused || snap.Items[0].State != StateUncertain {
96 t.Fatal("edit resumed uncertain delivery")
97 }
98 rev := s.Snapshot().Revision
99 missing := "missing"
100 if err := s.MoveItemBefore(ids[0], &missing, rev); !errors.Is(err, ErrAnchorMissing) {
101 t.Fatal(err)
102 }
103 if err := s.MoveItemBefore(ids[0], nil, rev); err != nil {
104 t.Fatal(err)
105 }
106 if err := s.MoveItemBefore(ids[1], nil, rev); !errors.Is(err, ErrOrderChanged) {
107 t.Fatal(err)
108 }
109 s.Close()
110 s, err = Open(path, Limits{})
111 if err != nil {
112 t.Fatal(err)
113 }
114 defer s.Close()
115 snap := s.Snapshot()
116 if !snap.Paused || snap.Items[0].ID != ids[1] || snap.Items[2].ID != ids[0] {
117 t.Fatalf("order not durable: %+v", snap)
118 }
119 }
120
121 func TestVersionedAppendCannotOverwriteEditAndReplaysAlias(t *testing.T) {
122 s, err := Open(filepath.Join(t.TempDir(), "s.jsonl"), Limits{})
123 if err != nil {
124 t.Fatal(err)
125 }
126 defer s.Close()
127 receipt, err := s.Enqueue(EnqueueRequest{Envelope: PromptEnvelope{SubmitText: "original"}})
128 if err != nil {
129 t.Fatal(err)
130 }
131 meta, env, _ := s.ReadItem(receipt.ItemID)
132 version := ContentVersion(meta)
133 env.SubmitText = "edited"
134 updated, err := s.UpdateItemIfVersion(meta.ID, env, version)
135 if err != nil {
136 t.Fatal(err)
137 }
138 alias := PromptEnvelope{SubmitText: "append", Source: "bot"}
139 env.SubmitText = "original\nappend"
140 if _, err := s.UpdateItemWithIdempotencyIfVersion(meta.ID, env, "append-1", alias, version); !errors.Is(err, ErrContentChanged) {
141 t.Fatalf("stale append overwrote edit: %v", err)
142 }
143 env.SubmitText = "edited\nappend"
144 version = ContentVersion(updated)
145 if _, err := s.UpdateItemWithIdempotencyIfVersion(meta.ID, env, "append-1", alias, version); err != nil {
146 t.Fatal(err)
147 }
148 env.SubmitText += "\nappend"
149 if _, err := s.UpdateItemWithIdempotencyIfVersion(meta.ID, env, "append-1", alias, version); err != nil {
150 t.Fatalf("lost-response retry must replay alias: %v", err)
151 }
152 _, stored, _ := s.ReadItem(meta.ID)
153 if stored.SubmitText != "edited\nappend" {
154 t.Fatalf("duplicated append: %q", stored.SubmitText)
155 }
156 }
157
157 lines GO