1
16
17 package wait
18
19 import (
20 "context"
21 "errors"
22 "fmt"
23 "testing"
24 )
25
26 type errWrapper struct {
27 wrapped error
28 }
29
30 func (w errWrapper) Unwrap() error {
31 return w.wrapped
32 }
33 func (w errWrapper) Error() string {
34 return fmt.Sprintf("wrapped: %v", w.wrapped)
35 }
36
37 type errNotWrapper struct {
38 wrapped error
39 }
40
41 func (w errNotWrapper) Error() string {
42 return fmt.Sprintf("wrapped: %v", w.wrapped)
43 }
44
45 func TestInterrupted(t *testing.T) {
46 tests := []struct {
47 name string
48 err error
49 want bool
50 }{
51 {
52 err: ErrWaitTimeout,
53 want: true,
54 },
55 {
56 err: context.Canceled,
57 want: true,
58 }, {
59 err: context.DeadlineExceeded,
60 want: true,
61 },
62 {
63 err: errWrapper{ErrWaitTimeout},
64 want: true,
65 },
66 {
67 err: errWrapper{context.Canceled},
68 want: true,
69 },
70 {
71 err: errWrapper{context.DeadlineExceeded},
72 want: true,
73 },
74 {
75 err: ErrorInterrupted(nil),
76 want: true,
77 },
78 {
79 err: ErrorInterrupted(errors.New("unknown")),
80 want: true,
81 },
82 {
83 err: ErrorInterrupted(context.Canceled),
84 want: true,
85 },
86 {
87 err: ErrorInterrupted(ErrWaitTimeout),
88 want: true,
89 },
90
91 {
92 err: nil,
93 },
94 {
95 err: errors.New("not a cancellation"),
96 },
97 {
98 err: errNotWrapper{ErrWaitTimeout},
99 },
100 {
101 err: errNotWrapper{context.Canceled},
102 },
103 {
104 err: errNotWrapper{context.DeadlineExceeded},
105 },
106 }
107 for _, tt := range tests {
108 t.Run(tt.name, func(t *testing.T) {
109 if got := Interrupted(tt.err); got != tt.want {
110 t.Errorf("Interrupted() = %v, want %v", got, tt.want)
111 }
112 })
113 }
114 }
115
116 func TestErrorInterrupted(t *testing.T) {
117 internalErr := errInterrupted{}
118 if ErrorInterrupted(internalErr) != internalErr {
119 t.Fatalf("error should not be wrapped twice")
120 }
121
122 internalErr = errInterrupted{errInterrupted{}}
123 if ErrorInterrupted(internalErr) != internalErr {
124 t.Fatalf("object should be identical")
125 }
126
127 in := errors.New("test")
128 actual, expected := ErrorInterrupted(in), (errInterrupted{in})
129 if actual != expected {
130 t.Fatalf("did not wrap error")
131 }
132 if !errors.Is(actual, errWaitTimeout) {
133 t.Fatalf("does not obey errors.Is contract")
134 }
135 if actual.Error() != in.Error() {
136 t.Fatalf("unexpected error output")
137 }
138 if !Interrupted(actual) {
139 t.Fatalf("is not Interrupted")
140 }
141 if Interrupted(in) {
142 t.Fatalf("should not be Interrupted")
143 }
144 }
145
View as plain text