This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.discovery.commons-1.0.10 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-discovery-commons.git
commit 3529e4f60899739eaa94ecb2e22e7fce9eb2f364 Author: Stefan Egli <[email protected]> AuthorDate: Thu Nov 5 11:03:07 2015 +0000 SLING-5267 : fixed testTwoNodesOneLeaving by making wait times safer, asserting for background-runnable done-state, plus added more logging in case this one is still not perfectly stable on jenkins git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/discovery/commons@1712742 13f79535-47bb-0310-9956-ffa450edef68 --- .../base/AbstractServiceWithBackgroundCheck.java | 8 +++- .../spi/base/OakBacklogClusterSyncService.java | 3 +- .../spi/base/TestOakSyncTokenService.java | 53 +++++++++++++++++++--- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/AbstractServiceWithBackgroundCheck.java b/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/AbstractServiceWithBackgroundCheck.java index 29088b1..84f2f76 100644 --- a/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/AbstractServiceWithBackgroundCheck.java +++ b/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/AbstractServiceWithBackgroundCheck.java @@ -37,7 +37,7 @@ public abstract class AbstractServiceWithBackgroundCheck { * calling BackgroundCheck.check and looping until it * returns true */ - private final class BackgroundCheckRunnable implements Runnable { + final class BackgroundCheckRunnable implements Runnable { private final Runnable callback; private final BackgroundCheck check; private final long timeoutMillis; @@ -61,6 +61,12 @@ public abstract class AbstractServiceWithBackgroundCheck { this.waitInterval = waitInterval; this.threadName = threadName; } + + boolean isDone() { + synchronized(waitObj) { + return done; + } + } @Override public void run() { diff --git a/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/OakBacklogClusterSyncService.java b/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/OakBacklogClusterSyncService.java index fa07268..8fbe1cb 100644 --- a/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/OakBacklogClusterSyncService.java +++ b/src/main/java/org/apache/sling/discovery/commons/providers/spi/base/OakBacklogClusterSyncService.java @@ -18,6 +18,7 @@ */ package org.apache.sling.discovery.commons.providers.spi.base; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -207,7 +208,7 @@ public class OakBacklogClusterSyncService extends AbstractServiceWithBackgroundC // 1) 'deactivating' must be empty if (deactivatingIds.length!=0) { - logger.info("getBacklogStatus: there are deactivating instances: "+deactivatingIds); + logger.info("getBacklogStatus: there are deactivating instances: "+Arrays.toString(deactivatingIds)); return BacklogStatus.HAS_BACKLOG; } diff --git a/src/test/java/org/apache/sling/discovery/commons/providers/spi/base/TestOakSyncTokenService.java b/src/test/java/org/apache/sling/discovery/commons/providers/spi/base/TestOakSyncTokenService.java index 726dd95..e767571 100644 --- a/src/test/java/org/apache/sling/discovery/commons/providers/spi/base/TestOakSyncTokenService.java +++ b/src/test/java/org/apache/sling/discovery/commons/providers/spi/base/TestOakSyncTokenService.java @@ -19,6 +19,8 @@ package org.apache.sling.discovery.commons.providers.spi.base; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.UUID; @@ -32,16 +34,18 @@ import org.apache.sling.discovery.commons.providers.ViewStateManager; import org.apache.sling.discovery.commons.providers.base.DummyListener; import org.apache.sling.discovery.commons.providers.base.TestHelper; import org.apache.sling.discovery.commons.providers.base.ViewStateManagerFactory; -import org.apache.sling.discovery.commons.providers.spi.base.DiscoveryLiteConfig; -import org.apache.sling.discovery.commons.providers.spi.base.IdMapService; -import org.apache.sling.discovery.commons.providers.spi.base.OakBacklogClusterSyncService; +import org.apache.sling.discovery.commons.providers.spi.base.AbstractServiceWithBackgroundCheck.BackgroundCheckRunnable; import org.apache.sling.jcr.api.SlingRepository; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TestOakSyncTokenService { + private final static Logger logger = LoggerFactory.getLogger(TestOakSyncTokenService.class); + private static final String SYNCTOKEN_PATH = "/var/discovery/commons/synctokens"; private static final String IDMAP_PATH = "/var/discovery/commons/idmap"; @@ -92,6 +96,7 @@ public class TestOakSyncTokenService { @Before public void setup() throws Exception { + logger.info("setup: start"); RepositoryTestHelper.resetRepo(); memoryNS = new MemoryNodeStore(); repository1 = RepositoryTestHelper.newOakRepository(memoryNS); @@ -101,10 +106,12 @@ public class TestOakSyncTokenService { factory2 = RepositoryTestHelper.mockResourceResolverFactory(repository2); slingId1 = UUID.randomUUID().toString(); idMapService1 = IdMapService.testConstructor(new SimpleCommonsConfig(), new DummySlingSettingsService(slingId1), factory1); + logger.info("setup: end"); } @After public void tearDown() throws Exception { + logger.info("teardown: start"); if (repository1!=null) { RepositoryTestHelper.stopRepository(repository1); repository1 = null; @@ -113,10 +120,12 @@ public class TestOakSyncTokenService { RepositoryTestHelper.stopRepository(repository2); repository2 = null; } + logger.info("teardown: end"); } @Test public void testOneNode() throws Exception { + logger.info("testOneNode: start"); DummyTopologyView one = TestHelper.newView(true, slingId1, slingId1, slingId1); Lock lock = new ReentrantLock(); OakBacklogClusterSyncService cs = OakBacklogClusterSyncService.testConstructorAndActivate(new SimpleCommonsConfig(), idMapService1, new DummySlingSettingsService(slingId1), factory1); @@ -138,10 +147,12 @@ public class TestOakSyncTokenService { cs.triggerBackgroundCheck(); assertEquals(0, vsm.waitForAsyncEvents(1000)); assertEquals(1, l.countEvents()); + logger.info("testOneNode: end"); } @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(); @@ -156,8 +167,32 @@ public class TestOakSyncTokenService { 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); @@ -165,15 +200,15 @@ public class TestOakSyncTokenService { ViewStateManager vsm2 = ViewStateManagerFactory.newViewStateManager(lock2, cs2); cs1.triggerBackgroundCheck(); cs2.triggerBackgroundCheck(); - assertEquals(0, l.countEvents()); + assertEquals(1, l.countEvents()); DescriptorHelper.setDiscoveryLiteDescriptor(factory2, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(2).seq(3).activeIds(1, 2)); cs1.triggerBackgroundCheck(); cs2.triggerBackgroundCheck(); - assertEquals(0, l.countEvents()); + assertEquals(1, l.countEvents()); DescriptorHelper.setDiscoveryLiteDescriptor(factory1, new DiscoveryLiteDescriptorBuilder().setFinal(true).me(1).seq(3).activeIds(1, 2)); cs1.triggerBackgroundCheck(); cs2.triggerBackgroundCheck(); - assertEquals(0, l.countEvents()); + assertEquals(1, l.countEvents()); vsm2.handleActivated(); assertTrue(idMapService1.waitForInit(5000)); assertTrue(idMapService2.waitForInit(5000)); @@ -185,17 +220,23 @@ public class TestOakSyncTokenService { 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()); -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
