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