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