~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/worker/uniter/hook/sender_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2012-2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package hook_test
 
5
 
 
6
import (
 
7
        "time"
 
8
 
 
9
        jc "github.com/juju/testing/checkers"
 
10
        gc "gopkg.in/check.v1"
 
11
        "gopkg.in/juju/charm.v6-unstable/hooks"
 
12
 
 
13
        statetesting "github.com/juju/juju/state/testing"
 
14
        coretesting "github.com/juju/juju/testing"
 
15
        "github.com/juju/juju/worker/uniter/hook"
 
16
        "github.com/juju/juju/worker/uniter/hook/hooktesting"
 
17
)
 
18
 
 
19
type HookSenderSuite struct{}
 
20
 
 
21
var _ = gc.Suite(&HookSenderSuite{})
 
22
 
 
23
func assertNext(c *gc.C, out chan hook.Info, expect hook.Info) {
 
24
        select {
 
25
        case <-time.After(coretesting.LongWait):
 
26
                c.Fatalf("timed out waiting for %#v", expect)
 
27
        case actual, ok := <-out:
 
28
                c.Assert(ok, jc.IsTrue)
 
29
                c.Assert(actual, gc.Equals, expect)
 
30
        }
 
31
}
 
32
 
 
33
func assertEmpty(c *gc.C, out chan hook.Info) {
 
34
        select {
 
35
        case <-time.After(coretesting.ShortWait):
 
36
        case actual, ok := <-out:
 
37
                c.Fatalf("got unexpected %#v %#v", actual, ok)
 
38
        }
 
39
}
 
40
 
 
41
func (s *HookSenderSuite) TestSendsHooks(c *gc.C) {
 
42
        expect := hooktesting.HookList(hooks.Install, hooks.ConfigChanged, hooks.Start)
 
43
        source := hook.NewListSource(expect)
 
44
        out := make(chan hook.Info)
 
45
        sender := hook.NewSender(out, source)
 
46
        defer statetesting.AssertStop(c, sender)
 
47
 
 
48
        for i := range expect {
 
49
                assertNext(c, out, expect[i])
 
50
        }
 
51
        assertEmpty(c, out)
 
52
        statetesting.AssertStop(c, sender)
 
53
        c.Assert(source.Empty(), jc.IsTrue)
 
54
}
 
55
 
 
56
func (s *HookSenderSuite) TestStopsHooks(c *gc.C) {
 
57
        expect := hooktesting.HookList(hooks.Install, hooks.ConfigChanged, hooks.Start)
 
58
        source := hook.NewListSource(expect)
 
59
        out := make(chan hook.Info)
 
60
        sender := hook.NewSender(out, source)
 
61
        defer statetesting.AssertStop(c, sender)
 
62
 
 
63
        assertNext(c, out, expect[0])
 
64
        assertNext(c, out, expect[1])
 
65
        statetesting.AssertStop(c, sender)
 
66
        assertEmpty(c, out)
 
67
        c.Assert(source.Next(), gc.Equals, expect[2])
 
68
}
 
69
 
 
70
func (s *HookSenderSuite) TestHandlesUpdatesFullQueue(c *gc.C) {
 
71
        source := hooktesting.NewFullUnbufferedSource()
 
72
        defer statetesting.AssertStop(c, source)
 
73
 
 
74
        out := make(chan hook.Info)
 
75
        sender := hook.NewSender(out, source)
 
76
        defer statetesting.AssertStop(c, sender)
 
77
 
 
78
        // Check we're being sent hooks but not updates.
 
79
        assertActive := func() {
 
80
                assertNext(c, out, hook.Info{Kind: hooks.Install})
 
81
                select {
 
82
                case update, ok := <-source.UpdatesC:
 
83
                        c.Fatalf("got unexpected update: %#v %#v", update, ok)
 
84
                case <-time.After(coretesting.ShortWait):
 
85
                }
 
86
        }
 
87
        assertActive()
 
88
 
 
89
        // Send an event on the Changes() chan.
 
90
        select {
 
91
        case source.ChangesC <- source.NewChange("sent"):
 
92
        case <-time.After(coretesting.LongWait):
 
93
                c.Fatalf("could not send change")
 
94
        }
 
95
 
 
96
        // Now that a change has been delivered, nothing should be sent on the out
 
97
        // chan, or read from the changes chan, until the Update method has completed.
 
98
        select {
 
99
        case source.ChangesC <- source.NewChange("notSent"):
 
100
                c.Fatalf("sent extra change while updating queue")
 
101
        case hi, ok := <-out:
 
102
                c.Fatalf("got unexpected hook while updating queue: %#v %#v", hi, ok)
 
103
        case got, ok := <-source.UpdatesC:
 
104
                c.Assert(ok, jc.IsTrue)
 
105
                c.Assert(got, gc.Equals, "sent")
 
106
        case <-time.After(coretesting.LongWait):
 
107
                c.Fatalf("timed out")
 
108
        }
 
109
 
 
110
        // Check we're still being sent hooks and not updates.
 
111
        assertActive()
 
112
}
 
113
 
 
114
func (s *HookSenderSuite) TestHandlesUpdatesFullQueueSpam(c *gc.C) {
 
115
        source := hooktesting.NewFullBufferedSource()
 
116
        defer statetesting.AssertStop(c, source)
 
117
 
 
118
        out := make(chan hook.Info)
 
119
        sender := hook.NewSender(out, source)
 
120
        defer statetesting.AssertStop(c, sender)
 
121
 
 
122
        // Spam all channels continuously for a bit.
 
123
        timeout := time.After(coretesting.LongWait)
 
124
        hookCount := 0
 
125
        changeCount := 0
 
126
        updateCount := 0
 
127
        for i := 0; i < 100; i++ {
 
128
                select {
 
129
                case hi, ok := <-out:
 
130
                        c.Assert(ok, jc.IsTrue)
 
131
                        c.Assert(hi, gc.DeepEquals, hook.Info{Kind: hooks.Install})
 
132
                        hookCount++
 
133
                case source.ChangesC <- source.NewChange("sent"):
 
134
                        changeCount++
 
135
                case update, ok := <-source.UpdatesC:
 
136
                        c.Assert(ok, jc.IsTrue)
 
137
                        c.Assert(update, gc.Equals, "sent")
 
138
                        updateCount++
 
139
                case <-timeout:
 
140
                        c.Fatalf("not enough things happened in time")
 
141
                }
 
142
        }
 
143
 
 
144
        // Once we've finished sending, exhaust the updates...
 
145
        for i := updateCount; i < changeCount && updateCount < changeCount; i++ {
 
146
                select {
 
147
                case update, ok := <-source.UpdatesC:
 
148
                        c.Assert(ok, jc.IsTrue)
 
149
                        c.Assert(update, gc.Equals, "sent")
 
150
                        updateCount++
 
151
                case <-timeout:
 
152
                        c.Fatalf("expected %d updates, got %d", changeCount, updateCount)
 
153
                }
 
154
        }
 
155
 
 
156
        // ...and check sane end state to validate the foregoing.
 
157
        c.Check(hookCount, gc.Not(gc.Equals), 0)
 
158
        c.Check(changeCount, gc.Not(gc.Equals), 0)
 
159
}
 
160
 
 
161
func (s *HookSenderSuite) TestHandlesUpdatesEmptyQueue(c *gc.C) {
 
162
        source := hooktesting.NewEmptySource()
 
163
        defer statetesting.AssertStop(c, source)
 
164
 
 
165
        out := make(chan hook.Info)
 
166
        sender := hook.NewSender(out, source)
 
167
        defer statetesting.AssertStop(c, sender)
 
168
 
 
169
        // Check no hooks are sent and no updates delivered.
 
170
        assertIdle := func() {
 
171
                select {
 
172
                case hi, ok := <-out:
 
173
                        c.Fatalf("got unexpected hook: %#v %#v", hi, ok)
 
174
                case update, ok := <-source.UpdatesC:
 
175
                        c.Fatalf("got unexpected update: %#v %#v", update, ok)
 
176
                case <-time.After(coretesting.ShortWait):
 
177
                }
 
178
        }
 
179
        assertIdle()
 
180
 
 
181
        // Send an event on the Changes() chan.
 
182
        timeout := time.After(coretesting.LongWait)
 
183
        select {
 
184
        case source.ChangesC <- source.NewChange("sent"):
 
185
        case <-timeout:
 
186
                c.Fatalf("timed out")
 
187
        }
 
188
 
 
189
        // Now that a change has been delivered, nothing should be sent on the out
 
190
        // chan, or read from the changes chan, until the Update method has completed.
 
191
        select {
 
192
        case source.ChangesC <- source.NewChange("notSent"):
 
193
                c.Fatalf("sent extra update while updating queue")
 
194
        case hi, ok := <-out:
 
195
                c.Fatalf("got unexpected hook while updating queue: %#v %#v", hi, ok)
 
196
        case got, ok := <-source.UpdatesC:
 
197
                c.Assert(ok, jc.IsTrue)
 
198
                c.Assert(got, gc.Equals, "sent")
 
199
        case <-timeout:
 
200
                c.Fatalf("timed out")
 
201
        }
 
202
 
 
203
        // Now the change has been delivered, nothing should be happening.
 
204
        assertIdle()
 
205
}
 
206
 
 
207
func (s *HookSenderSuite) TestHandlesUpdatesEmptyQueueSpam(c *gc.C) {
 
208
        source := hooktesting.NewEmptySource()
 
209
        defer statetesting.AssertStop(c, source)
 
210
 
 
211
        out := make(chan hook.Info)
 
212
        sender := hook.NewSender(out, source)
 
213
        defer statetesting.AssertStop(c, sender)
 
214
 
 
215
        // Spam all channels continuously for a bit.
 
216
        timeout := time.After(coretesting.LongWait)
 
217
        changeCount := 0
 
218
        updateCount := 0
 
219
        for i := 0; i < 100; i++ {
 
220
                select {
 
221
                case hi, ok := <-out:
 
222
                        c.Fatalf("got unexpected hook: %#v %#v", hi, ok)
 
223
                case source.ChangesC <- source.NewChange("sent"):
 
224
                        changeCount++
 
225
                case update, ok := <-source.UpdatesC:
 
226
                        c.Assert(ok, jc.IsTrue)
 
227
                        c.Assert(update, gc.Equals, "sent")
 
228
                        updateCount++
 
229
                case <-timeout:
 
230
                        c.Fatalf("not enough things happened in time")
 
231
                }
 
232
        }
 
233
 
 
234
        // Check sane end state.
 
235
        c.Check(changeCount, gc.Equals, 50)
 
236
        c.Check(updateCount, gc.Equals, 50)
 
237
}