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; }