返回 DeepSeek-Reasonix
cancel_observation_test.go
根目录 / internal / control / cancel_observation_test.go
1 package control
2
3 import (
4 "context"
5 "sync"
6 "testing"
7 "time"
8 )
9
10 func TestCancelSessionSignalsAndAcknowledgesWhileSamplingBlocked(t *testing.T) {
11 isolateControlConfigHome(t)
12 c := newOwnedTestController(t, Options{SessionDir: t.TempDir()})
13 defer c.Close()
14 started, cancelled, releaseBody := make(chan struct{}), make(chan struct{}), make(chan struct{})
15 defer close(releaseBody)
16 c.runGuarded(func(ctx context.Context) error {
17 close(started)
18 <-ctx.Done()
19 close(cancelled)
20 <-releaseBody
21 return ctx.Err()
22 })
23 <-started
24 c.runtimeState.mu.Lock()
25 unlock := sync.OnceFunc(c.runtimeState.mu.Unlock)
26 defer unlock()
27 returned := make(chan CancelReceipt, 1)
28 go func() { returned <- c.CancelSessionFrom("test") }()
29 select {
30 case <-cancelled:
31 case <-time.After(5 * time.Second):
32 t.Fatal("Stop waited for state observation before signalling execution")
33 }
34 select {
35 case receipt := <-returned:
36 if !receipt.Accepted || receipt.AlreadyIdle || receipt.RuntimeEpoch == "" {
37 t.Fatalf("incorrect cancellation receipt: %+v", receipt)
38 }
39 case <-time.After(5 * time.Second):
40 t.Fatal("Stop receipt waited for state observation")
41 }
42 }
43
44 func TestMaintenanceCancelAcknowledgesWhilePublicationBlocked(t *testing.T) {
45 isolateControlConfigHome(t)
46 c := newOwnedTestController(t, Options{SessionDir: t.TempDir()})
47 defer c.Close()
48 ctx, cancel := context.WithCancel(context.Background())
49 op := &controllerMaintenance{maintenanceIdentity: maintenanceIdentity{id: "cancel-test"}, activity: "running", cancel: cancel, done: make(chan struct{})}
50 c.mu.Lock()
51 c.maintenance = op
52 c.mu.Unlock()
53 defer func() {
54 c.mu.Lock()
55 c.maintenance = nil
56 close(op.done)
57 c.mu.Unlock()
58 }()
59 op.publishMu.Lock()
60 defer op.publishMu.Unlock()
61 returned := make(chan CancelReceipt, 1)
62 go func() { returned <- c.CancelSessionFrom("test") }()
63 select {
64 case <-ctx.Done():
65 case <-time.After(5 * time.Second):
66 t.Fatal("maintenance cancellation did not signal its owner")
67 }
68 select {
69 case receipt := <-returned:
70 if !receipt.Accepted || receipt.AlreadyIdle {
71 t.Fatalf("maintenance receipt = %+v", receipt)
72 }
73 case <-time.After(5 * time.Second):
74 t.Fatal("maintenance receipt waited for publication")
75 }
76 }
77
77 lines GO