You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by st...@apache.org on 2015/10/20 16:12:34 UTC

svn commit: r1709601 [11/11] - in /sling/trunk/bundles/extensions/discovery: base/ base/src/ base/src/main/ base/src/main/java/ base/src/main/java/org/ base/src/main/java/org/apache/ base/src/main/java/org/apache/sling/ base/src/main/java/org/apache/sl...

Modified: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/heartbeat/HeartbeatTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/heartbeat/HeartbeatTest.java?rev=1709601&r1=1709600&r2=1709601&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/heartbeat/HeartbeatTest.java (original)
+++ sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/heartbeat/HeartbeatTest.java Tue Oct 20 14:12:31 2015
@@ -25,17 +25,12 @@ import static org.junit.Assert.assertNul
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import java.io.Serializable;
 import java.util.Calendar;
-import java.util.Date;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Set;
-import java.util.UUID;
 
 import javax.jcr.Property;
 
@@ -45,14 +40,15 @@ import org.apache.sling.api.resource.Mod
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.commons.scheduler.Scheduler;
 import org.apache.sling.discovery.TopologyEvent;
 import org.apache.sling.discovery.TopologyEventListener;
 import org.apache.sling.discovery.TopologyView;
+import org.apache.sling.discovery.base.its.setup.VirtualInstance;
 import org.apache.sling.discovery.impl.DiscoveryServiceImpl;
 import org.apache.sling.discovery.impl.cluster.voting.VotingHelper;
 import org.apache.sling.discovery.impl.cluster.voting.VotingView;
-import org.apache.sling.discovery.impl.setup.Instance;
+import org.apache.sling.discovery.impl.setup.FullJR2VirtualInstance;
+import org.apache.sling.discovery.impl.setup.FullJR2VirtualInstanceBuilder;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -118,7 +114,7 @@ public class HeartbeatTest {
         
     }
     
-    Set<Instance> instances = new HashSet<Instance>();
+    Set<VirtualInstance> instances = new HashSet<VirtualInstance>();
     private Level logLevel;
     
     @Before
@@ -133,10 +129,9 @@ public class HeartbeatTest {
         final org.apache.log4j.Logger discoveryLogger = LogManager.getRootLogger().getLogger("org.apache.sling.discovery");
         discoveryLogger.setLevel(logLevel);
 
-        Instance.setSingletonScheduler(null);
-        Iterator<Instance> it = instances.iterator();
+        Iterator<VirtualInstance> it = instances.iterator();
         while(it.hasNext()) {
-            Instance i = it.next();
+            VirtualInstance i = it.next();
             i.stop();
         }
     }
@@ -148,14 +143,23 @@ public class HeartbeatTest {
     
     @Test
     public void testPartitioningWithFailingScheduler() throws Throwable {
-        installFailingScheduler();
         doTestPartitioning(false);
     }
     
+    public FullJR2VirtualInstanceBuilder newBuilder() {
+        return new FullJR2VirtualInstanceBuilder();
+    }
+    
     public void doTestPartitioning(boolean scheduler) throws Throwable {
         logger.info("doTestPartitioning: creating slowMachine...");
-        Instance slowMachine = Instance.newStandaloneInstance("/var/discovery/impl/", "slow", true, 10 /*10sec timeout*/, 
-                999 /* 999sec interval: to disable it*/, 0, UUID.randomUUID().toString());
+        FullJR2VirtualInstanceBuilder builder = newBuilder();
+        builder.setDebugName("slow")
+                .newRepository("/var/discovery/impl/", true)
+                .setConnectorPingTimeout(10 /* 10 sec timeout */)
+                .setConnectorPingInterval(999 /* 999 sec interval: to disable it */)
+                .setMinEventDelay(0)
+                .withFailingScheduler(!scheduler);
+        FullJR2VirtualInstance slowMachine = builder.fullBuild();
         assertEquals(1, slowMachine.getDiscoveryService().getTopology().getInstances().size());
         assertEquals(slowMachine.getSlingId(), slowMachine.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
         instances.add(slowMachine);
@@ -164,7 +168,14 @@ public class HeartbeatTest {
         slowMachine.bindTopologyEventListener(slowListener);
         
         logger.info("doTestPartitioning: creating fastMachine1...");
-        Instance fastMachine1 = Instance.newClusterInstance("/var/discovery/impl/", "fast1", slowMachine, false, 10, 1, 0);
+        FullJR2VirtualInstanceBuilder fastBuilder1 = newBuilder();
+        fastBuilder1.setDebugName("fast1")
+                .useRepositoryOf(slowMachine)
+                .setConnectorPingTimeout(10)
+                .setConnectorPingInterval(1)
+                .setMinEventDelay(0)
+                .withFailingScheduler(!scheduler);
+        FullJR2VirtualInstance fastMachine1 = fastBuilder1.fullBuild();
         assertEquals(1, fastMachine1.getDiscoveryService().getTopology().getInstances().size());
         assertEquals(fastMachine1.getSlingId(), fastMachine1.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
         instances.add(fastMachine1);
@@ -173,7 +184,14 @@ public class HeartbeatTest {
         fastMachine1.bindTopologyEventListener(fastListener1);
 
         logger.info("doTestPartitioning: creating fastMachine2...");
-        Instance fastMachine2 = Instance.newClusterInstance("/var/discovery/impl/", "fast2", slowMachine, false, 10, 1, 0);
+        FullJR2VirtualInstanceBuilder fullBuilder2 = newBuilder();
+        fullBuilder2.setDebugName("fast2")
+                .useRepositoryOf(slowMachine)
+                .setConnectorPingTimeout(10)
+                .setConnectorPingInterval(1)
+                .setMinEventDelay(0)
+                .withFailingScheduler(!scheduler);
+        FullJR2VirtualInstance fastMachine2 = fullBuilder2.fullBuild();
         assertEquals(1, fastMachine2.getDiscoveryService().getTopology().getInstances().size());
         assertEquals(fastMachine2.getSlingId(), fastMachine2.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
         instances.add(fastMachine2);
@@ -181,7 +199,14 @@ public class HeartbeatTest {
         fastMachine2.bindTopologyEventListener(fastListener2);
 
         logger.info("doTestPartitioning: creating fastMachine3...");
-        Instance fastMachine3 = Instance.newClusterInstance("/var/discovery/impl/", "fast3", slowMachine, false, 10, 1, 0);
+        FullJR2VirtualInstanceBuilder fullBuilder3 = newBuilder();
+        fullBuilder3.setDebugName("fast3")
+                .useRepositoryOf(slowMachine)
+                .setConnectorPingTimeout(10)
+                .setConnectorPingInterval(1)
+                .setMinEventDelay(0)
+                .withFailingScheduler(!scheduler);
+        FullJR2VirtualInstance fastMachine3 = fullBuilder3.fullBuild();
         assertEquals(1, fastMachine3.getDiscoveryService().getTopology().getInstances().size());
         assertEquals(fastMachine3.getSlingId(), fastMachine3.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
         instances.add(fastMachine3);
@@ -189,27 +214,51 @@ public class HeartbeatTest {
         fastMachine3.bindTopologyEventListener(fastListener3);
 
         logger.info("doTestPartitioning: creating fastMachine4...");
-        Instance fastMachine4 = Instance.newClusterInstance("/var/discovery/impl/", "fast4", slowMachine, false, 10, 1, 0);
+        FullJR2VirtualInstanceBuilder fullBuilder4 = newBuilder();
+        fullBuilder4.setDebugName("fast4")
+                .useRepositoryOf(slowMachine)
+                .setConnectorPingTimeout(10)
+                .setConnectorPingInterval(1)
+                .setMinEventDelay(0)
+                .withFailingScheduler(!scheduler);
+        FullJR2VirtualInstance fastMachine4 = fullBuilder4.fullBuild();
         assertEquals(1, fastMachine4.getDiscoveryService().getTopology().getInstances().size());
         assertEquals(fastMachine4.getSlingId(), fastMachine4.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
         instances.add(fastMachine4);
         SimpleTopologyEventListener fastListener4 = new SimpleTopologyEventListener("fast4");
         fastMachine4.bindTopologyEventListener(fastListener4);
         
+        logger.info("doTestPartitioning: --------------------------------");
         logger.info("doTestPartitioning: letting heartbeats be sent by all instances for a few loops...");
+        logger.info("doTestPartitioning: --------------------------------");
         HeartbeatHandler hhSlow = slowMachine.getHeartbeatHandler();
         for(int i=0; i<3; i++) {
+            logger.info("doTestPartitioning: --------------------------------");
+            logger.info("doTestPartitioning: doing pinging with hhSlow now...");
+            logger.info("doTestPartitioning: --------------------------------");
             hhSlow.issueHeartbeat();
-            hhSlow.checkView();
+            hhSlow.doCheckView();
             if (!scheduler) {
+                logger.info("doTestPartitioning: --------------------------------");
+                logger.info("doTestPartitioning: doing pinging with fastMachine1 now...");
+                logger.info("doTestPartitioning: --------------------------------");
                 fastMachine1.getHeartbeatHandler().issueHeartbeat();
-                fastMachine1.getHeartbeatHandler().checkView();
+                fastMachine1.getHeartbeatHandler().doCheckView();
+                logger.info("doTestPartitioning: --------------------------------");
+                logger.info("doTestPartitioning: doing pinging with fastMachine2 now...");
+                logger.info("doTestPartitioning: --------------------------------");
                 fastMachine2.getHeartbeatHandler().issueHeartbeat();
-                fastMachine2.getHeartbeatHandler().checkView();
+                fastMachine2.getHeartbeatHandler().doCheckView();
+                logger.info("doTestPartitioning: --------------------------------");
+                logger.info("doTestPartitioning: doing pinging with fastMachine3 now...");
+                logger.info("doTestPartitioning: --------------------------------");
                 fastMachine3.getHeartbeatHandler().issueHeartbeat();
-                fastMachine3.getHeartbeatHandler().checkView();
+                fastMachine3.getHeartbeatHandler().doCheckView();
+                logger.info("doTestPartitioning: --------------------------------");
+                logger.info("doTestPartitioning: doing pinging with fastMachine4 now...");
+                logger.info("doTestPartitioning: --------------------------------");
                 fastMachine4.getHeartbeatHandler().issueHeartbeat();
-                fastMachine4.getHeartbeatHandler().checkView();
+                fastMachine4.getHeartbeatHandler().doCheckView();
             }
             Thread.sleep(1000);
         }
@@ -242,13 +291,13 @@ public class HeartbeatTest {
         for(int i=0; i<12; i++) {
             if (!scheduler) {
                 fastMachine1.getHeartbeatHandler().issueHeartbeat();
-                fastMachine1.getHeartbeatHandler().checkView();
+                fastMachine1.getHeartbeatHandler().doCheckView();
                 fastMachine2.getHeartbeatHandler().issueHeartbeat();
-                fastMachine2.getHeartbeatHandler().checkView();
+                fastMachine2.getHeartbeatHandler().doCheckView();
                 fastMachine3.getHeartbeatHandler().issueHeartbeat();
-                fastMachine3.getHeartbeatHandler().checkView();
+                fastMachine3.getHeartbeatHandler().doCheckView();
                 fastMachine4.getHeartbeatHandler().issueHeartbeat();
-                fastMachine4.getHeartbeatHandler().checkView();
+                fastMachine4.getHeartbeatHandler().doCheckView();
             }
             Thread.sleep(1000);
         }
@@ -298,28 +347,28 @@ public class HeartbeatTest {
             //assertEquals(5, slowTopo.getInstances().size());
             if (!scheduler) {
                 fastMachine1.getHeartbeatHandler().issueHeartbeat();
-                fastMachine1.getHeartbeatHandler().checkView();
+                fastMachine1.getHeartbeatHandler().doCheckView();
                 fastMachine2.getHeartbeatHandler().issueHeartbeat();
-                fastMachine2.getHeartbeatHandler().checkView();
+                fastMachine2.getHeartbeatHandler().doCheckView();
                 fastMachine3.getHeartbeatHandler().issueHeartbeat();
-                fastMachine3.getHeartbeatHandler().checkView();
+                fastMachine3.getHeartbeatHandler().doCheckView();
                 fastMachine4.getHeartbeatHandler().issueHeartbeat();
-                fastMachine4.getHeartbeatHandler().checkView();
+                fastMachine4.getHeartbeatHandler().doCheckView();
             }
         }
 
         for(int i=0; i<4; i++) {
             hhSlow.issueHeartbeat();
-            hhSlow.checkView();
+            hhSlow.doCheckView();
             if (!scheduler) {
                 fastMachine1.getHeartbeatHandler().issueHeartbeat();
-                fastMachine1.getHeartbeatHandler().checkView();
+                fastMachine1.getHeartbeatHandler().doCheckView();
                 fastMachine2.getHeartbeatHandler().issueHeartbeat();
-                fastMachine2.getHeartbeatHandler().checkView();
+                fastMachine2.getHeartbeatHandler().doCheckView();
                 fastMachine3.getHeartbeatHandler().issueHeartbeat();
-                fastMachine3.getHeartbeatHandler().checkView();
+                fastMachine3.getHeartbeatHandler().doCheckView();
                 fastMachine4.getHeartbeatHandler().issueHeartbeat();
-                fastMachine4.getHeartbeatHandler().checkView();
+                fastMachine4.getHeartbeatHandler().doCheckView();
             }
             Thread.sleep(1000);
         }
@@ -354,24 +403,36 @@ public class HeartbeatTest {
      */
     @Test
     public void testSlowAndFastMachine() throws Throwable {
-        doTestSlowAndFastMachine();
+        doTestSlowAndFastMachine(false);
     }
 
     @Test
     public void testSlowAndFastMachineWithFailingScheduler() throws Throwable {
-        installFailingScheduler();
-        doTestSlowAndFastMachine();
+        doTestSlowAndFastMachine(true);
     }
 
-    public void doTestSlowAndFastMachine() throws Throwable {
+    public void doTestSlowAndFastMachine(boolean withFailingScheduler) throws Throwable {
         logger.info("doTestSlowAndFastMachine: creating slowMachine... (w/o heartbeat runner)");
-        Instance slowMachine = Instance.newStandaloneInstance("/var/discovery/impl/", "slow", true, 5 /*5sec timeout*/, 
-                999 /* 999sec interval: to disable it*/, 0, UUID.randomUUID().toString());
+        FullJR2VirtualInstanceBuilder slowBuilder = newBuilder();
+        slowBuilder.setDebugName("slow")
+                .newRepository("/var/discovery/impl/", true)
+                .setConnectorPingTimeout(5 /*5 sec timeout */)
+                .setConnectorPingInterval(999 /* 999sec interval: to disable it */)
+                .setMinEventDelay(0)
+                .withFailingScheduler(withFailingScheduler);
+        FullJR2VirtualInstance slowMachine = slowBuilder.fullBuild();
         instances.add(slowMachine);
         SimpleTopologyEventListener slowListener = new SimpleTopologyEventListener("slow");
         slowMachine.bindTopologyEventListener(slowListener);
         logger.info("doTestSlowAndFastMachine: creating fastMachine... (w/o heartbeat runner)");
-        Instance fastMachine = Instance.newClusterInstance("/var/discovery/impl/", "fast", slowMachine, false, 5, 999, 0);
+        FullJR2VirtualInstanceBuilder fastBuilder = newBuilder();
+        fastBuilder.setDebugName("fast")
+                .useRepositoryOf(slowMachine)
+                .setConnectorPingTimeout(5)
+                .setConnectorPingInterval(999)
+                .setMinEventDelay(0)
+                .withFailingScheduler(withFailingScheduler);
+        FullJR2VirtualInstance fastMachine = fastBuilder.fullBuild();
         instances.add(fastMachine);
         SimpleTopologyEventListener fastListener = new SimpleTopologyEventListener("fast");
         fastMachine.bindTopologyEventListener(fastListener);
@@ -389,9 +450,9 @@ public class HeartbeatTest {
         logger.info("doTestSlowAndFastMachine: send a couple of heartbeats to connect the two..");
         for(int i=0; i<5; i++) {
             hhSlow.issueHeartbeat();
-            hhSlow.checkView();
+            hhSlow.doCheckView();
             hhFast.issueHeartbeat();
-            hhFast.checkView();
+            hhFast.doCheckView();
             Thread.sleep(100);
         }
         logger.info("doTestSlowAndFastMachine: now the two instances should be connected.");
@@ -411,13 +472,13 @@ public class HeartbeatTest {
         for(int i=0; i<6; i++) {
             Thread.sleep(1500);
             hhFast.issueHeartbeat();
-            hhFast.checkView();
+            hhFast.doCheckView();
         }
         logger.info("doTestSlowAndFastMachine: now the fastMachine should have decoupled the slow one");
         fastMachine.dumpRepo();
-        hhFast.checkView(); // one more for the start of the vote
+        hhFast.doCheckView(); // one more for the start of the vote
         fastMachine.dumpRepo();
-        hhFast.checkView(); // and one for the promotion
+        hhFast.doCheckView(); // and one for the promotion
 
         // after 9 sec hhSlow's heartbeat will have timed out, so hhFast will not see hhSlow anymore
         fastMachine.dumpRepo();
@@ -430,7 +491,7 @@ public class HeartbeatTest {
         
         // after those 6 sec, hhSlow does the check (6sec between heartbeat and check)
         logger.info("doTestSlowAndFastMachine: slowMachine is going to do a checkView next - and will detect being decoupled");
-        hhSlow.checkView();
+        hhSlow.doCheckView();
         slowMachine.dumpRepo();
         logger.info("doTestSlowAndFastMachine: slowMachine is going to also do a heartbeat next");
         hhSlow.issueHeartbeat();
@@ -452,9 +513,9 @@ public class HeartbeatTest {
         logger.info("doTestSlowAndFastMachine: now let both fast and slow issue heartbeats...");
         for(int i=0; i<4; i++) {
             hhFast.issueHeartbeat();
-            hhFast.checkView();
+            hhFast.doCheckView();
             hhSlow.issueHeartbeat();
-            hhSlow.checkView();
+            hhSlow.doCheckView();
             Thread.sleep(1000);
         }
         logger.info("doTestSlowAndFastMachine: by now the two should have joined");
@@ -471,54 +532,6 @@ public class HeartbeatTest {
         assertEquals(3, slowListener.getEventCount());
     }
     
-    private void installFailingScheduler() throws Exception {
-        Instance.setSingletonScheduler(new Scheduler() {
-            
-            @Override
-            public void removeJob(String name) throws NoSuchElementException {
-                // nothing to do here
-            }
-            
-            @Override
-            public boolean fireJobAt(String name, Object job, Map<String, Serializable> config, Date date, int times, long period) {
-                return false;
-            }
-            
-            @Override
-            public void fireJobAt(String name, Object job, Map<String, Serializable> config, Date date) throws Exception {
-                throw new Exception("cos you are really worth it");
-            }
-            
-            @Override
-            public boolean fireJob(Object job, Map<String, Serializable> config, int times, long period) {
-                return false;
-            }
-            
-            @Override
-            public void fireJob(Object job, Map<String, Serializable> config) throws Exception {
-                throw new Exception("cos you are really worth it");
-            }
-            
-            @Override
-            public void addPeriodicJob(String name, Object job, Map<String, Serializable> config, long period, boolean canRunConcurrently,
-                    boolean startImmediate) throws Exception {
-                throw new Exception("cos you are really worth it");
-            }
-            
-            @Override
-            public void addPeriodicJob(String name, Object job, Map<String, Serializable> config, long period, boolean canRunConcurrently)
-                    throws Exception {
-                throw new Exception("cos you are really worth it");
-            }
-            
-            @Override
-            public void addJob(String name, Object job, Map<String, Serializable> config, String schedulingExpression,
-                    boolean canRunConcurrently) throws Exception {
-                throw new Exception("cos you are really worth it");
-            }
-        });
-    }
-
     /**
      * SLING-5027 : test to reproduce the voting loop
      * (and verify that it's fixed)
@@ -526,20 +539,37 @@ public class HeartbeatTest {
     @Test
     public void testVotingLoop() throws Throwable {
         logger.info("testVotingLoop: creating slowMachine1...");
-        Instance slowMachine1 = Instance.newStandaloneInstance("/var/discovery/impl/", "slow1", true, 600 /*600sec timeout*/, 
-                999 /* 999sec interval: to disable it*/, 0, UUID.randomUUID().toString());
+        FullJR2VirtualInstanceBuilder slowBuilder1 = newBuilder();
+        slowBuilder1.setDebugName("slow1")
+            .newRepository("/var/discovery/impl/", true)
+            .setConnectorPingTimeout(600 /* 600 sec timeout */)
+            .setConnectorPingInterval(999 /* 999 sec interval: to disable it */)
+            .setMinEventDelay(0);
+        FullJR2VirtualInstance slowMachine1 = slowBuilder1.fullBuild();
         instances.add(slowMachine1);
         SimpleTopologyEventListener slowListener1 = new SimpleTopologyEventListener("slow1");
         slowMachine1.bindTopologyEventListener(slowListener1);
         
         logger.info("testVotingLoop: creating slowMachine2...");
-        Instance slowMachine2 = Instance.newClusterInstance("/var/discovery/impl/", "slow2", slowMachine1, false, 600, 999, 0);
+        FullJR2VirtualInstanceBuilder slowBuilder2 = newBuilder();
+        slowBuilder2.setDebugName("slow2")
+            .useRepositoryOf(slowMachine1)
+            .setConnectorPingTimeout(600 /* 600 sec timeout */)
+            .setConnectorPingInterval(999 /* 999 sec interval: to disable it */)
+            .setMinEventDelay(0);
+        FullJR2VirtualInstance slowMachine2 = slowBuilder2.fullBuild();
         instances.add(slowMachine2);
         SimpleTopologyEventListener slowListener2 = new SimpleTopologyEventListener("slow2");
         slowMachine2.bindTopologyEventListener(slowListener2);
         
         logger.info("testVotingLoop: creating fastMachine...");
-        Instance fastMachine = Instance.newClusterInstance("/var/discovery/impl/", "fast", slowMachine1, false, 600, 999, 0);
+        FullJR2VirtualInstanceBuilder fastBuilder = newBuilder();
+        fastBuilder.setDebugName("fast")
+            .useRepositoryOf(slowMachine1)
+            .setConnectorPingTimeout(600 /* 600 sec timeout */)
+            .setConnectorPingInterval(999 /* 999 sec interval: to disable it */)
+            .setMinEventDelay(0);
+        FullJR2VirtualInstance fastMachine = fastBuilder.fullBuild();
         instances.add(fastMachine);
         SimpleTopologyEventListener fastListener = new SimpleTopologyEventListener("fast");
         fastMachine.bindTopologyEventListener(fastListener);
@@ -570,7 +600,7 @@ public class HeartbeatTest {
         // only the fast one will vote, the slow one doesn't.
         // that will cause a voting loop
         logger.info("testVotingLoop: let the fast one do a checkView, thus initiate a voting");
-        hhFast.checkView();
+        hhFast.doCheckView();
         
         Calendar previousVotedAt = null;
         for(int i=0; i<5; i++) {
@@ -583,7 +613,7 @@ public class HeartbeatTest {
                     .getAdministrativeResourceResolver(null);
             try{
                 List<VotingView> ongoingVotings = 
-                        VotingHelper.listOpenNonWinningVotings(resourceResolver, fastMachine.getConfig());
+                        VotingHelper.listOpenNonWinningVotings(resourceResolver, fastMachine.getFullConfig());
                 assertNotNull(ongoingVotings);
                 assertEquals(1, ongoingVotings.size());
                 VotingView ongoingVote = ongoingVotings.get(0);

Modified: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/EstablishedInstanceDescriptionTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/EstablishedInstanceDescriptionTest.java?rev=1709601&r1=1709600&r2=1709601&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/EstablishedInstanceDescriptionTest.java (original)
+++ sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/EstablishedInstanceDescriptionTest.java Tue Oct 20 14:12:31 2015
@@ -21,17 +21,17 @@ package org.apache.sling.discovery.impl.
 import java.util.Map;
 
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.discovery.impl.common.DefaultClusterViewImpl;
-import org.apache.sling.discovery.impl.common.DefaultInstanceDescriptionImpl;
-import org.apache.sling.discovery.impl.common.InstanceDescriptionTest;
-import org.apache.sling.discovery.impl.setup.MockedResource;
-import org.apache.sling.discovery.impl.setup.MockedResourceResolver;
+import org.apache.sling.discovery.base.its.setup.mock.MockedResource;
+import org.apache.sling.discovery.base.its.setup.mock.MockedResourceResolver;
+import org.apache.sling.discovery.commons.providers.DefaultClusterView;
+import org.apache.sling.discovery.commons.providers.DefaultInstanceDescription;
+import org.apache.sling.discovery.commons.providers.DefaultInstanceDescriptionTest;
 
-public class EstablishedInstanceDescriptionTest extends InstanceDescriptionTest {
+public class EstablishedInstanceDescriptionTest extends DefaultInstanceDescriptionTest {
 
     @Override
-    public DefaultInstanceDescriptionImpl constructInstanceDescription(
-            DefaultClusterViewImpl clusterView, boolean isLeader,
+    public DefaultInstanceDescription constructInstanceDescription(
+            DefaultClusterView clusterView, boolean isLeader,
             boolean isOwn, String theSlingId, Map<String, String> properties)
             throws Exception {
 

Modified: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/ResourceHelperWithoutJcrTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/ResourceHelperWithoutJcrTest.java?rev=1709601&r1=1709600&r2=1709601&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/ResourceHelperWithoutJcrTest.java (original)
+++ sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/resource/ResourceHelperWithoutJcrTest.java Tue Oct 20 14:12:31 2015
@@ -26,6 +26,7 @@ import java.util.Map;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.discovery.commons.providers.util.ResourceHelper;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Rule;

Added: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstance.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstance.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstance.java (added)
+++ sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstance.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.discovery.impl.setup;
+
+import org.apache.sling.discovery.base.its.setup.VirtualInstance;
+import org.apache.sling.discovery.impl.Config;
+import org.apache.sling.discovery.impl.common.heartbeat.HeartbeatHandler;
+
+public class FullJR2VirtualInstance extends VirtualInstance {
+
+    private FullJR2VirtualInstanceBuilder fullBuilder;
+
+    public FullJR2VirtualInstance(FullJR2VirtualInstanceBuilder builder) throws Exception {
+        super(builder);
+        fullBuilder = builder;
+    }
+
+    public HeartbeatHandler getHeartbeatHandler() {
+        return (HeartbeatHandler) getViewChecker();
+    }
+
+    public void stopVoting() {
+        fullBuilder.stopVoting();
+    }
+
+    public Config getFullConfig() {
+        return fullBuilder.getConfig();
+    }
+
+}

Propchange: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstanceBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstanceBuilder.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstanceBuilder.java (added)
+++ sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstanceBuilder.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.discovery.impl.setup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.ObservationManager;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.testing.jcr.RepositoryProvider;
+import org.apache.sling.discovery.base.commons.BaseDiscoveryService;
+import org.apache.sling.discovery.base.commons.ClusterViewService;
+import org.apache.sling.discovery.base.commons.ViewChecker;
+import org.apache.sling.discovery.base.commons.UndefinedClusterViewException;
+import org.apache.sling.discovery.base.its.setup.ModifiableTestBaseConfig;
+import org.apache.sling.discovery.base.its.setup.VirtualInstance;
+import org.apache.sling.discovery.base.its.setup.VirtualInstanceBuilder;
+import org.apache.sling.discovery.base.its.setup.mock.MockFactory;
+import org.apache.sling.discovery.impl.DiscoveryServiceImpl;
+import org.apache.sling.discovery.impl.cluster.ClusterViewServiceImpl;
+import org.apache.sling.discovery.impl.cluster.voting.VotingHandler;
+import org.apache.sling.discovery.impl.common.heartbeat.HeartbeatHandler;
+import org.apache.sling.discovery.impl.common.resource.EstablishedInstanceDescription;
+
+public class FullJR2VirtualInstanceBuilder extends VirtualInstanceBuilder {
+
+    private String path;
+
+    private TestConfig config;
+
+    private Object[] additionalServices;
+
+    private VotingEventListener observationListener;
+
+    private ObservationManager observationManager;
+    
+    @Override
+    public VirtualInstanceBuilder createNewRepository() throws Exception {
+        this.factory = MockFactory.mockResourceResolverFactory();
+        return this;
+    }
+
+    @Override
+    public VirtualInstanceBuilder setPath(String path) {
+        if (ownRepository) {
+            // then that's fine
+            this.path = path;
+        } else {
+            // then that's not fine
+            throw new IllegalStateException("cannot set path on inherited repo");
+        }
+        return this;
+    }
+    
+    TestConfig getConfig() {
+        if (config==null) {
+            config = createConfig();
+        }
+        return config;
+    }
+    
+    private TestConfig createConfig() {
+        TestConfig c = new TestConfig(path);
+        return c;
+    }
+    
+    @Override
+    public ModifiableTestBaseConfig getConnectorConfig() {
+        return getConfig();
+    }
+    
+    @Override
+    protected ViewChecker createViewChecker() throws Exception {
+        return HeartbeatHandler.testConstructor(getSlingSettingsService(), getResourceResolverFactory(), getAnnouncementRegistry(), getConnectorRegistry(), getConfig(), getScheduler());
+    }
+    
+    @Override
+    protected BaseDiscoveryService createDiscoveryService() throws Exception {
+        return DiscoveryServiceImpl.testConstructor(getResourceResolverFactory(), getAnnouncementRegistry(), getConnectorRegistry(), getClusterViewService(), getHeartbeatHandler(), getSlingSettingsService(), getScheduler(), getConfig());
+    }
+    
+    @Override
+    protected ClusterViewService createClusterViewService() {
+        return ClusterViewServiceImpl.testConstructor(getSlingSettingsService(), getResourceResolverFactory(), getConfig());
+    }
+
+    private HeartbeatHandler getHeartbeatHandler() throws Exception {
+        if (viewChecker==null) {
+            throw new IllegalStateException("heartbeatHandler not yet initialized");
+        }
+        return (HeartbeatHandler) getViewChecker();
+    }
+    
+    @Override
+    public Object[] getAdditionalServices(VirtualInstance instance) throws Exception {
+        if (additionalServices==null) {
+            additionalServices = createAdditionalServices(instance);
+        }
+        return additionalServices;
+    }
+
+    private Object[] createAdditionalServices(VirtualInstance instance) throws Exception {
+        Object[] additionals = new Object[1];
+        
+        VotingHandler votingHandler = VotingHandler.testConstructor(getSlingSettingsService(), getResourceResolverFactory(), getConfig());
+        additionals[0] = votingHandler;
+        
+        observationListener = new VotingEventListener(instance, votingHandler, getSlingId());
+        ResourceResolver resourceResolver = getResourceResolverFactory()
+                .getAdministrativeResourceResolver(null);
+        Session session = resourceResolver.adaptTo(Session.class);
+        observationManager = session.getWorkspace()
+                .getObservationManager();
+        observationManager.addEventListener(
+                observationListener
+                , Event.NODE_ADDED | Event.NODE_REMOVED | Event.NODE_MOVED
+                        | Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED
+                        | Event.PROPERTY_REMOVED | Event.PERSIST, "/", true,
+                null,
+                null, false);
+
+        return additionals;
+    }
+    
+    void stopVoting() {
+        if (observationListener!=null) {
+            observationListener.stop();
+            observationListener = null;
+        }
+    }
+
+    public FullJR2VirtualInstance fullBuild() throws Exception {
+        return (FullJR2VirtualInstance) build();
+    }
+    
+    @Override
+    public VirtualInstance build() throws Exception {
+        if (path==null) {
+            if (ownRepository) {
+                setPath("/var/discovery/impl/");
+                getConfig().setPath("/var/discovery/impl/");
+            } else {
+                FullJR2VirtualInstanceBuilder other = (FullJR2VirtualInstanceBuilder) hookedToBuilder;
+                this.path = other.path;
+                getConfig().setPath(other.path);
+            }
+        }
+        if (path==null) {
+            throw new IllegalStateException("no path set");
+        }
+        if (!path.startsWith("/")) {
+            throw new IllegalStateException("path must start with /: "+path);
+        }
+        if (!path.endsWith("/")) {
+            throw new IllegalStateException("path must end with /: "+path);
+        }
+        return new FullJR2VirtualInstance(this) {
+            @Override
+            public void stop() throws Exception {
+                if ((observationListener != null) && (observationManager != null)) {
+                    logger.info("stop: removing listener for slingId="+slingId+": "+observationListener);
+                    observationManager.removeEventListener(observationListener);
+                } else {
+                    logger.warn("stop: could not remove listener for slingId="+slingId+", debugName="+debugName+", observationManager="+observationManager+", observationListener="+observationListener);
+                }
+                if (observationListener!=null) {
+                    observationListener.stop();
+                }
+                super.stop();
+            }
+            
+            @Override
+            public void assertEstablishedView() {
+                super.assertEstablishedView();
+                try {
+                    assertEquals(EstablishedInstanceDescription.class, this
+                            .getClusterViewService().getLocalClusterView().getInstances().get(0)
+                            .getClass());
+                } catch (UndefinedClusterViewException e) {
+                    fail("Undefined clusterView: "+e);
+                }
+            }
+        };
+    }
+    
+    @Override
+    protected void resetRepo() throws Exception {
+        Session l = RepositoryProvider.instance().getRepository()
+                .loginAdministrative(null);
+        try {
+            l.removeItem("/var");
+            l.save();
+            l.logout();
+        } catch (Exception e) {
+            l.refresh(false);
+            l.logout();
+        }
+    }
+
+    
+}

Propchange: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/FullJR2VirtualInstanceBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/TestConfig.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/TestConfig.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/TestConfig.java (added)
+++ sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/TestConfig.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.discovery.impl.setup;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.sling.discovery.base.its.setup.ModifiableTestBaseConfig;
+import org.apache.sling.discovery.impl.Config;
+
+public class TestConfig extends Config implements ModifiableTestBaseConfig {
+
+    long heartbeatTimeout = 20;
+    long heartbeatInterval = 20;
+    int minEventDelay = 1;
+    List<String> whitelist;
+    private String drPath;
+    
+    public TestConfig(String path) {
+        this.drPath = path;
+    }
+    
+    @Override
+    protected String getDiscoveryResourcePath() {
+        return drPath;
+    }
+    
+    @Override
+    public long getHeartbeatInterval() {
+        return heartbeatInterval;
+    }
+
+    public void setHeartbeatInterval(long heartbeatInterval) {
+        this.heartbeatInterval = heartbeatInterval;
+    }
+
+    @Override
+    public long getHeartbeatTimeout() {
+        return heartbeatTimeout;
+    }
+
+    public void setHeartbeatTimeout(long heartbeatTimeout) {
+        this.heartbeatTimeout = heartbeatTimeout;
+    }
+
+    @Override
+    public int getMinEventDelay() {
+        return minEventDelay;
+    }
+
+    public void setMinEventDelay(int minEventDelay) {
+        this.minEventDelay = minEventDelay;
+    }
+
+    @Override
+    public String[] getTopologyConnectorWhitelist() {
+        if (whitelist==null) {
+            return null;
+        }
+        return whitelist.toArray(new String[whitelist.size()]);
+    }
+
+    public void addTopologyConnectorWhitelistEntry(String whitelistEntry) {
+        if (whitelist==null) {
+            whitelist = new LinkedList<String>();
+        }
+        whitelist.add(whitelistEntry);
+    }
+
+    @Override
+    public int getBackoffStableFactor() {
+        return 1;
+    }
+
+    @Override
+    public int getBackoffStandbyFactor() {
+        return 1;
+    }
+
+    @Override
+    public void setViewCheckTimeout(int viewCheckTimeout) {
+        setHeartbeatTimeout(viewCheckTimeout);
+    }
+
+    @Override
+    public void setViewCheckInterval(int viewCheckInterval) {
+        setHeartbeatInterval(viewCheckInterval);
+    }
+
+    public void setPath(String path) {
+        drPath = path;
+    }
+    
+}
\ No newline at end of file

Propchange: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/TestConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/VotingEventListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/VotingEventListener.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/VotingEventListener.java (added)
+++ sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/VotingEventListener.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.discovery.impl.setup;
+
+import java.util.Properties;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.discovery.base.its.setup.VirtualInstance;
+import org.apache.sling.discovery.impl.cluster.voting.VotingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class VotingEventListener implements EventListener {
+    
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * 
+     */
+    private final VirtualInstance instance;
+    private final VotingHandler votingHandler;
+    volatile boolean stopped = false;
+    private final String slingId;
+    
+    public VotingEventListener(VirtualInstance instance, VotingHandler votingHandler, String slingId) {
+        this.instance = instance;
+        this.votingHandler = votingHandler;
+        this.slingId = slingId;
+    }
+    
+    public void stop() {
+        logger.debug("stop: stopping listener for slingId: "+slingId);
+        stopped = true;
+    }
+
+    public void onEvent(EventIterator events) {
+        if (stopped) {
+            logger.info("onEvent: listener: "+slingId+" getting late events even though stopped: "+events.hasNext());
+            return;
+        }
+        try {
+            while (!stopped && events.hasNext()) {
+                Event event = events.nextEvent();
+                Properties properties = new Properties();
+                String topic;
+                if (event.getType() == Event.NODE_ADDED) {
+                    topic = SlingConstants.TOPIC_RESOURCE_ADDED;
+                } else if (event.getType() == Event.NODE_MOVED) {
+                    topic = SlingConstants.TOPIC_RESOURCE_CHANGED;
+                } else if (event.getType() == Event.NODE_REMOVED) {
+                    topic = SlingConstants.TOPIC_RESOURCE_REMOVED;
+                } else {
+                    topic = SlingConstants.TOPIC_RESOURCE_CHANGED;
+                }
+                try {
+                    properties.put("path", event.getPath());
+                    org.osgi.service.event.Event osgiEvent = new org.osgi.service.event.Event(
+                            topic, properties);
+                    logger.debug("onEvent: delivering event to listener: "+slingId+", stopped: "+stopped+", event: "+osgiEvent);
+                    votingHandler.handleEvent(osgiEvent);
+                } catch (RepositoryException e) {
+                    logger.warn("RepositoryException: " + e, e);
+                }
+            }
+            if (stopped) {
+                logger.info("onEvent: listener stopped: "+slingId+", pending events: "+events.hasNext());
+            }
+        } catch (Throwable th) {
+            try {
+                this.instance.dumpRepo();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            logger.error(
+                    "Throwable occurred in onEvent: " + th, th);
+        }
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/VotingEventListener.java
------------------------------------------------------------------------------
    svn:eol-style = native