返回 DeepSeek-Reasonix
run_test.go
根目录 / internal / proc / run_test.go
1 package proc
2
3 import (
4 "context"
5 "errors"
6 "testing"
7 "time"
8 )
9
10 func TestWaitForTrackedCommandReturnsWhenWaitStallsAfterCancel(t *testing.T) {
11 ctx, cancel := context.WithCancel(context.Background())
12 cancel()
13 tracked := &TrackedCommand{}
14 releaseWait := make(chan struct{})
15 defer close(releaseWait)
16
17 start := time.Now()
18 err := waitForTrackedCommand(ctx, tracked, func() error {
19 <-releaseWait
20 return nil
21 }, 20*time.Millisecond, time.Millisecond, time.Millisecond)
22 elapsed := time.Since(start)
23
24 if !errors.Is(err, context.Canceled) {
25 t.Fatalf("error = %v, want context.Canceled", err)
26 }
27 if elapsed > time.Second {
28 t.Fatalf("cancelled stalled wait returned too slowly: %v", elapsed)
29 }
30 if tracked.Diagnostics().KillCalls == 0 {
31 t.Fatal("tracked command was not killed")
32 }
33 if !tracked.Diagnostics().CancelWaitGraceExpired {
34 t.Fatal("cancelled stalled wait did not record grace expiry")
35 }
36 }
37
38 func TestWaitForTrackedCommandKeepsWaitErrorAfterCancel(t *testing.T) {
39 ctx, cancel := context.WithCancel(context.Background())
40 tracked := &TrackedCommand{}
41 waitStarted := make(chan struct{})
42 releaseWait := make(chan struct{})
43 errWait := errors.New("wait failed after cancel")
44 done := make(chan error, 1)
45
46 go func() {
47 done <- waitForTrackedCommand(ctx, tracked, func() error {
48 close(waitStarted)
49 <-releaseWait
50 return errWait
51 }, time.Second, time.Millisecond, time.Millisecond)
52 }()
53
54 <-waitStarted
55 cancel()
56 waitUntilTrackedCommandKilled(t, tracked)
57 close(releaseWait)
58
59 select {
60 case err := <-done:
61 if err.Error() != context.Canceled.Error() {
62 t.Fatalf("error text = %q, want %q", err.Error(), context.Canceled.Error())
63 }
64 if !errors.Is(err, context.Canceled) {
65 t.Fatalf("error = %v, want context.Canceled", err)
66 }
67 if !errors.Is(err, errWait) {
68 t.Fatalf("error = %v, want wrapped wait error %v", err, errWait)
69 }
70 case <-time.After(time.Second):
71 t.Fatal("timed out waiting for cancelled command wait")
72 }
73 }
74
75 func waitUntilTrackedCommandKilled(t *testing.T, tracked *TrackedCommand) {
76 t.Helper()
77 deadline := time.After(time.Second)
78 for {
79 if tracked.Diagnostics().KillCalls > 0 {
80 return
81 }
82 select {
83 case <-deadline:
84 t.Fatal("timed out waiting for tracked command kill")
85 default:
86 time.Sleep(time.Millisecond)
87 }
88 }
89 }
90
90 lines GO