-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshutdownhandler_test.go
135 lines (109 loc) · 3.21 KB
/
shutdownhandler_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package app
import (
"container/heap"
"context"
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestShutdownhandlerHeap(t *testing.T) {
h := shutdownHeap{}
heap.Init(&h)
assert.Equal(t, h.Len(), 0, "a new heap must be empty")
assert.Panics(t, func() {
heap.Push(&h, nil)
}, "Push should panic if value is nil")
assert.Panics(t, func() {
heap.Push(&h, ShutdownHandler{})
}, "Push should panic if if value type is not *ShutdownHandler")
sh1 := &ShutdownHandler{
Name: "sh1",
Priority: ShutdownPriority(0),
}
sh2 := &ShutdownHandler{
Name: "sh2",
Priority: ShutdownPriority(10),
}
sh3 := &ShutdownHandler{
Name: "sh3",
Priority: ShutdownPriority(5),
}
sh4 := &ShutdownHandler{
Name: "sh4",
Priority: ShutdownPriority(5),
}
heap.Push(&h, sh1)
heap.Push(&h, sh2)
heap.Push(&h, sh4)
heap.Push(&h, sh3)
assert.Equal(t, h.Len(), 4, "heap should have 4 elements")
p1 := heap.Pop(&h)
p2 := heap.Pop(&h)
p3 := heap.Pop(&h)
p4 := heap.Pop(&h)
assert.Equal(t, sh1, p4, "sh1 has de lowest priority and must be popped last")
assert.Equal(t, sh2, p1, "sh2 has the highest priority and must be popped first")
assert.Equal(t, sh3, p3, "sh3 must be popped after sh4 and before sh1")
assert.Equal(t, sh4, p2, "sh4 must be popped after sh2 and before sh3")
assert.Equal(t, h.Len(), 0, "heap should be empty")
}
func TestShutdownHandlerExecute(t *testing.T) {
assert.Panics(t, func() {
sh := &ShutdownHandler{}
err := sh.Execute(context.Background())
assert.NoError(t, err)
}, "should panic if Handler is not set")
sh := &ShutdownHandler{
Name: "my_shutdown_handler",
Handler: func(context.Context) error {
return nil
},
}
assert.NoError(t, sh.err)
err := sh.Execute(context.TODO())
assert.NoError(t, err)
assert.NoError(t, sh.err)
sh = &ShutdownHandler{
Name: "my_failed_shutdown_handler",
Handler: func(context.Context) error {
return errors.New("my error")
},
Policy: ErrorPolicyAbort,
}
err = sh.Execute(context.TODO())
assert.EqualError(t, err, "shutdown handler 'my_failed_shutdown_handler' failed: my error")
err2 := sh.Execute(context.TODO())
assert.Equal(t, err, err2, "a second execution of handler should return the first error")
}
func TestShutdownHandlerExecute_CanceledContext(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
sh := &ShutdownHandler{
Name: "my_failed_shutdown_handler",
Handler: func(context.Context) error {
return errors.New("my error")
},
Policy: ErrorPolicyAbort,
}
err := sh.Execute(ctx)
assert.EqualError(t, err, "shutdown handler 'my_failed_shutdown_handler' failed: context canceled")
}
func TestShutdownHandlerExecute_Timeout(t *testing.T) {
sh := &ShutdownHandler{
Name: "my_failed_shutdown_handler",
Handler: func(ctx context.Context) error {
select {
case <-time.After(2 * time.Nanosecond):
return nil
case <-ctx.Done():
return errors.New("custom handler error on deadline exceeded")
}
},
Policy: ErrorPolicyAbort,
Timeout: time.Nanosecond,
}
ctx := context.Background()
err := sh.Execute(ctx)
assert.EqualError(t, err, "shutdown handler 'my_failed_shutdown_handler' failed: custom handler error on deadline exceeded")
}