@@ -60,10 +60,12 @@ func (m *msg) IsDeclaration() bool {
60
60
type peer struct {
61
61
mockedMethods map [string ]struct {}
62
62
mock.Mock
63
- id string
64
- peers map [string ]* peer
65
- sharedLock * sync.RWMutex
66
- msgChan chan Msg
63
+ id string
64
+ peers map [string ]* peer
65
+ sharedLock * sync.RWMutex
66
+ msgChan chan Msg
67
+ isLeaderFromCallback bool
68
+ callbackInvoked bool
67
69
LeaderElectionService
68
70
}
69
71
@@ -126,6 +128,11 @@ func (p *peer) Peers() []Peer {
126
128
return peers
127
129
}
128
130
131
+ func (p * peer ) leaderCallback (isLeader bool ) {
132
+ p .isLeaderFromCallback = isLeader
133
+ p .callbackInvoked = true
134
+ }
135
+
129
136
func createPeers (spawnInterval time.Duration , ids ... int ) []* peer {
130
137
peers := make ([]* peer , len (ids ))
131
138
peerMap := make (map [string ]* peer )
@@ -143,16 +150,16 @@ func createPeers(spawnInterval time.Duration, ids ...int) []*peer {
143
150
func createPeer (id int , peerMap map [string ]* peer , l * sync.RWMutex ) * peer {
144
151
idStr := fmt .Sprintf ("p%d" , id )
145
152
c := make (chan Msg , 100 )
146
- p := & peer {id : idStr , peers : peerMap , sharedLock : l , msgChan : c , mockedMethods : make (map [string ]struct {})}
147
- p .LeaderElectionService = NewLeaderElectionService (p , idStr )
153
+ p := & peer {id : idStr , peers : peerMap , sharedLock : l , msgChan : c , mockedMethods : make (map [string ]struct {}), isLeaderFromCallback : false , callbackInvoked : false }
154
+ p .LeaderElectionService = NewLeaderElectionService (p , idStr , p . leaderCallback )
148
155
l .Lock ()
149
156
peerMap [idStr ] = p
150
157
l .Unlock ()
151
158
return p
152
159
153
160
}
154
161
155
- func waitForLeaderElection (t * testing.T , peers []* peer ) []string {
162
+ func waitForMultipleLeadersElection (t * testing.T , peers []* peer , leadersNum int ) []string {
156
163
end := time .Now ().Add (testTimeout )
157
164
for time .Now ().Before (end ) {
158
165
var leaders []string
@@ -161,7 +168,7 @@ func waitForLeaderElection(t *testing.T, peers []*peer) []string {
161
168
leaders = append (leaders , p .id )
162
169
}
163
170
}
164
- if len (leaders ) > 0 {
171
+ if len (leaders ) >= leadersNum {
165
172
return leaders
166
173
}
167
174
time .Sleep (testPollInterval )
@@ -170,6 +177,10 @@ func waitForLeaderElection(t *testing.T, peers []*peer) []string {
170
177
return nil
171
178
}
172
179
180
+ func waitForLeaderElection (t * testing.T , peers []* peer ) []string {
181
+ return waitForMultipleLeadersElection (t , peers , 1 )
182
+ }
183
+
173
184
func TestInitPeersAtSameTime (t * testing.T ) {
174
185
t .Parallel ()
175
186
// Scenario: Peers are spawned at the same time
@@ -179,6 +190,7 @@ func TestInitPeersAtSameTime(t *testing.T) {
179
190
leaders := waitForLeaderElection (t , peers )
180
191
isP0leader := peers [len (peers )- 1 ].IsLeader ()
181
192
assert .True (t , isP0leader , "p0 isn't a leader. Leaders are: %v" , leaders )
193
+ assert .True (t , peers [len (peers )- 1 ].isLeaderFromCallback , "p0 didn't got leaderhip change callback invoked" )
182
194
assert .Len (t , leaders , 1 , "More than 1 leader elected" )
183
195
}
184
196
@@ -257,6 +269,18 @@ func TestConvergence(t *testing.T) {
257
269
finalLeaders := waitForLeaderElection (t , combinedPeers )
258
270
assert .Len (t , finalLeaders , 1 , "Combined peer group was suppose to have 1 leader exactly" )
259
271
assert .Equal (t , leaders1 [0 ], finalLeaders [0 ], "Combined peer group has different leader than expected:" )
272
+
273
+ for _ , p := range combinedPeers {
274
+ if p .id == finalLeaders [0 ] {
275
+ assert .True (t , p .isLeaderFromCallback , "Leadership callback result is wrong for " , p .id )
276
+ assert .True (t , p .callbackInvoked , "Leadership callback wasn't invoked for " , p .id )
277
+ } else {
278
+ assert .False (t , p .isLeaderFromCallback , "Leadership callback result is wrong for " , p .id )
279
+ if p .id == leaders2 [0 ] {
280
+ assert .True (t , p .callbackInvoked , "Leadership callback wasn't invoked for " , p .id )
281
+ }
282
+ }
283
+ }
260
284
}
261
285
262
286
func TestLeadershipTakeover (t * testing.T ) {
@@ -286,20 +310,36 @@ func TestPartition(t *testing.T) {
286
310
leaders := waitForLeaderElection (t , peers )
287
311
assert .Len (t , leaders , 1 , "Only 1 leader should have been elected" )
288
312
assert .Equal (t , "p0" , leaders [0 ])
313
+ assert .True (t , peers [len (peers )- 1 ].isLeaderFromCallback , "Leadership callback result is wrong for %s" , peers [len (peers )- 1 ].id )
314
+
289
315
for _ , p := range peers {
290
316
p .On ("Peers" ).Return ([]Peer {})
291
317
p .On ("Gossip" , mock .Anything )
292
318
}
293
319
time .Sleep (leadershipDeclarationInterval + leaderAliveThreshold * 2 )
294
- leaders = waitForLeaderElection (t , peers )
295
- assert .Len (t , leaders , len (leaders ))
320
+ leaders = waitForMultipleLeadersElection (t , peers , 6 )
321
+ assert .Len (t , leaders , 6 )
322
+ for _ , p := range peers {
323
+ assert .True (t , p .isLeaderFromCallback , "Leadership callback result is wrong for %s" , p .id )
324
+ }
325
+
296
326
for _ , p := range peers {
297
327
p .sharedLock .Lock ()
298
328
p .mockedMethods = make (map [string ]struct {})
329
+ p .callbackInvoked = false
299
330
p .sharedLock .Unlock ()
300
331
}
301
332
time .Sleep (leadershipDeclarationInterval + leaderAliveThreshold * 2 )
302
333
leaders = waitForLeaderElection (t , peers )
303
334
assert .Len (t , leaders , 1 , "Only 1 leader should have been elected" )
304
335
assert .Equal (t , "p0" , leaders [0 ])
336
+ for _ , p := range peers {
337
+ if p .id == leaders [0 ] {
338
+ assert .True (t , p .isLeaderFromCallback , "Leadership callback result is wrong for %" , p .id )
339
+ } else {
340
+ assert .False (t , p .isLeaderFromCallback , "Leadership callback result is wrong for %s" , p .id )
341
+ assert .True (t , p .callbackInvoked , "Leadership callback wasn't invoked for %s" , p .id )
342
+ }
343
+ }
344
+
305
345
}
0 commit comments