-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgroup_test.go
157 lines (139 loc) · 3.15 KB
/
group_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
151
152
153
154
155
156
157
package stop
import (
"syscall"
"testing"
"time"
)
type MockStopper struct {
stopCalls int
waitForStoppedCalls int
}
func (ms *MockStopper) IsStopping() bool {
return false
}
func (ms *MockStopper) IsStopped() bool {
return false
}
func (ms *MockStopper) Stop() {
ms.stopCalls++
}
func (ms *MockStopper) StopChannel() chan bool {
return nil
}
func (ms *MockStopper) Stopped() {}
func (ms *MockStopper) StoppedChannel() chan bool {
return nil
}
func (ms *MockStopper) WaitForStopped() {
ms.waitForStoppedCalls++
}
func TestNewGroup(t *testing.T) {
sg := NewGroup()
if sg == nil {
t.Fatal("sg was unexpectedly nil")
}
if sg.isStopping {
t.Errorf("expected sg.isStopping to be false, got true")
}
if sg.stop == nil {
t.Errorf("sg.stop was unexpectedly nil")
}
if sg.wg == nil {
t.Errorf("sg.wg was unexpectedly nil")
}
}
func TestGroupAdd(t *testing.T) {
sg := NewGroup()
ms := &MockStopper{}
sg.Add(ms)
if ms.stopCalls != 0 {
t.Errorf("ms.stopCalls = %d; expected 0", ms.stopCalls)
}
if ms.waitForStoppedCalls != 0 {
t.Errorf("ms.waitForStoppedCalls = %d; expected 0", ms.waitForStoppedCalls)
}
close(sg.stop)
sg.wg.Wait()
if ms.stopCalls != 1 {
t.Errorf("ms.stopCalls = %d; expected 1", ms.stopCalls)
}
if ms.waitForStoppedCalls != 1 {
t.Errorf("ms.waitForStoppedCalls = %d; expected 1", ms.waitForStoppedCalls)
}
}
func TestGroupAddEarlyStop(t *testing.T) {
// This test is validating that calling stop on a stopper unblocks the
// stop group cleanup goroutine for the stopper.
sg := NewGroup()
ms := NewChannelStopper()
sg.Add(ms)
ms.Stopped()
timer := time.AfterFunc(100*time.Millisecond, func() {
t.Error("Group Add() did not unblock after 100ms")
close(sg.stop)
})
sg.wg.Wait()
timer.Stop()
}
func TestGroupIsStopping(t *testing.T) {
sg := NewGroup()
if sg.IsStopping() {
t.Error("sg.IsStopping() is true, expected false")
}
sg.isStopping = true
if !sg.IsStopping() {
t.Error("sg.IsStopping() is false, expected true")
}
}
func TestGroupStop(t *testing.T) {
sg := NewGroup()
if sg.isStopping {
t.Error("sg.isStopping is true, expected false")
}
sg.Stop()
if !sg.isStopping {
t.Error("sg.isStopping is false, expected true")
}
select {
case <-sg.stop:
case <-time.After(1 * time.Second):
t.Error("Stop() did not close the stop channel")
}
// Test that you can call Stop more than once. Without the isStopping guard,
// closing the channel twice would cause a panic.
sg.Stop()
}
func TestGroupStopChannel(t *testing.T) {
sg := NewGroup()
if sg.stop != sg.StopChannel() {
t.Errorf("sg.stop = %#v; expected %#v", sg.stop, sg.StopChannel())
}
}
func TestGroupStopOnSignal(t *testing.T) {
sg := NewGroup()
sg.StopOnSignal(syscall.SIGWINCH)
err := syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
if err != nil {
t.Error(err)
}
select {
case <-sg.stop:
case <-time.After(1 * time.Second):
t.Error("Signal did not close stop channel")
}
}
func TestGroupWait(t *testing.T) {
ch := make(chan bool)
sg := NewGroup()
sg.wg.Add(1)
go func() {
sg.Wait()
close(ch)
}()
sg.wg.Done()
select {
case <-ch:
case <-time.After(1 * time.Second):
t.Error("sg.Wait() didn't complete")
}
}