1
16
17 package ktesting
18
19 import (
20 "context"
21 "errors"
22 "os"
23 "strings"
24 "testing"
25 "time"
26
27 "github.com/stretchr/testify/assert"
28 )
29
30 func TestCleanupErr(t *testing.T) {
31 actual := cleanupErr(t.Name())
32 if !errors.Is(actual, context.Canceled) {
33 t.Errorf("cleanupErr %T should be a %T", actual, context.Canceled)
34 }
35 }
36
37 func TestCause(t *testing.T) {
38 timeoutCause := canceledError("I timed out")
39 parentCause := errors.New("parent canceled")
40
41 t.Parallel()
42 for name, tt := range map[string]struct {
43 parentCtx context.Context
44 timeout time.Duration
45 sleep time.Duration
46 cancelCause string
47 expectErr, expectCause error
48 expectDeadline time.Duration
49 }{
50 "nothing": {
51 parentCtx: context.Background(),
52 timeout: 5 * time.Millisecond,
53 sleep: time.Millisecond,
54 },
55 "timeout": {
56 parentCtx: context.Background(),
57 timeout: time.Millisecond,
58 sleep: 5 * time.Millisecond,
59 expectErr: context.Canceled,
60 expectCause: canceledError(timeoutCause),
61 },
62 "parent-canceled": {
63 parentCtx: func() context.Context {
64 ctx, cancel := context.WithCancel(context.Background())
65 cancel()
66 return ctx
67 }(),
68 timeout: time.Millisecond,
69 sleep: 5 * time.Millisecond,
70 expectErr: context.Canceled,
71 expectCause: context.Canceled,
72 },
73 "parent-cause": {
74 parentCtx: func() context.Context {
75 ctx, cancel := context.WithCancelCause(context.Background())
76 cancel(parentCause)
77 return ctx
78 }(),
79 timeout: time.Millisecond,
80 sleep: 5 * time.Millisecond,
81 expectErr: context.Canceled,
82 expectCause: parentCause,
83 },
84 "deadline-no-parent": {
85 parentCtx: context.Background(),
86 timeout: time.Minute,
87 expectDeadline: time.Minute,
88 },
89 "deadline-parent": {
90 parentCtx: func() context.Context {
91 ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
92 t.Cleanup(cancel)
93 return ctx
94 }(),
95 timeout: 2 * time.Minute,
96 expectDeadline: time.Minute,
97 },
98 "deadline-child": {
99 parentCtx: func() context.Context {
100 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
101 t.Cleanup(cancel)
102 return ctx
103 }(),
104 timeout: time.Minute,
105 expectDeadline: time.Minute,
106 },
107 } {
108 tt := tt
109 t.Run(name, func(t *testing.T) {
110 ctx, cancel := withTimeout(tt.parentCtx, t, tt.timeout, timeoutCause.Error())
111 if tt.cancelCause != "" {
112 cancel(tt.cancelCause)
113 }
114 if tt.expectDeadline != 0 {
115 actualDeadline, ok := ctx.Deadline()
116 if assert.True(t, ok, "should have had a deadline") {
117
118
119
120
121 ci, _ := os.LookupEnv("CI")
122 switch strings.ToLower(ci) {
123 case "yes", "true", "1":
124
125 default:
126 assert.InDelta(t, time.Until(actualDeadline), tt.expectDeadline, float64(time.Second), "remaining time till Deadline()")
127 }
128 }
129 }
130 time.Sleep(tt.sleep)
131 actualErr := ctx.Err()
132 actualCause := context.Cause(ctx)
133 ci, _ := os.LookupEnv("CI")
134 switch strings.ToLower(ci) {
135 case "yes", "true", "1":
136
137 default:
138 assert.Equal(t, tt.expectErr, actualErr, "ctx.Err()")
139 assert.Equal(t, tt.expectCause, actualCause, "context.Cause()")
140 }
141 })
142 }
143 }
144
View as plain text