返回 DeepSeek-Reasonix
event_tail_test.go
根目录 / internal / taskmonitor / event_tail_test.go
1 package taskmonitor
2
3 import (
4 "context"
5 "encoding/json"
6 "os"
7 "path/filepath"
8 "testing"
9 "time"
10 )
11
12 func TestReadEventTailKeepsIncompleteLineForRetry(t *testing.T) {
13 t.Parallel()
14 root := t.TempDir()
15 store := NewFileStore(filepath.Join(".reasonix", "tasks"))
16 now := time.Now()
17 first := TaskEvent{Timestamp: now, EventType: "state_change", TaskID: "task", State: TaskStateRunning}
18 if err := store.AppendAuditEvent(context.Background(), root, first); err != nil {
19 t.Fatal(err)
20 }
21 tail, err := store.ReadEventTail(context.Background(), root, "task", 0)
22 if err != nil || len(tail.Items) != 1 {
23 t.Fatalf("first tail=%#v err=%v", tail, err)
24 }
25 checkpoint := tail.NextOffset
26 second := TaskEvent{Sequence: 2, Timestamp: now.Add(time.Second), EventType: "state_change", TaskID: "task", State: TaskStateSucceeded}
27 line, _ := json.Marshal(second)
28 path := filepath.Join(root, ".reasonix", "tasks", "task", "events.jsonl")
29 f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0o600)
30 if err != nil {
31 t.Fatal(err)
32 }
33 _, _ = f.Write(line)
34 _ = f.Close()
35 tail, err = store.ReadEventTail(context.Background(), root, "task", checkpoint)
36 if err != nil || len(tail.Items) != 0 || tail.NextOffset != checkpoint {
37 t.Fatalf("incomplete tail=%#v err=%v", tail, err)
38 }
39 f, err = os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0o600)
40 if err != nil {
41 t.Fatal(err)
42 }
43 _, _ = f.Write([]byte{'\n'})
44 _ = f.Close()
45 tail, err = store.ReadEventTail(context.Background(), root, "task", checkpoint)
46 if err != nil || len(tail.Items) != 1 || tail.Items[0].Sequence != 2 {
47 t.Fatalf("completed tail=%#v err=%v", tail, err)
48 }
49 }
50
50 lines GO