Merge lp:~dave-cheney/juju-core/124-worker-peergrouper-mock-fix into lp:~go-bot/juju-core/trunk

Proposed by Dave Cheney
Status: Rejected
Rejected by: Dave Cheney
Proposed branch: lp:~dave-cheney/juju-core/124-worker-peergrouper-mock-fix
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 94 lines (+30/-12)
1 file modified
worker/peergrouper/mock_test.go (+30/-12)
To merge this branch: bzr merge lp:~dave-cheney/juju-core/124-worker-peergrouper-mock-fix
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+214170@code.launchpad.net

Description of the change

mock_test server uses fixed order

Update lp 1299958

In a previous attempt to fix this issue it was pointed out that the order of the top level is important. https://codereview.appspot.com/82490043/#msg2

However the mock server does not respect any order as the fakeMachines are stored in a map.

This CL attempts to solve the problem by storing fake machines in a slice. However if you run this test repeatedly you will see the results are still not stable and in fact the test was relying on a small map to order its keys.

https://codereview.appspot.com/84430044/

To post a comment you must log in.
Revision history for this message
Dave Cheney (dave-cheney) wrote :
Download full text (3.6 KiB)

Reviewers: mp+214170_code.launchpad.net,

Message:
Please take a look.

Description:
mock_test server uses fixed order

Update lp 1299958

In a previous attempt to fix this issue it was pointed out that the
order of the top level is important.
https://codereview.appspot.com/82490043/#msg2

However the mock server does not respect any order as the fakeMachines
are stored in a map.

This CL attempts to solve the problem by storing fake machines in a
slice. However if you run this test repeatedly you will see the results
are still not stable and in fact the test was relying on a small map to
order its keys.

https://code.launchpad.net/~dave-cheney/juju-core/124-worker-peergrouper-mock-fix/+merge/214170

(do not edit description out of merge proposal)

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

Affected files (+32, -12 lines):
   A [revision details]
   M worker/peergrouper/mock_test.go

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-20140404064032-dyb8bxnswgcrfxvm
+New revision: <email address hidden>

Index: worker/peergrouper/mock_test.go
=== modified file 'worker/peergrouper/mock_test.go'
--- worker/peergrouper/mock_test.go 2014-03-28 07:27:26 +0000
+++ worker/peergrouper/mock_test.go 2014-04-04 07:15:19 +0000
@@ -26,8 +26,11 @@
  // that we don't want to directly depend on in unit tests.

  type fakeState struct {
- mu sync.Mutex
- machines map[string]*fakeMachine
+ mu sync.Mutex
+ machines []struct {
+ id string
+ *fakeMachine
+ }
   stateServers voyeur.Value // of *state.StateServerInfo
   session *fakeMongoSession
   check func(st *fakeState) error
@@ -105,9 +108,7 @@
  }

  func newFakeState() *fakeState {
- st := &fakeState{
- machines: make(map[string]*fakeMachine),
- }
+ st := new(fakeState)
   st.session = newFakeMongoSession(st)
   st.stateServers.Set(&state.StateServerInfo{})
   return st
@@ -171,14 +172,25 @@
  func (st *fakeState) machine(id string) *fakeMachine {
   st.mu.Lock()
   defer st.mu.Unlock()
- return st.machines[id]
+ return st.machine0(id)
+}
+
+// machine0 is like machine but must only be called when
+// st.mu.Lock() is held.
+func (st *fakeState) machine0(id string) *fakeMachine {
+ for _, m := range st.machines {
+ if m.id == id {
+ return m.fakeMachine
+ }
+ }
+ return nil
  }

  func (st *fakeState) Machine(id string) (stateMachine, error) {
   if err := errorFor("State.Machine", id); err != nil {
    return nil, err
   }
- if m := st.machine(id); m != nil {
+ if m := st.machine0(id); m != nil {
    return m, nil
   }
   return nil, errors.NotFoundf("machine %s", id)
@@ -188,7 +200,7 @@
   st.mu.Lock()
   defer st.mu.Unlock()
   logger.Infof("fakeState.addMachine %q", id)
- if st.machines[id] != nil {
+ if st.machine0(id) != nil {
    panic(fmt.Errorf("id %q already used", id))
   }
   m := &fakeMachine{
@@ -198,7 +210,10 @@
     wantsVote: wantsVote,
    },
   }
- st.machines[id] = m
+ st.machines = append(st.machines, struct {
+ id string
+ *fakeMachine
+ }{id, m}...

Read more...

Revision history for this message
Dave Cheney (dave-cheney) wrote :
Revision history for this message
Tim Penhey (thumper) wrote :

LGTM

While I'm not entirely happy with the method name machine0, I can't
think of a better one for this.

https://codereview.appspot.com/84430044/

Revision history for this message
Dave Cheney (dave-cheney) wrote :

You shouldn't LGTM this change. It doesn't fix the problem, but it does highlight that the behaviour the test expects is not provided by the code.

> On 7 Apr 2014, at 9:29, <email address hidden> wrote:
>
> LGTM
>
> While I'm not entirely happy with the method name machine0, I can't
> think of a better one for this.
>
> https://codereview.appspot.com/84430044/

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

I don't understand this CL. The order of machines (which is what it
seems this CL is trying to fix) doesn't matter, but
the order of addresses within a machine does. In the previous
review I made my remark because it was treating {{addr2 addr1} {addr3}}
as equivalent to {{addr1 addr3} {addr2}}, whereas it should
actually be treating it as equivalent to {{addr3} {{addr2 addr1}} only.

Perhaps this was needless pedantry because I *think* that
in the peergrouper tests we only ever assign one address
to any given machine. It's perhaps still worth getting right
though.

https://codereview.appspot.com/84430044/

Unmerged revisions

2566. By Dave Cheney

Mock test should order results

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'worker/peergrouper/mock_test.go'
2--- worker/peergrouper/mock_test.go 2014-03-28 07:27:26 +0000
3+++ worker/peergrouper/mock_test.go 2014-04-04 07:21:06 +0000
4@@ -26,8 +26,11 @@
5 // that we don't want to directly depend on in unit tests.
6
7 type fakeState struct {
8- mu sync.Mutex
9- machines map[string]*fakeMachine
10+ mu sync.Mutex
11+ machines []struct {
12+ id string
13+ *fakeMachine
14+ }
15 stateServers voyeur.Value // of *state.StateServerInfo
16 session *fakeMongoSession
17 check func(st *fakeState) error
18@@ -105,9 +108,7 @@
19 }
20
21 func newFakeState() *fakeState {
22- st := &fakeState{
23- machines: make(map[string]*fakeMachine),
24- }
25+ st := new(fakeState)
26 st.session = newFakeMongoSession(st)
27 st.stateServers.Set(&state.StateServerInfo{})
28 return st
29@@ -171,14 +172,25 @@
30 func (st *fakeState) machine(id string) *fakeMachine {
31 st.mu.Lock()
32 defer st.mu.Unlock()
33- return st.machines[id]
34+ return st.machine0(id)
35+}
36+
37+// machine0 is like machine but must only be called when
38+// st.mu.Lock() is held.
39+func (st *fakeState) machine0(id string) *fakeMachine {
40+ for _, m := range st.machines {
41+ if m.id == id {
42+ return m.fakeMachine
43+ }
44+ }
45+ return nil
46 }
47
48 func (st *fakeState) Machine(id string) (stateMachine, error) {
49 if err := errorFor("State.Machine", id); err != nil {
50 return nil, err
51 }
52- if m := st.machine(id); m != nil {
53+ if m := st.machine0(id); m != nil {
54 return m, nil
55 }
56 return nil, errors.NotFoundf("machine %s", id)
57@@ -188,7 +200,7 @@
58 st.mu.Lock()
59 defer st.mu.Unlock()
60 logger.Infof("fakeState.addMachine %q", id)
61- if st.machines[id] != nil {
62+ if st.machine0(id) != nil {
63 panic(fmt.Errorf("id %q already used", id))
64 }
65 m := &fakeMachine{
66@@ -198,7 +210,10 @@
67 wantsVote: wantsVote,
68 },
69 }
70- st.machines[id] = m
71+ st.machines = append(st.machines, struct {
72+ id string
73+ *fakeMachine
74+ }{id, m})
75 m.val.Set(m.doc)
76 return m
77 }
78@@ -206,10 +221,13 @@
79 func (st *fakeState) removeMachine(id string) {
80 st.mu.Lock()
81 defer st.mu.Unlock()
82- if st.machines[id] == nil {
83- panic(fmt.Errorf("removing non-existent machine %q", id))
84+ for i, m := range st.machines {
85+ if m.id == id {
86+ st.machines = append(st.machines[:i], st.machines[i+1:]...)
87+ return
88+ }
89 }
90- delete(st.machines, id)
91+ panic(fmt.Errorf("removing non-existent machine %q", id))
92 }
93
94 func (st *fakeState) setStateServers(ids ...string) {

Subscribers

People subscribed via source and target branches

to status/vote changes: