-
Notifications
You must be signed in to change notification settings - Fork 4
/
manager_test.go
109 lines (78 loc) · 2.18 KB
/
manager_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
package runnable
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
)
type mockRunnable struct {
called bool
calledChan chan struct{}
cancelled bool
cancelledChan chan struct{}
errChan chan error
}
func newMockRunnable() *mockRunnable {
return &mockRunnable{
calledChan: make(chan struct{}),
cancelledChan: make(chan struct{}),
errChan: make(chan error),
}
}
func (r *mockRunnable) Run(ctx context.Context) error {
r.called = true
close(r.calledChan)
<-ctx.Done()
r.cancelled = true
close(r.cancelledChan)
return <-r.errChan
}
func TestManager_Cancellation(t *testing.T) {
g := NewManager()
g.Add(newDummyRunnable())
AssertRunnableRespectCancellation(t, g.Build(), time.Millisecond*100)
AssertRunnableRespectPreCancelledContext(t, g.Build())
}
func TestManager_Without_Runnable(t *testing.T) {
g := NewManager()
AssertRunnableRespectCancellation(t, g.Build(), time.Millisecond*100)
}
func TestManager_Dying_Runnable(t *testing.T) {
g := NewManager()
g.Add(newDyingRunnable())
AssertTimeout(t, time.Second*1, func() {
err := g.Build().Run(context.Background())
require.EqualError(t, err, "manager: dyingRunnable crashed with dying")
})
}
func TestManager_ShutdownTimeout(t *testing.T) {
g := NewManager(ManagerShutdownTimeout(time.Second))
g.Add(newBlockedRunnable())
ctx := cancelledContext()
AssertTimeout(t, time.Second*2, func() {
err := g.Build().Run(ctx)
require.EqualError(t, err, "manager: blockedRunnable is still running")
})
}
func TestManager(t *testing.T) {
g := NewManager()
web := newMockRunnable()
db := newMockRunnable()
g.Add(db)
g.Add(web, db)
errChan := make(chan error)
ctx, cancel := context.WithCancel(context.Background())
go func() {
errChan <- g.Build().Run(ctx)
}()
<-web.calledChan // "web" has started
<-db.calledChan // "db" has started
cancel() // shutdown the manager
<-web.cancelledChan // "web" is cancelled
time.Sleep(time.Millisecond * 100)
require.False(t, db.cancelled) // "db" should not be shutdown yet
web.errChan <- nil // "web" shuts down
<-db.cancelledChan // "db" can be cancelled now
db.errChan <- nil // "db" shuts down
require.NoError(t, <-errChan)
}