返回 DeepSeek-Reasonix
resume_lease_order_test.go
根目录 / internal / cli / resume_lease_order_test.go
1 package cli
2
3 import (
4 "errors"
5 "path/filepath"
6 "testing"
7
8 "reasonix/internal/agent"
9 "reasonix/internal/control"
10 )
11
12 func TestBindAndLoadCLIResumeHoldsLeaseBeforeReading(t *testing.T) {
13 path := filepath.Join(t.TempDir(), "resume.jsonl")
14 saveTestSession(t, path, "latest prompt")
15
16 leases := control.NewSessionLeaseKeeper()
17 defer leases.Release()
18 loaded, err := bindAndLoadCLIResume(leases, path, func(candidate string) (*agent.Session, error) {
19 contender, acquireErr := agent.TryAcquireSessionLease(candidate)
20 if contender != nil {
21 contender.Release()
22 }
23 if !errors.Is(acquireErr, agent.ErrSessionLeaseHeld) {
24 t.Fatalf("loader observed lease error %v, want held", acquireErr)
25 }
26 return agent.LoadSession(candidate)
27 })
28 if err != nil {
29 t.Fatal(err)
30 }
31 if loaded == nil {
32 t.Fatal("resume returned a nil session")
33 }
34 }
35
36 func TestBindAndLoadCLIResumeDoesNotReadHeldSession(t *testing.T) {
37 path := filepath.Join(t.TempDir(), "held.jsonl")
38 holder, err := agent.TryAcquireSessionLease(path)
39 if err != nil {
40 t.Fatal(err)
41 }
42 defer holder.Release()
43
44 leases := control.NewSessionLeaseKeeper()
45 defer leases.Release()
46 called := false
47 _, err = bindAndLoadCLIResume(leases, path, func(string) (*agent.Session, error) {
48 called = true
49 return nil, nil
50 })
51 if !errors.Is(err, agent.ErrSessionLeaseHeld) {
52 t.Fatalf("bindAndLoadCLIResume error = %v, want held", err)
53 }
54 if called {
55 t.Fatal("held session was read before takeover acquired its lease")
56 }
57 }
58
59 func TestCommitSessionSwitchAcquiresTargetBeforeLoading(t *testing.T) {
60 dir := t.TempDir()
61 source := filepath.Join(dir, "source.jsonl")
62 target := filepath.Join(dir, "target.jsonl")
63 leases := control.NewSessionLeaseKeeper()
64 defer leases.Release()
65 if err := leases.Rebind(source); err != nil {
66 t.Fatal(err)
67 }
68 m := &chatTUI{leases: leases}
69 wantErr := errors.New("stop after ownership check")
70 err := m.commitSessionSwitchWithLoader(target, func(candidate string) (*agent.Session, error) {
71 contender, acquireErr := agent.TryAcquireSessionLease(candidate)
72 if contender != nil {
73 contender.Release()
74 }
75 if !errors.Is(acquireErr, agent.ErrSessionLeaseHeld) {
76 t.Fatalf("switch loader observed lease error %v, want held", acquireErr)
77 }
78 return nil, wantErr
79 })
80 if !errors.Is(err, wantErr) {
81 t.Fatalf("commitSessionSwitch error = %v, want %v", err, wantErr)
82 }
83 if got := leases.HeldPath(); got != agent.CanonicalSessionPath(source) {
84 t.Fatalf("source lease was not restored after load failure: %q", got)
85 }
86 }
87
87 lines GO