1a5d7abc784a771de1dcd7c68c7121d882c81e4e
[mdsal.git] / singleton-service / mdsal-singleton-dom-impl / src / test / java / org / opendaylight / mdsal / singleton / dom / impl / SyncEOSClusterSingletonServiceProviderTest.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.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.Mockito.atLeastOnce;
13 import static org.mockito.Mockito.never;
14 import static org.mockito.Mockito.times;
15 import static org.mockito.Mockito.verify;
16 import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.LOCAL_OWNERSHIP_GRANTED;
17 import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.LOCAL_OWNERSHIP_LOST_NEW_OWNER;
18 import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.REMOTE_OWNERSHIP_CHANGED;
19 import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.REMOTE_OWNERSHIP_LOST_NO_OWNER;
20
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.junit.MockitoJUnitRunner;
24 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
25
26 /**
27  * Synchronous test suite.
28  */
29 @RunWith(MockitoJUnitRunner.StrictStubs.class)
30 public class SyncEOSClusterSingletonServiceProviderTest extends AbstractEOSClusterSingletonServiceProviderTest {
31     /**
32      * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
33      *
34      * @throws Exception if the condition does not meet
35      */
36     @Test
37     public void takeDoubleLeadershipClusterSingletonServiceTest() throws Exception {
38         final var reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService);
39         assertNotNull(reg);
40         verify(mockEos).registerCandidate(ENTITY);
41         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
42         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
43         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
44         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
45         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
46         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
47         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
48         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
49         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
50         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, REMOTE_OWNERSHIP_CHANGED, false);
51         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
52         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
53         verify(mockEosDoubleEntityListReg, never()).close();
54         verify(mockEosEntityListReg, never()).close();
55         verify(mockEntityCandReg, never()).close();
56         verify(mockDoubleEntityCandReg).close();
57     }
58
59     /**
60      * Test checks unexpected change for MASTER-TO-SLAVE double Candidate role change.
61      *
62      * @throws Exception if the condition does not meet
63      */
64     @Test
65     public void unexpectedLostLeadershipDoubleCandidateTest() throws Exception {
66         final var reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService);
67         assertNotNull(reg);
68         verify(mockEos).registerCandidate(ENTITY);
69         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
70         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
71         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
72         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, REMOTE_OWNERSHIP_CHANGED, false);
73         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
74         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
75         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
76         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
77         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
78         verify(mockEosDoubleEntityListReg, never()).close();
79         verify(mockEntityCandReg, never()).close();
80         verify(mockDoubleEntityCandReg, never()).close();
81         reg.close();
82         verify(mockEosEntityListReg, never()).close();
83         verify(mockEosDoubleEntityListReg, never()).close();
84         verify(mockEntityCandReg, atLeastOnce()).close();
85         verify(mockDoubleEntityCandReg).close();
86         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
87         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
88         verify(mockEntityCandReg).close();
89         verify(mockEosDoubleEntityListReg, never()).close();
90     }
91
92     /**
93      * Test checks inJeopardy Cluster Node state for Master Instance.
94      *
95      * @throws Exception if the condition does not meet
96      */
97     @Test
98     public void inJeopardyMasterTest() throws Exception {
99         final var reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService);
100         assertNotNull(reg);
101         verify(mockEos).registerCandidate(ENTITY);
102         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
103         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
104         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
105         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, REMOTE_OWNERSHIP_CHANGED, false);
106         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
107         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
108         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
109         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, REMOTE_OWNERSHIP_LOST_NO_OWNER, true);
110         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
111         verify(mockEosEntityListReg, never()).close();
112         verify(mockEosDoubleEntityListReg, never()).close();
113         verify(mockEntityCandReg, never()).close();
114         verify(mockDoubleEntityCandReg, never()).close();
115     }
116
117     /**
118      * Test checks close processing for {@link ServiceRegistration}.
119      *
120      * @throws Exception if the condition does not meet
121      */
122     @Test
123     public void closeClusterSingletonServiceRegistrationMasterTest() throws Exception {
124         final var reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService);
125         assertNotNull(reg);
126         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
127         verify(mockEos).registerCandidate(ENTITY);
128         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
129         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
130         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
131         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
132         reg.close();
133         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
134         verify(mockEosEntityListReg, never()).close();
135         verify(mockEosDoubleEntityListReg, never()).close();
136         verify(mockEntityCandReg).close();
137         verify(mockDoubleEntityCandReg).close();
138         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
139     }
140
141     /**
142      * Test checks close processing for {@link ServiceRegistration}.
143      *
144      * @throws Exception if the condition does not meet
145      */
146     @Test
147     public void closeClusterSingletonServiceRegistrationMasterCloseWithNotificationTimesTest() throws Exception {
148         final var reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService);
149         assertNotNull(reg);
150         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
151         verify(mockEos).registerCandidate(ENTITY);
152         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
153         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
154         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
155         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
156         reg.close();
157         verify(mockEosEntityListReg, never()).close();
158         verify(mockEosDoubleEntityListReg, never()).close();
159         verify(mockEntityCandReg, atLeastOnce()).close();
160         verify(mockDoubleEntityCandReg).close();
161         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
162     }
163
164     /**
165      * Test checks close processing for {@link ServiceRegistration}.
166      *
167      * @throws Exception if the condition does not meet
168      */
169     @Test
170     public void closeClusterSingletonServiceRegistrationMasterCloseCoupleTimesTest() throws Exception {
171         final var reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService);
172         assertNotNull(reg);
173         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
174         verify(mockEos).registerCandidate(ENTITY);
175         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
176         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
177         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
178         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
179         reg.close();
180         reg.close();
181         verify(mockEosEntityListReg, never()).close();
182         verify(mockEosDoubleEntityListReg, never()).close();
183         verify(mockEntityCandReg).close();
184         verify(mockDoubleEntityCandReg).close();
185         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
186         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
187         verify(mockEosDoubleEntityListReg, never()).close();
188     }
189
190     /**
191      * Verify that closing a group does not prevent next incarnation of it to be registered and the next incarnation
192      * will become active once the old incarnation finishes cleaning up.
193      */
194     @Test
195     public void testTwoIncarnations() throws Exception {
196         var reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService);
197         assertNotNull(reg);
198         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
199         verify(mockEos).registerCandidate(ENTITY);
200         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
201         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
202         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
203         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
204
205         // Close, triggers unregistration, but we will not continue with it.
206         reg.close();
207         verify(mockEosEntityListReg, never()).close();
208         verify(mockEosDoubleEntityListReg, never()).close();
209         verify(mockEntityCandReg).close();
210         verify(mockDoubleEntityCandReg).close();
211         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
212
213         // Instantiate the next incarnation
214         reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService2);
215         verify(mockEos).registerCandidate(ENTITY);
216         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
217
218         // Drive the old incarnation to closure, resetting mocks as needed
219         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
220         verify(mockEosDoubleEntityListReg, never()).close();
221
222         // Reset mocks for reuse. The next change should see the previous group terminate and the next incarnation
223         // to start coming up
224         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
225         verify(mockEos, times(2)).registerCandidate(ENTITY);
226         clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
227         verify(mockEos, times(2)).registerCandidate(DOUBLE_ENTITY);
228         clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
229         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
230
231         // Check for potential service mixup
232         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
233
234         verify(mockEosEntityListReg, never()).close();
235         verify(mockEosDoubleEntityListReg, never()).close();
236     }
237 }