Merge lp:~fwereade/juju-core/reinstate-relation-watch-tests into lp:~go-bot/juju-core/trunk

Proposed by William Reade
Status: Merged
Approved by: William Reade
Approved revision: no longer in the source branch.
Merged at revision: 1735
Proposed branch: lp:~fwereade/juju-core/reinstate-relation-watch-tests
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 518 lines (+484/-3)
1 file modified
state/relationunit_test.go (+484/-3)
To merge this branch: bzr merge lp:~fwereade/juju-core/reinstate-relation-watch-tests
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+183189@code.launchpad.net

Commit message

state: reinstate accidentally-dropped tests

Aside from removal of the tests for the Joined field (which is no longer sent,
because it's redundant (preexisting change)), this was a mechanical rename
job from the original. It's reassuring to observe that behaviour had not
otherwise changed detectably in the interim.

https://codereview.appspot.com/13401045/

Description of the change

state: reinstate accidentally-dropped tests

Aside from removal of the tests for the Joined field (which is no longer sent,
because it's redundant (preexisting change)), this was a mechanical rename
job from the original. It's reassuring to observe that behaviour had not
otherwise changed detectably in the interim.

https://codereview.appspot.com/13401045/

To post a comment you must log in.
Revision history for this message
William Reade (fwereade) wrote :

Reviewers: mp+183189_code.launchpad.net,

Message:
Please take a look.

Description:
state: reinstate accidentally-dropped tests

Aside from removal of the tests for the Joined field (which is no longer
sent,
because it's redundant (preexisting change)), this was a mechanical
rename
job from the original. It's reassuring to observe that behaviour had not
otherwise changed detectably in the interim.

https://code.launchpad.net/~fwereade/juju-core/reinstate-relation-watch-tests/+merge/183189

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/13401045/

Affected files:
   A [revision details]
   M state/relationunit_test.go

Revision history for this message
Roger Peppe (rogpeppe) wrote :

On 2013/08/30 14:30:20, fwereade wrote:
> Please take a look.

assuming this is mechanical and pre-reviewed, LGTM.

https://codereview.appspot.com/13401045/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'state/relationunit_test.go'
2--- state/relationunit_test.go 2013-08-20 15:29:55 +0000
3+++ state/relationunit_test.go 2013-08-30 14:19:19 +0000
4@@ -4,7 +4,9 @@
5 package state_test
6
7 import (
8+ "fmt"
9 "sort"
10+ "strconv"
11 "time"
12
13 gc "launchpad.net/gocheck"
14@@ -14,9 +16,11 @@
15 "launchpad.net/juju-core/state"
16 "launchpad.net/juju-core/state/testing"
17 coretesting "launchpad.net/juju-core/testing"
18- "launchpad.net/juju-core/testing/checkers"
19+ jc "launchpad.net/juju-core/testing/checkers"
20 )
21
22+type RUs []*state.RelationUnit
23+
24 type RelationUnitSuite struct {
25 ConnSuite
26 }
27@@ -325,7 +329,7 @@
28 c.Assert(err, gc.IsNil)
29 s.assertInScope(c, pr.ru1, false)
30 err = rel.Refresh()
31- c.Assert(err, checkers.Satisfies, errors.IsNotFoundError)
32+ c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
33
34 // The settings were not themselves actually deleted yet...
35 assertSettings()
36@@ -741,4 +745,481 @@
37 return u, ru
38 }
39
40-type RUs []*state.RelationUnit
41+type WatchScopeSuite struct {
42+ ConnSuite
43+}
44+
45+var _ = gc.Suite(&WatchScopeSuite{})
46+
47+func (s *WatchScopeSuite) TestPeer(c *gc.C) {
48+ // Create a service and get a peer relation.
49+ riak, err := s.State.AddService("riak", s.AddTestingCharm(c, "riak"))
50+ c.Assert(err, gc.IsNil)
51+ riakEP, err := riak.Endpoint("ring")
52+ c.Assert(err, gc.IsNil)
53+ rels, err := riak.Relations()
54+ c.Assert(err, gc.IsNil)
55+ c.Assert(rels, gc.HasLen, 1)
56+ rel := rels[0]
57+
58+ // Add some units to the service and set their private addresses; get
59+ // the relevant RelationUnits.
60+ // (Private addresses should be set by their unit agents on
61+ // startup; this test does not include that, but Join expects
62+ // the information to be available, and uses it to populate the
63+ // relation settings node.)
64+ addUnit := func(i int) *state.RelationUnit {
65+ unit, err := riak.AddUnit()
66+ c.Assert(err, gc.IsNil)
67+ err = unit.SetPrivateAddress(fmt.Sprintf("riak%d.example.com", i))
68+ c.Assert(err, gc.IsNil)
69+ ru, err := rel.Unit(unit)
70+ c.Assert(err, gc.IsNil)
71+ c.Assert(ru.Endpoint(), gc.Equals, riakEP)
72+ return ru
73+ }
74+ ru0 := addUnit(0)
75+ ru1 := addUnit(1)
76+ ru2 := addUnit(2)
77+
78+ // ---------- Single unit ----------
79+
80+ // Start watching the relation from the perspective of the first unit.
81+ w0 := ru0.Watch()
82+ defer testing.AssertStop(c, w0)
83+ s.assertChange(c, w0, nil, nil)
84+ s.assertNoChange(c, w0)
85+
86+ // Join the first unit to the relation, and change the settings, and
87+ // check that nothing apparently happens.
88+ err = ru0.EnterScope(nil)
89+ c.Assert(err, gc.IsNil)
90+ s0 := changeSettings(c, ru0)
91+ s.assertNoChange(c, w0)
92+
93+ // ---------- Two units ----------
94+
95+ // Now join another unit to the relation...
96+ err = ru1.EnterScope(nil)
97+ c.Assert(err, gc.IsNil)
98+
99+ // ...and check that the first relation unit sees the change.
100+ s1, err := ru1.Settings()
101+ c.Assert(err, gc.IsNil)
102+ expectChanged := map[string]map[string]interface{}{
103+ "riak/1": s1.Map(),
104+ }
105+ s.assertChange(c, w0, expectChanged, nil)
106+ s.assertNoChange(c, w0)
107+
108+ // Join again, check it's a no-op.
109+ err = ru1.EnterScope(nil)
110+ c.Assert(err, gc.IsNil)
111+ s.assertNoChange(c, w0)
112+
113+ // Start watching the relation from the perspective of the second unit,
114+ // and check that it sees the right state.
115+ w1 := ru1.Watch()
116+ defer testing.AssertStop(c, w1)
117+ expectChanged = map[string]map[string]interface{}{
118+ "riak/0": s0.Map(),
119+ }
120+ s.assertChange(c, w1, expectChanged, nil)
121+ s.assertNoChange(c, w1)
122+
123+ // ---------- Three units ----------
124+
125+ // Whoa, it works. Ok, check the third unit's opinion of the state.
126+ w2 := ru2.Watch()
127+ defer testing.AssertStop(c, w2)
128+ expectChanged = map[string]map[string]interface{}{
129+ "riak/0": s0.Map(),
130+ "riak/1": s1.Map(),
131+ }
132+ s.assertChange(c, w2, expectChanged, nil)
133+ s.assertNoChange(c, w2)
134+
135+ // Join the third unit, and check the first and second units see it.
136+ err = ru2.EnterScope(nil)
137+ c.Assert(err, gc.IsNil)
138+ s2, err := ru2.Settings()
139+ c.Assert(err, gc.IsNil)
140+ expectChanged = map[string]map[string]interface{}{
141+ "riak/2": s2.Map(),
142+ }
143+ s.assertChange(c, w0, expectChanged, nil)
144+ s.assertNoChange(c, w0)
145+ s.assertChange(c, w1, expectChanged, nil)
146+ s.assertNoChange(c, w1)
147+
148+ // Change the second unit's settings, and check that only
149+ // the first and third see changes.
150+ s1 = changeSettings(c, ru1)
151+ s.assertNoChange(c, w1)
152+ expectChanged = map[string]map[string]interface{}{
153+ "riak/1": s1.Map(),
154+ }
155+ s.assertChange(c, w0, expectChanged, nil)
156+ s.assertNoChange(c, w0)
157+ s.assertChange(c, w2, expectChanged, nil)
158+ s.assertNoChange(c, w2)
159+
160+ // ---------- Two units again ----------
161+
162+ // Depart the second unit, and check that the first and third detect it.
163+ err = ru1.LeaveScope()
164+ c.Assert(err, gc.IsNil)
165+ expectDeparted := []string{"riak/1"}
166+ s.assertChange(c, w0, nil, expectDeparted)
167+ s.assertNoChange(c, w0)
168+ s.assertChange(c, w2, nil, expectDeparted)
169+ s.assertNoChange(c, w2)
170+
171+ // Change its settings, and check the others don't observe anything.
172+ s1 = changeSettings(c, ru1)
173+ s.assertNoChange(c, w0)
174+ s.assertNoChange(c, w2)
175+
176+ // Check no spurious events showed up on the second unit's watch, and check
177+ // it closes cleanly.
178+ s.assertNoChange(c, w1)
179+ testing.AssertStop(c, w1)
180+
181+ // OK, we're done here. Cleanup, and error detection during same,
182+ // will be handled by the deferred kill/stop calls. Phew.
183+}
184+
185+func (s *WatchScopeSuite) TestProviderRequirerGlobal(c *gc.C) {
186+ // Create a pair of services and a relation between them.
187+ mysql, err := s.State.AddService("mysql", s.AddTestingCharm(c, "mysql"))
188+ c.Assert(err, gc.IsNil)
189+ mysqlEP, err := mysql.Endpoint("server")
190+ c.Assert(err, gc.IsNil)
191+ wordpress, err := s.State.AddService("wordpress", s.AddTestingCharm(c, "wordpress"))
192+ c.Assert(err, gc.IsNil)
193+ wordpressEP, err := wordpress.Endpoint("db")
194+ c.Assert(err, gc.IsNil)
195+ rel, err := s.State.AddRelation(mysqlEP, wordpressEP)
196+ c.Assert(err, gc.IsNil)
197+
198+ // Add some units to the services and set their private addresses.
199+ addUnit := func(srv *state.Service, sub string, ep state.Endpoint) *state.RelationUnit {
200+ unit, err := srv.AddUnit()
201+ c.Assert(err, gc.IsNil)
202+ ru, err := rel.Unit(unit)
203+ c.Assert(err, gc.IsNil)
204+ c.Assert(ru.Endpoint(), gc.Equals, ep)
205+ return ru
206+ }
207+ msru0 := addUnit(mysql, "ms0", mysqlEP)
208+ msru1 := addUnit(mysql, "ms1", mysqlEP)
209+ wpru0 := addUnit(wordpress, "wp0", wordpressEP)
210+ wpru1 := addUnit(wordpress, "wp1", wordpressEP)
211+
212+ // ---------- Single role active ----------
213+
214+ // Watch the relation from the perspective of the first provider unit and
215+ // check initial event.
216+ msw0 := msru0.Watch()
217+ defer testing.AssertStop(c, msw0)
218+ s.assertChange(c, msw0, nil, nil)
219+ s.assertNoChange(c, msw0)
220+
221+ // Join the unit to the relation, change its settings, and check that
222+ // nothing apparently happens.
223+ err = msru0.EnterScope(nil)
224+ c.Assert(err, gc.IsNil)
225+ mss0 := changeSettings(c, msru0)
226+ s.assertNoChange(c, msw0)
227+
228+ // Join the second provider unit, start its watch, and check what it thinks the
229+ // state of the relation is.
230+ err = msru1.EnterScope(nil)
231+ c.Assert(err, gc.IsNil)
232+ msw1 := msru1.Watch()
233+ defer testing.AssertStop(c, msw1)
234+ s.assertChange(c, msw1, nil, nil)
235+ s.assertNoChange(c, msw1)
236+
237+ // Change the unit's settings, and check that neither provider unit
238+ // observes any change.
239+ mss1 := changeSettings(c, msru1)
240+ s.assertNoChange(c, msw1)
241+ s.assertNoChange(c, msw0)
242+
243+ // ---------- Two roles active ----------
244+
245+ // Start watches from both requirer units' perspectives, and check that
246+ // they see the provider units.
247+ expectChanged := map[string]map[string]interface{}{
248+ "mysql/0": mss0.Map(),
249+ "mysql/1": mss1.Map(),
250+ }
251+ wpw0 := wpru0.Watch()
252+ defer testing.AssertStop(c, wpw0)
253+ s.assertChange(c, wpw0, expectChanged, nil)
254+ s.assertNoChange(c, wpw0)
255+ wpw1 := wpru1.Watch()
256+ defer testing.AssertStop(c, wpw1)
257+ s.assertChange(c, wpw1, expectChanged, nil)
258+ s.assertNoChange(c, wpw1)
259+
260+ // Join the first requirer unit, and check the provider units see it.
261+ err = wpru0.EnterScope(nil)
262+ c.Assert(err, gc.IsNil)
263+ wps0, err := wpru0.Settings()
264+ c.Assert(err, gc.IsNil)
265+ expectChanged = map[string]map[string]interface{}{
266+ "wordpress/0": wps0.Map(),
267+ }
268+ s.assertChange(c, msw0, expectChanged, nil)
269+ s.assertNoChange(c, msw0)
270+ s.assertChange(c, msw1, expectChanged, nil)
271+ s.assertNoChange(c, msw1)
272+
273+ // Join again, check no-op.
274+ err = wpru0.EnterScope(nil)
275+ c.Assert(err, gc.IsNil)
276+ s.assertNoChange(c, msw0)
277+ s.assertNoChange(c, msw1)
278+
279+ // Join the second requirer, and check the provider units see the change.
280+ err = wpru1.EnterScope(nil)
281+ c.Assert(err, gc.IsNil)
282+ wps1, err := wpru1.Settings()
283+ c.Assert(err, gc.IsNil)
284+ expectChanged = map[string]map[string]interface{}{
285+ "wordpress/1": wps1.Map(),
286+ }
287+ s.assertChange(c, msw0, expectChanged, nil)
288+ s.assertNoChange(c, msw0)
289+ s.assertChange(c, msw1, expectChanged, nil)
290+ s.assertNoChange(c, msw1)
291+
292+ // Verify that neither requirer has observed any change to the relation.
293+ s.assertNoChange(c, wpw0)
294+ s.assertNoChange(c, wpw1)
295+
296+ // Change settings for the first requirer, check providers see it...
297+ wps0 = changeSettings(c, wpru0)
298+ expectChanged = map[string]map[string]interface{}{
299+ "wordpress/0": wps0.Map(),
300+ }
301+ s.assertChange(c, msw0, expectChanged, nil)
302+ s.assertNoChange(c, msw0)
303+ s.assertChange(c, msw1, expectChanged, nil)
304+ s.assertNoChange(c, msw1)
305+
306+ // ...and requirers don't.
307+ s.assertNoChange(c, wpw0)
308+ s.assertNoChange(c, wpw1)
309+
310+ // Depart the second requirer and check the providers see it...
311+ err = wpru1.LeaveScope()
312+ c.Assert(err, gc.IsNil)
313+ expectDeparted := []string{"wordpress/1"}
314+ s.assertChange(c, msw0, nil, expectDeparted)
315+ s.assertNoChange(c, msw0)
316+ s.assertChange(c, msw1, nil, expectDeparted)
317+ s.assertNoChange(c, msw1)
318+
319+ // ...and the requirers don't.
320+ s.assertNoChange(c, wpw0)
321+ s.assertNoChange(c, wpw1)
322+
323+ // Cleanup handled by defers as before.
324+}
325+
326+func (s *WatchScopeSuite) TestProviderRequirerContainer(c *gc.C) {
327+ // Create a pair of services and a relation between them.
328+ mysql, err := s.State.AddService("mysql", s.AddTestingCharm(c, "mysql"))
329+ c.Assert(err, gc.IsNil)
330+ mysqlEP, err := mysql.Endpoint("juju-info")
331+ c.Assert(err, gc.IsNil)
332+ logging, err := s.State.AddService("logging", s.AddTestingCharm(c, "logging"))
333+ c.Assert(err, gc.IsNil)
334+ loggingEP, err := logging.Endpoint("info")
335+ c.Assert(err, gc.IsNil)
336+ rel, err := s.State.AddRelation(mysqlEP, loggingEP)
337+ c.Assert(err, gc.IsNil)
338+
339+ // Change mysqlEP to match the endpoint that will actually be used by the relation.
340+ mysqlEP.Scope = charm.ScopeContainer
341+
342+ // Add some units to the services and set their private addresses.
343+ addUnits := func(i int) (*state.RelationUnit, *state.RelationUnit) {
344+ msu, err := mysql.AddUnit()
345+ c.Assert(err, gc.IsNil)
346+ msru, err := rel.Unit(msu)
347+ c.Assert(err, gc.IsNil)
348+ c.Assert(msru.Endpoint(), gc.Equals, mysqlEP)
349+ err = msru.EnterScope(nil)
350+ c.Assert(err, gc.IsNil)
351+ err = msru.LeaveScope()
352+ c.Assert(err, gc.IsNil)
353+ lgu, err := s.State.Unit("logging/" + strconv.Itoa(i))
354+ c.Assert(err, gc.IsNil)
355+ lgru, err := rel.Unit(lgu)
356+ c.Assert(err, gc.IsNil)
357+ c.Assert(lgru.Endpoint(), gc.Equals, loggingEP)
358+ return msru, lgru
359+ }
360+ msru0, lgru0 := addUnits(0)
361+ msru1, lgru1 := addUnits(1)
362+
363+ // ---------- Single role active ----------
364+
365+ // Start watching the relation from the perspective of the first unit, and
366+ // check the initial event.
367+ msw0 := msru0.Watch()
368+ defer testing.AssertStop(c, msw0)
369+ s.assertChange(c, msw0, nil, nil)
370+ s.assertNoChange(c, msw0)
371+
372+ // Join the unit to the relation, change its settings, and check that
373+ // nothing apparently happens.
374+ err = msru0.EnterScope(nil)
375+ c.Assert(err, gc.IsNil)
376+ mss0 := changeSettings(c, msru0)
377+ s.assertNoChange(c, msw0)
378+
379+ // Watch the relation from the perspective of the second provider, and
380+ // check initial event.
381+ msw1 := msru1.Watch()
382+ defer testing.AssertStop(c, msw1)
383+ s.assertChange(c, msw1, nil, nil)
384+ s.assertNoChange(c, msw1)
385+
386+ // Join the second provider unit to the relation, and check that neither
387+ // watching unit observes any change.
388+ err = msru1.EnterScope(nil)
389+ c.Assert(err, gc.IsNil)
390+ s.assertNoChange(c, msw1)
391+ s.assertNoChange(c, msw0)
392+
393+ // Change the unit's settings, and check that nothing apparently happens.
394+ mss1 := changeSettings(c, msru1)
395+ s.assertNoChange(c, msw1)
396+ s.assertNoChange(c, msw0)
397+
398+ // ---------- Two roles active ----------
399+
400+ // Start a watch from the first requirer unit's perspective, and check it
401+ // only sees the first provider (with which it shares a container).
402+ lgw0 := lgru0.Watch()
403+ defer testing.AssertStop(c, lgw0)
404+ expectChanged := map[string]map[string]interface{}{
405+ "mysql/0": mss0.Map(),
406+ }
407+ s.assertChange(c, lgw0, expectChanged, nil)
408+ s.assertNoChange(c, lgw0)
409+
410+ // Join the first requirer unit, and check that only the first provider
411+ // observes the change.
412+ err = lgru0.EnterScope(nil)
413+ c.Assert(err, gc.IsNil)
414+ lgs0, err := lgru0.Settings()
415+ c.Assert(err, gc.IsNil)
416+ expectChanged = map[string]map[string]interface{}{
417+ "logging/0": lgs0.Map(),
418+ }
419+ s.assertChange(c, msw0, expectChanged, nil)
420+ s.assertNoChange(c, msw0)
421+ s.assertNoChange(c, msw1)
422+ s.assertNoChange(c, lgw0)
423+
424+ // Watch from the second requirer's perspective, and check it only sees the
425+ // second provider.
426+ lgw1 := lgru1.Watch()
427+ defer testing.AssertStop(c, lgw1)
428+ expectChanged = map[string]map[string]interface{}{
429+ "mysql/1": mss1.Map(),
430+ }
431+ s.assertChange(c, lgw1, expectChanged, nil)
432+ s.assertNoChange(c, lgw1)
433+
434+ // Join the second requirer, and check that the first provider observes it...
435+ err = lgru1.EnterScope(nil)
436+ c.Assert(err, gc.IsNil)
437+ lgs1, err := lgru1.Settings()
438+ c.Assert(err, gc.IsNil)
439+ expectChanged = map[string]map[string]interface{}{
440+ "logging/1": lgs1.Map(),
441+ }
442+ s.assertChange(c, msw1, expectChanged, nil)
443+ s.assertNoChange(c, msw1)
444+
445+ // ...and that nothing else sees anything.
446+ s.assertNoChange(c, msw0)
447+ s.assertNoChange(c, lgw0)
448+ s.assertNoChange(c, lgw1)
449+
450+ // Change the second provider's settings and check that the second
451+ // requirer notices...
452+ mss1 = changeSettings(c, msru1)
453+ expectChanged = map[string]map[string]interface{}{
454+ "mysql/1": mss1.Map(),
455+ }
456+ s.assertChange(c, lgw1, expectChanged, nil)
457+ s.assertNoChange(c, lgw1)
458+
459+ // ...but that nothing else does.
460+ s.assertNoChange(c, msw0)
461+ s.assertNoChange(c, msw1)
462+ s.assertNoChange(c, msw0)
463+
464+ // Finally, depart the first provider, and check that only the first
465+ // requirer observes any change.
466+ err = msru0.LeaveScope()
467+ c.Assert(err, gc.IsNil)
468+ expectDeparted := []string{"mysql/0"}
469+ s.assertChange(c, lgw0, nil, expectDeparted)
470+ s.assertNoChange(c, lgw0)
471+ s.assertNoChange(c, lgw1)
472+ s.assertNoChange(c, msw0)
473+ s.assertNoChange(c, msw1)
474+
475+ // Again, I think we're done, and can be comfortable that the appropriate
476+ // connections are in place.
477+}
478+
479+func changeSettings(c *gc.C, ru *state.RelationUnit) *state.Settings {
480+ node, err := ru.Settings()
481+ c.Assert(err, gc.IsNil)
482+ value, _ := node.Get("value")
483+ v, _ := value.(int)
484+ node.Set("value", v+1)
485+ _, err = node.Write()
486+ c.Assert(err, gc.IsNil)
487+ return node
488+}
489+
490+func (s *WatchScopeSuite) assertChange(
491+ c *gc.C, w *state.RelationUnitsWatcher,
492+ changed map[string]map[string]interface{},
493+ departed []string,
494+) {
495+ s.State.StartSync()
496+ select {
497+ case ch, ok := <-w.Changes():
498+ if !ok {
499+ c.Fatalf("channel closed; watcher error: %#v", w.Err())
500+ }
501+ c.Assert(ch.Changed, gc.HasLen, len(changed))
502+ for name, m := range changed {
503+ c.Assert(ch.Changed[name].Settings, gc.DeepEquals, m)
504+ }
505+ c.Assert(departed, jc.SameContents, ch.Departed)
506+ case <-time.After(5 * time.Second):
507+ c.Fatalf("expected changed %#v, departed %#v; got nothing", changed, departed)
508+ }
509+}
510+
511+func (s *WatchScopeSuite) assertNoChange(c *gc.C, w *state.RelationUnitsWatcher) {
512+ s.State.StartSync()
513+ select {
514+ case ch := <-w.Changes():
515+ c.Fatalf("got %#v, expected nothing", ch)
516+ case <-time.After(50 * time.Millisecond):
517+ }
518+}

Subscribers

People subscribed via source and target branches

to status/vote changes: