返回 DeepSeek-Reasonix
session_listing_repair_publish_cancel_test.go
根目录 / internal / agent / session_listing_repair_publish_cancel_test.go
1 package agent
2
3 import (
4 "context"
5 "errors"
6 "os"
7 "path/filepath"
8 "strings"
9 "testing"
10 "time"
11
12 "reasonix/internal/provider"
13 "reasonix/internal/store"
14 )
15
16 func TestRepairSessionListingProjectionCancelsDuringPublish(t *testing.T) {
17 dir := t.TempDir()
18 path := filepath.Join(dir, "large-publish.jsonl")
19 writeSessionFile(t, path, []provider.Message{{
20 Role: provider.RoleUser, Content: "large", Images: []string{strings.Repeat("a", 49<<20)},
21 }})
22 wrong := strings.Repeat("0", 64)
23 if err := SaveBranchMeta(path, BranchMeta{
24 ID: BranchID(path), Revision: 7, ContentDigest: wrong, SchemaVersion: 1,
25 }); err != nil {
26 t.Fatal(err)
27 }
28
29 ctx, cancel := context.WithCancel(context.Background())
30 publishStarted := make(chan struct{})
31 ctx = withSessionPublishStartHook(ctx, func() {
32 close(publishStarted)
33 <-ctx.Done()
34 })
35 done := make(chan error, 1)
36 go func() {
37 _, err := RepairSessionListingProjection(ctx, path)
38 done <- err
39 }()
40 select {
41 case <-publishStarted:
42 case <-time.After(30 * time.Second):
43 cancel()
44 t.Fatal("repair never reached transcript publication")
45 }
46 if !sessionPublishTempExists(t, dir) {
47 cancel()
48 t.Fatal("publication boundary did not create its temp file")
49 }
50 cancelStarted := time.Now()
51 cancel()
52 select {
53 case err := <-done:
54 if !errors.Is(err, context.Canceled) {
55 t.Fatalf("repair err = %v, want context cancellation", err)
56 }
57 case <-time.After(2 * time.Second):
58 t.Fatal("publish cancellation did not release the session locks promptly")
59 }
60 if elapsed := time.Since(cancelStarted); elapsed > 2*time.Second {
61 t.Fatalf("publish cancellation took %v", elapsed)
62 }
63 if sessionPublishTempExists(t, dir) {
64 t.Fatal("canceled repair left a transcript temp file")
65 }
66 meta, ok, err := LoadBranchMeta(path)
67 if err != nil || !ok || meta.Revision != 7 || meta.ContentDigest != wrong {
68 t.Fatalf("canceled repair published meta: ok=%v err=%v meta=%+v", ok, err, meta)
69 }
70 for _, sidecar := range []string{store.SessionEventIndex(path), store.SessionDisplayIndex(path)} {
71 if _, err := os.Stat(sidecar); !os.IsNotExist(err) {
72 t.Fatalf("canceled repair published sidecar %q: %v", sidecar, err)
73 }
74 }
75 }
76
77 func sessionPublishTempExists(t *testing.T, dir string) bool {
78 t.Helper()
79 entries, err := os.ReadDir(dir)
80 if err != nil {
81 t.Fatal(err)
82 }
83 for _, entry := range entries {
84 if strings.HasPrefix(entry.Name(), ".session.") && strings.HasSuffix(entry.Name(), ".tmp") {
85 return true
86 }
87 }
88 return false
89 }
90
90 lines GO