use of org.apache.sling.discovery.commons.providers.DummyTopologyView in project sling by apache.
the class TestOakSyncTokenService method testTwoNodesOneLeaving.
@Test
public void testTwoNodesOneLeaving() throws Exception {
logger.info("testTwoNodesOneLeaving: start");
String slingId2 = UUID.randomUUID().toString();
DummyTopologyView two1 = TestHelper.newView(true, slingId1, slingId1, slingId1, slingId2);
Lock lock1 = new ReentrantLock();
OakBacklogClusterSyncService cs1 = OakBacklogClusterSyncService.testConstructorAndActivate(new SimpleCommonsConfig(), idMapService1, new DummySlingSettingsService(slingId1), factory1);
ViewStateManager vsm1 = ViewStateManagerFactory.newViewStateManager(lock1, cs1);
DummyListener l = new DummyListener();
vsm1.bind(l);
vsm1.handleActivated();
vsm1.handleNewView(two1);
cs1.triggerBackgroundCheck();
assertEquals(0, l.countEvents());
DescriptorHelper.setDiscoveryLiteDescriptor(factory1, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(1).seq(1).activeIds(1).deactivatingIds(2));
cs1.triggerBackgroundCheck();
assertEquals(0, l.countEvents());
// make an assertion that the background runnable is at this stage - even with
// a 2sec sleep - waiting for the deactivating instance to disappear
logger.info("testTwoNodesOneLeaving: sync service should be waiting for backlog to disappear");
Thread.sleep(2000);
BackgroundCheckRunnable backgroundCheckRunnable = cs1.backgroundCheckRunnable;
assertNotNull(backgroundCheckRunnable);
assertFalse(backgroundCheckRunnable.isDone());
assertFalse(backgroundCheckRunnable.cancelled());
// release the deactivating instance by removing it from the clusterView
logger.info("testTwoNodesOneLeaving: freeing backlog - sync service should finish up");
DescriptorHelper.setDiscoveryLiteDescriptor(factory1, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(1).seq(2).activeIds(1));
cs1.triggerBackgroundCheck();
// now give this thing 2 sec to settle
Thread.sleep(2000);
// after that, the backgroundRunnable should be done and no events stuck in vsm
backgroundCheckRunnable = cs1.backgroundCheckRunnable;
assertNotNull(backgroundCheckRunnable);
assertFalse(backgroundCheckRunnable.cancelled());
assertTrue(backgroundCheckRunnable.isDone());
assertEquals(0, vsm1.waitForAsyncEvents(1000));
logger.info("testTwoNodesOneLeaving: setting up 2nd node");
Lock lock2 = new ReentrantLock();
IdMapService idMapService2 = IdMapService.testConstructor(new SimpleCommonsConfig(), new DummySlingSettingsService(slingId2), factory2);
OakBacklogClusterSyncService cs2 = OakBacklogClusterSyncService.testConstructorAndActivate(new SimpleCommonsConfig(), idMapService2, new DummySlingSettingsService(slingId2), factory2);
ViewStateManager vsm2 = ViewStateManagerFactory.newViewStateManager(lock2, cs2);
cs1.triggerBackgroundCheck();
cs2.triggerBackgroundCheck();
assertEquals(1, l.countEvents());
DescriptorHelper.setDiscoveryLiteDescriptor(factory2, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(2).seq(3).activeIds(1, 2));
cs1.triggerBackgroundCheck();
cs2.triggerBackgroundCheck();
assertEquals(1, l.countEvents());
DescriptorHelper.setDiscoveryLiteDescriptor(factory1, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(1).seq(3).activeIds(1, 2));
cs1.triggerBackgroundCheck();
cs2.triggerBackgroundCheck();
assertEquals(1, l.countEvents());
vsm2.handleActivated();
assertTrue(idMapService1.waitForInit(5000));
assertTrue(idMapService2.waitForInit(5000));
DummyTopologyView two2 = TestHelper.newView(two1.getLocalClusterSyncTokenId(), two1.getLocalInstance().getClusterView().getId(), true, slingId1, slingId1, slingId1, slingId2);
vsm2.handleNewView(two2);
cs1.triggerBackgroundCheck();
cs1.triggerBackgroundCheck();
cs2.triggerBackgroundCheck();
cs2.triggerBackgroundCheck();
assertEquals(0, vsm1.waitForAsyncEvents(1000));
assertEquals(1, l.countEvents());
logger.info("testTwoNodesOneLeaving: removing instance2 from the view - even though vsm1 didn't really know about it, it should send a TOPOLOGY_CHANGING - we leave it as deactivating for now...");
DummyTopologyView oneLeaving = two1.clone();
oneLeaving.removeInstance(slingId2);
DescriptorHelper.setDiscoveryLiteDescriptor(factory1, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(1).seq(1).activeIds(1).deactivatingIds(2));
vsm1.handleNewView(oneLeaving);
cs1.triggerBackgroundCheck();
cs2.triggerBackgroundCheck();
// wait for TOPOLOGY_CHANGING to be received by vsm1
assertEquals(0, vsm1.waitForAsyncEvents(5000));
assertEquals(2, l.countEvents());
logger.info("testTwoNodesOneLeaving: marking instance2 as no longer deactivating, so vsm1 should now send a TOPOLOGY_CHANGED");
DescriptorHelper.setDiscoveryLiteDescriptor(factory1, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(1).seq(2).activeIds(1).inactiveIds(2));
cs1.triggerBackgroundCheck();
cs2.triggerBackgroundCheck();
// wait for TOPOLOGY_CHANGED to be received by vsm1
assertEquals(0, vsm1.waitForAsyncEvents(5000));
RepositoryTestHelper.dumpRepo(factory1);
assertEquals(3, l.countEvents());
}
use of org.apache.sling.discovery.commons.providers.DummyTopologyView in project sling by apache.
the class TestHelper method newView.
public static DummyTopologyView newView(String syncId, String clusterId, boolean isCurrent, String leaderId, String localId, String... slingIds) {
DummyTopologyView topology = new DummyTopologyView(syncId);
DefaultClusterView cluster = new DefaultClusterView(clusterId);
for (String slingId : slingIds) {
DefaultInstanceDescription id = new DefaultInstanceDescription(cluster, slingId.equals(leaderId), slingId.equals(localId), slingId, new HashMap<String, String>());
topology.addInstanceDescription(id);
}
if (!isCurrent) {
topology.setNotCurrent();
}
return topology;
}
use of org.apache.sling.discovery.commons.providers.DummyTopologyView in project sling by apache.
the class TestSlowViewStateManager method testClusterSyncService_withConcurrency.
//TODO test takes env 10sec
@Category(Slow.class)
@Test
public void testClusterSyncService_withConcurrency() throws Exception {
final org.apache.log4j.Logger commonsLogger = LogManager.getRootLogger().getLogger("org.apache.sling.discovery.commons.providers");
final org.apache.log4j.Level logLevel = commonsLogger.getLevel();
// change here to DEBUG in case of issues with this test
commonsLogger.setLevel(Level.INFO);
final Semaphore serviceSemaphore = new Semaphore(0);
final Semaphore testSemaphore = new Semaphore(0);
final ReentrantLock lock = new ReentrantLock();
final ClusterSyncServiceWithSemaphore cs = new ClusterSyncServiceWithSemaphore(lock, serviceSemaphore);
mgr = new ViewStateManagerImpl(lock, cs);
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final String slingId1 = UUID.randomUUID().toString();
final String slingId2 = UUID.randomUUID().toString();
final String slingId3 = UUID.randomUUID().toString();
final String clusterId = UUID.randomUUID().toString();
final DefaultClusterView cluster = new DefaultClusterView(clusterId);
final DummyTopologyView view1 = new DummyTopologyView().addInstance(slingId1, cluster, true, true).addInstance(slingId2, cluster, false, false).addInstance(slingId3, cluster, false, false);
final DummyTopologyView view2 = DummyTopologyView.clone(view1).removeInstance(slingId2);
final DummyTopologyView view3 = DummyTopologyView.clone(view1).removeInstance(slingId2).removeInstance(slingId3);
async(new Runnable() {
public void run() {
mgr.handleNewView(view1);
}
});
Thread.sleep(1000);
TestHelper.assertNoEvents(listener);
assertEquals("should have one thread now waiting", 1, serviceSemaphore.getQueueLength());
// release the first one only
serviceSemaphore.release(1);
Thread.sleep(1000);
assertEvents(listener, EventHelper.newInitEvent(view1));
mgr.handleChanging();
assertEquals(0, mgr.waitForAsyncEvents(500));
assertEvents(listener, EventHelper.newChangingEvent(view1));
async(new Runnable() {
public void run() {
mgr.handleNewView(view2);
}
});
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
logger.debug("run: asserting no events");
TestHelper.assertNoEvents(listener);
assertEquals("should have one thread now waiting", 1, serviceSemaphore.getQueueLength());
assertFalse("should not be locked", lock.isLocked());
logger.debug("run: issuing a second event");
// before releasing, issue another event, lets do a combination of changing/changed
async(new Runnable() {
public void run() {
logger.debug("run2: calling handleChanging...");
mgr.handleChanging();
try {
logger.debug("run2: done with handleChanging, acquiring testSemaphore...");
testSemaphore.acquire();
logger.debug("run2: calling handleNewView...");
mgr.handleNewView(view3);
logger.debug("run2: done with handleNewView...");
} catch (InterruptedException e) {
// fail
logger.error("interrupted: " + e, e);
}
}
});
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
int remainingAsyncEvents = mgr.waitForAsyncEvents(2000);
logger.info("run: result of waitForAsyncEvent is: " + remainingAsyncEvents);
assertEquals("should have one thread now waiting", 1, serviceSemaphore.getQueueLength());
assertEquals("should be acquiring (by thread2)", 1, testSemaphore.getQueueLength());
// releasing the testSemaphore
testSemaphore.release();
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
assertEquals("should have two async events now in the queue or being sent", 2, mgr.waitForAsyncEvents(500));
assertEquals("but should only have 1 thread actually sitting on the semaphore waiting", 1, serviceSemaphore.getQueueLength());
logger.debug("run: releasing consistencyService");
// release the first one only
serviceSemaphore.release(1);
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
assertFalse("should not be locked", lock.isLocked());
// this should not have triggered any event
TestHelper.assertNoEvents(listener);
// then release the 2nd one
serviceSemaphore.release(1);
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
logger.debug("run: asserting 1 event");
final TopologyEvent changedEvent = EventHelper.newChangedEvent(view1, view3);
assertEvents(listener, changedEvent);
// back to default
commonsLogger.setLevel(Level.INFO);
}
use of org.apache.sling.discovery.commons.providers.DummyTopologyView in project sling by apache.
the class TestViewStateManager method testActivateChangedBindDuplicateHandleNewView.
@Test
public void testActivateChangedBindDuplicateHandleNewView() throws Exception {
final DummyListener listener = new DummyListener();
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final DummyTopologyView view = new DummyTopologyView().addInstance();
mgr.handleNewView(view);
TestHelper.assertNoEvents(listener);
mgr.bind(listener);
assertEvents(listener, EventHelper.newInitEvent(view));
mgr.handleNewView(DummyTopologyView.clone(view));
TestHelper.assertNoEvents(listener);
randomEventLoop(defaultRandom, listener);
}
use of org.apache.sling.discovery.commons.providers.DummyTopologyView in project sling by apache.
the class TestViewStateManager method testChangedPropertiesChanged.
@Test
public void testChangedPropertiesChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.installMinEventDelayHandler(new DiscoveryService() {
@Override
public TopologyView getTopology() {
throw new IllegalStateException("not yet impl");
}
}, new DummyScheduler(), 1);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleChanging();
TestHelper.assertNoEvents(listener);
final BaseTopologyView view1 = new DummyTopologyView().addInstance();
InstanceDescription instance1 = view1.getInstances().iterator().next();
ClusterView cluster1 = instance1.getClusterView();
mgr.handleNewView(view1);
assertEvents(listener, EventHelper.newInitEvent(view1));
DefaultClusterView cluster2 = new DefaultClusterView(new String(cluster1.getId()));
final BaseTopologyView view2 = new DummyTopologyView(view1.getLocalClusterSyncTokenId()).addInstance(instance1.getSlingId(), cluster2, instance1.isLeader(), instance1.isLocal());
DefaultInstanceDescription instance2 = (DefaultInstanceDescription) view2.getLocalInstance();
instance2.setProperty("foo", "bar");
mgr.handleNewView(view2);
assertEvents(listener, EventHelper.newPropertiesChangedEvent(view1, view2));
}
Aggregations