Modified: 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/cluster/TopologyEventTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/cluster/TopologyEventTest.java?rev=1704604&r1=1704603&r2=1704604&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/cluster/TopologyEventTest.java
 (original)
+++ 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/cluster/TopologyEventTest.java
 Tue Sep 22 12:35:19 2015
@@ -20,9 +20,9 @@ package org.apache.sling.discovery.impl.
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import java.util.Iterator;
 import java.util.UUID;
 
 import org.apache.log4j.Level;
@@ -76,6 +76,7 @@ public class TopologyEventTest {
     
     /**
      * Tests the fact that the INIT event is delayed until voting has succeeded
+     * (which is the default with SLIGN-5030 and SLING-4959
      * @throws Throwable 
      */
     @Test
@@ -83,7 +84,7 @@ public class TopologyEventTest {
         logger.info("testDelayedInitEvent: start");
         instance1 = Instance.newStandaloneInstance("/var/discovery/impl/", 
                 "firstInstanceA", true, 20 /* heartbeat-timeout */, 3 /*min 
event delay*/,
-                UUID.randomUUID().toString(), true 
/*delayInitEventUntilVoted*/);
+                UUID.randomUUID().toString());
         AssertingTopologyEventListener l1 = new 
AssertingTopologyEventListener("instance1.l1");
         instance1.bindTopologyEventListener(l1);
         logger.info("testDelayedInitEvent: instance1 created, no events 
expected yet. slingId="+instance1.slingId);
@@ -114,7 +115,7 @@ public class TopologyEventTest {
         
         logger.info("testDelayedInitEvent: creating instance2");
         instance2 = Instance.newClusterInstance("/var/discovery/impl/", 
-                "secondInstanceB", instance1, false, 20, 3, 
UUID.randomUUID().toString(), true);
+                "secondInstanceB", instance1, false, 20, 3, 
UUID.randomUUID().toString());
         logger.info("testDelayedInitEvent: instance2 created with 
slingId="+instance2.slingId);
         AssertingTopologyEventListener l2 = new 
AssertingTopologyEventListener("instance2.l2");
         instance2.bindTopologyEventListener(l2);
@@ -182,146 +183,68 @@ public class TopologyEventTest {
         logger.info("testDelayedInitEvent: end");
     }
     
-    /**
-     * Tests the fact that the INIT event is NOT delayed (until voting has 
succeeded)
-     * when the config is set accordingly (ie: config test).
-     * @throws Throwable 
-     */
     @Test
-    public void testNonDelayedInitEvent() throws Throwable {
-        logger.info("testNonDelayedInitEvent: start");
+    public void testGetDuringDelay() throws Throwable {
         instance1 = Instance.newStandaloneInstance("/var/discovery/impl/", 
-                "firstInstanceB", true, 20 /* heartbeat-timeout */, 10 /*min 
event delay*/,
-                UUID.randomUUID().toString(), false 
/*delayInitEventUntilVoted*/);
-        AssertingTopologyEventListener l1 = new 
AssertingTopologyEventListener("instance1.l1") {
-            private volatile boolean firstEvent = false;
-            @Override
-            public void handleTopologyEvent(TopologyEvent event) {
-                super.handleTopologyEvent(event);
-                if (firstEvent) {
-                    // only handle the first event - that one must be INIT 
with isCurrent==false
-                    assertFalse(event.getNewView().isCurrent());
-                    firstEvent = false;
-                }
-            }
-        };
-        l1.addExpected(Type.TOPOLOGY_INIT);
+                "firstInstanceA", true, 20 /* heartbeat-timeout */, 6 /*min 
event delay*/,
+                UUID.randomUUID().toString());
+        AssertingTopologyEventListener l1 = new 
AssertingTopologyEventListener("instance1.l1");
+        l1.addExpected(TopologyEvent.Type.TOPOLOGY_INIT);
         instance1.bindTopologyEventListener(l1);
-
-        Thread.sleep(500); // SLING-4755: async event sending requires some 
minimal wait time nowadays
         
-        // when delayInitEventUntilVoted is disabled, the INIT event is sent 
immediately
-        assertEquals(1, l1.getEvents().size());
-        assertEquals(0, l1.getUnexpectedCount());
-        assertEquals(0, l1.getRemainingExpectedCount());
+        TopologyView earlyTopo = instance1.getDiscoveryService().getTopology();
+        assertNotNull(earlyTopo);
+        assertFalse(earlyTopo.isCurrent());
+        assertEquals(1, earlyTopo.getInstances().size());
+        
+        for(int i=0; i<4; i++) {
+            instance1.runHeartbeatOnce();
+            Thread.sleep(125);
+        }
+        TopologyView secondTopo = 
instance1.getDiscoveryService().getTopology();
+        assertEquals(1, secondTopo.getInstances().size());
+        assertEquals(instance1.getSlingId(), 
secondTopo.getInstances().iterator().next().getSlingId());
+        assertTrue(secondTopo.isCurrent());
+        instance1.dumpRepo();
+        assertEquals(earlyTopo.getLocalInstance().getClusterView().getId(),
+                secondTopo.getLocalInstance().getClusterView().getId());
 
-        instance1.runHeartbeatOnce();
-        Thread.sleep(1000);
-        // no further event now:
-        assertEquals(1, l1.getEvents().size());
-        assertEquals(0, l1.getUnexpectedCount());
-        assertEquals(0, l1.getRemainingExpectedCount());
-        
-        instance1.runHeartbeatOnce();
-        // still no further event, only INIT
-        assertEquals(1, l1.getEvents().size());
+        Thread.sleep(500);
+        // should have gotten the INIT, hence 0 remaining expected events
         assertEquals(0, l1.getRemainingExpectedCount());
         assertEquals(0, l1.getUnexpectedCount());
         
+        l1.addExpected(TopologyEvent.Type.TOPOLOGY_CHANGING);
         instance2 = Instance.newClusterInstance("/var/discovery/impl/", 
-                "secondInstanceB", instance1, false, 20, 10, 
UUID.randomUUID().toString(), false);
-        AssertingTopologyEventListener l2 = new 
AssertingTopologyEventListener("instance2.l2");
-        l2.addExpected(Type.TOPOLOGY_INIT);
+                "secondInstanceB", instance1, false, 20, 1, 
UUID.randomUUID().toString());
+        AssertingTopologyEventListener l2 = new 
AssertingTopologyEventListener("instance2.l1");
+        l2.addExpected(TopologyEvent.Type.TOPOLOGY_INIT);
         instance2.bindTopologyEventListener(l2);
-        AssertingTopologyEventListener l1Two = new 
AssertingTopologyEventListener("instance1.l1Two");
-        l1Two.addExpected(Type.TOPOLOGY_INIT);
-        instance1.bindTopologyEventListener(l1Two);
-        
-        Thread.sleep(500); // SLING-4755: async event sending requires some 
minimal wait time nowadays
 
-        // just because instance2 is started doesn't kick off any events yet 
-        // since instance2 didn't send heartbeats yet
-        assertEquals(1, l1.getEvents().size()); // one event
-        assertEquals(0, l1.getRemainingExpectedCount()); // the expected one
-        assertEquals(0, l1.getUnexpectedCount());
-        assertEquals(1, l2.getEvents().size());
-        assertEquals(0, l2.getUnexpectedCount());
-        assertEquals(1, l1Two.getEvents().size());
-        assertEquals(0, l1Two.getRemainingExpectedCount()); // the expected one
-        assertEquals(0, l1Two.getUnexpectedCount());
+        for(int i=0; i<4; i++) {
+            instance2.runHeartbeatOnce();
+            instance1.runHeartbeatOnce();
+            Thread.sleep(750);
+        }
         
-        // one heartbeat doesn't change the history yet
-        instance1.runHeartbeatOnce();
-        instance2.runHeartbeatOnce();
-        assertEquals(1, l1.getEvents().size()); // one event
         assertEquals(0, l1.getUnexpectedCount());
-        assertEquals(1, l2.getEvents().size());
-        assertEquals(0, l2.getUnexpectedCount());
-        assertEquals(1, l1Two.getEvents().size());
-        assertEquals(0, l1Two.getUnexpectedCount());
+        TopologyView topo2 = instance2.getDiscoveryService().getTopology();
+        assertTrue(topo2.isCurrent());
+        assertEquals(2, topo2.getInstances().size());
+        TopologyView topo1 = instance1.getDiscoveryService().getTopology();
+        assertTrue(topo1.isCurrent());
+        assertEquals(2, topo1.getInstances().size());
         
-        // the second & third heartbeat though triggers the voting etc
-        l1.addExpected(Type.TOPOLOGY_CHANGING);
-        l1Two.addExpected(Type.TOPOLOGY_CHANGING);
-        l2.addExpected(Type.TOPOLOGY_CHANGING);
-        instance1.runHeartbeatOnce();
-        instance2.runHeartbeatOnce();
-        Thread.sleep(1500);
-        instance1.runHeartbeatOnce();
-        instance2.runHeartbeatOnce();
-        Thread.sleep(1500);
-        logger.info("testNonDelayedInitEvent: instance1: "+instance1.slingId);
-        logger.info("testNonDelayedInitEvent: instance2: "+instance2.slingId);
-        instance1.dumpRepo();
-        assertEquals(0, l1.getUnexpectedCount());
-        assertEquals(2, l1.getEvents().size());
-        assertEquals(0, l2.getUnexpectedCount());
-        assertEquals(2, l2.getEvents().size());
-        assertEquals(0, l1Two.getUnexpectedCount());
-        assertEquals(2, l1Two.getEvents().size());
-        
-        // now meanwhile - for SLING-4638 : register a listener 'late':
-        // this one should get an INIT with a newView that has 
isCurrent()==false
-        AssertingTopologyEventListener late = new 
AssertingTopologyEventListener("instance1.late") {
-            @Override
-            public void handleTopologyEvent(TopologyEvent event) {
-                super.handleTopologyEvent(event);
-                if (event.getType()==Type.TOPOLOGY_INIT) {
-                    // also check if the newView has isCurrent==false
-                    if (event.getNewView().isCurrent()) {
-                        fail("for TOPOLOGY_INIT: new view is expected to be 
not current, but it is: "+event);
-                    }
-                    // plus lets now directly ask the discovery service for 
getTopology and check that
-                    TopologyView topology = 
instance1.getDiscoveryService().getTopology();
-                    if (topology.isCurrent()) {
-                        fail("for TOPOLOGY_INIT: discovery service is expected 
to have a topology that is not current, but it is: "+topology);
-                    }
-                }
-            }
-        };
-        late.addExpected(Type.TOPOLOGY_INIT);
-        instance1.bindTopologyEventListener(late);
-
-        // wait until CHANGED is sent - which is 10 sec after CHANGING - we 
already waited 3 sec above, so 12sec more should be enough
-        l1.addExpected(Type.TOPOLOGY_CHANGED);
-        l1Two.addExpected(Type.TOPOLOGY_CHANGED);
-        l2.addExpected(Type.TOPOLOGY_CHANGED);
-        Thread.sleep(12000);
-        final Iterator<TopologyEvent> it = l1.getEvents().iterator();
-        while(it.hasNext()) {
-               final TopologyEvent e = it.next();
-               logger.info("testNonDelayedInitEvent: got event: "+e);
-        }
+        l1.addExpected(TopologyEvent.Type.TOPOLOGY_CHANGED);
+        Thread.sleep(5000);
+        assertEquals(0, l1.getRemainingExpectedCount());
         assertEquals(0, l1.getUnexpectedCount());
-        assertEquals(3, l1.getEvents().size()); // one event
+        assertEquals(0, l2.getRemainingExpectedCount());
         assertEquals(0, l2.getUnexpectedCount());
-        assertEquals(3, l2.getEvents().size());
-        assertEquals(0, l1Two.getUnexpectedCount());
-        assertEquals(3, l1Two.getEvents().size());
-        if (late.getErrorMsg()!=null) {
-            fail(late.getErrorMsg());
-        }
-        logger.info("testNonDelayedInitEvent: end");
+        assertTrue(instance2.getDiscoveryService().getTopology().isCurrent());
+        assertEquals(2, 
instance2.getDiscoveryService().getTopology().getInstances().size());
+        assertTrue(instance1.getDiscoveryService().getTopology().isCurrent());
+        assertEquals(2, 
instance1.getDiscoveryService().getTopology().getInstances().size());
     }
     
-}
+}
\ No newline at end of file

Added: 
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=1704604&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/heartbeat/HeartbeatTest.java
 (added)
+++ 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/common/heartbeat/HeartbeatTest.java
 Tue Sep 22 12:35:19 2015
@@ -0,0 +1,430 @@
+/*
+ * 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.common.heartbeat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.UUID;
+
+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.impl.DiscoveryServiceImpl;
+import org.apache.sling.discovery.impl.setup.Instance;
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+public class HeartbeatTest {
+    
+    class SimpleTopologyEventListener implements TopologyEventListener {
+
+        private TopologyEvent lastEvent;
+        private int eventCount;
+        private final String name;
+
+        public SimpleTopologyEventListener(String name) {
+            this.name = name;
+        }
+        
+        @Override
+        public void handleTopologyEvent(TopologyEvent event) {
+            String msg = event.toString();
+            TopologyView newView = event.getNewView();
+            switch(event.getType()) {
+                case PROPERTIES_CHANGED: {
+                    msg = 
String.valueOf(TopologyEvent.Type.PROPERTIES_CHANGED);
+                    break;
+                }
+                case TOPOLOGY_CHANGED: {
+                    msg = TopologyEvent.Type.TOPOLOGY_CHANGED + ", newView 
contains "+newView.getInstances().size()+", 
newView.isCurrent="+newView.isCurrent();
+                    break;
+                }
+                case TOPOLOGY_CHANGING: {
+                    msg = TopologyEvent.Type.TOPOLOGY_CHANGING + ", oldView 
contained "+event.getOldView().getInstances().size()+", 
oldView.isCurrent="+event.getOldView().isCurrent();
+                    break;
+                }
+                case TOPOLOGY_INIT: {
+                    if (newView==null) {
+                        msg = TopologyEvent.Type.TOPOLOGY_INIT + ", newView 
contains null: "+newView;
+                    } else if (newView.getInstances()==null) {
+                        msg = TopologyEvent.Type.TOPOLOGY_INIT + ", newView 
contains no instances:"+newView+", newView.isCurrent="+newView.isCurrent();
+                    } else {
+                        msg = TopologyEvent.Type.TOPOLOGY_INIT + ", newView 
contains "+newView.getInstances().size()+", 
newView.isCurrent="+newView.isCurrent();
+                    }
+                    break;
+                }
+            }
+            
LoggerFactory.getLogger(this.getClass()).info("handleTopologyEvent["+name+"]: 
"+msg);
+            lastEvent = event;
+            eventCount++;
+        }
+        
+        public int getEventCount() {
+            return eventCount;
+        }
+        
+        public TopologyEvent getLastEvent() {
+            return lastEvent;
+        }
+        
+    }
+    
+    Set<Instance> instances = new HashSet<Instance>();
+    
+    @After
+    public void tearDown() throws Exception {
+        Instance.setSingletonScheduler(null);
+        Iterator<Instance> it = instances.iterator();
+        while(it.hasNext()) {
+            Instance i = it.next();
+            i.stop();
+        }
+    }
+
+    @Test
+    public void testPartitioning() throws Throwable {
+        doTestPartitioning(true);
+    }
+    
+    @Test
+    public void testPartitioningWithFailingScheduler() throws Throwable {
+        installFailingScheduler();
+        doTestPartitioning(false);
+    }
+    
+    public void doTestPartitioning(boolean scheduler) throws Throwable {
+        Instance slowMachine = 
Instance.newStandaloneInstance("/var/discovery/impl/", "slow", true, 5 /*5sec 
timeout*/, 
+                999 /* 999sec interval: to disable it*/, 0, 
UUID.randomUUID().toString());
+        assertEquals(1, 
slowMachine.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(slowMachine.getSlingId(), 
slowMachine.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
+        instances.add(slowMachine);
+        SimpleTopologyEventListener slowListener = new 
SimpleTopologyEventListener("slow");
+        slowMachine.bindTopologyEventListener(slowListener);
+        Instance fastMachine1 = 
Instance.newClusterInstance("/var/discovery/impl/", "fast1", slowMachine, 
false, 5, 1, 0);
+        assertEquals(1, 
fastMachine1.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(fastMachine1.getSlingId(), 
fastMachine1.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
+        instances.add(fastMachine1);
+        SimpleTopologyEventListener fastListener1 = new 
SimpleTopologyEventListener("fast1");
+        fastMachine1.bindTopologyEventListener(fastListener1);
+        Instance fastMachine2 = 
Instance.newClusterInstance("/var/discovery/impl/", "fast2", slowMachine, 
false, 5, 1, 0);
+        assertEquals(1, 
fastMachine2.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(fastMachine2.getSlingId(), 
fastMachine2.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
+        instances.add(fastMachine2);
+        SimpleTopologyEventListener fastListener2 = new 
SimpleTopologyEventListener("fast2");
+        fastMachine2.bindTopologyEventListener(fastListener2);
+        Instance fastMachine3 = 
Instance.newClusterInstance("/var/discovery/impl/", "fast3", slowMachine, 
false, 5, 1, 0);
+        assertEquals(1, 
fastMachine3.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(fastMachine3.getSlingId(), 
fastMachine3.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
+        instances.add(fastMachine3);
+        SimpleTopologyEventListener fastListener3 = new 
SimpleTopologyEventListener("fast3");
+        fastMachine3.bindTopologyEventListener(fastListener3);
+        Instance fastMachine4 = 
Instance.newClusterInstance("/var/discovery/impl/", "fast4", slowMachine, 
false, 5, 1, 0);
+        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);
+        
+        HeartbeatHandler hhSlow = slowMachine.getHeartbeatHandler();
+        for(int i=0; i<3; i++) {
+            hhSlow.issueHeartbeat();
+            hhSlow.checkView();
+            if (!scheduler) {
+                fastMachine1.getHeartbeatHandler().issueHeartbeat();
+                fastMachine1.getHeartbeatHandler().checkView();
+                fastMachine2.getHeartbeatHandler().issueHeartbeat();
+                fastMachine2.getHeartbeatHandler().checkView();
+                fastMachine3.getHeartbeatHandler().issueHeartbeat();
+                fastMachine3.getHeartbeatHandler().checkView();
+                fastMachine4.getHeartbeatHandler().issueHeartbeat();
+                fastMachine4.getHeartbeatHandler().checkView();
+            }
+            Thread.sleep(1000);
+        }
+        
+        // at this stage the 4 fast plus the slow instance should all see each 
other
+        assertNotNull(fastListener1.getLastEvent());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
fastListener1.getLastEvent().getType());
+        assertEquals(5, 
fastListener1.getLastEvent().getNewView().getInstances().size());
+        assertNotNull(fastListener2.getLastEvent());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
fastListener2.getLastEvent().getType());
+        assertEquals(5, 
fastListener2.getLastEvent().getNewView().getInstances().size());
+        assertNotNull(fastListener3.getLastEvent());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
fastListener3.getLastEvent().getType());
+        assertEquals(5, 
fastListener3.getLastEvent().getNewView().getInstances().size());
+        assertNotNull(fastListener4.getLastEvent());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
fastListener4.getLastEvent().getType());
+        assertEquals(5, 
fastListener4.getLastEvent().getNewView().getInstances().size());
+        assertNotNull(slowListener.getLastEvent());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
slowListener.getLastEvent().getType());
+        assertEquals(5, 
slowListener.getLastEvent().getNewView().getInstances().size());
+        
+        // after 7sec the slow instance' heartbeat should have timed out
+        for(int i=0; i<7; i++) {
+            if (!scheduler) {
+                fastMachine1.getHeartbeatHandler().issueHeartbeat();
+                fastMachine1.getHeartbeatHandler().checkView();
+                fastMachine2.getHeartbeatHandler().issueHeartbeat();
+                fastMachine2.getHeartbeatHandler().checkView();
+                fastMachine3.getHeartbeatHandler().issueHeartbeat();
+                fastMachine3.getHeartbeatHandler().checkView();
+                fastMachine4.getHeartbeatHandler().issueHeartbeat();
+                fastMachine4.getHeartbeatHandler().checkView();
+            }
+            Thread.sleep(1000);
+        }
+        
+        // so the fast listeners should only see 4 instances remaining
+        for(int i=0; i<5; i++) {
+            Thread.sleep(2000);
+            assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener1.getLastEvent().getType());
+            assertEquals(4, 
fastListener1.getLastEvent().getNewView().getInstances().size());
+            assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener2.getLastEvent().getType());
+            assertEquals(4, 
fastListener2.getLastEvent().getNewView().getInstances().size());
+            assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener3.getLastEvent().getType());
+            assertEquals(4, 
fastListener3.getLastEvent().getNewView().getInstances().size());
+            assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener4.getLastEvent().getType());
+            assertEquals(4, 
fastListener4.getLastEvent().getNewView().getInstances().size());
+
+            // and the slow instance should be isolated
+            
assertFalse(slowMachine.getDiscoveryService().getTopology().isCurrent());
+            assertEquals(5, 
slowMachine.getDiscoveryService().getTopology().getInstances().size());
+            if (i==0) {
+                assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
slowListener.getLastEvent().getType());
+            } else {
+                assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGING, 
slowListener.getLastEvent().getType());
+            }
+            //TODO but only after 'handlePotentialTopologyChange' is called
+            // which either happens via handleTopologyChanged (via the 
TopologyChangeHandler)
+            // or via updateProperties
+            DiscoveryServiceImpl slowDisco = (DiscoveryServiceImpl) 
slowMachine.getDiscoveryService();
+            slowDisco.updateProperties();
+            // that should have triggered an async event - which takes a 
little moment
+            Thread.sleep(200);
+            assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGING, 
slowListener.getLastEvent().getType());
+            assertEquals(2, slowListener.getEventCount());
+            TopologyView slowTopo = 
slowMachine.getDiscoveryService().getTopology();
+            assertNotNull(slowTopo);
+            assertFalse(slowTopo.isCurrent());
+            assertEquals(5, slowTopo.getInstances().size());
+        }
+
+        for(int i=0; i<3; i++) {
+            hhSlow.issueHeartbeat();
+            hhSlow.checkView();
+            if (!scheduler) {
+                fastMachine1.getHeartbeatHandler().issueHeartbeat();
+                fastMachine1.getHeartbeatHandler().checkView();
+                fastMachine2.getHeartbeatHandler().issueHeartbeat();
+                fastMachine2.getHeartbeatHandler().checkView();
+                fastMachine3.getHeartbeatHandler().issueHeartbeat();
+                fastMachine3.getHeartbeatHandler().checkView();
+                fastMachine4.getHeartbeatHandler().issueHeartbeat();
+                fastMachine4.getHeartbeatHandler().checkView();
+            }
+            Thread.sleep(1000);
+        }
+        
+        // now all should be in one cluster again
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener1.getLastEvent().getType());
+        assertEquals(5, 
fastListener1.getLastEvent().getNewView().getInstances().size());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener2.getLastEvent().getType());
+        assertEquals(5, 
fastListener2.getLastEvent().getNewView().getInstances().size());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener3.getLastEvent().getType());
+        assertEquals(5, 
fastListener3.getLastEvent().getNewView().getInstances().size());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener4.getLastEvent().getType());
+        assertEquals(5, 
fastListener4.getLastEvent().getNewView().getInstances().size());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
slowListener.getLastEvent().getType());
+        assertEquals(5, 
slowListener.getLastEvent().getNewView().getInstances().size());
+    }
+    
+    /**
+     * This tests the case where one machine is slow with sending heartbeats
+     * and should thus trigger the second, fast machine to kick it out of the 
topology.
+     * But the slow one should also get a TOPOLOGY_CHANGING but just not get a
+     * TOPOLOGY_CHANGED until it finally sends heartbeats again and the voting 
can 
+     * happen again.
+     */
+    @Test
+    public void testSlowAndFastMachine() throws Throwable {
+        doTestSlowAndFastMachine();
+    }
+
+    @Test
+    public void testSlowAndFastMachineWithFailingScheduler() throws Throwable {
+        installFailingScheduler();
+        doTestSlowAndFastMachine();
+    }
+
+    public void doTestSlowAndFastMachine() throws Throwable {
+        Instance slowMachine = 
Instance.newStandaloneInstance("/var/discovery/impl/", "slow", true, 5 /*5sec 
timeout*/, 
+                999 /* 999sec interval: to disable it*/, 0, 
UUID.randomUUID().toString());
+        instances.add(slowMachine);
+        SimpleTopologyEventListener slowListener = new 
SimpleTopologyEventListener("slow");
+        slowMachine.bindTopologyEventListener(slowListener);
+        Instance fastMachine = 
Instance.newClusterInstance("/var/discovery/impl/", "fast", slowMachine, false, 
5, 999, 0);
+        instances.add(fastMachine);
+        SimpleTopologyEventListener fastListener = new 
SimpleTopologyEventListener("fast");
+        fastMachine.bindTopologyEventListener(fastListener);
+        HeartbeatHandler hhSlow = slowMachine.getHeartbeatHandler();
+        HeartbeatHandler hhFast = fastMachine.getHeartbeatHandler();
+        
+        Thread.sleep(1000);
+        
assertFalse(fastMachine.getDiscoveryService().getTopology().isCurrent());
+        
assertFalse(slowMachine.getDiscoveryService().getTopology().isCurrent());
+        assertNull(fastListener.getLastEvent());
+        assertNull(slowListener.getLastEvent());
+
+        // make few rounds of heartbeats so that the two instances see each 
other
+        for(int i=0; i<5; i++) {
+            hhSlow.issueHeartbeat();
+            hhSlow.checkView();
+            hhFast.issueHeartbeat();
+            hhFast.checkView();
+            Thread.sleep(100);
+        }
+        slowMachine.dumpRepo();
+        
+        assertEquals(2, 
slowMachine.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(2, 
fastMachine.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
fastListener.getLastEvent().getType());
+        assertEquals(1, fastListener.getEventCount());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, 
slowListener.getLastEvent().getType());
+        assertEquals(1, slowListener.getEventCount());
+        
+        // now let the slow machine be slow while the fast one updates as 
expected
+        hhSlow.issueHeartbeat();
+        for(int i=0; i<6; i++) {
+            Thread.sleep(1500);
+            hhFast.issueHeartbeat();
+            hhFast.checkView();
+        }
+        fastMachine.dumpRepo();
+        hhFast.checkView(); // one more for the start of the vote
+        fastMachine.dumpRepo();
+        hhFast.checkView(); // and one for the promotion
+
+        // after 9 sec hhSlow's heartbeat will have timed out, so hhFast will 
not see hhSlow anymore
+        fastMachine.dumpRepo();
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener.getLastEvent().getType());
+        assertEquals(3, fastListener.getEventCount());
+        assertEquals(1, 
fastMachine.getDiscoveryService().getTopology().getInstances().size());
+        
+        TopologyView topo = slowMachine.getDiscoveryService().getTopology();
+        assertFalse(topo.isCurrent());
+        
+        // after those 6 sec, hhSlow does the check (6sec between heartbeat 
and check)
+        hhSlow.checkView();
+        slowMachine.dumpRepo();
+        hhSlow.issueHeartbeat();
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener.getLastEvent().getType());
+        assertEquals(3, fastListener.getEventCount());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGING, 
slowListener.getLastEvent().getType());
+        assertEquals(2, slowListener.getEventCount());
+        Thread.sleep(8000);
+        // even after 8 sec the slow lsitener did not send a TOPOLOGY_CHANGED 
yet
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGING, 
slowListener.getLastEvent().getType());
+        
assertFalse(slowMachine.getDiscoveryService().getTopology().isCurrent());
+        assertEquals(2, slowListener.getEventCount());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener.getLastEvent().getType());
+        assertEquals(1, 
fastMachine.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(3, fastListener.getEventCount());
+        
+        // make few rounds of heartbeats so that the two instances see each 
other again
+        for(int i=0; i<4; i++) {
+            hhFast.issueHeartbeat();
+            hhFast.checkView();
+            hhSlow.issueHeartbeat();
+            hhSlow.checkView();
+            Thread.sleep(1000);
+        }
+        
+        // this should have put the two together again
+        // even after 8 sec the slow lsitener did not send a TOPOLOGY_CHANGED 
yet
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
fastListener.getLastEvent().getType());
+        
assertTrue(fastMachine.getDiscoveryService().getTopology().isCurrent());
+        assertEquals(2, 
fastMachine.getDiscoveryService().getTopology().getInstances().size());
+        assertEquals(5, fastListener.getEventCount());
+        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, 
slowListener.getLastEvent().getType());
+        
assertTrue(slowMachine.getDiscoveryService().getTopology().isCurrent());
+        assertEquals(2, 
slowMachine.getDiscoveryService().getTopology().getInstances().size());
+        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");
+            }
+        });
+    }
+}

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

Modified: 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/Instance.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/Instance.java?rev=1704604&r1=1704603&r2=1704604&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/Instance.java
 (original)
+++ 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/setup/Instance.java
 Tue Sep 22 12:35:19 2015
@@ -64,6 +64,7 @@ import org.apache.sling.discovery.impl.C
 import org.apache.sling.discovery.impl.DiscoveryServiceImpl;
 import org.apache.sling.discovery.impl.cluster.ClusterViewService;
 import org.apache.sling.discovery.impl.cluster.ClusterViewServiceImpl;
+import org.apache.sling.discovery.impl.cluster.UndefinedClusterViewException;
 import org.apache.sling.discovery.impl.cluster.voting.VotingHandler;
 import org.apache.sling.discovery.impl.common.heartbeat.HeartbeatHandler;
 import 
org.apache.sling.discovery.impl.topology.announcement.AnnouncementRegistry;
@@ -94,7 +95,6 @@ public class Instance {
         long heartbeatInterval;
         int minEventDelay;
         List<String> whitelist;
-        private boolean delayInitEventUntilVoted;
 
         @Override
         public long getHeartbeatInterval() {
@@ -148,15 +148,6 @@ public class Instance {
             return 1;
         }
         
-        @Override
-        public boolean isDelayInitEventUntilVoted() {
-            return this.delayInitEventUntilVoted;
-        }
-        
-        public void setDelayInitEventUntilVoted(boolean 
delayInitEventUntilVoted) {
-            this.delayInitEventUntilVoted = delayInitEventUntilVoted;
-        }
-        
     }
 
     private final static Logger logger = 
LoggerFactory.getLogger(Instance.class);
@@ -187,8 +178,17 @@ public class Instance {
     private int serviceId = 999;
 
     private static Scheduler singletonScheduler = null;
+    
+    private static Scheduler scheduler = null;
+    
+    public static void setSingletonScheduler(Scheduler scheduler) throws 
Exception {
+        Instance.scheduler = scheduler;
+    }
 
-    private static Scheduler getSingletonScheduler() throws Exception {
+    public static Scheduler getSingletonScheduler() throws Exception {
+        if (scheduler!=null) {
+            return scheduler;
+        }
        if (singletonScheduler!=null) {
                return singletonScheduler;
        }
@@ -260,7 +260,7 @@ public class Instance {
     private Instance(String debugName,
             ResourceResolverFactory resourceResolverFactory, boolean resetRepo)
             throws Exception {
-       this("/var/discovery/impl/", debugName, resourceResolverFactory, 
resetRepo, 20, 20, 1, UUID.randomUUID().toString(), false);
+       this("/var/discovery/impl/", debugName, resourceResolverFactory, 
resetRepo, 20, 20, 1, UUID.randomUUID().toString());
     }
     
     private class MyEventListener implements EventListener {
@@ -300,7 +300,7 @@ public class Instance {
                         properties.put("path", event.getPath());
                         org.osgi.service.event.Event osgiEvent = new 
org.osgi.service.event.Event(
                                 topic, properties);
-                        logger.info("onEvent: delivering event to listener: 
"+slingId+", stopped: "+stopped+", event: "+osgiEvent);
+                        logger.debug("onEvent: delivering event to listener: 
"+slingId+", stopped: "+stopped+", event: "+osgiEvent);
                         votingHandler.handleEvent(osgiEvent);
                     } catch (RepositoryException e) {
                         logger.warn("RepositoryException: " + e, e);
@@ -323,8 +323,7 @@ public class Instance {
 
     private Instance(String discoveryResourcePath, String debugName,
             ResourceResolverFactory resourceResolverFactory, boolean resetRepo,
-            final int heartbeatTimeout, final int heartbeatInterval, final int 
minEventDelay, String slingId,
-            boolean delayInitEventUntilVoted)
+            final int heartbeatTimeout, final int heartbeatInterval, final int 
minEventDelay, String slingId)
             throws Exception {
        this.slingId = slingId;
         this.debugName = debugName;
@@ -339,7 +338,6 @@ public class Instance {
         config.setHeartbeatInterval(heartbeatInterval);
         config.setMinEventDelay(minEventDelay);
         config.addTopologyConnectorWhitelistEntry("127.0.0.1");
-        config.setDelayInitEventUntilVoted(delayInitEventUntilVoted);
 
         PrivateAccessor.setField(config, "discoveryResourcePath", 
discoveryResourcePath);
 
@@ -407,38 +405,31 @@ public class Instance {
     }
 
     public static Instance newStandaloneInstance(String discoveryResourcePath, 
String debugName,
-            boolean resetRepo, int heartbeatTimeout, int minEventDelay, String 
slingId, boolean delayInitEventUntilVoted) throws Exception {
+            boolean resetRepo, int heartbeatTimeout, int minEventDelay, String 
slingId) throws Exception {
         ResourceResolverFactory resourceResolverFactory = MockFactory
                 .mockResourceResolverFactory();
-        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
slingId, delayInitEventUntilVoted);
+        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
slingId);
     }
     
     public static Instance newStandaloneInstance(String discoveryResourcePath, 
String debugName,
-            boolean resetRepo, int heartbeatTimeout, int heartbeatInterval, 
int minEventDelay, String slingId, boolean delayInitEventUntilVoted) throws 
Exception {
-        ResourceResolverFactory resourceResolverFactory = MockFactory
-                .mockResourceResolverFactory();
-        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, heartbeatInterval, 
minEventDelay, slingId, delayInitEventUntilVoted);
-    }
-
-    public static Instance newStandaloneInstance(String discoveryResourcePath, 
String debugName,
-            boolean resetRepo, int heartbeatTimeout, int minEventDelay, String 
slingId) throws Exception {
+            boolean resetRepo, int heartbeatTimeout, int heartbeatInterval, 
int minEventDelay, String slingId) throws Exception {
         ResourceResolverFactory resourceResolverFactory = MockFactory
                 .mockResourceResolverFactory();
-        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
slingId, false);
+        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, heartbeatInterval, 
minEventDelay, slingId);
     }
 
     public static Instance newStandaloneInstance(String discoveryResourcePath, 
String debugName,
             boolean resetRepo, int heartbeatTimeout, int minEventDelay) throws 
Exception {
         ResourceResolverFactory resourceResolverFactory = MockFactory
                 .mockResourceResolverFactory();
-        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
UUID.randomUUID().toString(), false);
+        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
UUID.randomUUID().toString());
     }
 
     public static Instance newStandaloneInstance(String discoveryResourcePath, 
String debugName,
             boolean resetRepo, int heartbeatTimeout, int heartbeatInterval, 
int minEventDelay) throws Exception {
         ResourceResolverFactory resourceResolverFactory = MockFactory
                 .mockResourceResolverFactory();
-        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, heartbeatInterval, 
minEventDelay, UUID.randomUUID().toString(), false);
+        return new Instance(discoveryResourcePath, debugName, 
resourceResolverFactory, resetRepo, heartbeatTimeout, heartbeatInterval, 
minEventDelay, UUID.randomUUID().toString());
     }
 
     public static Instance newStandaloneInstance(String debugName,
@@ -449,23 +440,18 @@ public class Instance {
     }
 
     public static Instance newClusterInstance(String discoveryResourcePath, 
String debugName, Instance other,
-            boolean resetRepo, int heartbeatTimeout, int minEventDelay, String 
slingId, boolean delayInitEventUntilVoted) throws Exception {
-        return new Instance(discoveryResourcePath, debugName, 
other.resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
slingId, delayInitEventUntilVoted);
-    }
-
-    public static Instance newClusterInstance(String discoveryResourcePath, 
String debugName, Instance other,
             boolean resetRepo, int heartbeatTimeout, int minEventDelay, String 
slingId) throws Exception {
-        return new Instance(discoveryResourcePath, debugName, 
other.resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
slingId, false);
+        return new Instance(discoveryResourcePath, debugName, 
other.resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
slingId);
     }
 
     public static Instance newClusterInstance(String discoveryResourcePath, 
String debugName, Instance other,
             boolean resetRepo, int heartbeatTimeout, int minEventDelay) throws 
Exception {
-        return new Instance(discoveryResourcePath, debugName, 
other.resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
UUID.randomUUID().toString(), false);
+        return new Instance(discoveryResourcePath, debugName, 
other.resourceResolverFactory, resetRepo, heartbeatTimeout, 20, minEventDelay, 
UUID.randomUUID().toString());
     }
 
     public static Instance newClusterInstance(String discoveryResourcePath, 
String debugName, Instance other,
             boolean resetRepo, int heartbeatTimeout, int heartbeatInterval, 
int minEventDelay) throws Exception {
-        return new Instance(discoveryResourcePath, debugName, 
other.resourceResolverFactory, resetRepo, heartbeatTimeout, heartbeatInterval, 
minEventDelay, UUID.randomUUID().toString(), false);
+        return new Instance(discoveryResourcePath, debugName, 
other.resourceResolverFactory, resetRepo, heartbeatTimeout, heartbeatInterval, 
minEventDelay, UUID.randomUUID().toString());
     }
 
     public static Instance newClusterInstance(String debugName, Instance other,
@@ -550,7 +536,7 @@ public class Instance {
         return connectorRegistry.registerOutgoingConnector(clusterViewService, 
new URL(url));
     }
 
-    public InstanceDescription getLocalInstanceDescription() {
+    public InstanceDescription getLocalInstanceDescription() throws 
UndefinedClusterViewException {
        final Iterator<InstanceDescription> it = 
getClusterViewService().getClusterView().getInstances().iterator();
        while(it.hasNext()) {
                final InstanceDescription id = it.next();
@@ -695,4 +681,11 @@ public class Instance {
         return config;
     }
 
+    public HeartbeatHandler getHeartbeatHandler() {
+        return heartbeatHandler;
+    }
+    
+    public void installVotingOnHeartbeatHandler() throws NoSuchFieldException {
+        PrivateAccessor.setField(heartbeatHandler, "votingHandler", 
votingHandler);
+    }
 }

Modified: 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/LargeTopologyWithHubTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/LargeTopologyWithHubTest.java?rev=1704604&r1=1704603&r2=1704604&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/LargeTopologyWithHubTest.java
 (original)
+++ 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/LargeTopologyWithHubTest.java
 Tue Sep 22 12:35:19 2015
@@ -18,12 +18,15 @@
  */
 package org.apache.sling.discovery.impl.topology;
 
+import static org.junit.Assert.assertNotNull;
+
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.sling.commons.testing.junit.Retry;
 import org.apache.sling.commons.testing.junit.RetryRule;
+import org.apache.sling.discovery.ClusterView;
 import org.apache.sling.discovery.TopologyView;
 import org.apache.sling.discovery.impl.setup.Instance;
 import org.apache.sling.testing.tools.sling.TimeoutsProvider;
@@ -41,7 +44,7 @@ public class LargeTopologyWithHubTest {
     private static List<Instance> instances;
     private static Instance hub;
     private static List<String> slingIds;
-    private static final int TEST_SIZE = 100;
+    private static final int TEST_SIZE = 50;
     
     @Rule
     public final RetryRule retryRule = new RetryRule();
@@ -51,8 +54,14 @@ public class LargeTopologyWithHubTest {
         instances = new LinkedList<Instance>();
         final int defaultHeartbeatTimeout = 3600; // 1 hour should be enough, 
really
         final int heartbeatTimeout = 
TimeoutsProvider.getInstance().getTimeout(defaultHeartbeatTimeout);
-        hub = TopologyTestHelper.createInstance(instances, 
"/var/discovery/impl/hub/", "hub", heartbeatTimeout, 1000, 1);
+        hub = TopologyTestHelper.createInstance(instances, 
"/var/discovery/impl/hub/", "hub", true, heartbeatTimeout, 5, 1);
         hub.getConfig().setHeartbeatTimeout(heartbeatTimeout);
+        hub.installVotingOnHeartbeatHandler();
+        hub.runHeartbeatOnce();
+        hub.runHeartbeatOnce();
+        assertNotNull(hub.getClusterViewService().getClusterView());
+        hub.startHeartbeats(1);
+        hub.dumpRepo();
         
         slingIds = new LinkedList<String>();
         slingIds.add(hub.getSlingId());
@@ -60,8 +69,13 @@ public class LargeTopologyWithHubTest {
                 + "(default: "+defaultHeartbeatTimeout+")");
         for(int i=0; i<TEST_SIZE; i++) {
             logger.info("setUp: creating instance"+i);
-            Instance instance = TopologyTestHelper.createInstance(instances, 
"/var/discovery/impl/i"+i+"/", "instance"+i, heartbeatTimeout, 10, 1);
+            Instance instance = TopologyTestHelper.createInstance(instances, 
"/var/discovery/impl/i"+i+"/", "instance"+i, false, heartbeatTimeout, 5, 1);
             instance.getConfig().setHeartbeatTimeout(heartbeatTimeout);
+            instance.installVotingOnHeartbeatHandler();
+            instance.runHeartbeatOnce();
+            instance.runHeartbeatOnce();
+            ClusterView clusterView = 
instance.getClusterViewService().getClusterView();
+            assertNotNull(clusterView);
             new Connector(instance, hub);
             slingIds.add(instance.getSlingId());
         }
@@ -80,6 +94,7 @@ public class LargeTopologyWithHubTest {
     public void testLargeTopologyWithHub() throws Exception {
         hub.dumpRepo();
         final TopologyView tv = hub.getDiscoveryService().getTopology();
+        assertNotNull(tv);
         logger.info(
                 "testLargeTopologyWithHub: checking if all connectors are 
registered, TopologyView has {} Instances", 
                 tv.getInstances().size());

Modified: 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTest.java?rev=1704604&r1=1704603&r2=1704604&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTest.java
 (original)
+++ 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTest.java
 Tue Sep 22 12:35:19 2015
@@ -50,13 +50,19 @@ public class TopologyTest {
     
     @Test
     public void testTwoNodes() throws Throwable {
-        Instance instance1 = TopologyTestHelper.createInstance(instances, 
"instance1");
-        Instance instance2 = TopologyTestHelper.createInstance(instances, 
"instance2");
+        Instance instance1 = TopologyTestHelper.createInstance(instances, 
"/var/discovery/impl1/", "instance1", true, 200, 20, 1);
+        Instance instance2 = TopologyTestHelper.createInstance(instances, 
"/var/discovery/impl2/", "instance2", false, 200, 20, 1);
         instance1.getConfig().setHeartbeatTimeout(8);
         instance1.getConfig().setHeartbeatInterval(1);
         instance2.getConfig().setHeartbeatTimeout(2);
         instance2.getConfig().setHeartbeatInterval(1);
         
+        for(int i=0; i<5; i++) {
+            instance1.runHeartbeatOnce();
+            instance2.runHeartbeatOnce();
+            Thread.sleep(500);
+        }
+        
         Set<InstanceDescription> instances1 = 
instance1.getDiscoveryService().getTopology().getInstances();
         Set<InstanceDescription> instances2 = 
instance2.getDiscoveryService().getTopology().getInstances();
         

Modified: 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTestHelper.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTestHelper.java?rev=1704604&r1=1704603&r2=1704604&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTestHelper.java
 (original)
+++ 
sling/trunk/bundles/extensions/discovery/impl/src/test/java/org/apache/sling/discovery/impl/topology/TopologyTestHelper.java
 Tue Sep 22 12:35:19 2015
@@ -147,8 +147,8 @@ public class TopologyTestHelper {
     }
 
     public static Instance createInstance(Collection<Instance> instances, 
String discoveryResourcePath, String debugName,
-            int heartbeatTimeout, int heartbeatInterval, int minEventDelay) 
throws Exception {
-        final Instance instance = 
Instance.newStandaloneInstance(discoveryResourcePath, debugName, true, 
heartbeatTimeout, heartbeatInterval, minEventDelay);
+            boolean resetRepo, int heartbeatTimeout, int heartbeatInterval, 
int minEventDelay) throws Exception {
+        final Instance instance = 
Instance.newStandaloneInstance(discoveryResourcePath, debugName, resetRepo, 
heartbeatTimeout, heartbeatInterval, minEventDelay);
         instances.add(instance);
         return instance;
     }


Reply via email to