Search in sources :

Example 6 with AssertingTopologyEventListener

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());
}
Also used : AssertingTopologyEventListener(org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener) LinkedList(java.util.LinkedList) UndefinedClusterViewException(org.apache.sling.discovery.base.commons.UndefinedClusterViewException) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Example 7 with AssertingTopologyEventListener

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");
}
Also used : AssertingTopologyEventListener(org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener) PropertyProviderImpl(org.apache.sling.discovery.base.its.setup.mock.PropertyProviderImpl) Test(org.junit.Test)

Example 8 with AssertingTopologyEventListener

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");
}
Also used : AssertingTopologyEventListener(org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener) AcceptsMultiple(org.apache.sling.discovery.base.its.setup.mock.AcceptsMultiple) UndefinedClusterViewException(org.apache.sling.discovery.base.commons.UndefinedClusterViewException) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Aggregations

AssertingTopologyEventListener (org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener)8 Test (org.junit.Test)8 TopologyView (org.apache.sling.discovery.TopologyView)3 UndefinedClusterViewException (org.apache.sling.discovery.base.commons.UndefinedClusterViewException)3 Category (org.junit.experimental.categories.Category)2 LinkedList (java.util.LinkedList)1 TopologyEvent (org.apache.sling.discovery.TopologyEvent)1 AbstractDiscoveryServiceTest (org.apache.sling.discovery.base.its.AbstractDiscoveryServiceTest)1 VirtualInstanceBuilder (org.apache.sling.discovery.base.its.setup.VirtualInstanceBuilder)1 AcceptsMultiple (org.apache.sling.discovery.base.its.setup.mock.AcceptsMultiple)1 PropertyProviderImpl (org.apache.sling.discovery.base.its.setup.mock.PropertyProviderImpl)1 FullJR2VirtualInstanceBuilder (org.apache.sling.discovery.impl.setup.FullJR2VirtualInstanceBuilder)1 OakDiscoveryService (org.apache.sling.discovery.oak.OakDiscoveryService)1 OakVirtualInstanceBuilder (org.apache.sling.discovery.oak.its.setup.OakVirtualInstanceBuilder)1