LEFT | RIGHT |
(no file at all) | |
1 package uniter | 1 package uniter |
2 | 2 |
3 import ( | 3 import ( |
4 . "launchpad.net/gocheck" | 4 . "launchpad.net/gocheck" |
5 "launchpad.net/juju-core/charm" | 5 "launchpad.net/juju-core/charm" |
6 "launchpad.net/juju-core/juju/testing" | 6 "launchpad.net/juju-core/juju/testing" |
7 "launchpad.net/juju-core/state" | 7 "launchpad.net/juju-core/state" |
8 "launchpad.net/juju-core/worker" | 8 "launchpad.net/juju-core/worker" |
9 "time" | 9 "time" |
10 ) | 10 ) |
(...skipping 11 matching lines...) Expand all Loading... |
22 s.JujuConnSuite.SetUpTest(c) | 22 s.JujuConnSuite.SetUpTest(c) |
23 s.ch = s.AddTestingCharm(c, "dummy") | 23 s.ch = s.AddTestingCharm(c, "dummy") |
24 var err error | 24 var err error |
25 s.svc, err = s.State.AddService("dummy", s.ch) | 25 s.svc, err = s.State.AddService("dummy", s.ch) |
26 c.Assert(err, IsNil) | 26 c.Assert(err, IsNil) |
27 s.unit, err = s.svc.AddUnit() | 27 s.unit, err = s.svc.AddUnit() |
28 c.Assert(err, IsNil) | 28 c.Assert(err, IsNil) |
29 } | 29 } |
30 | 30 |
31 func (s *FilterSuite) TestUnitDeath(c *C) { | 31 func (s *FilterSuite) TestUnitDeath(c *C) { |
32 » f := newFilter(s.unit) | 32 » f, err := newFilter(s.State, s.unit.Name()) |
| 33 » c.Assert(err, IsNil) |
33 defer f.Stop() | 34 defer f.Stop() |
34 assertNotClosed := func() { | 35 assertNotClosed := func() { |
35 s.State.StartSync() | 36 s.State.StartSync() |
36 select { | 37 select { |
37 case <-time.After(50 * time.Millisecond): | 38 case <-time.After(50 * time.Millisecond): |
38 » » case <-f.unitDying(): | 39 » » case <-f.UnitDying(): |
39 c.Fatalf("unexpected receive") | 40 c.Fatalf("unexpected receive") |
40 } | 41 } |
41 } | 42 } |
42 assertNotClosed() | 43 assertNotClosed() |
43 | 44 |
44 // Irrelevant change. | 45 // Irrelevant change. |
45 » err := s.unit.SetResolved(state.ResolvedRetryHooks) | 46 » err = s.unit.SetResolved(state.ResolvedRetryHooks) |
46 c.Assert(err, IsNil) | 47 c.Assert(err, IsNil) |
47 assertNotClosed() | 48 assertNotClosed() |
48 | 49 |
49 // Set dying. | 50 // Set dying. |
50 err = s.unit.EnsureDying() | 51 err = s.unit.EnsureDying() |
51 c.Assert(err, IsNil) | 52 c.Assert(err, IsNil) |
52 assertClosed := func() { | 53 assertClosed := func() { |
53 s.State.StartSync() | 54 s.State.StartSync() |
54 select { | 55 select { |
55 case <-time.After(50 * time.Millisecond): | 56 case <-time.After(50 * time.Millisecond): |
56 c.Fatalf("dying not detected") | 57 c.Fatalf("dying not detected") |
57 » » case _, ok := <-f.unitDying(): | 58 » » case _, ok := <-f.UnitDying(): |
58 c.Assert(ok, Equals, false) | 59 c.Assert(ok, Equals, false) |
59 } | 60 } |
60 } | 61 } |
61 assertClosed() | 62 assertClosed() |
62 | 63 |
63 // Another irrelevant change. | 64 // Another irrelevant change. |
64 err = s.unit.ClearResolved() | 65 err = s.unit.ClearResolved() |
65 c.Assert(err, IsNil) | 66 c.Assert(err, IsNil) |
66 assertClosed() | 67 assertClosed() |
67 | 68 |
| 69 // Set dead. |
68 err = s.unit.EnsureDead() | 70 err = s.unit.EnsureDead() |
69 c.Assert(err, IsNil) | 71 c.Assert(err, IsNil) |
70 s.State.StartSync() | 72 s.State.StartSync() |
71 select { | 73 select { |
72 case <-f.Dying(): | 74 case <-f.Dying(): |
73 case <-time.After(50 * time.Millisecond): | 75 case <-time.After(50 * time.Millisecond): |
74 c.Fatalf("dead not detected") | 76 c.Fatalf("dead not detected") |
75 } | 77 } |
76 c.Assert(f.Wait(), Equals, worker.ErrDead) | 78 c.Assert(f.Wait(), Equals, worker.ErrDead) |
77 } | 79 } |
78 | 80 |
79 func (s *FilterSuite) TestServiceDeath(c *C) { | 81 func (s *FilterSuite) TestServiceDeath(c *C) { |
80 » f := newFilter(s.unit) | 82 » f, err := newFilter(s.State, s.unit.Name()) |
| 83 » c.Assert(err, IsNil) |
81 defer f.Stop() | 84 defer f.Stop() |
82 s.State.StartSync() | 85 s.State.StartSync() |
83 select { | 86 select { |
84 case <-time.After(50 * time.Millisecond): | 87 case <-time.After(50 * time.Millisecond): |
85 » case <-f.unitDying(): | 88 » case <-f.UnitDying(): |
86 c.Fatalf("unexpected receive") | 89 c.Fatalf("unexpected receive") |
87 } | 90 } |
88 | 91 |
89 » err := s.svc.EnsureDying() | 92 » err = s.svc.EnsureDying() |
90 c.Assert(err, IsNil) | 93 c.Assert(err, IsNil) |
91 timeout := time.After(500 * time.Millisecond) | 94 timeout := time.After(500 * time.Millisecond) |
92 loop: | 95 loop: |
93 for { | 96 for { |
94 select { | 97 select { |
95 » » case <-f.unitDying(): | 98 » » case <-f.UnitDying(): |
96 break loop | 99 break loop |
97 case <-time.After(50 * time.Millisecond): | 100 case <-time.After(50 * time.Millisecond): |
98 s.State.StartSync() | 101 s.State.StartSync() |
99 case <-timeout: | 102 case <-timeout: |
100 c.Fatalf("dead not detected") | 103 c.Fatalf("dead not detected") |
101 } | 104 } |
102 } | 105 } |
103 err = s.unit.Refresh() | 106 err = s.unit.Refresh() |
104 c.Assert(err, IsNil) | 107 c.Assert(err, IsNil) |
105 c.Assert(s.unit.Life(), Equals, state.Dying) | 108 c.Assert(s.unit.Life(), Equals, state.Dying) |
106 | 109 |
107 // Can't set s.svc to Dead while it still has units. | 110 // Can't set s.svc to Dead while it still has units. |
108 } | 111 } |
109 | 112 |
110 func (s *FilterSuite) TestResolvedEvents(c *C) { | 113 func (s *FilterSuite) TestResolvedEvents(c *C) { |
111 » f := newFilter(s.unit) | 114 » f, err := newFilter(s.State, s.unit.Name()) |
112 » defer f.Stop() | 115 » c.Assert(err, IsNil) |
113 | 116 » defer f.Stop() |
114 » // Initial event. | 117 |
| 118 » // No initial event; not worth mentioning ResolvedNone. |
| 119 » assertNoChange := func() { |
| 120 » » s.State.StartSync() |
| 121 » » select { |
| 122 » » case rm := <-f.ResolvedEvents(): |
| 123 » » » c.Fatalf("unexpected %#v", rm) |
| 124 » » case <-time.After(50 * time.Millisecond): |
| 125 » » } |
| 126 » } |
| 127 » assertNoChange() |
| 128 |
| 129 » // Request an event; no interesting event is available. |
| 130 » f.WantResolvedEvent() |
| 131 » assertNoChange() |
| 132 |
| 133 » // Change the unit in an irrelevant way; no events. |
| 134 » err = s.unit.SetCharm(s.ch) |
| 135 » c.Assert(err, IsNil) |
| 136 » assertNoChange() |
| 137 |
| 138 » // Change the unit's resolved to an interesting value; new event receive
d. |
| 139 » err = s.unit.SetResolved(state.ResolvedRetryHooks) |
| 140 » c.Assert(err, IsNil) |
115 assertChange := func(expect state.ResolvedMode) { | 141 assertChange := func(expect state.ResolvedMode) { |
116 s.State.Sync() | 142 s.State.Sync() |
117 select { | 143 select { |
118 » » case rm := <-f.resolvedEvents(): | 144 » » case rm := <-f.ResolvedEvents(): |
119 » » » c.Assert(*rm, Equals, expect) | 145 » » » c.Assert(rm, Equals, expect) |
120 case <-time.After(50 * time.Millisecond): | 146 case <-time.After(50 * time.Millisecond): |
121 c.Fatalf("timed out") | 147 c.Fatalf("timed out") |
122 } | 148 } |
123 } | 149 } |
124 assertChange(state.ResolvedNone) | |
125 assertNoChange := func() { | |
126 s.State.StartSync() | |
127 select { | |
128 case rm := <-f.resolvedEvents(): | |
129 c.Fatalf("unexpected %#v", rm) | |
130 case <-time.After(50 * time.Millisecond): | |
131 } | |
132 } | |
133 assertNoChange() | |
134 | |
135 // Request an event; it matches the previous one. | |
136 f.wantResolvedEvent() | |
137 assertChange(state.ResolvedNone) | |
138 assertNoChange() | |
139 | |
140 // Change the unit in an irrelevant way; no events. | |
141 err := s.unit.SetCharm(s.ch) | |
142 c.Assert(err, IsNil) | |
143 assertNoChange() | |
144 | |
145 // Change the unit's resolved; new event received. | |
146 err = s.unit.SetResolved(state.ResolvedRetryHooks) | |
147 c.Assert(err, IsNil) | |
148 assertChange(state.ResolvedRetryHooks) | 150 assertChange(state.ResolvedRetryHooks) |
149 assertNoChange() | 151 assertNoChange() |
150 | 152 |
151 // Request a few events, and change the unit a few times; when | 153 // Request a few events, and change the unit a few times; when |
152 // we finally receive, only the most recent state is sent. | 154 // we finally receive, only the most recent state is sent. |
153 » f.wantResolvedEvent() | 155 » f.WantResolvedEvent() |
154 err = s.unit.ClearResolved() | 156 err = s.unit.ClearResolved() |
155 c.Assert(err, IsNil) | 157 c.Assert(err, IsNil) |
156 » f.wantResolvedEvent() | 158 » f.WantResolvedEvent() |
157 err = s.unit.SetResolved(state.ResolvedNoHooks) | 159 err = s.unit.SetResolved(state.ResolvedNoHooks) |
158 c.Assert(err, IsNil) | 160 c.Assert(err, IsNil) |
159 » f.wantResolvedEvent() | 161 » f.WantResolvedEvent() |
160 » err = s.unit.ClearResolved() | 162 » assertChange(state.ResolvedNoHooks) |
161 » c.Assert(err, IsNil) | |
162 » f.wantResolvedEvent() | |
163 » assertChange(state.ResolvedNone) | |
164 assertNoChange() | 163 assertNoChange() |
165 } | 164 } |
166 | 165 |
167 func (s *FilterSuite) TestCharmEvents(c *C) { | 166 func (s *FilterSuite) TestCharmEvents(c *C) { |
168 » f := newFilter(s.unit) | 167 » f, err := newFilter(s.State, s.unit.Name()) |
169 » defer f.Stop() | 168 » c.Assert(err, IsNil) |
170 | 169 » defer f.Stop() |
171 » // Initial event. | 170 |
172 » assertChange := func(url *charm.URL, force bool) { | 171 » // No initial event is sent. |
| 172 » assertNoChange := func() { |
| 173 » » s.State.StartSync() |
| 174 » » select { |
| 175 » » case sch := <-f.UpgradeEvents(): |
| 176 » » » c.Fatalf("unexpected %#v", sch) |
| 177 » » case <-time.After(50 * time.Millisecond): |
| 178 » » } |
| 179 » } |
| 180 » assertNoChange() |
| 181 |
| 182 » // Request an event relative to the existing state; nothing. |
| 183 » f.WantUpgradeEvent(s.ch.URL(), false) |
| 184 » assertNoChange() |
| 185 |
| 186 » // Change the service in an irrelevant way; no events. |
| 187 » err = s.svc.SetExposed() |
| 188 » c.Assert(err, IsNil) |
| 189 » assertNoChange() |
| 190 |
| 191 » // Change the service's charm; new event received. |
| 192 » ch := s.AddTestingCharm(c, "dummy-v2") |
| 193 » err = s.svc.SetCharm(ch, false) |
| 194 » c.Assert(err, IsNil) |
| 195 » assertChange := func(url *charm.URL) { |
173 s.State.Sync() | 196 s.State.Sync() |
174 select { | 197 select { |
175 » » case ch := <-f.charmEvents(): | 198 » » case sch := <-f.UpgradeEvents(): |
176 » » » c.Assert(ch, DeepEquals, &charmChange{url, force}) | 199 » » » c.Assert(sch.URL(), DeepEquals, url) |
177 case <-time.After(50 * time.Millisecond): | 200 case <-time.After(50 * time.Millisecond): |
178 c.Fatalf("timed out") | 201 c.Fatalf("timed out") |
179 } | 202 } |
180 } | 203 } |
181 » assertChange(s.ch.URL(), false) | 204 » assertChange(ch.URL()) |
182 » assertNoChange := func() { | 205 » assertNoChange() |
183 » » s.State.StartSync() | 206 |
184 » » select { | 207 » // Request a change relative to the original state, unforced; |
185 » » case ch := <-f.charmEvents(): | 208 » // same event is sent. |
186 » » » c.Fatalf("unexpected %#v", ch) | 209 » f.WantUpgradeEvent(s.ch.URL(), false) |
187 » » case <-time.After(50 * time.Millisecond): | 210 » assertChange(ch.URL()) |
188 » » } | 211 » assertNoChange() |
189 » } | 212 |
190 » assertNoChange() | 213 » // Request a forced change relative to the initial state; no change... |
191 | 214 » f.WantUpgradeEvent(s.ch.URL(), true) |
192 » // Request an event; it matches the previous one. | 215 » assertNoChange() |
193 » f.wantCharmEvent() | 216 |
194 » assertChange(s.ch.URL(), false) | 217 » // ...and still no change when we have a forced upgrade to that state... |
195 » assertNoChange() | |
196 | |
197 » // Change the service in an irrelevant way; no events. | |
198 » err := s.svc.SetExposed() | |
199 » c.Assert(err, IsNil) | |
200 » assertNoChange() | |
201 | |
202 » // Change the service's charm; new event received. | |
203 err = s.svc.SetCharm(s.ch, true) | 218 err = s.svc.SetCharm(s.ch, true) |
204 c.Assert(err, IsNil) | 219 c.Assert(err, IsNil) |
205 » assertChange(s.ch.URL(), true) | 220 » assertNoChange() |
206 » assertNoChange() | 221 |
207 | 222 » // ...but a *forced* change to a different charm does generate an event. |
208 » // Request a few events, and change the unit a few times; when | |
209 » // we finally receive, only the most recent state is sent. | |
210 » f.wantCharmEvent() | |
211 » ch := s.AddTestingCharm(c, "dummy-v2") | |
212 err = s.svc.SetCharm(ch, true) | 223 err = s.svc.SetCharm(ch, true) |
213 » c.Assert(err, IsNil) | 224 » assertChange(ch.URL()) |
214 » f.wantCharmEvent() | |
215 » err = s.svc.SetCharm(ch, false) | |
216 » c.Assert(err, IsNil) | |
217 » f.wantCharmEvent() | |
218 » assertChange(ch.URL(), false) | |
219 assertNoChange() | 225 assertNoChange() |
220 } | 226 } |
221 | 227 |
222 func (s *FilterSuite) TestConfigEvents(c *C) { | 228 func (s *FilterSuite) TestConfigEvents(c *C) { |
223 » f := newFilter(s.unit) | 229 » f, err := newFilter(s.State, s.unit.Name()) |
| 230 » c.Assert(err, IsNil) |
224 defer f.Stop() | 231 defer f.Stop() |
225 | 232 |
226 // Initial event. | 233 // Initial event. |
227 assertChange := func() { | 234 assertChange := func() { |
228 s.State.Sync() | 235 s.State.Sync() |
229 select { | 236 select { |
230 » » case _, ok := <-f.configEvents(): | 237 » » case _, ok := <-f.ConfigEvents(): |
231 c.Assert(ok, Equals, true) | 238 c.Assert(ok, Equals, true) |
232 case <-time.After(50 * time.Millisecond): | 239 case <-time.After(50 * time.Millisecond): |
233 c.Fatalf("timed out") | 240 c.Fatalf("timed out") |
234 } | 241 } |
235 } | 242 } |
236 assertChange() | 243 assertChange() |
237 assertNoChange := func() { | 244 assertNoChange := func() { |
238 s.State.StartSync() | 245 s.State.StartSync() |
239 select { | 246 select { |
240 » » case <-f.configEvents(): | 247 » » case <-f.ConfigEvents(): |
241 c.Fatalf("unexpected config event") | 248 c.Fatalf("unexpected config event") |
242 case <-time.After(50 * time.Millisecond): | 249 case <-time.After(50 * time.Millisecond): |
243 } | 250 } |
244 } | 251 } |
245 assertNoChange() | 252 assertNoChange() |
246 | 253 |
247 // Request an event; it matches the previous one. | 254 // Request an event; it matches the previous one. |
248 » f.wantConfigEvent() | 255 » f.WantConfigEvent() |
249 assertChange() | 256 assertChange() |
250 assertNoChange() | 257 assertNoChange() |
251 | 258 |
252 // Change the config; new event received. | 259 // Change the config; new event received. |
253 node, err := s.svc.Config() | 260 node, err := s.svc.Config() |
254 c.Assert(err, IsNil) | 261 c.Assert(err, IsNil) |
255 node.Set("skill-level", 9001) | 262 node.Set("skill-level", 9001) |
256 _, err = node.Write() | 263 _, err = node.Write() |
257 c.Assert(err, IsNil) | 264 c.Assert(err, IsNil) |
258 assertChange() | 265 assertChange() |
259 assertNoChange() | 266 assertNoChange() |
260 | 267 |
261 » // Request a few events, and change the unit a few times; when | 268 » // Request a few events, and change the config a few times; when |
262 // we finally receive, only a single event is sent. | 269 // we finally receive, only a single event is sent. |
263 » f.wantConfigEvent() | 270 » f.WantConfigEvent() |
264 node.Set("title", "20,000 leagues in the cloud") | 271 node.Set("title", "20,000 leagues in the cloud") |
265 _, err = node.Write() | 272 _, err = node.Write() |
266 c.Assert(err, IsNil) | 273 c.Assert(err, IsNil) |
267 » f.wantConfigEvent() | 274 » f.WantConfigEvent() |
268 node.Set("outlook", "precipitous") | 275 node.Set("outlook", "precipitous") |
269 _, err = node.Write() | 276 _, err = node.Write() |
270 c.Assert(err, IsNil) | 277 c.Assert(err, IsNil) |
271 » f.wantConfigEvent() | 278 » f.WantConfigEvent() |
272 » assertChange() | 279 » assertChange() |
273 » assertNoChange() | 280 » assertNoChange() |
274 } | 281 } |
LEFT | RIGHT |