use of org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener in project sling by apache.
the class AbstractClusterTest method testLongRunningListener.
/**
* Test plan:
* * have a discoveryservice with two listeners registered
* * one of them (the 'first' one) is long running
* * during one of the topology changes, when the first
* one is hit, deactivate the discovery service
* * that deactivation used to block (SLING-4755) due
* to synchronized(lock) which was blocked by the
* long running listener. With having asynchronous
* event sending this should no longer be the case
* * also, once asserted that deactivation finished,
* and that the first listener is still busy, make
* sure that once the first listener finishes, that
* the second listener still gets the event
* @throws Throwable
*/
//TODO: this takes env 15sec
@Category(Slow.class)
@Test
public void testLongRunningListener() throws Throwable {
// let the instance1 become alone, instance2 is idle
instance1.getConfig().setViewCheckTimeout(2);
instance2.getConfig().setViewCheckTimeout(2);
logger.info("testLongRunningListener : letting instance2 remain silent from now on");
instance1.heartbeatsAndCheckView();
Thread.sleep(1500);
instance1.heartbeatsAndCheckView();
Thread.sleep(1500);
instance1.heartbeatsAndCheckView();
Thread.sleep(1500);
instance1.heartbeatsAndCheckView();
logger.info("testLongRunningListener : instance 2 should now be considered dead");
// instance1.dumpRepo();
LongRunningListener longRunningListener1 = new LongRunningListener();
AssertingTopologyEventListener fastListener2 = new AssertingTopologyEventListener();
fastListener2.addExpected(Type.TOPOLOGY_INIT);
longRunningListener1.assertNoFail();
assertEquals(1, fastListener2.getRemainingExpectedCount());
logger.info("testLongRunningListener : binding longRunningListener1 ...");
instance1.bindTopologyEventListener(longRunningListener1);
logger.info("testLongRunningListener : binding fastListener2 ...");
instance1.bindTopologyEventListener(fastListener2);
logger.info("testLongRunningListener : waiting a bit for longRunningListener1 to receive the TOPOLOGY_INIT event");
// SLING-4755: async event sending requires some minimal wait time nowadays
Thread.sleep(2500);
assertEquals(0, fastListener2.getRemainingExpectedCount());
assertTrue(longRunningListener1.initReceived);
// after INIT, now do an actual change where listener1 will do a long-running handling
fastListener2.addExpected(Type.TOPOLOGY_CHANGING);
fastListener2.addExpected(Type.TOPOLOGY_CHANGED);
instance1.getConfig().setViewCheckTimeout(10);
instance2.getConfig().setViewCheckTimeout(10);
instance1.heartbeatsAndCheckView();
instance2.heartbeatsAndCheckView();
Thread.sleep(500);
instance1.heartbeatsAndCheckView();
instance2.heartbeatsAndCheckView();
Thread.sleep(500);
instance1.heartbeatsAndCheckView();
instance2.heartbeatsAndCheckView();
Thread.sleep(500);
instance1.dumpRepo();
longRunningListener1.assertNoFail();
// nothing unexpected should arrive at listener2:
assertEquals(0, fastListener2.getUnexpectedCount());
// however, listener2 should only get one (CHANGING) event, cos the CHANGED event is still blocked
assertEquals(1, fastListener2.getRemainingExpectedCount());
// and also listener2 should only get CHANGING, the CHANGED is blocked via changedSemaphore
assertEquals(1, longRunningListener1.noninitReceived);
Thread.sleep(2000);
assertTrue(longRunningListener1.getChangedSemaphore().hasQueuedThreads());
Thread.sleep(2000);
// even after a 2sec sleep things should be unchanged:
assertEquals(0, fastListener2.getUnexpectedCount());
assertEquals(1, fastListener2.getRemainingExpectedCount());
assertEquals(1, longRunningListener1.noninitReceived);
assertTrue(longRunningListener1.getChangedSemaphore().hasQueuedThreads());
// now let's simulate SLING-4755: deactivation while longRunningListener1 does long processing
// - which is simulated by waiting on changedSemaphore.
final List<Exception> asyncException = new LinkedList<Exception>();
Thread th = new Thread(new Runnable() {
@Override
public void run() {
try {
instance1.stop();
} catch (Exception e) {
synchronized (asyncException) {
asyncException.add(e);
}
}
}
});
th.start();
logger.info("Waiting max 4 sec...");
th.join(4000);
logger.info("Done waiting max 4 sec...");
if (th.isAlive()) {
logger.warn("Thread still alive: " + th.isAlive());
// release before issuing fail as otherwise test will block forever
longRunningListener1.getChangedSemaphore().release();
fail("Thread was still alive");
}
logger.info("Thread was no longer alive: " + th.isAlive());
synchronized (asyncException) {
logger.info("Async exceptions: " + asyncException.size());
if (asyncException.size() != 0) {
// release before issuing fail as otherwise test will block forever
longRunningListener1.getChangedSemaphore().release();
fail("async exceptions: " + asyncException.size() + ", first: " + asyncException.get(0));
}
}
// now the test consists of
// a) the fact that we reached this place without unlocking the changedSemaphore
// b) when we now unlock the changedSemaphore the remaining events should flush through
longRunningListener1.getChangedSemaphore().release();
// shouldn't take long and then things should have flushed:
Thread.sleep(500);
assertEquals(0, fastListener2.getUnexpectedCount());
assertEquals(0, fastListener2.getRemainingExpectedCount());
assertEquals(2, longRunningListener1.noninitReceived);
assertFalse(longRunningListener1.getChangedSemaphore().hasQueuedThreads());
}
use of org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener in project sling by apache.
the class AbstractSingleInstanceTest method testTopologyEventListeners.
@Test
public void testTopologyEventListeners() throws Throwable {
logger.info("testTopologyEventListeners: start");
instance.heartbeatsAndCheckView();
logger.info("testTopologyEventListeners: 1st sleep 2s");
Thread.sleep(2000);
instance.heartbeatsAndCheckView();
logger.info("testTopologyEventListeners: 2nd sleep 2s");
Thread.sleep(2000);
AssertingTopologyEventListener assertingTopologyEventListener = new AssertingTopologyEventListener();
assertingTopologyEventListener.addExpected(Type.TOPOLOGY_INIT);
logger.info("testTopologyEventListeners: binding the event listener");
instance.bindTopologyEventListener(assertingTopologyEventListener);
// SLING-4755: async event sending requires some minimal wait time nowadays
Thread.sleep(1000);
assertEquals(0, assertingTopologyEventListener.getRemainingExpectedCount());
final String propertyName = UUID.randomUUID().toString();
propertyValue = UUID.randomUUID().toString();
PropertyProviderImpl pp = new PropertyProviderImpl();
pp.setProperty(propertyName, propertyValue);
assertingTopologyEventListener.addExpected(Type.PROPERTIES_CHANGED);
assertEquals(1, assertingTopologyEventListener.getRemainingExpectedCount());
assertEquals(0, pp.getGetCnt());
instance.bindPropertyProvider(pp, propertyName);
logger.info("testTopologyEventListeners: 3rd sleep 1.5s");
Thread.sleep(1500);
logger.info("testTopologyEventListeners: dumping due to failure: ");
assertingTopologyEventListener.dump();
assertEquals(0, assertingTopologyEventListener.getRemainingExpectedCount());
// we can only assume that the getProperty was called at least once - it
// could be called multiple times though..
assertTrue(pp.getGetCnt() > 0);
assertingTopologyEventListener.addExpected(Type.PROPERTIES_CHANGED);
assertEquals(1, assertingTopologyEventListener.getRemainingExpectedCount());
pp.setGetCnt(0);
propertyValue = UUID.randomUUID().toString();
pp.setProperty(propertyName, propertyValue);
assertEquals(0, pp.getGetCnt());
instance.heartbeatsAndCheckView();
logger.info("testTopologyEventListeners: 4th sleep 2s");
Thread.sleep(2000);
assertEquals(0, assertingTopologyEventListener.getRemainingExpectedCount());
assertEquals(2, pp.getGetCnt());
// a heartbeat repeat should not result in another call though
instance.heartbeatsAndCheckView();
logger.info("testTopologyEventListeners: 5th sleep 2s");
Thread.sleep(2000);
assertEquals(0, assertingTopologyEventListener.getRemainingExpectedCount());
assertEquals(3, pp.getGetCnt());
logger.info("testTopologyEventListeners: done");
}
use of org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener in project sling by apache.
the class AbstractClusterTest method testAdditionalInstance.
//TODO: this takes env 15sec
@Category(Slow.class)
@Test
public void testAdditionalInstance() throws Throwable {
logger.info("testAdditionalInstance: start");
assertNotNull(instance1);
assertNotNull(instance2);
assertEquals(instance1.getSlingId(), instance1.getClusterViewService().getSlingId());
assertEquals(instance2.getSlingId(), instance2.getClusterViewService().getSlingId());
try {
instance1.getClusterViewService().getLocalClusterView();
fail("should complain");
} catch (UndefinedClusterViewException e) {
// ok
}
try {
instance2.getClusterViewService().getLocalClusterView();
fail("should complain");
} catch (UndefinedClusterViewException e) {
// ok
}
instance1.heartbeatsAndCheckView();
instance2.heartbeatsAndCheckView();
instance1.dumpRepo();
logger.info("testAdditionalInstance: 1st 2s sleep");
Thread.sleep(2000);
instance1.heartbeatsAndCheckView();
instance2.heartbeatsAndCheckView();
logger.info("testAdditionalInstance: 2nd 2s sleep");
Thread.sleep(2000);
instance1.dumpRepo();
String clusterId1 = instance1.getClusterViewService().getLocalClusterView().getId();
logger.info("clusterId1=" + clusterId1);
String clusterId2 = instance2.getClusterViewService().getLocalClusterView().getId();
logger.info("clusterId2=" + clusterId2);
assertEquals(clusterId1, clusterId2);
assertEquals(2, instance1.getClusterViewService().getLocalClusterView().getInstances().size());
assertEquals(2, instance2.getClusterViewService().getLocalClusterView().getInstances().size());
AssertingTopologyEventListener assertingTopologyEventListener = new AssertingTopologyEventListener();
assertingTopologyEventListener.addExpected(Type.TOPOLOGY_INIT);
assertEquals(1, assertingTopologyEventListener.getRemainingExpectedCount());
instance1.bindTopologyEventListener(assertingTopologyEventListener);
// SLING-4755: async event sending requires some minimal wait time nowadays
Thread.sleep(500);
assertEquals(0, assertingTopologyEventListener.getRemainingExpectedCount());
// startup instance 3
AcceptsMultiple acceptsMultiple = new AcceptsMultiple(Type.TOPOLOGY_CHANGING, Type.TOPOLOGY_CHANGED);
assertingTopologyEventListener.addExpected(acceptsMultiple);
assertingTopologyEventListener.addExpected(acceptsMultiple);
instance3 = newBuilder().setDebugName("thirdInstance").useRepositoryOf(instance1).build();
for (int i = 0; i < 4; i++) {
instance1.heartbeatsAndCheckView();
instance2.heartbeatsAndCheckView();
instance3.heartbeatsAndCheckView();
logger.info("testAdditionalInstance: i=" + i + ", 2s sleep");
Thread.sleep(2000);
}
assertEquals(1, acceptsMultiple.getEventCnt(Type.TOPOLOGY_CHANGING));
assertEquals(1, acceptsMultiple.getEventCnt(Type.TOPOLOGY_CHANGED));
logger.info("testAdditionalInstance: end");
}
Aggregations