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