BUG-8858: rework singleton group locking
[mdsal.git] / singleton-service / mdsal-singleton-dom-impl / src / test / java / org / opendaylight / mdsal / singleton / dom / impl / ClusterSingletonServiceGroupImplTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.mdsal.singleton.dom.impl;
10
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.mockito.Mockito.doNothing;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.never;
18 import static org.mockito.Mockito.verify;
19 import static org.opendaylight.mdsal.singleton.dom.impl.AbstractClusterSingletonServiceProviderImpl.CLOSE_SERVICE_ENTITY_TYPE;
20 import static org.opendaylight.mdsal.singleton.dom.impl.AbstractClusterSingletonServiceProviderImpl.SERVICE_ENTITY_TYPE;
21
22 import com.google.common.util.concurrent.Futures;
23 import com.google.common.util.concurrent.ListenableFuture;
24 import java.util.concurrent.ExecutionException;
25 import org.junit.Before;
26 import org.junit.Test;
27 import org.mockito.Mock;
28 import org.mockito.MockitoAnnotations;
29 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
30 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
31 import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipCandidateRegistration;
32 import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipChange;
33 import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipListener;
34 import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipService;
35 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
36 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
37 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
38 import org.opendaylight.mdsal.singleton.dom.impl.util.TestEntity;
39 import org.opendaylight.mdsal.singleton.dom.impl.util.TestInstanceIdentifier;
40
41 /**
42  * Testing {@link ClusterSingletonServiceGroupImpl}.
43  */
44 public class ClusterSingletonServiceGroupImplTest {
45     private static final String SERVICE_IDENTIFIER = "TestServiceIdent";
46     private static final ServiceGroupIdentifier SERVICE_GROUP_IDENT = ServiceGroupIdentifier.create(SERVICE_IDENTIFIER);
47
48     private static final TestEntity MAIN_ENTITY = new TestEntity(SERVICE_ENTITY_TYPE, SERVICE_IDENTIFIER);
49     private static final TestEntity CLOSE_ENTITY = new TestEntity(CLOSE_SERVICE_ENTITY_TYPE, SERVICE_IDENTIFIER);
50
51     @Mock
52     private ClusterSingletonService mockClusterSingletonService;
53     @Mock
54     private ClusterSingletonService mockClusterSingletonServiceSecond;
55     @Mock
56     private GenericEntityOwnershipCandidateRegistration<?, ?> mockEntityCandReg;
57     @Mock
58     private GenericEntityOwnershipCandidateRegistration<?, ?> mockCloseEntityCandReg;
59     @Mock
60     private GenericEntityOwnershipListener<TestInstanceIdentifier,
61         GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity>> mockEosListener;
62
63     @Mock
64     private GenericEntityOwnershipService<TestInstanceIdentifier,TestEntity,
65         GenericEntityOwnershipListener<TestInstanceIdentifier,
66             GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity>>> mockEosService;
67
68     private ClusterSingletonServiceGroupImpl<TestInstanceIdentifier,TestEntity,
69         GenericEntityOwnershipChange<TestInstanceIdentifier,TestEntity>,
70             GenericEntityOwnershipListener<TestInstanceIdentifier,
71                 GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity>>,
72                     GenericEntityOwnershipService<TestInstanceIdentifier, TestEntity,
73                         GenericEntityOwnershipListener<TestInstanceIdentifier,
74                             GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity>>>> singletonServiceGroup;
75
76     /**
77      * Initialization functionality for every Tests in this suite.
78      *
79      * @throws CandidateAlreadyRegisteredException unexpected exception.
80      */
81     @Before
82     public void setup() throws CandidateAlreadyRegisteredException {
83         MockitoAnnotations.initMocks(this);
84
85         doReturn(mockEntityCandReg).when(mockEosService).registerCandidate(MAIN_ENTITY);
86         doReturn(mockCloseEntityCandReg).when(mockEosService).registerCandidate(CLOSE_ENTITY);
87         doNothing().when(mockEntityCandReg).close();
88         doNothing().when(mockCloseEntityCandReg).close();
89         doNothing().when(mockClusterSingletonService).instantiateServiceInstance();
90         doReturn(Futures.immediateFuture(null)).when(mockClusterSingletonService).closeServiceInstance();
91
92         doReturn(SERVICE_GROUP_IDENT).when(mockClusterSingletonService).getIdentifier();
93         doReturn(SERVICE_GROUP_IDENT).when(mockClusterSingletonServiceSecond).getIdentifier();
94
95         singletonServiceGroup = new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, MAIN_ENTITY, CLOSE_ENTITY,
96             mockEosService);
97     }
98
99     /**
100      * Test NULL ServiceIdent input for new ServiceGroup instance.
101      */
102     @Test(expected = NullPointerException.class)
103     public void instantiationClusterSingletonServiceGroupNullIdentTest() {
104         new ClusterSingletonServiceGroupImpl<>(null, MAIN_ENTITY, CLOSE_ENTITY, mockEosService);
105     }
106
107     /**
108      * Test empty ServiceIdent input for new ServiceGroup instance.
109      */
110     @Test(expected = IllegalArgumentException.class)
111     public void instantiationClusterSingletonServiceGroupEmptyIdentTest() {
112         new ClusterSingletonServiceGroupImpl<>("", MAIN_ENTITY, CLOSE_ENTITY, mockEosService);
113     }
114
115     /**
116      * Test NULL MainEntity input for new ServiceGroup instance.
117      */
118     @Test(expected = NullPointerException.class)
119     public void instantiationClusterSingletonServiceGroupNullMainEntityTest() {
120         new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, null, CLOSE_ENTITY, mockEosService);
121     }
122
123     /**
124      * Test NULL CloseEntity input for new ServiceGroup instance.
125      */
126     @Test(expected = NullPointerException.class)
127     public void instantiationClusterSingletonServiceGroupNullCloseEntityTest() {
128         new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, MAIN_ENTITY, null, mockEosService);
129     }
130
131     /**
132      * Test NULL EntityOwnershipService input for new ServiceGroup instance.
133      */
134     @Test(expected = NullPointerException.class)
135     public void instantiationClusterSingletonServiceGroupNullEOS_Test() {
136         new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, MAIN_ENTITY, CLOSE_ENTITY, null);
137     }
138
139     /**
140      * Test GoldPath for initialization ServiceGroup.
141      */
142     @Test
143     public void initializationClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
144         singletonServiceGroup.initialize();
145         verify(mockEosService).registerCandidate(MAIN_ENTITY);
146     }
147
148     /**
149      * Test GoldPath for NO-TO-SLAVE entity Candidate role change.
150      *
151      * @throws CandidateAlreadyRegisteredException - unexpected exception
152      */
153     @Test
154     public void initializationSlaveTest() throws CandidateAlreadyRegisteredException {
155         singletonServiceGroup.initialize();
156         verify(mockEosService).registerCandidate(MAIN_ENTITY);
157         singletonServiceGroup.registerService(mockClusterSingletonService);
158         singletonServiceGroup.ownershipChanged(getEntityToSlave());
159         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
160         verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
161     }
162
163     /**
164      * Test GoldPath for NO-TO-SLAVE but without MASTER entity Candidate role change.
165      *
166      * @throws CandidateAlreadyRegisteredException - unexpected exception
167      */
168     @Test
169     public void initializationNoMasterTest() throws CandidateAlreadyRegisteredException {
170         singletonServiceGroup.initialize();
171         verify(mockEosService).registerCandidate(MAIN_ENTITY);
172         singletonServiceGroup.registerService(mockClusterSingletonService);
173         singletonServiceGroup.ownershipChanged(getEntityToSlaveNoMaster());
174         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
175         verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
176     }
177
178     /**
179      * Test GoldPath for InJeopardy entity Candidate role change.
180      *
181      * @throws CandidateAlreadyRegisteredException - unexpected exception
182      */
183     @Test
184     public void initializationInJeopardyTest() throws CandidateAlreadyRegisteredException {
185         singletonServiceGroup.initialize();
186         verify(mockEosService).registerCandidate(MAIN_ENTITY);
187         singletonServiceGroup.registerService(mockClusterSingletonService);
188         singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
189         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
190         verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
191     }
192
193     /**
194      * Test GoldPath for registration SingletonService.
195      *
196      * @throws CandidateAlreadyRegisteredException - unexpected exception
197      */
198     @Test
199     public void serviceRegistrationClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
200         singletonServiceGroup.initialize();
201         verify(mockEosService).registerCandidate(MAIN_ENTITY);
202         singletonServiceGroup.registerService(mockClusterSingletonService);
203     }
204
205     /**
206      * Test GoldPath for registration SingletonService.
207      *
208      * @throws CandidateAlreadyRegisteredException - unexpected exception
209      */
210     @Test
211     public void serviceRegistrationClusterSingletonServiceGroupTwoServiceTest()
212             throws CandidateAlreadyRegisteredException {
213         singletonServiceGroup.initialize();
214         verify(mockEosService).registerCandidate(MAIN_ENTITY);
215         singletonServiceGroup.registerService(mockClusterSingletonService);
216         singletonServiceGroup.registerService(mockClusterSingletonServiceSecond);
217     }
218
219     /**
220      * Test GoldPath for unregistration SingletonService don't call closeServiceInstance
221      * without mastership and don't remove ServiceGroup from map.
222      *
223      * @throws CandidateAlreadyRegisteredException - unexpected exception
224      */
225     @Test
226     public void serviceUnregistrationClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
227         singletonServiceGroup.initialize();
228         verify(mockEosService).registerCandidate(MAIN_ENTITY);
229         singletonServiceGroup.registerService(mockClusterSingletonService);
230         assertTrue(singletonServiceGroup.unregisterService(mockClusterSingletonService));
231         verify(mockClusterSingletonService, never()).closeServiceInstance();
232     }
233
234     /**
235      * Test GoldPath for unregistration SingletonService don't call closeServiceInstance
236      *     without mastership and don't remove ServiceGroup from map.
237      *
238      * @throws CandidateAlreadyRegisteredException - unexpected exception
239      */
240     @Test
241     public void serviceUnregistrationClusterSingletonServiceGroupTwoServicesTest()
242             throws CandidateAlreadyRegisteredException {
243         singletonServiceGroup.initialize();
244         verify(mockEosService).registerCandidate(MAIN_ENTITY);
245         singletonServiceGroup.registerService(mockClusterSingletonService);
246         singletonServiceGroup.registerService(mockClusterSingletonServiceSecond);
247         assertFalse(singletonServiceGroup.unregisterService(mockClusterSingletonService));
248         verify(mockClusterSingletonService, never()).closeServiceInstance();
249     }
250
251     /**
252      * Test GoldPath get Slave role for registered main entity.
253      *
254      * @throws CandidateAlreadyRegisteredException - unexpected exception
255      */
256     @Test
257     public void getSlaveClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
258         singletonServiceGroup.initialize();
259         verify(mockEosService).registerCandidate(MAIN_ENTITY);
260         singletonServiceGroup.registerService(mockClusterSingletonService);
261         singletonServiceGroup.ownershipChanged(getEntityToSlave());
262         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
263     }
264
265     /**
266      * Test GoldPath get Master role for registered main entity.
267      *
268      * @throws CandidateAlreadyRegisteredException - unexpected exception
269      */
270     @Test
271     public void tryToTakeLeaderClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
272         singletonServiceGroup.initialize();
273         verify(mockEosService).registerCandidate(MAIN_ENTITY);
274         singletonServiceGroup.registerService(mockClusterSingletonService);
275         singletonServiceGroup.ownershipChanged(getEntityToMaster());
276         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
277         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
278     }
279
280     /**
281      * Test GoldPath get Master role for registered close entity.
282      *
283      * @throws CandidateAlreadyRegisteredException - unexpected exception
284      */
285     @Test
286     public void takeMasterClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
287         singletonServiceGroup.initialize();
288         verify(mockEosService).registerCandidate(MAIN_ENTITY);
289         singletonServiceGroup.registerService(mockClusterSingletonService);
290         singletonServiceGroup.ownershipChanged(getEntityToMaster());
291         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
292         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
293         singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
294         verify(mockClusterSingletonService).instantiateServiceInstance();
295     }
296
297     /**
298      * Test GoldPath get Master role for registered entity but initial Slave
299      *     role for closeEntity.
300      *
301      * @throws CandidateAlreadyRegisteredException - unexpected exception
302      */
303     @Test
304     public void waitToTakeMasterClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
305         singletonServiceGroup.initialize();
306         verify(mockEosService).registerCandidate(MAIN_ENTITY);
307         singletonServiceGroup.registerService(mockClusterSingletonService);
308         singletonServiceGroup.ownershipChanged(getEntityToMaster());
309         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
310         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
311         singletonServiceGroup.ownershipChanged(getInitDoubleEntityToSlave());
312         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
313         verify(mockClusterSingletonService, never()).closeServiceInstance();
314     }
315
316     /**
317      * Test inJeopardy validation during wait phase for Master role for closeEntity.
318      *
319      * @throws CandidateAlreadyRegisteredException - unexpected exception
320      */
321     @Test
322     public void inJeopardyInWaitPhaseClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
323         singletonServiceGroup.initialize();
324         verify(mockEosService).registerCandidate(MAIN_ENTITY);
325         singletonServiceGroup.registerService(mockClusterSingletonService);
326         singletonServiceGroup.ownershipChanged(getEntityToMaster());
327         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
328         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
329         singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
330         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
331         verify(mockClusterSingletonService, never()).closeServiceInstance();
332     }
333
334     /**
335      * Test inJeopardy validation during wait phase for Master role for closeEntity.
336      *
337      * @throws CandidateAlreadyRegisteredException - unexpected exception
338      */
339     @Test
340     public void inJeopardyInWaitPhaseClusterSingletonServiceGroupTwoServiceTest()
341             throws CandidateAlreadyRegisteredException {
342         singletonServiceGroup.initialize();
343         verify(mockEosService).registerCandidate(MAIN_ENTITY);
344         singletonServiceGroup.registerService(mockClusterSingletonService);
345         singletonServiceGroup.registerService(mockClusterSingletonServiceSecond);
346         singletonServiceGroup.ownershipChanged(getEntityToMaster());
347         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
348         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
349         singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
350         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
351         verify(mockClusterSingletonService, never()).closeServiceInstance();
352     }
353
354     /**
355      * Test inJeopardy validation for holding leadership.
356      *
357      * @throws CandidateAlreadyRegisteredException - unexpected exception
358      */
359     @Test
360     public void inJeopardyLeaderClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
361         singletonServiceGroup.initialize();
362         verify(mockEosService).registerCandidate(MAIN_ENTITY);
363         singletonServiceGroup.registerService(mockClusterSingletonService);
364         singletonServiceGroup.ownershipChanged(getEntityToMaster());
365         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
366         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
367         singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
368         verify(mockClusterSingletonService).instantiateServiceInstance();
369         singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
370         verify(mockClusterSingletonService).closeServiceInstance();
371     }
372
373     /**
374      * Test GoldPath for SLAVE-TO-MASTER entity Candidate role change.
375      *
376      * @throws CandidateAlreadyRegisteredException - unexpected exception
377      */
378     @Test
379     public void lostLeaderClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
380         singletonServiceGroup.initialize();
381         verify(mockEosService).registerCandidate(MAIN_ENTITY);
382         singletonServiceGroup.registerService(mockClusterSingletonService);
383         singletonServiceGroup.ownershipChanged(getEntityToMaster());
384         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
385         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
386         singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
387         verify(mockClusterSingletonService).instantiateServiceInstance();
388         singletonServiceGroup.ownershipChanged(getEntityToSlave());
389         verify(mockClusterSingletonService).closeServiceInstance();
390     }
391
392     /**
393      * Test checks validation Error processing for SLAVE-TO-MASTER entity Candidate role change.
394      *     Not initialized provider has to close and remove all singletonServices from Group and
395      *     Group itself remove too.
396      */
397     @Test(expected = RuntimeException.class)
398     public void tryToTakeLeaderForNotInitializedGroupTest() {
399         singletonServiceGroup.registerService(mockClusterSingletonService);
400     }
401
402     /**
403      * Test checks closing processing for close {@link ClusterSingletonServiceRegistration}.
404      *
405      * @throws CandidateAlreadyRegisteredException - unexpected exception
406      */
407     @Test
408     public void checkClosingRegistrationTest() throws CandidateAlreadyRegisteredException {
409         singletonServiceGroup.initialize();
410         verify(mockEosService).registerCandidate(MAIN_ENTITY);
411         singletonServiceGroup.registerService(mockClusterSingletonService);
412         singletonServiceGroup.ownershipChanged(getEntityToMaster());
413         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
414         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
415         singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
416         verify(mockClusterSingletonService).instantiateServiceInstance();
417         assertTrue(singletonServiceGroup.unregisterService(mockClusterSingletonService));
418         verify(mockClusterSingletonService, never()).closeServiceInstance();
419         singletonServiceGroup.ownershipChanged(getEntityToSlaveNoMaster());
420         verify(mockClusterSingletonService).closeServiceInstance();
421     }
422
423     /**
424      * Test checks validation Error processing for MASTER-TO-SLAVE closeEntity Candidate role change.
425      *
426      * @throws CandidateAlreadyRegisteredException - unexpected exception
427      */
428     @Test
429     public void checkClosingUnexpectedDoubleEntityForMasterOwnershipChangeRegistrationTest()
430             throws CandidateAlreadyRegisteredException {
431         singletonServiceGroup.initialize();
432         verify(mockEosService).registerCandidate(MAIN_ENTITY);
433         singletonServiceGroup.registerService(mockClusterSingletonService);
434         singletonServiceGroup.ownershipChanged(getEntityToMaster());
435         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
436         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
437         singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
438         verify(mockClusterSingletonService).instantiateServiceInstance();
439         singletonServiceGroup.ownershipChanged(getDoubleEntityToSlave());
440         verify(mockClusterSingletonService, never()).closeServiceInstance();
441     }
442
443     /**
444      * Test checks validation Error processing for MASTER-TO-SLAVE closeEntity Candidate role change
445      *     without closeEntity registration.
446      *
447      * @throws CandidateAlreadyRegisteredException - unexpected exception
448      */
449     @Test
450     public void checkClosingUnexpectedDoubleEntityForSlaveOwnershipChangeRegistrationTest()
451             throws CandidateAlreadyRegisteredException {
452         singletonServiceGroup.initialize();
453         verify(mockEosService).registerCandidate(MAIN_ENTITY);
454         singletonServiceGroup.registerService(mockClusterSingletonService);
455         singletonServiceGroup.ownershipChanged(getEntityToSlave());
456         verify(mockClusterSingletonService, never()).instantiateServiceInstance();
457         verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
458         singletonServiceGroup.ownershipChanged(getDoubleEntityToSlave());
459         verify(mockClusterSingletonService, never()).closeServiceInstance();
460     }
461
462     @Test
463     public void testRegisterCloseShutdown() throws CandidateAlreadyRegisteredException, InterruptedException,
464             ExecutionException {
465         initializeGroupAndStartService();
466
467         assertTrue(singletonServiceGroup.unregisterService(mockClusterSingletonService));
468         verify(mockClusterSingletonService, never()).closeServiceInstance();
469         verify(mockEntityCandReg, never()).close();
470
471         final ListenableFuture<?> future = singletonServiceGroup.closeClusterSingletonGroup();
472         assertNotNull(future);
473         assertFalse(future.isDone());
474         verify(mockClusterSingletonService, never()).closeServiceInstance();
475         verify(mockEntityCandReg).close();
476
477         singletonServiceGroup.ownershipChanged(getEntityToSlave());
478         verify(mockClusterSingletonService).closeServiceInstance();
479         verify(mockCloseEntityCandReg).close();
480
481         singletonServiceGroup.ownershipChanged(getDoubleEntityToSlave());
482         assertTrue(future.isDone());
483         assertNull(future.get());
484     }
485
486     private void initialize() throws CandidateAlreadyRegisteredException {
487         singletonServiceGroup.initialize();
488         verify(mockEosService).registerCandidate(MAIN_ENTITY);
489     }
490
491     private void initializeGroupAndStartService() throws CandidateAlreadyRegisteredException {
492         initialize();
493         singletonServiceGroup.registerService(mockClusterSingletonService);
494         singletonServiceGroup.ownershipChanged(getEntityToMaster());
495         verify(mockEosService).registerCandidate(CLOSE_ENTITY);
496         singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
497         verify(mockClusterSingletonService).instantiateServiceInstance();
498     }
499
500     private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToMaster() {
501         return new GenericEntityOwnershipChange<>(MAIN_ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED);
502     }
503
504     private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToSlave() {
505         return new GenericEntityOwnershipChange<>(MAIN_ENTITY,
506                 EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER);
507     }
508
509     private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToSlaveNoMaster() {
510         return new GenericEntityOwnershipChange<>(MAIN_ENTITY,
511                 EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NO_OWNER);
512     }
513
514     private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getDoubleEntityToMaster() {
515         return new GenericEntityOwnershipChange<>(CLOSE_ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED);
516     }
517
518     private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getDoubleEntityToSlave() {
519         return new GenericEntityOwnershipChange<>(CLOSE_ENTITY,
520                 EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER);
521     }
522
523     private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getInitDoubleEntityToSlave() {
524         return new GenericEntityOwnershipChange<>(CLOSE_ENTITY, EntityOwnershipChangeState.REMOTE_OWNERSHIP_CHANGED);
525     }
526
527     private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToJeopardy() {
528         return new GenericEntityOwnershipChange<>(MAIN_ENTITY,
529                 EntityOwnershipChangeState.REMOTE_OWNERSHIP_LOST_NO_OWNER, true);
530     }
531 }