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