返回 DeepSeek-Reasonix
session_transition_test.go
根目录 / internal / control / session_transition_test.go
1 package control
2
3 import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "reasonix/internal/agent"
9 "reasonix/internal/event"
10 "reasonix/internal/provider"
11 )
12
13 func transitionController(t *testing.T) (*Controller, *agent.Agent, *SessionLeaseKeeper, string) {
14 t.Helper()
15 dir := t.TempDir()
16 path := filepath.Join(dir, "session.jsonl")
17 sess := agent.NewSession("sys")
18 sess.Add(provider.Message{Role: provider.RoleUser, Content: "hello"})
19 if err := sess.SaveIfAbsent(path); err != nil {
20 t.Fatal(err)
21 }
22 exec := agent.New(nil, nil, sess, agent.Options{}, event.Discard)
23 ctrl := newOwnedTestController(t, Options{Runner: exec, Executor: exec, SessionDir: dir, SessionPath: path, Sink: event.Discard})
24 keeper := NewSessionLeaseKeeper()
25 if err := keeper.Rebind(path); err != nil {
26 t.Fatal(err)
27 }
28 if err := keeper.BindControllerAuthority(ctrl); err != nil {
29 t.Fatal(err)
30 }
31 t.Cleanup(keeper.Release)
32 return ctrl, exec, keeper, path
33 }
34
35 func assertTransitionOwner(t *testing.T, ctrl *Controller, exec *agent.Agent, keeper *SessionLeaseKeeper, originalPath string) {
36 t.Helper()
37 targetPath := ctrl.SessionPath()
38 if targetPath == originalPath {
39 t.Fatal("session path did not rotate")
40 }
41 if got := keeper.HeldPath(); got != agent.CanonicalSessionPath(targetPath) {
42 t.Fatalf("keeper path = %q, want %q", got, agent.CanonicalSessionPath(targetPath))
43 }
44 if auth := exec.Session().WriteAuthority(); auth == nil || !auth.Covers(targetPath) {
45 t.Fatal("rotated Session was published without target authority")
46 }
47 }
48
49 func TestNewSessionTransfersWriterBeforePublish(t *testing.T) {
50 ctrl, exec, keeper, originalPath := transitionController(t)
51 if err := ctrl.NewSession(); err != nil {
52 t.Fatalf("NewSession: %v", err)
53 }
54 assertTransitionOwner(t, ctrl, exec, keeper, originalPath)
55 if _, err := os.Stat(originalPath); err != nil {
56 t.Fatalf("NewSession removed parent transcript: %v", err)
57 }
58 }
59
60 func TestClearSessionTransfersWriterBeforePublish(t *testing.T) {
61 ctrl, exec, keeper, originalPath := transitionController(t)
62 if err := ctrl.ClearSession(); err != nil {
63 t.Fatalf("ClearSession: %v", err)
64 }
65 assertTransitionOwner(t, ctrl, exec, keeper, originalPath)
66 if _, err := os.Stat(originalPath); !os.IsNotExist(err) {
67 t.Fatalf("ClearSession source stat = %v, want removed", err)
68 }
69 }
70
70 lines GO