返回 DeepSeek-Reasonix
cancellation_test.go
根目录 / desktop / internal / hostrpc / cancellation_test.go
1 package hostrpc
2
3 import (
4 "context"
5 "errors"
6 "testing"
7 )
8
9 var cancelWhileDecoding context.CancelFunc
10
11 type cancelingArgument string
12 type requestContextKey struct{}
13
14 func (*cancelingArgument) UnmarshalJSON([]byte) error { cancelWhileDecoding(); return nil }
15
16 type cancellationTarget struct {
17 calls int
18 cancel context.CancelFunc
19 seen context.Context
20 }
21
22 func (f *cancellationTarget) DecodeWrite(cancelingArgument) { f.calls++ }
23 func (f *cancellationTarget) Write() string { f.calls++; f.cancel(); return "committed" }
24 func (f *cancellationTarget) Cooperative(ctx context.Context, value string) (string, error) {
25 f.seen = ctx
26 f.calls++
27 return value, nil
28 }
29
30 func TestCancellationAfterDecodeDoesNotDispatch(t *testing.T) {
31 ctx, cancel := context.WithCancel(context.Background())
32 defer cancel()
33 cancelWhileDecoding = cancel
34 t.Cleanup(func() { cancelWhileDecoding = nil })
35 target := &cancellationTarget{}
36 _, err := mustRegistry(t, target, nil).Invoke(ctx, "DecodeWrite", raw(`"value"`))
37 if !errors.Is(err, context.Canceled) || target.calls != 0 {
38 t.Fatalf("err=%v calls=%d", err, target.calls)
39 }
40 }
41
42 func TestDispatchedWriteKeepsSuccessAfterCancellation(t *testing.T) {
43 ctx, cancel := context.WithCancel(context.Background())
44 defer cancel()
45 target := &cancellationTarget{cancel: cancel}
46 got, err := mustRegistry(t, target, nil).Invoke(ctx, "Write", nil)
47 if err != nil || got != "committed" || target.calls != 1 || ctx.Err() == nil {
48 t.Fatalf("result=%v err=%v calls=%d", got, err, target.calls)
49 }
50 }
51
52 func TestLeadingContextIsHostOnlyAndPassedToOwner(t *testing.T) {
53 target := &cancellationTarget{}
54 r := mustRegistry(t, target, nil)
55 ctx := context.WithValue(context.Background(), requestContextKey{}, "request")
56 got, err := r.Invoke(ctx, "Cooperative", raw(`"value"`))
57 if err != nil || got != "value" || target.seen != ctx {
58 t.Fatalf("result=%v err=%v context=%v", got, err, target.seen)
59 }
60 for _, cmd := range r.Commands() {
61 if cmd.Name == "Cooperative" && (len(cmd.Params) != 1 || cmd.Params[0].Kind != KindString || cmd.Cancellation != "cooperative-context") {
62 t.Fatalf("wire command=%+v", cmd)
63 }
64 }
65 }
66
66 lines GO