-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraceful_shutdown_test.go
150 lines (128 loc) · 4.34 KB
/
graceful_shutdown_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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package gfshutdown_test
import (
"context"
"errors"
"testing"
"time"
gfshutdown "github.com/gelmium/graceful-shutdown"
)
func TestGracefulShutdown(t *testing.T) {
// Define a mock operation that waits for a specified duration before returning.
mockOp := func(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(100 * time.Millisecond):
return nil
}
}
// Define a map of operations to be passed to GracefulShutdown.
ops := map[string]gfshutdown.Operation{
"op1": mockOp,
"op2": mockOp,
}
// Define a timeout for the GracefulShutdown function.
timeout := 1 * time.Second
// Call GracefulShutdown with a trigger context that is immediately cancelled.
triggerCtx, cancel := context.WithCancel(context.Background())
cancel()
wait := gfshutdown.GracefulShutdown(triggerCtx, timeout, ops)
// Ensure that the function waits for all operations to complete before returning.
select {
case r := <-wait:
// Waited for all operations to complete.
if r != 0 {
t.Error("GracefulShutdown did not exit gracefully")
}
case <-time.After(2 * time.Second):
t.Error("GracefulShutdown did not wait for all operations to complete")
}
}
func TestGracefulShutdownWithError(t *testing.T) {
// Define a mock operation that returns an error.
mockOp := func(ctx context.Context) error {
return errors.New("operation failed")
}
// Define a map of operations to be passed to GracefulShutdown.
ops := map[string]gfshutdown.Operation{
"op1": mockOp,
}
// Define a timeout for the GracefulShutdown function.
timeout := 1 * time.Second
// Call GracefulShutdown with a trigger context that is immediately cancelled.
triggerCtx, cancel := context.WithCancel(context.Background())
cancel()
wait := gfshutdown.GracefulShutdown(triggerCtx, timeout, ops)
// Ensure that the function waits for all operations to complete before returning.
select {
case r := <-wait:
// Waited for all operations to complete
if r != 0 {
t.Error("GracefulShutdown did not exit gracefully")
}
case <-time.After(2 * time.Second):
t.Error("GracefulShutdown did not wait for all operations to complete")
}
}
// Add a test case with timeout.
func TestGracefulShutdownWithTimeoutInTime(t *testing.T) {
// Define a mock operation that waits for a specified duration before returning.
mockOp := func(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(900 * time.Millisecond):
return nil
}
}
// Define a map of operations to be passed to GracefulShutdown.
ops := map[string]gfshutdown.Operation{
"op1": mockOp,
}
// Define a timeout for the GracefulShutdown function.
timeout := 1 * time.Second
// Call GracefulShutdown with a trigger context that is immediately cancelled.
triggerCtx, cancel := context.WithCancel(context.Background())
cancel()
wait := gfshutdown.GracefulShutdown(triggerCtx, timeout, ops)
// Ensure that the function waits for all operations to complete before returning.
select {
case r := <-wait:
// Gracefully shutdown before 1 seconds timeout.
if r != 0 {
t.Error("GracefulShutdown did not exit gracefully")
}
break
case <-time.After(2 * time.Second):
// Waited for all operations to complete.
t.Error("GracefulShutdown did not timeout but instead wait for all operations to complete")
}
}
func TestGracefulShutdownWithTimeoutTimedOut(t *testing.T) {
// Define a mock operation that waits for a specified duration before returning.
mockOp := func(ctx context.Context) error {
<-time.After(2 * time.Second)
return nil
}
// Define a map of operations to be passed to GracefulShutdown.
ops := map[string]gfshutdown.Operation{
"op1": mockOp,
}
// Define a timeout for the GracefulShutdown function
timeout := 1 * time.Second
// Call GracefulShutdown with a trigger context that is immediately cancelled
triggerCtx, cancel := context.WithCancel(context.Background())
cancel()
wait := gfshutdown.GracefulShutdown(triggerCtx, timeout, ops)
// Ensure that the function waits for all operations to complete before returning
select {
case r := <-wait:
// GracefulShutdown did not timed out to force exit
if r != 1 {
t.Error("GracefulShutdown did not time out")
}
case <-time.After(2 * time.Second):
// Waited for all operations to complete
t.Error("GracefulShutdown did not timeout but instead wait for all operations to complete")
}
}