private final S entityOwnershipService;
private final String clusterSingletonGroupIdentifier;
- private final Semaphore clusterLock = new Semaphore(1);
+ private final Semaphore clusterLock = new Semaphore(1, true);
/* Entity instances */
private final E serviceEntity;
private final E doubleCandidateEntity;
+ // TODO :it needs to rewrite for StateMachine (INITIALIZED, TRY_TO_TAKE_LEADERSHIP, LEADER, FOLLOWER, TERMINATED)
+ // INITIALIZED : we have registered baseCandidate and we are waiting for first EOS response (!do we really need it?)
+ // FOLLOWER : baseCandidate is registered correctly
+ // TRY_TO_TAKE_LEADERSHIP : guardCandidate is registered correctly
+ // LEADER : both candidate have mastership from EOS
+ // TERMINATED : service go down
@GuardedBy("clusterLock")
private boolean hasOwnership = false;
@GuardedBy("clusterLock")
boolean needReleaseLock = false;
final ListenableFuture<List<Void>> destroyFuture;
try {
- needReleaseLock = clusterLock.tryAcquire(10, TimeUnit.SECONDS);
+ needReleaseLock = clusterLock.tryAcquire(1, TimeUnit.SECONDS);
} catch (final Exception e) {
- LOG.warn("Unexpected Exception for service Provider {} in closing phase.",
- clusterSingletonGroupIdentifier, e);
+ LOG.warn("Unexpected Exception for service Provider {} in closing phase.", clusterSingletonGroupIdentifier,
+ e);
} finally {
if (serviceEntityCandidateReg != null) {
serviceEntityCandidateReg.close();
for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
serviceCloseFutureList.add(service.closeServiceInstance());
}
+ hasOwnership = false;
}
destroyFuture = Futures.allAsList(serviceCloseFutureList);
final Semaphore finalRelease = needReleaseLock ? clusterLock : null;
- Futures.addCallback(destroyFuture, newAsyncCloseCallback(finalRelease));
+ Futures.addCallback(destroyFuture, newAsyncCloseCallback(finalRelease, true));
}
return destroyFuture;
}
} catch (final Exception e) {
LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
needCloseProviderInstance = true;
+ throw new RuntimeException(e);
} finally {
closeResources(needReleaseLock, needCloseProviderInstance);
}
} catch (final Exception e) {
LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
needCloseProviderInstance = true;
+ throw new RuntimeException(e);
} finally {
closeResources(needReleaseLock, needCloseProviderInstance);
}
try {
clusterLock.acquire();
needReleaseLock = true;
- serviceGroup.remove(service);
- if (hasOwnership) {
- service.closeServiceInstance();
+ if (serviceGroup.size() > 1) {
+ if (hasOwnership) {
+ service.closeServiceInstance();
+ }
+ serviceGroup.remove(service);
+ LOG.debug("Service {} was removed from group.", service.getIdentifier().getValue());
+ } else {
+ needCloseProviderInstance = true;
}
} catch (final Exception e) {
LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
needCloseProviderInstance = true;
+ throw new RuntimeException(e);
} finally {
closeResources(needReleaseLock, needCloseProviderInstance);
- if (serviceGroup.isEmpty()) {
- this.closeClusterSingletonGroup();
- }
}
}
@SuppressWarnings("checkstyle:IllegalCatch")
@Override
public void ownershipChanged(final C ownershipChange) {
- LOG.debug("Ownership change {} for ClusterSingletonServiceGrou {}", ownershipChange,
+ LOG.debug("Ownership change {} for ClusterSingletonServiceGroup {}", ownershipChange,
clusterSingletonGroupIdentifier);
try {
if (ownershipChange.inJeopardy()) {
* SLAVE to MASTER : ownershipChange.getState().isOwner() && !ownershipChange.getState().wasOwner()
*/
takeOwnership();
- } else if (EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER.equals(ownershipChange.getState())
- || EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NO_OWNER
- .equals(ownershipChange.getState())) {
- /*
- * MASTER to SLAVE : !ownershipChange.getState().isOwner() && ownershipChange.getState().wasOwner()
- */
- LOG.warn("Unexpected lost doubleCandidate {} leadership. Close service instance {}",
- doubleCandidateEntity, clusterSingletonGroupIdentifier);
- lostOwnership();
} else {
/* Not needed notifications */
LOG.debug("Not processed doubleCandidate OwnershipChange {} in service Provider {}",
} else {
LOG.warn("Unexpected EntityOwnershipChangeEvent for entity {}", ownershipChange);
}
- } catch (Exception e) {
+ } catch (final Exception e) {
LOG.error("Unexpected Exception for service Provider {}", clusterSingletonGroupIdentifier, e);
// TODO : think about close ... is it necessary?
}
try {
clusterLock.acquire();
needReleaseLock = true;
- Verify.verify(serviceEntityCandidateReg != null);
- Verify.verify(asyncCloseEntityCandidateReg == null);
- asyncCloseEntityCandidateReg = entityOwnershipService.registerCandidate(doubleCandidateEntity);
- } catch (Exception e) {
+ if (serviceEntityCandidateReg != null) {
+ Verify.verify(asyncCloseEntityCandidateReg == null);
+ asyncCloseEntityCandidateReg = entityOwnershipService.registerCandidate(doubleCandidateEntity);
+ } else {
+ LOG.debug("Service {} is closed, so don't to tryTakeLeadership", clusterSingletonGroupIdentifier);
+ }
+ } catch (final Exception e) {
LOG.error("Unexpected exception state for service Provider {} in TryToTakeLeadership",
clusterSingletonGroupIdentifier, e);
needCloseProviderInstance = true;
try {
clusterLock.acquire();
needReleaseLock = true;
- Verify.verify(serviceEntityCandidateReg != null);
- Verify.verify(asyncCloseEntityCandidateReg != null);
- for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
- service.instantiateServiceInstance();
+ if (serviceEntityCandidateReg != null) {
+ Verify.verify(asyncCloseEntityCandidateReg != null);
+ for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
+ service.instantiateServiceInstance();
+ }
+ hasOwnership = true;
+ } else {
+ LOG.debug("Service {} is closed, so don't take leadership", clusterSingletonGroupIdentifier);
}
- hasOwnership = true;
} catch (final Exception e) {
LOG.error("Unexpected exception state for service Provider {} in TakeLeadership",
clusterSingletonGroupIdentifier, e);
try {
clusterLock.acquire();
needReleaseLock = true;
- Verify.verify(serviceEntityCandidateReg != null);
final List<ListenableFuture<Void>> serviceCloseFutureList = new ArrayList<>();
if (hasOwnership) {
Verify.verify(asyncCloseEntityCandidateReg != null);
for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
serviceCloseFutureList.add(service.closeServiceInstance());
}
+ hasOwnership = false;
}
final ListenableFuture<List<Void>> destroyFuture = Futures.allAsList(serviceCloseFutureList);
- Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock));
+ if (serviceEntityCandidateReg != null) {
+ // we don't want to remove this instance from map
+ Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock, false));
+ } else {
+ // we have to remove this ClusterSingletonServiceGroup instance from map
+ Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock, true));
+ }
/*
* We wish to stop all possible EOS activities before we don't close
* a close candidate registration that acts as a guard. So we don't want
/*
* Help method for finalization every acquired functionality
*/
+ @GuardedBy("clusterLock")
private void closeResources(final boolean needReleaseLock, final boolean needCloseProvider) {
- if (needReleaseLock) {
- clusterLock.release();
- }
if (needCloseProvider) {
- final ListenableFuture<List<Void>> closeFutureList = this.closeClusterSingletonGroup();
- Futures.addCallback(closeFutureList, new FutureCallback<List<Void>>() {
-
- @Override
- public void onSuccess(final List<Void> result) {
- removeThisGroupFromProvider(null);
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- removeThisGroupFromProvider(throwable);
- }
- });
+ // The Game Over for this ClusterSingletonServiceGroup instance
+ if (serviceEntityCandidateReg != null) {
+ serviceEntityCandidateReg.close();
+ serviceEntityCandidateReg = null;
+ }
+ // Remove instance immediately because actual state is follower or initialization
+ if (asyncCloseEntityCandidateReg == null) {
+ allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
+ }
}
- }
- /*
- * Help method for final ClusterSingletonGroup removing
- */
- protected void removeThisGroupFromProvider(@Nullable final Throwable throwable) {
- LOG.debug("Removing ClusterSingletonServiceGroup {}", clusterSingletonGroupIdentifier);
- if (throwable != null) {
- LOG.warn("Unexpected problem by closingResources ClusterSingletonServiceGroup {}",
- clusterSingletonGroupIdentifier);
+ if (needReleaseLock) {
+ clusterLock.release();
}
- allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
}
/*
* Help method creates FutureCallback for suspend Future
*/
- private FutureCallback<List<Void>> newAsyncCloseCallback(@Nullable final Semaphore semaphore) {
+ private FutureCallback<List<Void>> newAsyncCloseCallback(@Nullable final Semaphore semaphore,
+ final boolean isInCloseProcess) {
final Consumer<Throwable> closeEntityCandidateRegistration = (@Nullable final Throwable throwable) -> {
if (throwable != null) {
LOG.warn("Unexpected error closing service instance {}", clusterSingletonGroupIdentifier, throwable);
asyncCloseEntityCandidateReg.close();
asyncCloseEntityCandidateReg = null;
}
+ if (isInCloseProcess) {
+ allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
+ }
if (semaphore != null) {
semaphore.release();
}
- allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
};
return new FutureCallback<List<Void>>() {
--- /dev/null
+/*
+ * 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.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+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.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
+import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+
+/*
+ * Testing {@link DOMClusterSingletonServiceProviderImpl} implementation
+ */
+public final class DOMClusterSingletonServiceProviderAsyncImplTest {
+
+ private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
+ private static final String CLOSE_SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.AsyncServiceCloseEntityType";
+ private static final String SERVICE_NAME = "testServiceName";
+
+ @Mock
+ private DOMEntityOwnershipService mockEos;
+ @Mock
+ private DOMEntityOwnershipCandidateRegistration mockEntityCandReg;
+ @Mock
+ private DOMEntityOwnershipCandidateRegistration mockDoubleEntityCandReg;
+ @Mock
+ private DOMEntityOwnershipListenerRegistration mockEosEntityListReg;
+ @Mock
+ private DOMEntityOwnershipListenerRegistration mockEosDoubleEntityListReg;
+
+ private DOMClusterSingletonServiceProviderImpl clusterSingletonServiceProvider;
+ private TestClusterSingletonAsyncServiceInstance clusterSingletonService;
+ private TestClusterSingletonAsyncServiceInstance clusterSingletonService2;
+
+ private final DOMEntity entity = new DOMEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
+ private final DOMEntity doubleEntity = new DOMEntity(CLOSE_SERVICE_ENTITY_TYPE, SERVICE_NAME);
+
+ protected static Timer timer;
+ protected static long ASYNC_TIME_DELAY_SEC = 100L;
+
+ @BeforeClass
+ public static void asyncInitTest() {
+ timer = new Timer();
+ }
+
+ @AfterClass
+ public static void cleanTest() {
+ timer.cancel();
+ }
+
+ /**
+ * Initialization functionality for every Tests in this suite.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ doNothing().when(mockEosEntityListReg).close();
+ doNothing().when(mockEosDoubleEntityListReg).close();
+ doNothing().when(mockEntityCandReg).close();
+ doNothing().when(mockDoubleEntityCandReg).close();
+ doReturn(mockEosEntityListReg).when(mockEos).registerListener(eq(SERVICE_ENTITY_TYPE),
+ any(DOMClusterSingletonServiceProviderImpl.class));
+ doReturn(mockEosDoubleEntityListReg).when(mockEos).registerListener(eq(CLOSE_SERVICE_ENTITY_TYPE),
+ any(DOMClusterSingletonServiceProviderImpl.class));
+ doReturn(mockEntityCandReg).when(mockEos).registerCandidate(entity);
+ doReturn(mockDoubleEntityCandReg).when(mockEos).registerCandidate(doubleEntity);
+
+ clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(mockEos);
+ clusterSingletonServiceProvider.initializeProvider();
+ verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+ verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+
+ clusterSingletonService = new TestClusterSingletonAsyncServiceInstance();
+ clusterSingletonService2 = new TestClusterSingletonAsyncServiceInstance();
+
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks NullPointer for null {@link DOMEntityOwnershipService} input value.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test(expected = NullPointerException.class)
+ public void initializationClusterSingletonServiceProviderNullInputTest() throws Exception {
+ clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(null);
+ }
+
+ /**
+ * Test GoldPath for close {@link DOMClusterSingletonServiceProviderImpl}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceProviderTest() throws Exception {
+ verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+ verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+ clusterSingletonServiceProvider.close();
+ verify(mockEosEntityListReg).close();
+ verify(mockEosDoubleEntityListReg).close();
+ }
+
+ /**
+ * Test parser ServiceIdentifier from Entity.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void makeEntityClusterSingletonServiceProviderTest() throws Exception {
+ final DOMEntity testEntity = clusterSingletonServiceProvider.createEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
+ Assert.assertEquals(entity, testEntity);
+ final DOMEntity testDbEn = clusterSingletonServiceProvider.createEntity(CLOSE_SERVICE_ENTITY_TYPE,
+ SERVICE_NAME);
+ Assert.assertEquals(doubleEntity, testDbEn);
+ }
+
+ /**
+ * Test parser ServiceIdentifier from Entity.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void getIdentifierClusterSingletonServiceProviderTest() throws Exception {
+ final String entityIdentifier = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(entity);
+ Assert.assertEquals(SERVICE_NAME, entityIdentifier);
+ final String doubleEntityId = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(doubleEntity);
+ Assert.assertEquals(SERVICE_NAME, doubleEntityId);
+ }
+
+ /**
+ * Test GoldPath for initialization {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void initializationClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result SLAVE {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void slaveInitClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ verify(mockEos, never()).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result SLAVE, but NO-MASTER {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void slaveInitNoMasterClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlaveNoMaster());
+ verify(mockEos, never()).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void masterInitClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void masterInitSlaveDoubleCandidateClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void takeLeadershipClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg).close();
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void masterInitClusterSingletonServiceTwoServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ Assert.assertNotNull(reg2);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void takeLeadershipClusterSingletonServiceTwoAddDuringWaitPhaseServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ Assert.assertNotNull(reg2);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void takeLeadershipClusterSingletonServiceTowServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ Assert.assertNotNull(reg2);
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks CandidateAlreadyRegisteredException processing in initialization phase.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test(expected = RuntimeException.class)
+ public void initializationClusterSingletonServiceCandidateAlreadyRegistredTest() throws Exception {
+ doThrow(CandidateAlreadyRegisteredException.class).when(mockEos).registerCandidate(entity);
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNull(reg);
+ }
+
+ /**
+ * Test GoldPath for lostLeadership during tryToTakeLeadership with ownership result MASTER
+ * {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void lostLeadershipDuringTryToTakeLeadershipClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for lostLeadership with ownership result MASTER-TO-SLAVE {@link ClusterSingletonService}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void lostLeadershipClusterSingletonServiceTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ reg.close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, atLeastOnce()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToJeopardy());
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg).close();
+ }
+
+ /**
+ * Test checks inJeopardy Cluster Node state for Slave Instance.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void inJeopardySlaveTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ verify(mockEos, never()).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToJeopardy());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ 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 closeClusterSingletonServiceRegistrationNoRoleTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationNoRoleTwoServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ Assert.assertNotNull(reg2);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationSlaveTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationSlaveTwoServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ Assert.assertNotNull(reg2);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ reg.close();
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, atLeastOnce()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ reg.close();
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, atLeastOnce()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ reg.close();
+ reg.close();
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, atLeastOnce()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationMasterTwoServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ Assert.assertNotNull(reg2);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks validation Error processing for SLAVE-TO-MASTER entity Candidate role change.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void tryToTakeLeaderForClosedServiceRegistrationTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ Assert.assertNotNull(reg);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ Assert.assertNotNull(reg2);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ reg.close();
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+
+ private DOMEntityOwnershipChange getEntityToMaster() {
+ return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, true, true));
+ }
+
+ private DOMEntityOwnershipChange getEntityToSlave() {
+ return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(true, false, true));
+ }
+
+ private DOMEntityOwnershipChange getInitEntityToSlave() {
+ return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, true));
+ }
+
+ private DOMEntityOwnershipChange getInitEntityToSlaveNoMaster() {
+ return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, false));
+ }
+
+ private DOMEntityOwnershipChange getDoubleEntityToMaster() {
+ return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(false, true, true));
+ }
+
+ private DOMEntityOwnershipChange getInitDoubleEntityToSlave() {
+ return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(false, false, true));
+ }
+
+ private DOMEntityOwnershipChange getDoubleEntityToSlave() {
+ return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(true, false, true));
+ }
+
+ private DOMEntityOwnershipChange getEntityToJeopardy() {
+ return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, false), true);
+ }
+
+ /*
+ * Base states for AbstractClusterProjectProvider
+ */
+ enum TestClusterSingletonServiceState {
+ /*
+ * State represents a correct Instantiated process
+ */
+ STARTED,
+ /*
+ * State represents a correct call abstract method instantiatingProject
+ */
+ INITIALIZED,
+ /*
+ * State represents a correct call abstract method destryingProject
+ */
+ DESTROYED;
+ }
+
+ /*
+ * Test implementation of {@link ClusterSingletonService}
+ */
+ class TestClusterSingletonAsyncServiceInstance implements ClusterSingletonService {
+
+ private final ServiceGroupIdentifier serviceId = ServiceGroupIdentifier.create(SERVICE_NAME);
+ private TestClusterSingletonServiceState serviceState;
+ protected SettableFuture<Void> future;
+
+ TestClusterSingletonAsyncServiceInstance() {
+ this.serviceState = TestClusterSingletonServiceState.INITIALIZED;
+ }
+
+ @Override
+ public void instantiateServiceInstance() {
+ this.serviceState = TestClusterSingletonServiceState.STARTED;
+ }
+
+ @Override
+ public ListenableFuture<Void> closeServiceInstance() {
+ this.serviceState = TestClusterSingletonServiceState.DESTROYED;
+ future = SettableFuture.create();
+ timer.schedule(new TimerTask() {
+
+ @Override
+ public void run() {
+ future.set(null);
+ }
+ }, ASYNC_TIME_DELAY_SEC);
+ return future;
+ }
+
+ public TestClusterSingletonServiceState getServiceState() {
+ return serviceState;
+ }
+
+ @Override
+ public ServiceGroupIdentifier getIdentifier() {
+ return serviceId;
+ }
+ }
+}
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
}
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg).close();
+ }
+
/**
* Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
*
*
* @throws Exception if the condition does not meet
*/
- @Test
+ @Test(expected = RuntimeException.class)
public void initializationClusterSingletonServiceCandidateAlreadyRegistredTest() throws Exception {
doThrow(CandidateAlreadyRegisteredException.class).when(mockEos).registerCandidate(entity);
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
}
/**
- * Test checks umexpected change for MASTER-TO-SLAVE double Candidate role change.
+ * Test checks unexpected change for MASTER-TO-SLAVE double Candidate role change.
*
* @throws Exception if the condition does not meet
*/
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, atLeastOnce()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
reg.close();
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg).close();
}
/**
- * Test checks close procesing for {@link ClusterSingletonServiceRegistration}.
+ * 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);
+ Assert.assertNotNull(reg);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, atLeastOnce()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * 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);
+ Assert.assertNotNull(reg);
+ Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(entity);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(doubleEntity);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ reg.close();
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ verify(mockEntityCandReg, atLeastOnce()).close();
+ verify(mockDoubleEntityCandReg, atLeastOnce()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
*
* @throws Exception if the condition does not meet
*/
* Base states for AbstractClusterProjectProvider.
*/
enum TestClusterSingletonServiceState {
+
/**
* State represents a correct Instantiated process.
*/
+
STARTED,
/**
* State represents a correct call abstract method instantiatingProject.
*/
INITIALIZED,
+
/**
* State represents a correct call abstract method destryingProject.
*/