Clean up mdsal-singleton-dom-impl
[mdsal.git] / singleton-service / mdsal-singleton-dom-impl / src / test / java / org / opendaylight / mdsal / singleton / dom / impl / AsyncEOSClusterSingletonServiceProviderTest.java
diff --git a/singleton-service/mdsal-singleton-dom-impl/src/test/java/org/opendaylight/mdsal/singleton/dom/impl/AsyncEOSClusterSingletonServiceProviderTest.java b/singleton-service/mdsal-singleton-dom-impl/src/test/java/org/opendaylight/mdsal/singleton/dom/impl/AsyncEOSClusterSingletonServiceProviderTest.java
new file mode 100644 (file)
index 0000000..b0a6324
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.singleton.dom.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.LOCAL_OWNERSHIP_GRANTED;
+import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.LOCAL_OWNERSHIP_LOST_NEW_OWNER;
+import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.LOCAL_OWNERSHIP_RETAINED_WITH_NO_CHANGE;
+import static org.opendaylight.mdsal.eos.common.api.EntityOwnershipStateChange.REMOTE_OWNERSHIP_CHANGED;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import java.util.Timer;
+import java.util.TimerTask;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+
+/*
+ * Testing {@link DOMClusterSingletonServiceProviderImpl} implementation
+ */
+@RunWith(MockitoJUnitRunner.StrictStubs.class)
+public final class AsyncEOSClusterSingletonServiceProviderTest extends AbstractEOSClusterSingletonServiceProviderTest {
+    /*
+     * Test implementation of {@link ClusterSingletonService}
+     */
+    public static class TestClusterSingletonAsyncServiceInstance extends TestClusterSingletonService {
+        @Override
+        public ListenableFuture<Void> closeServiceInstance() {
+            super.closeServiceInstance();
+
+            final SettableFuture<Void> future = SettableFuture.create();
+            TIMER.schedule(new TimerTask() {
+                @Override
+                public void run() {
+                    future.set(null);
+                }
+            }, ASYNC_TIME_DELAY_MILLIS);
+            return future;
+        }
+    }
+
+    public static final long ASYNC_TIME_DELAY_MILLIS = 100L;
+    public static Timer TIMER;
+
+    @BeforeClass
+    public static void asyncInitTest() {
+        TIMER = new Timer();
+    }
+
+    @AfterClass
+    public static void cleanTest() {
+        TIMER.cancel();
+    }
+
+    @Override
+    TestClusterSingletonService instantiateService() {
+        return new TestClusterSingletonAsyncServiceInstance();
+    }
+
+    /**
+     * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
+     *
+     * @throws Exception if the condition does not meet
+     */
+    @Test
+    public void takeDoubleLeadershipClusterSingletonServiceTest() throws Exception {
+        final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+                .registerClusterSingletonService(clusterSingletonService);
+        assertNotNull(reg);
+        verify(mockEos).registerCandidate(ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
+        assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+        Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
+        verify(mockDoubleEntityCandReg).close();
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, REMOTE_OWNERSHIP_CHANGED, false);
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        verify(mockEosDoubleEntityListReg, never()).close();
+        verify(mockEosEntityListReg, never()).close();
+        verify(mockEntityCandReg, never()).close();
+    }
+
+    /**
+     * Test checks unexpected change for MASTER-TO-SLAVE double Candidate role change.
+     *
+     * @throws Exception if the condition does not meet
+     */
+    @Test
+    public void unexpectedLostLeadershipDoubleCandidateTest() throws Exception {
+        final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+                .registerClusterSingletonService(clusterSingletonService);
+        assertNotNull(reg);
+        verify(mockEos).registerCandidate(ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, REMOTE_OWNERSHIP_CHANGED, false);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_LOST_NEW_OWNER, false);
+        assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+        Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
+        verify(mockEosDoubleEntityListReg, never()).close();
+        verify(mockEntityCandReg, never()).close();
+        verify(mockDoubleEntityCandReg, never()).close();
+        reg.close();
+        verify(mockEosDoubleEntityListReg, never()).close();
+        verify(mockEntityCandReg).close();
+        verify(mockDoubleEntityCandReg).close();
+    }
+
+    /**
+     * Test checks inJeopardy Cluster Node state for Master Instance.
+     *
+     * @throws Exception if the condition does not meet
+     */
+    @Test
+    public void inJeopardyMasterTest() throws Exception {
+        final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+                .registerClusterSingletonService(clusterSingletonService);
+        assertNotNull(reg);
+        verify(mockEos).registerCandidate(ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, REMOTE_OWNERSHIP_CHANGED, false);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_RETAINED_WITH_NO_CHANGE, true);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_RETAINED_WITH_NO_CHANGE, true);
+        assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+        Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
+        verify(mockEosEntityListReg, never()).close();
+        verify(mockEosDoubleEntityListReg, never()).close();
+        verify(mockEntityCandReg, never()).close();
+        verify(mockDoubleEntityCandReg, never()).close();
+    }
+
+    /**
+     * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+     *
+     * @throws Exception if the condition does not meet
+     */
+    @Test
+    public void closeClusterSingletonServiceRegistrationMasterTest() throws Exception {
+        final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+                .registerClusterSingletonService(clusterSingletonService);
+        assertNotNull(reg);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        verify(mockEos).registerCandidate(ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        reg.close();
+        verify(mockEntityCandReg).close();
+        verify(mockDoubleEntityCandReg, never()).close();
+        assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+        Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
+        verify(mockDoubleEntityCandReg).close();
+        verify(mockEosEntityListReg, never()).close();
+        verify(mockEosDoubleEntityListReg, never()).close();
+    }
+
+    /**
+     * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+     *
+     * @throws Exception if the condition does not meet
+     */
+    @Test
+    public void closeClusterSingletonServiceRegistrationMasterCloseWithNotificationTimesTest() throws Exception {
+        final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+                .registerClusterSingletonService(clusterSingletonService);
+        assertNotNull(reg);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        verify(mockEos).registerCandidate(ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        reg.close();
+        verify(mockEntityCandReg).close();
+        verify(mockDoubleEntityCandReg, never()).close();
+        assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+        Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
+        verify(mockDoubleEntityCandReg).close();
+        verify(mockEosEntityListReg, never()).close();
+        verify(mockEosDoubleEntityListReg, never()).close();
+    }
+
+    /**
+     * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+     *
+     * @throws Exception if the condition does not meet
+     */
+    @Test
+    public void closeClusterSingletonServiceRegistrationMasterCloseCoupleTimesTest() throws Exception {
+        final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+                .registerClusterSingletonService(clusterSingletonService);
+        assertNotNull(reg);
+        assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+        verify(mockEos).registerCandidate(ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+        clusterSingletonServiceProvider.ownershipChanged(DOUBLE_ENTITY, LOCAL_OWNERSHIP_GRANTED, false);
+        assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+        reg.close();
+        reg.close();
+        verify(mockEntityCandReg).close();
+        verify(mockDoubleEntityCandReg, never()).close();
+        assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+
+        Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
+        verify(mockEosEntityListReg, never()).close();
+        verify(mockEosDoubleEntityListReg, never()).close();
+        verify(mockDoubleEntityCandReg).close();
+    }
+}