Rework ClusterSingletonServiceGroupImpl locking
[mdsal.git] / singleton-service / mdsal-singleton-dom-impl / src / test / java / org / opendaylight / mdsal / singleton / dom / impl / DOMClusterSingletonServiceProviderAsyncImplTest.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.never;
14 import static org.mockito.Mockito.verify;
15
16 import com.google.common.util.concurrent.ListenableFuture;
17 import com.google.common.util.concurrent.SettableFuture;
18 import java.util.Timer;
19 import java.util.TimerTask;
20 import org.junit.AfterClass;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
24 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
25
26 /*
27  * Testing {@link DOMClusterSingletonServiceProviderImpl} implementation
28  */
29 public final class DOMClusterSingletonServiceProviderAsyncImplTest extends AbstractDOMClusterServiceProviderTest {
30     /*
31      * Test implementation of {@link ClusterSingletonService}
32      */
33     static class TestClusterSingletonAsyncServiceInstance extends TestClusterSingletonService {
34         @Override
35         public ListenableFuture<Void> closeServiceInstance() {
36             super.closeServiceInstance();
37
38             final SettableFuture<Void> future = SettableFuture.create();
39             TIMER.schedule(new TimerTask() {
40                 @Override
41                 public void run() {
42                     future.set(null);
43                 }
44             }, ASYNC_TIME_DELAY_MILLIS);
45             return future;
46         }
47     }
48
49     protected static final long ASYNC_TIME_DELAY_MILLIS = 100L;
50     protected static Timer TIMER;
51
52     @BeforeClass
53     public static void asyncInitTest() {
54         TIMER = new Timer();
55     }
56
57     @AfterClass
58     public static void cleanTest() {
59         TIMER.cancel();
60     }
61
62     @Override
63     TestClusterSingletonService instantiateService() {
64         return new TestClusterSingletonAsyncServiceInstance();
65     }
66
67     /**
68      * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
69      *
70      * @throws Exception if the condition does not meet
71      */
72     @Test
73     public void takeDoubleLeadershipClusterSingletonServiceTest() throws Exception {
74         final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
75                 .registerClusterSingletonService(clusterSingletonService);
76         assertNotNull(reg);
77         verify(mockEos).registerCandidate(ENTITY);
78         clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
79         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
80         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
81         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
82         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
83         clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
84         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
85         Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
86         verify(mockDoubleEntityCandReg).close();
87         clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
88         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
89         clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
90         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
91         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
92         verify(mockEosDoubleEntityListReg, never()).close();
93         verify(mockEosEntityListReg, never()).close();
94         verify(mockEntityCandReg, never()).close();
95     }
96
97     /**
98      * Test checks unexpected change for MASTER-TO-SLAVE double Candidate role change.
99      *
100      * @throws Exception if the condition does not meet
101      */
102     @Test
103     public void unexpectedLostLeadershipDoubleCandidateTest() throws Exception {
104         final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
105                 .registerClusterSingletonService(clusterSingletonService);
106         assertNotNull(reg);
107         verify(mockEos).registerCandidate(ENTITY);
108         clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
109         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
110         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
111         clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
112         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
113         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
114         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
115         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToSlave());
116         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
117         Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
118         verify(mockEosDoubleEntityListReg, never()).close();
119         verify(mockEntityCandReg, never()).close();
120         verify(mockDoubleEntityCandReg, never()).close();
121         reg.close();
122         verify(mockEosDoubleEntityListReg, never()).close();
123         verify(mockEntityCandReg).close();
124         verify(mockDoubleEntityCandReg).close();
125     }
126
127     /**
128      * Test checks inJeopardy Cluster Node state for Master Instance.
129      *
130      * @throws Exception if the condition does not meet
131      */
132     @Test
133     public void inJeopardyMasterTest() throws Exception {
134         final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
135                 .registerClusterSingletonService(clusterSingletonService);
136         assertNotNull(reg);
137         verify(mockEos).registerCandidate(ENTITY);
138         clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
139         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
140         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
141         clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
142         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
143         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
144         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
145         clusterSingletonServiceProvider.ownershipChanged(getEntityMasterJeopardy());
146         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
147         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityMasterJeopardy());
148         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
149         Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
150         verify(mockEosEntityListReg, never()).close();
151         verify(mockEosDoubleEntityListReg, never()).close();
152         verify(mockEntityCandReg, never()).close();
153         verify(mockDoubleEntityCandReg, never()).close();
154     }
155
156     /**
157      * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
158      *
159      * @throws Exception if the condition does not meet
160      */
161     @Test
162     public void closeClusterSingletonServiceRegistrationMasterTest() throws Exception {
163         final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
164                 .registerClusterSingletonService(clusterSingletonService);
165         assertNotNull(reg);
166         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
167         verify(mockEos).registerCandidate(ENTITY);
168         clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
169         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
170         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
171         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
172         reg.close();
173         verify(mockEntityCandReg).close();
174         verify(mockDoubleEntityCandReg, never()).close();
175         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
176         Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
177         verify(mockDoubleEntityCandReg).close();
178         verify(mockEosEntityListReg, never()).close();
179         verify(mockEosDoubleEntityListReg, never()).close();
180     }
181
182     /**
183      * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
184      *
185      * @throws Exception if the condition does not meet
186      */
187     @Test
188     public void closeClusterSingletonServiceRegistrationMasterCloseWithNotificationTimesTest() throws Exception {
189         final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
190                 .registerClusterSingletonService(clusterSingletonService);
191         assertNotNull(reg);
192         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
193         verify(mockEos).registerCandidate(ENTITY);
194         clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
195         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
196         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
197         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
198         reg.close();
199         verify(mockEntityCandReg).close();
200         verify(mockDoubleEntityCandReg, never()).close();
201         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
202         Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
203         verify(mockDoubleEntityCandReg).close();
204         verify(mockEosEntityListReg, never()).close();
205         verify(mockEosDoubleEntityListReg, never()).close();
206     }
207
208     /**
209      * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
210      *
211      * @throws Exception if the condition does not meet
212      */
213     @Test
214     public void closeClusterSingletonServiceRegistrationMasterCloseCoupleTimesTest() throws Exception {
215         final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
216                 .registerClusterSingletonService(clusterSingletonService);
217         assertNotNull(reg);
218         assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
219         verify(mockEos).registerCandidate(ENTITY);
220         clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
221         verify(mockEos).registerCandidate(DOUBLE_ENTITY);
222         clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
223         assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
224         reg.close();
225         reg.close();
226         verify(mockEntityCandReg).close();
227         verify(mockDoubleEntityCandReg, never()).close();
228         assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
229
230         Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
231         verify(mockEosEntityListReg, never()).close();
232         verify(mockEosDoubleEntityListReg, never()).close();
233         verify(mockDoubleEntityCandReg).close();
234     }
235 }