You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by st...@apache.org on 2015/10/20 16:12:34 UTC
svn commit: r1709601 [6/11] - in /sling/trunk/bundles/extensions/discovery:
base/ base/src/ base/src/main/ base/src/main/java/ base/src/main/java/org/
base/src/main/java/org/apache/ base/src/main/java/org/apache/sling/
base/src/main/java/org/apache/sli...
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/AbstractTopologyEventTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/AbstractTopologyEventTest.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/AbstractTopologyEventTest.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/AbstractTopologyEventTest.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,252 @@
+/*
+ * 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.base.its;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEvent.Type;
+import org.apache.sling.discovery.TopologyView;
+import org.apache.sling.discovery.base.its.setup.VirtualInstance;
+import org.apache.sling.discovery.base.its.setup.VirtualInstanceBuilder;
+import org.apache.sling.discovery.base.its.setup.mock.AssertingTopologyEventListener;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test class covering correct sending of TopologyEvents
+ * in various scenarios (which are not covered in other tests already).
+ */
+public abstract class AbstractTopologyEventTest {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private VirtualInstance instance1;
+ private VirtualInstance instance2;
+
+ private Level logLevel;
+
+ @Before
+ public void setup() throws Exception {
+ final org.apache.log4j.Logger discoveryLogger = LogManager.getRootLogger().getLogger("org.apache.sling.discovery");
+ logLevel = discoveryLogger.getLevel();
+ discoveryLogger.setLevel(Level.DEBUG);
+ }
+
+ @After
+ public void tearDown() throws Throwable {
+ if (instance1!=null) {
+ instance1.stopViewChecker();
+ instance1.stop();
+ instance1 = null;
+ }
+ if (instance2!=null) {
+ instance2.stopViewChecker();
+ instance2.stop();
+ instance2 = null;
+ }
+ final org.apache.log4j.Logger discoveryLogger = LogManager.getRootLogger().getLogger("org.apache.sling.discovery");
+ discoveryLogger.setLevel(logLevel);
+ }
+
+ public abstract VirtualInstanceBuilder newBuilder();
+
+ /**
+ * 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
+ public void testDelayedInitEvent() throws Throwable {
+ logger.info("testDelayedInitEvent: start");
+ instance1 = newBuilder().setDebugName("firstInstanceA")
+ .newRepository("/var/discovery/impl/", true)
+ .setConnectorPingTimeout(3 /* heartbeat-timeout */)
+ .setMinEventDelay(3 /*min event delay*/).build();
+ AssertingTopologyEventListener l1 = new AssertingTopologyEventListener("instance1.l1");
+ instance1.bindTopologyEventListener(l1);
+ logger.info("testDelayedInitEvent: instance1 created, no events expected yet. slingId="+instance1.slingId);
+
+ // should not have received any events yet
+ assertEquals(0, l1.getEvents().size());
+ assertEquals(0, l1.getUnexpectedCount());
+
+ // one heartbeat doesn't make a day yet - and is 2sec too early for the init
+ instance1.heartbeatsAndCheckView();
+ Thread.sleep(1200);
+ logger.info("testDelayedInitEvent: even after 500ms no events expected, as it needs more than 1 heartbeat");
+ // should not have received any events yet
+ assertEquals(0, l1.getEvents().size());
+ assertEquals(0, l1.getUnexpectedCount());
+
+ // but two are a good start
+ l1.addExpected(Type.TOPOLOGY_INIT);
+ instance1.heartbeatsAndCheckView();
+ Thread.sleep(1200);
+ instance1.heartbeatsAndCheckView();
+ Thread.sleep(1200);
+ logger.info("testDelayedInitEvent: 2nd/3rd heartbeat sent - now expecting a TOPOLOGY_INIT");
+ instance1.dumpRepo();
+ assertEquals(1, l1.getEvents().size()); // one event
+ assertEquals(0, l1.getRemainingExpectedCount()); // the expected one
+ assertEquals(0, l1.getUnexpectedCount());
+
+ logger.info("testDelayedInitEvent: creating instance2");
+ instance2 = newBuilder().setDebugName("secondInstanceB")
+ .useRepositoryOf(instance1)
+ .setConnectorPingTimeout(20)
+ .setMinEventDelay(3).build();
+ logger.info("testDelayedInitEvent: instance2 created with slingId="+instance2.slingId);
+ AssertingTopologyEventListener l2 = new AssertingTopologyEventListener("instance2.l2");
+ instance2.bindTopologyEventListener(l2);
+ logger.info("testDelayedInitEvent: listener instance2.l2 added - it should not get any events though");
+ AssertingTopologyEventListener l1Two = new AssertingTopologyEventListener("instance1.l1Two");
+ l1Two.addExpected(Type.TOPOLOGY_INIT);
+ logger.info("testDelayedInitEvent: listener instance1.l1Two added - it expects an INIT now");
+ 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(0, l2.getEvents().size());
+ assertEquals(0, l2.getUnexpectedCount());
+ assertEquals(1, l1Two.getEvents().size());
+ assertEquals(0, l1Two.getRemainingExpectedCount()); // the expected one
+ assertEquals(0, l1Two.getUnexpectedCount());
+
+
+ // the second & third heartbeat though triggers the voting etc
+ logger.info("testDelayedInitEvent: two more heartbeats should trigger events");
+ l1.addExpected(Type.TOPOLOGY_CHANGING);
+ l1Two.addExpected(Type.TOPOLOGY_CHANGING);
+ Thread.sleep(500);
+ l2.addExpected(Type.TOPOLOGY_INIT);
+ instance1.heartbeatsAndCheckView();
+ instance2.heartbeatsAndCheckView();
+ Thread.sleep(500);
+ instance1.heartbeatsAndCheckView();
+ instance2.heartbeatsAndCheckView();
+ Thread.sleep(500);
+ instance1.heartbeatsAndCheckView();
+ instance2.heartbeatsAndCheckView();
+ logger.info("testDelayedInitEvent: instance1: "+instance1.slingId);
+ logger.info("testDelayedInitEvent: instance2: "+instance2.slingId);
+ instance1.dumpRepo();
+ assertEquals(0, l1.getUnexpectedCount());
+ assertEquals(2, l1.getEvents().size());
+ assertEquals(0, l2.getUnexpectedCount());
+ assertEquals(1, l2.getEvents().size());
+ assertEquals(0, l1Two.getUnexpectedCount());
+ assertEquals(2, l1Two.getEvents().size());
+
+ // wait until CHANGED is sent - which is 3 sec after CHANGING
+ l1.addExpected(Type.TOPOLOGY_CHANGED);
+ l1Two.addExpected(Type.TOPOLOGY_CHANGED);
+ Thread.sleep(4000);
+ assertEquals(0, l1.getUnexpectedCount());
+ assertEquals(3, l1.getEvents().size()); // one event
+ assertEquals(0, l2.getUnexpectedCount());
+ assertEquals(1, l2.getEvents().size());
+ assertEquals(0, l1Two.getUnexpectedCount());
+ assertEquals(3, l1Two.getEvents().size());
+ logger.info("testDelayedInitEvent: end");
+ }
+
+ @Test
+ public void testGetDuringDelay() throws Throwable {
+ instance1 = newBuilder().setDebugName("firstInstanceA")
+ .newRepository("/var/discovery/impl/", true)
+ .setConnectorPingTimeout(20 /* heartbeat-timeout */)
+ .setMinEventDelay(6 /* min event delay */).build();
+ AssertingTopologyEventListener l1 = new AssertingTopologyEventListener("instance1.l1");
+ l1.addExpected(TopologyEvent.Type.TOPOLOGY_INIT);
+ instance1.bindTopologyEventListener(l1);
+
+ TopologyView earlyTopo = instance1.getDiscoveryService().getTopology();
+ assertNotNull(earlyTopo);
+ assertFalse(earlyTopo.isCurrent());
+ assertEquals(1, earlyTopo.getInstances().size());
+
+ for(int i=0; i<4; i++) {
+ instance1.heartbeatsAndCheckView();
+ 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();
+
+ assertEarlyAndFirstClusterViewIdMatches(earlyTopo, secondTopo);
+
+ 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 = newBuilder().setDebugName("secondInstanceB")
+ .useRepositoryOf(instance1)
+ .setConnectorPingTimeout(20)
+ .setMinEventDelay(1).build();
+ AssertingTopologyEventListener l2 = new AssertingTopologyEventListener("instance2.l1");
+ l2.addExpected(TopologyEvent.Type.TOPOLOGY_INIT);
+ instance2.bindTopologyEventListener(l2);
+
+ for(int i=0; i<4; i++) {
+ instance2.heartbeatsAndCheckView();
+ instance1.heartbeatsAndCheckView();
+ Thread.sleep(750);
+ }
+
+ assertEquals(0, l1.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());
+
+ l1.addExpected(TopologyEvent.Type.TOPOLOGY_CHANGED);
+ Thread.sleep(5000);
+ assertEquals(0, l1.getRemainingExpectedCount());
+ assertEquals(0, l1.getUnexpectedCount());
+ assertEquals(0, l2.getRemainingExpectedCount());
+ assertEquals(0, l2.getUnexpectedCount());
+ assertTrue(instance2.getDiscoveryService().getTopology().isCurrent());
+ assertEquals(2, instance2.getDiscoveryService().getTopology().getInstances().size());
+ assertTrue(instance1.getDiscoveryService().getTopology().isCurrent());
+ assertEquals(2, instance1.getDiscoveryService().getTopology().getInstances().size());
+ }
+
+ public abstract void assertEarlyAndFirstClusterViewIdMatches(TopologyView earlyTopo, TopologyView secondTopo);
+
+}
\ No newline at end of file
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/AbstractTopologyEventTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/TopologyTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/TopologyTest.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/TopologyTest.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/TopologyTest.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,150 @@
+/*
+ * 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.base.its;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.sling.discovery.InstanceDescription;
+import org.apache.sling.discovery.base.connectors.DummyVirtualInstanceBuilder;
+import org.apache.sling.discovery.base.connectors.announcement.Announcement;
+import org.apache.sling.discovery.base.its.setup.TopologyHelper;
+import org.apache.sling.discovery.base.its.setup.VirtualConnector;
+import org.apache.sling.discovery.base.its.setup.VirtualInstance;
+import org.apache.sling.discovery.base.its.setup.VirtualInstanceBuilder;
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TopologyTest {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final List<VirtualInstance> instances = new LinkedList<VirtualInstance>();
+
+ private VirtualInstanceBuilder newBuilder() {
+ return new DummyVirtualInstanceBuilder();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ for (Iterator<VirtualInstance> it = instances.iterator(); it.hasNext();) {
+ final VirtualInstance instance = it.next();
+ instance.stop();
+ }
+ }
+
+ @Test
+ public void testTwoNodes() throws Throwable {
+ VirtualInstanceBuilder builder1 = newBuilder()
+ .newRepository("/var/discovery/impl/", true)
+ .setDebugName("instance1")
+ .setConnectorPingInterval(20)
+ .setConnectorPingTimeout(200);
+ VirtualInstance instance1 = builder1.build();
+ instances.add(instance1);
+ VirtualInstanceBuilder builder2 = newBuilder()
+ .useRepositoryOf(builder1)
+ .setDebugName("instance2")
+ .setConnectorPingInterval(20)
+ .setConnectorPingTimeout(200);
+ VirtualInstance instance2 = builder2.build();
+ instances.add(instance2);
+ instance1.getConfig().setViewCheckTimeout(8);
+ instance1.getConfig().setViewCheckInterval(1);
+ instance2.getConfig().setViewCheckTimeout(2);
+ instance2.getConfig().setViewCheckInterval(1);
+
+ for(int i=0; i<5; i++) {
+ instance1.heartbeatsAndCheckView();
+ instance2.heartbeatsAndCheckView();
+ Thread.sleep(500);
+ }
+
+ Set<InstanceDescription> instances1 = instance1.getDiscoveryService().getTopology().getInstances();
+ Set<InstanceDescription> instances2 = instance2.getDiscoveryService().getTopology().getInstances();
+
+ assertEquals(1, instances1.size());
+ assertEquals(1, instances2.size());
+ assertEquals(instance1.getSlingId(), instances1.iterator().next().getSlingId());
+ assertEquals(instance2.getSlingId(), instances2.iterator().next().getSlingId());
+
+ new VirtualConnector(instance1, instance2);
+
+ // check instance 1's announcements
+ Collection<Announcement> instance1LocalAnnouncements =
+ instance1.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(1, instance1LocalAnnouncements.size());
+ Announcement instance1LocalAnnouncement = instance1LocalAnnouncements.iterator().next();
+ assertEquals(instance2.getSlingId(), instance1LocalAnnouncement.getOwnerId());
+ assertEquals(true, instance1LocalAnnouncement.isInherited());
+
+ // check instance 2's announcements
+ Collection<Announcement> instance2LocalAnnouncements =
+ instance2.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(1, instance2LocalAnnouncements.size());
+ Announcement instance2LocalAnnouncement = instance2LocalAnnouncements.iterator().next();
+ assertEquals(instance1.getSlingId(), instance2LocalAnnouncement.getOwnerId());
+ assertEquals(false, instance2LocalAnnouncement.isInherited());
+
+ // check topology
+ TopologyHelper.assertTopologyConsistsOf(instance1.getDiscoveryService().getTopology(), instance1.getSlingId(), instance2.getSlingId());
+ TopologyHelper.assertTopologyConsistsOf(instance2.getDiscoveryService().getTopology(), instance1.getSlingId(), instance2.getSlingId());
+
+ instance1LocalAnnouncements =
+ instance1.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(1, instance1LocalAnnouncements.size());
+ instance2LocalAnnouncements =
+ instance2.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(1, instance2LocalAnnouncements.size());
+
+ Thread.sleep(2200); // sleep of 2.2sec ensures instance2's heartbeat timeout (which is 2sec) hits
+
+ instance1LocalAnnouncements =
+ instance1.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(1, instance1LocalAnnouncements.size());
+ instance2LocalAnnouncements =
+ instance2.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(0, instance2LocalAnnouncements.size());
+
+ logger.info("testTwoNodes: instance1: "+instance1.getSlingId());
+ instance1.dumpRepo();
+ logger.info("testTwoNodes: instance2: "+instance2.getSlingId());
+ instance2.dumpRepo();
+ TopologyHelper.assertTopologyConsistsOf(instance1.getDiscoveryService().getTopology(), instance1.getSlingId(), instance2.getSlingId());
+ TopologyHelper.assertTopologyConsistsOf(instance2.getDiscoveryService().getTopology(), instance2.getSlingId());
+
+ Thread.sleep(6000); // another sleep 6s (2.2+6 = 8.2sec) ensures instance1's heartbeat timeout (which is 8sec) hits as well
+ instance1LocalAnnouncements =
+ instance1.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(0, instance1LocalAnnouncements.size());
+ instance2LocalAnnouncements =
+ instance2.getAnnouncementRegistry().listLocalAnnouncements();
+ assertEquals(0, instance2LocalAnnouncements.size());
+
+ TopologyHelper.assertTopologyConsistsOf(instance1.getDiscoveryService().getTopology(), instance1.getSlingId());
+ TopologyHelper.assertTopologyConsistsOf(instance2.getDiscoveryService().getTopology(), instance2.getSlingId());
+ }
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/TopologyTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/ModifiableTestBaseConfig.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/ModifiableTestBaseConfig.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/ModifiableTestBaseConfig.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/ModifiableTestBaseConfig.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,37 @@
+/*
+ * 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.base.its.setup;
+
+import org.apache.sling.discovery.base.connectors.BaseConfig;
+
+/**
+ * test extension of the BaseConfig that allows setting some
+ * parameters in test classes
+ */
+public interface ModifiableTestBaseConfig extends BaseConfig {
+
+ void addTopologyConnectorWhitelistEntry(String string);
+
+ void setMinEventDelay(int minEventDelay);
+
+ void setViewCheckTimeout(int viewCheckTimeout);
+
+ void setViewCheckInterval(int viewCheckInterval);
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/ModifiableTestBaseConfig.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/OSGiMock.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/OSGiMock.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/OSGiMock.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/OSGiMock.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,124 @@
+/*
+ * 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.base.its.setup;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.sling.discovery.base.its.setup.mock.MockFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OSGiMock {
+
+ private static final Logger logger = LoggerFactory.getLogger(OSGiMock.class);
+
+ private final List<Object> services = new LinkedList<Object>();
+
+ public void addService(Object service) {
+ if (service==null) {
+ throw new IllegalArgumentException("service must not be null");
+ }
+ services.add(service);
+ }
+
+ public void activateAll() throws Exception {
+ for (@SuppressWarnings("rawtypes")
+ Iterator it = services.iterator(); it.hasNext();) {
+ Object aService = it.next();
+
+ activate(aService);
+ }
+ }
+
+ public static void activate(Object aService) throws IllegalAccessException,
+ InvocationTargetException {
+ Class<?> clazz = aService.getClass();
+ while (clazz != null) {
+ Method[] methods = clazz.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (method.getName().equals("activate")) {
+ method.setAccessible(true);
+ if ( method.getParameterTypes().length == 0 ) {
+ logger.info("activate: activating "+aService+"...");
+ method.invoke(aService, null);
+ logger.info("activate: activating "+aService+" done.");
+ } else if (method.getParameterTypes().length==1 && (method.getParameterTypes()[0]==ComponentContext.class)){
+ logger.info("activate: activating "+aService+"...");
+ method.invoke(aService, MockFactory.mockComponentContext());
+ logger.info("activate: activating "+aService+" done.");
+ } else if (method.getParameterTypes().length==1 && (method.getParameterTypes()[0]==BundleContext.class)){
+ logger.info("activate: activating "+aService+"...");
+ method.invoke(aService, MockFactory.mockBundleContext());
+ logger.info("activate: activating "+aService+" done.");
+ } else {
+ throw new IllegalStateException("unsupported activate variant: "+method);
+ }
+ return;
+ }
+ }
+ clazz = clazz.getSuperclass();
+ }
+ }
+
+ public void deactivateAll() throws Exception {
+ for (@SuppressWarnings("rawtypes")
+ Iterator it = services.iterator(); it.hasNext();) {
+ Object aService = it.next();
+
+ deactivate(aService);
+ }
+ }
+
+ public static void deactivate(Object aService) throws IllegalAccessException,
+ InvocationTargetException {
+ Class<?> clazz = aService.getClass();
+ while (clazz != null) {
+ Method[] methods = clazz.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (method.getName().equals("deactivate")) {
+ method.setAccessible(true);
+ if ( method.getParameterTypes().length == 0 ) {
+ method.invoke(aService, null);
+ } else {
+ method.invoke(aService, MockFactory.mockComponentContext());
+ }
+ return;
+ }
+ }
+ clazz = clazz.getSuperclass();
+ }
+ }
+
+ public void addServices(Object[] additionalServices) {
+ if (additionalServices==null) {
+ return;
+ }
+ for (Object additionalService : additionalServices) {
+ addService(additionalService);
+ }
+ }
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/OSGiMock.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/TopologyHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/TopologyHelper.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/TopologyHelper.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/TopologyHelper.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,145 @@
+/*
+ * 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.base.its.setup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.sling.discovery.ClusterView;
+import org.apache.sling.discovery.InstanceDescription;
+import org.apache.sling.discovery.TopologyView;
+import org.apache.sling.discovery.base.commons.DefaultTopologyView;
+import org.apache.sling.discovery.commons.providers.DefaultClusterView;
+import org.apache.sling.discovery.commons.providers.DefaultInstanceDescription;
+
+import junitx.util.PrivateAccessor;
+
+public class TopologyHelper {
+
+ public static DefaultInstanceDescription createInstanceDescription(
+ ClusterView clusterView) {
+ return createInstanceDescription(UUID.randomUUID().toString(), false, clusterView);
+ }
+
+ public static DefaultInstanceDescription createInstanceDescription(
+ String instanceId, boolean isLocal, ClusterView clusterView) {
+ if (!(clusterView instanceof DefaultClusterView)) {
+ throw new IllegalArgumentException(
+ "Must pass a clusterView of type "
+ + DefaultClusterView.class);
+ }
+ DefaultInstanceDescription i = new DefaultInstanceDescription(
+ (DefaultClusterView) clusterView, false, isLocal, instanceId, new HashMap<String, String>());
+ return i;
+ }
+
+ public static DefaultTopologyView createTopologyView(String clusterViewId,
+ String slingId) {
+ DefaultTopologyView t = new DefaultTopologyView();
+ DefaultClusterView c = new DefaultClusterView(clusterViewId);
+ DefaultInstanceDescription i = new DefaultInstanceDescription(
+ c, true, false, slingId, new HashMap<String, String>());
+ Collection<InstanceDescription> instances = new LinkedList<InstanceDescription>();
+ instances.add(i);
+ t.addInstances(instances);
+ return t;
+ }
+
+ public static DefaultTopologyView cloneTopologyView(DefaultTopologyView original) {
+ DefaultTopologyView t = new DefaultTopologyView();
+ Iterator<ClusterView> it = original.getClusterViews().iterator();
+ while (it.hasNext()) {
+ DefaultClusterView c = (DefaultClusterView) it.next();
+ t.addInstances(clone(c).getInstances());
+ }
+ return t;
+ }
+
+ public static DefaultClusterView clone(DefaultClusterView original) {
+ DefaultClusterView c = new DefaultClusterView(original.getId());
+ Iterator<InstanceDescription> it = original.getInstances().iterator();
+ while (it.hasNext()) {
+ DefaultInstanceDescription id = (DefaultInstanceDescription) it
+ .next();
+ c.addInstanceDescription(cloneWOClusterView(id));
+ }
+ return c;
+ }
+
+ public static DefaultInstanceDescription cloneWOClusterView(
+ DefaultInstanceDescription original) {
+ DefaultInstanceDescription id = new DefaultInstanceDescription(
+ null, original.isLeader(), original.isLocal(),
+ original.getSlingId(), new HashMap<String, String>(
+ original.getProperties()));
+ return id;
+ }
+
+ public static DefaultInstanceDescription createAndAddInstanceDescription(
+ DefaultTopologyView newView, ClusterView clusterView) {
+ DefaultInstanceDescription i = createInstanceDescription(clusterView);
+ return addInstanceDescription(newView, i);
+ }
+
+ public static DefaultInstanceDescription addInstanceDescription(
+ DefaultTopologyView newView, DefaultInstanceDescription i) {
+ Collection<InstanceDescription> instances = new LinkedList<InstanceDescription>();
+ instances.add(i);
+ newView.addInstances(instances);
+ return i;
+ }
+
+ public static DefaultTopologyView cloneTopologyView(DefaultTopologyView view,
+ String newLeader) throws NoSuchFieldException {
+ final DefaultTopologyView clone = cloneTopologyView(view);
+ final DefaultClusterView cluster = (DefaultClusterView) clone.getClusterViews().iterator().next();
+ for (Iterator it = cluster.getInstances().iterator(); it.hasNext();) {
+ DefaultInstanceDescription id = (DefaultInstanceDescription) it.next();
+ PrivateAccessor.setField(id, "isLeader", id.getSlingId().equals(newLeader));
+ }
+ return clone;
+ }
+
+ public static void assertTopologyConsistsOf(TopologyView topology, String... slingIds) {
+ assertNotNull(topology);
+ assertEquals(slingIds.length, topology.getInstances().size());
+ for(int i=0; i<slingIds.length; i++) {
+ final String aSlingId = slingIds[i];
+ final Set<?> instances = topology.getInstances();
+ boolean found = false;
+ for (Iterator<?> it = instances.iterator(); it.hasNext();) {
+ InstanceDescription anInstance = (InstanceDescription) it.next();
+ if (anInstance.getSlingId().equals(aSlingId)) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found);
+ }
+ }
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/TopologyHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualConnector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualConnector.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualConnector.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualConnector.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,39 @@
+/*
+ * 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.base.its.setup;
+
+import org.apache.sling.discovery.base.connectors.ping.TopologyConnectorClientInformation;
+
+public class VirtualConnector {
+ @SuppressWarnings("unused")
+ private final VirtualInstance from;
+ @SuppressWarnings("unused")
+ private final VirtualInstance to;
+ private final int jettyPort;
+ @SuppressWarnings("unused")
+ private final TopologyConnectorClientInformation connectorInfo;
+
+ public VirtualConnector(VirtualInstance from, VirtualInstance to) throws Throwable {
+ this.from = from;
+ this.to = to;
+ to.startJetty();
+ this.jettyPort = to.getJettyPort();
+ this.connectorInfo = from.connectTo("http://localhost:"+jettyPort+"/system/console/topology/connector");
+ }
+}
\ No newline at end of file
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualConnector.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstance.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstance.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstance.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstance.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,374 @@
+/*
+ * 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.base.its.setup;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.jcr.Session;
+import javax.servlet.Servlet;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.commons.testing.jcr.RepositoryProvider;
+import org.apache.sling.discovery.InstanceDescription;
+import org.apache.sling.discovery.PropertyProvider;
+import org.apache.sling.discovery.TopologyEventListener;
+import org.apache.sling.discovery.base.commons.BaseDiscoveryService;
+import org.apache.sling.discovery.base.commons.ClusterViewService;
+import org.apache.sling.discovery.base.commons.ViewChecker;
+import org.apache.sling.discovery.base.commons.UndefinedClusterViewException;
+import org.apache.sling.discovery.base.connectors.announcement.AnnouncementRegistry;
+import org.apache.sling.discovery.base.connectors.ping.ConnectorRegistry;
+import org.apache.sling.discovery.base.connectors.ping.TopologyConnectorClientInformation;
+import org.apache.sling.discovery.base.connectors.ping.TopologyConnectorServlet;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.http.HttpService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import junitx.util.PrivateAccessor;
+
+public class VirtualInstance {
+
+ protected final static Logger logger = LoggerFactory.getLogger(VirtualInstance.class);
+
+ public final String slingId;
+
+ ClusterViewService clusterViewService;
+
+ private final ResourceResolverFactory resourceResolverFactory;
+
+ private final OSGiMock osgiMock;
+
+ private final BaseDiscoveryService discoveryService;
+
+ private final AnnouncementRegistry announcementRegistry;
+
+ private final ConnectorRegistry connectorRegistry;
+
+ protected final String debugName;
+
+ private ResourceResolver resourceResolver;
+
+ private int serviceId = 999;
+
+ private ViewCheckerRunner viewCheckerRunner = null;
+
+ private ServletContextHandler servletContext;
+
+ private Server jettyServer;
+
+ private ModifiableTestBaseConfig config;
+
+ private ViewChecker viewChecker;
+
+ private final VirtualInstanceBuilder builder;
+
+ private class ViewCheckerRunner implements Runnable {
+
+ private final int intervalInSeconds;
+
+ private boolean stopped_ = false;
+
+ public ViewCheckerRunner(int intervalInSeconds) {
+ this.intervalInSeconds = intervalInSeconds;
+ }
+
+ public synchronized void stop() {
+ logger.info("Stopping Instance ["+slingId+"]");
+ stopped_ = true;
+ }
+
+ public void run() {
+ while(true) {
+ synchronized(this) {
+ if (stopped_) {
+ logger.info("Instance ["+slingId+"] stopps.");
+ return;
+ }
+ }
+ try{
+ heartbeatsAndCheckView();
+ } catch(Exception e) {
+ logger.error("run: ping connector for slingId="+slingId+" threw exception: "+e, e);
+ }
+ try {
+ Thread.sleep(intervalInSeconds*1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+ }
+
+ }
+
+ public VirtualInstance(VirtualInstanceBuilder builder) throws Exception {
+ this.builder = builder;
+ this.slingId = builder.getSlingId();
+ this.debugName = builder.getDebugName();
+ logger.info("<init>: starting slingId="+slingId+", debugName="+debugName);
+
+ osgiMock = new OSGiMock();
+
+ this.resourceResolverFactory = builder.getResourceResolverFactory();
+
+ config = builder.getConnectorConfig();
+ config.addTopologyConnectorWhitelistEntry("127.0.0.1");
+ config.setMinEventDelay(builder.getMinEventDelay());
+
+ clusterViewService = builder.getClusterViewService();
+ announcementRegistry = builder.getAnnouncementRegistry();
+ connectorRegistry = builder.getConnectorRegistry();
+ viewChecker = builder.getViewChecker();
+ discoveryService = builder.getDiscoverService();
+
+ osgiMock.addService(clusterViewService);
+ osgiMock.addService(announcementRegistry);
+ osgiMock.addService(connectorRegistry);
+ osgiMock.addService(viewChecker);
+ osgiMock.addService(discoveryService);
+ osgiMock.addServices(builder.getAdditionalServices(this));
+
+ resourceResolver = resourceResolverFactory
+ .getAdministrativeResourceResolver(null);
+
+ if (builder.isResetRepo()) {
+ //SLING-4587 : do resetRepo before creating the observationListener
+ // otherwise it will get tons of events from the deletion of /var
+ // which the previous test could have left over.
+ // Doing it before addEventListener should prevent that.
+ builder.resetRepo();
+ }
+
+ osgiMock.activateAll();
+ }
+
+ @Override
+ public String toString() {
+ return "a [Test]Instance[slingId="+slingId+", debugName="+debugName+"]";
+ }
+
+ public void bindPropertyProvider(PropertyProvider propertyProvider,
+ String... propertyNames) throws Throwable {
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(Constants.SERVICE_ID, (long) serviceId++);
+ props.put(PropertyProvider.PROPERTY_PROPERTIES, propertyNames);
+
+ PrivateAccessor.invoke(discoveryService, "bindPropertyProvider",
+ new Class[] { PropertyProvider.class, Map.class },
+ new Object[] { propertyProvider, props });
+ }
+
+ public String getSlingId() {
+ return slingId;
+ }
+
+ public ClusterViewService getClusterViewService() {
+ return clusterViewService;
+ }
+
+ public BaseDiscoveryService getDiscoveryService() {
+ return discoveryService;
+ }
+
+ public AnnouncementRegistry getAnnouncementRegistry() {
+ return announcementRegistry;
+ }
+
+ public synchronized void startJetty() throws Throwable {
+ if (jettyServer!=null) {
+ return;
+ }
+ servletContext = new ServletContextHandler(ServletContextHandler.NO_SECURITY);
+ servletContext.setContextPath("/");
+
+ TopologyConnectorServlet servlet = new TopologyConnectorServlet();
+ PrivateAccessor.setField(servlet, "config", config);
+ PrivateAccessor.setField(servlet, "clusterViewService", clusterViewService);
+ PrivateAccessor.setField(servlet, "announcementRegistry", announcementRegistry);
+
+ Mockery context = new JUnit4Mockery();
+ final HttpService httpService = context.mock(HttpService.class);
+ context.checking(new Expectations() {
+ {
+ allowing(httpService).registerServlet(with(any(String.class)),
+ with(any(Servlet.class)),
+ with(any(Dictionary.class)),
+ with(any(HttpContext.class)));
+ }
+ });
+ PrivateAccessor.setField(servlet, "httpService", httpService);
+ ComponentContext cc = null;
+ PrivateAccessor.invoke(servlet, "activate", new Class[] {ComponentContext.class}, new Object[] {cc});
+
+ ServletHolder holder =
+ new ServletHolder(servlet);
+
+ servletContext.addServlet(holder, "/system/console/topology/*");
+
+ jettyServer = new Server();
+ jettyServer.setHandler(servletContext);
+ Connector connector=new SelectChannelConnector();
+ jettyServer.setConnectors(new Connector[]{connector});
+ jettyServer.start();
+ }
+
+ public synchronized int getJettyPort() {
+ if (jettyServer==null) {
+ throw new IllegalStateException("jettyServer not started");
+ }
+ final Connector[] connectors = jettyServer.getConnectors();
+ return connectors[0].getLocalPort();
+ }
+
+ public TopologyConnectorClientInformation connectTo(String url) throws MalformedURLException {
+ return connectorRegistry.registerOutgoingConnector(clusterViewService, new URL(url));
+ }
+
+ public InstanceDescription getLocalInstanceDescription() throws UndefinedClusterViewException {
+ final Iterator<InstanceDescription> it = getClusterViewService().getLocalClusterView().getInstances().iterator();
+ while(it.hasNext()) {
+ final InstanceDescription id = it.next();
+ if (slingId.equals(id.getSlingId())) {
+ return id;
+ }
+ }
+ fail("no local instanceDescription found");
+ // never called:
+ return null;
+ }
+
+ public void heartbeatsAndCheckView() {
+ logger.info("Instance ["+slingId+"] issues a pulse now "+new Date());
+ viewChecker.heartbeatAndCheckView();
+ }
+
+ public void startViewChecker(int intervalInSeconds) throws IllegalAccessException, InvocationTargetException {
+ logger.info("startViewChecker: intervalInSeconds="+intervalInSeconds);
+ if (viewCheckerRunner!=null) {
+ logger.info("startViewChecker: stopping first...");
+ viewCheckerRunner.stop();
+ logger.info("startViewChecker: stopped.");
+ }
+ logger.info("startViewChecker: activating...");
+ try{
+ OSGiMock.activate(viewChecker);
+ } catch(Error er) {
+ er.printStackTrace(System.out);
+ throw er;
+ } catch(RuntimeException re) {
+ re.printStackTrace(System.out);
+ }
+ logger.info("startViewChecker: initializing...");
+ viewCheckerRunner = new ViewCheckerRunner(intervalInSeconds);
+ Thread th = new Thread(viewCheckerRunner, "Test-ViewCheckerRunner ["+debugName+"]");
+ th.setDaemon(true);
+ logger.info("startViewChecker: starting thread...");
+ th.start();
+ logger.info("startViewChecker: done.");
+ }
+
+ public boolean isViewCheckerRunning() {
+ return (viewCheckerRunner!=null);
+ }
+
+ public void stopViewChecker() throws Throwable {
+ if (viewCheckerRunner!=null) {
+ viewCheckerRunner.stop();
+ viewCheckerRunner = null;
+ }
+ try{
+ OSGiMock.deactivate(viewChecker);
+ } catch(Error er) {
+ er.printStackTrace(System.out);
+ throw er;
+ } catch(RuntimeException re) {
+ re.printStackTrace(System.out);
+ throw re;
+ }
+ }
+
+ public void dumpRepo() throws Exception {
+ VirtualInstanceHelper.dumpRepo(resourceResolverFactory);
+ }
+
+ public ResourceResolverFactory getResourceResolverFactory() {
+ return resourceResolverFactory;
+ }
+
+ public void stop() throws Exception {
+ logger.info("stop: stopping slingId="+slingId+", debugName="+debugName);
+ try {
+ stopViewChecker();
+ } catch (Throwable e) {
+ throw new Exception("Caught Throwable in stopConnectorPinger: "+e, e);
+ }
+
+ if (resourceResolver != null) {
+ resourceResolver.close();
+ }
+ osgiMock.deactivateAll();
+ logger.info("stop: stopped slingId="+slingId+", debugName="+debugName);
+ }
+
+ public void bindTopologyEventListener(TopologyEventListener eventListener)
+ throws Throwable {
+ PrivateAccessor.invoke(discoveryService, "bindTopologyEventListener",
+ new Class[] { TopologyEventListener.class },
+ new Object[] { eventListener });
+ }
+
+ public ModifiableTestBaseConfig getConfig() {
+ return config;
+ }
+
+ public ViewChecker getViewChecker() {
+ return viewChecker;
+ }
+
+ public void assertEstablishedView() {
+ assertTrue(getDiscoveryService().getTopology().isCurrent());
+ }
+
+ public VirtualInstanceBuilder getBuilder() {
+ return builder;
+ }
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstance.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceBuilder.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceBuilder.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceBuilder.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,238 @@
+/*
+ * 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.base.its.setup;
+
+import java.util.UUID;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.commons.scheduler.Scheduler;
+import org.apache.sling.commons.scheduler.impl.QuartzScheduler;
+import org.apache.sling.commons.threads.ThreadPoolManager;
+import org.apache.sling.commons.threads.impl.DefaultThreadPoolManager;
+import org.apache.sling.discovery.base.commons.BaseDiscoveryService;
+import org.apache.sling.discovery.base.commons.ClusterViewService;
+import org.apache.sling.discovery.base.commons.ViewChecker;
+import org.apache.sling.discovery.base.connectors.announcement.AnnouncementRegistry;
+import org.apache.sling.discovery.base.connectors.announcement.AnnouncementRegistryImpl;
+import org.apache.sling.discovery.base.connectors.ping.ConnectorRegistry;
+import org.apache.sling.discovery.base.connectors.ping.ConnectorRegistryImpl;
+import org.apache.sling.discovery.base.its.setup.mock.FailingScheduler;
+import org.apache.sling.discovery.commons.providers.spi.impl.DummySlingSettingsService;
+import org.apache.sling.settings.SlingSettingsService;
+
+import junitx.util.PrivateAccessor;
+
+public abstract class VirtualInstanceBuilder {
+
+ private static Scheduler singletonScheduler = null;
+
+ public static Scheduler getSingletonScheduler() throws Exception {
+ if (singletonScheduler!=null) {
+ return singletonScheduler;
+ }
+ final Scheduler newscheduler = new QuartzScheduler();
+ final ThreadPoolManager tpm = new DefaultThreadPoolManager(null, null);
+ try {
+ PrivateAccessor.invoke(newscheduler, "bindThreadPoolManager",
+ new Class[] { ThreadPoolManager.class },
+ new Object[] { tpm });
+ } catch (Throwable e1) {
+ org.junit.Assert.fail(e1.toString());
+ }
+ OSGiMock.activate(newscheduler);
+ singletonScheduler = newscheduler;
+ return singletonScheduler;
+ }
+
+ private String debugName;
+ protected ResourceResolverFactory factory;
+ private boolean resetRepo;
+ private String slingId = UUID.randomUUID().toString();
+ private ClusterViewService clusterViewService;
+ protected ViewChecker viewChecker;
+ private AnnouncementRegistry announcementRegistry;
+ private ConnectorRegistry connectorRegistry;
+ private Scheduler scheduler;
+ private BaseDiscoveryService discoveryService;
+ private SlingSettingsService slingSettingsService;
+ protected boolean ownRepository;
+ private int minEventDelay = 1;
+ protected VirtualInstanceBuilder hookedToBuilder;
+
+ public VirtualInstanceBuilder() {
+ }
+
+ public VirtualInstanceBuilder newRepository(String path, boolean resetRepo) throws Exception {
+ createNewRepository();
+ ownRepository = true;
+ this.resetRepo = resetRepo;
+ setPath(path);
+ return this;
+ }
+
+ public abstract VirtualInstanceBuilder createNewRepository() throws Exception;
+
+ public VirtualInstanceBuilder useRepositoryOf(VirtualInstance other) throws Exception {
+ return useRepositoryOf(other.getBuilder());
+ }
+
+ public VirtualInstanceBuilder useRepositoryOf(VirtualInstanceBuilder other) throws Exception {
+ factory = other.factory;
+ hookedToBuilder = other;
+ ownRepository = false;
+ return this;
+ }
+
+ public VirtualInstanceBuilder setConnectorPingTimeout(int connectorPingTimeout) {
+ getConnectorConfig().setViewCheckTimeout(connectorPingTimeout);
+ return this;
+ }
+
+ public VirtualInstanceBuilder setConnectorPingInterval(int connectorPingInterval) {
+ getConnectorConfig().setViewCheckInterval(connectorPingInterval);
+ return this;
+ }
+
+ public boolean isResetRepo() {
+ return resetRepo;
+ }
+
+ public String getSlingId() {
+ return slingId;
+ }
+
+ public String getDebugName() {
+ return debugName;
+ }
+
+ public ResourceResolverFactory getResourceResolverFactory() {
+ return factory;
+ }
+
+ public ClusterViewService getClusterViewService() {
+ if (clusterViewService==null) {
+ clusterViewService = createClusterViewService();
+ }
+ return clusterViewService;
+ }
+
+ protected abstract ClusterViewService createClusterViewService();
+
+ public ViewChecker getViewChecker() throws Exception {
+ if (viewChecker==null) {
+ viewChecker = createViewChecker();
+ }
+ return viewChecker;
+ }
+
+ public AnnouncementRegistry getAnnouncementRegistry() {
+ if (announcementRegistry==null) {
+ announcementRegistry = createAnnouncementRegistry();
+ }
+ return announcementRegistry;
+ }
+
+ protected AnnouncementRegistry createAnnouncementRegistry() {
+ return AnnouncementRegistryImpl.testConstructor(
+ getResourceResolverFactory(), getSlingSettingsService(), getConnectorConfig());
+ }
+
+ public ConnectorRegistry getConnectorRegistry() {
+ if (connectorRegistry==null) {
+ connectorRegistry = createConnectorRegistry();
+ }
+ return connectorRegistry;
+ }
+
+ protected ConnectorRegistry createConnectorRegistry() {
+ return ConnectorRegistryImpl.testConstructor(announcementRegistry, getConnectorConfig());
+ }
+
+ protected abstract ViewChecker createViewChecker() throws Exception;
+
+ protected abstract VirtualInstanceBuilder setPath(String string);
+
+ public VirtualInstanceBuilder setDebugName(String debugName) {
+ this.debugName = debugName;
+ return this;
+ }
+
+ public abstract ModifiableTestBaseConfig getConnectorConfig();
+
+ public void setScheduler(Scheduler singletonScheduler) {
+ this.scheduler = singletonScheduler;
+ }
+
+ public Scheduler getScheduler() throws Exception {
+ if (scheduler == null) {
+ scheduler = getSingletonScheduler();
+ }
+ return scheduler;
+ }
+
+ public BaseDiscoveryService getDiscoverService() throws Exception {
+ if (discoveryService==null) {
+ discoveryService = createDiscoveryService();
+ }
+ return discoveryService;
+ }
+
+ protected abstract BaseDiscoveryService createDiscoveryService() throws Exception;
+
+ protected SlingSettingsService getSlingSettingsService() {
+ if (slingSettingsService==null) {
+ slingSettingsService = createSlingSettingsService();
+ }
+ return slingSettingsService;
+ }
+
+ protected SlingSettingsService createSlingSettingsService() {
+ return new DummySlingSettingsService(getSlingId());
+ }
+
+ public abstract Object[] getAdditionalServices(VirtualInstance instance) throws Exception;
+
+ public VirtualInstanceBuilder setMinEventDelay(int minEventDelay) {
+ this.minEventDelay = minEventDelay;
+ return this;
+ }
+
+ public int getMinEventDelay() {
+ return minEventDelay;
+ }
+
+ public VirtualInstance build() throws Exception {
+ return new VirtualInstance(this);
+ }
+
+ public VirtualInstanceBuilder setSlingId(String slingId) {
+ this.slingId = slingId;
+ return this;
+ }
+
+ public VirtualInstanceBuilder withFailingScheduler(boolean useFailingScheduler) {
+ if (useFailingScheduler) {
+ this.scheduler = new FailingScheduler();
+ }
+ return this;
+ }
+
+ protected abstract void resetRepo() throws Exception;
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceHelper.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceHelper.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceHelper.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,88 @@
+/*
+ * 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.base.its.setup;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VirtualInstanceHelper {
+
+ private final static Logger logger = LoggerFactory.getLogger(VirtualInstanceHelper.class);
+
+ public static void dumpRepo(ResourceResolverFactory resourceResolverFactory) throws Exception {
+ Session session = resourceResolverFactory
+ .getAdministrativeResourceResolver(null).adaptTo(Session.class);
+ logger.info("dumpRepo: ====== START =====");
+ logger.info("dumpRepo: repo = " + session.getRepository());
+
+ dump(session.getRootNode());
+
+ // session.logout();
+ logger.info("dumpRepo: ====== END =====");
+
+ session.logout();
+ }
+
+ public static void dump(Node node) throws RepositoryException {
+ if (node.getPath().equals("/jcr:system")
+ || node.getPath().equals("/rep:policy")) {
+ // ignore that one
+ return;
+ }
+
+ PropertyIterator pi = node.getProperties();
+ StringBuilder sb = new StringBuilder();
+ while (pi.hasNext()) {
+ Property p = pi.nextProperty();
+ sb.append(" ");
+ sb.append(p.getName());
+ sb.append("=");
+ if (p.getType() == PropertyType.BOOLEAN) {
+ sb.append(p.getBoolean());
+ } else if (p.getType() == PropertyType.STRING) {
+ sb.append(p.getString());
+ } else if (p.getType() == PropertyType.DATE) {
+ sb.append(p.getDate().getTime());
+ } else {
+ sb.append("<unknown type=" + p.getType() + "/>");
+ }
+ }
+
+ StringBuffer depth = new StringBuffer();
+ for(int i=0; i<node.getDepth(); i++) {
+ depth.append(" ");
+ }
+ logger.info(depth + "/" + node.getName() + " -- " + sb);
+ NodeIterator it = node.getNodes();
+ while (it.hasNext()) {
+ Node child = it.nextNode();
+ dump(child);
+ }
+ }
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualInstanceHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualRepository.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualRepository.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualRepository.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualRepository.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,27 @@
+/*
+ * 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.base.its.setup;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+
+public interface VirtualRepository {
+
+ ResourceResolverFactory getResourceResolverFactory();
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/VirtualRepository.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/WithholdingAppender.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/WithholdingAppender.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/WithholdingAppender.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/WithholdingAppender.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,82 @@
+/*
+ * 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 SF 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.base.its.setup;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.URL;
+
+import org.apache.log4j.Layout;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.WriterAppender;
+
+public class WithholdingAppender extends WriterAppender {
+
+ private final ByteArrayOutputStream baos;
+ private final Writer writer;
+
+ /**
+ * Install the WithholdingAppender, essentially muting all logging
+ * and withholding it until release() is called
+ * @return the WithholdingAppender that can be used to get the
+ * withheld log output
+ */
+ public static WithholdingAppender install() {
+ LogManager.getRootLogger().removeAllAppenders();
+ final WithholdingAppender withholdingAppender = new WithholdingAppender(
+ new PatternLayout("%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m\n"));
+ LogManager.getRootLogger().addAppender(withholdingAppender);
+ return withholdingAppender;
+ }
+
+ /**
+ * Release this WithholdingAppender and optionally dump what was
+ * withheld (eg in case of an exception)
+ * @param dumpToSysout
+ */
+ public void release(boolean dumpToSysout) {
+ LogManager.resetConfiguration();
+ URL log4jPropertiesFile = getClass().getResource("/log4j.properties");
+ PropertyConfigurator.configure(log4jPropertiesFile);
+ if (dumpToSysout) {
+ String withheldLogoutput = getBuffer();
+ System.out.println(withheldLogoutput);
+ }
+ }
+
+ public WithholdingAppender(Layout layout) {
+ this.layout = layout;
+ this.baos = new ByteArrayOutputStream();
+ this.writer = new BufferedWriter(new OutputStreamWriter(baos));
+ this.setWriter(writer);
+ }
+
+ public String getBuffer() {
+ try{
+ writer.flush();
+ } catch(IOException e) {
+ // ignore
+ }
+ return baos.toString();
+ }
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/WithholdingAppender.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsMultiple.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsMultiple.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsMultiple.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsMultiple.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,65 @@
+/*
+ * 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.base.its.setup.mock;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEvent.Type;
+
+public class AcceptsMultiple implements TopologyEventAsserter {
+
+ private final Type[] acceptedTypes;
+
+ private final Map<Type, Integer> counts = new HashMap<Type, Integer>();
+
+ public AcceptsMultiple(Type... acceptedTypes) {
+ this.acceptedTypes = acceptedTypes;
+ }
+
+ public synchronized void assertOk(TopologyEvent event) {
+ for (int i = 0; i < acceptedTypes.length; i++) {
+ Type aType = acceptedTypes[i];
+ if (aType == event.getType()) {
+ // perfect
+ Integer c = counts.remove(aType);
+ if (c == null) {
+ counts.put(aType, new Integer(1));
+ } else {
+ counts.put(aType, new Integer(c + 1));
+ }
+ return;
+ }
+ }
+
+ throw new IllegalStateException("Got an Event which I did not expect: "
+ + event.getType());
+ }
+
+ public synchronized int getEventCnt(Type type) {
+ Integer i = counts.get(type);
+ if (i!=null) {
+ return i;
+ } else {
+ return 0;
+ }
+ }
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsMultiple.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsParticularTopologyEvent.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsParticularTopologyEvent.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsParticularTopologyEvent.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsParticularTopologyEvent.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,50 @@
+/*
+ * 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.base.its.setup.mock;
+
+import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEvent.Type;
+
+public class AcceptsParticularTopologyEvent implements TopologyEventAsserter {
+
+ private final Type particularType;
+
+ private int eventCnt = 0;
+
+ /**
+ * @param singleInstanceTest
+ */
+ public AcceptsParticularTopologyEvent(Type particularType) {
+ this.particularType = particularType;
+ }
+
+ public void assertOk(TopologyEvent event) {
+ if (event.getType() == particularType) {
+ // fine
+ eventCnt++;
+ } else {
+ throw new IllegalStateException("expected " + particularType
+ + ", got " + event.getType());
+ }
+ }
+
+ public int getEventCnt() {
+ return eventCnt;
+ }
+}
\ No newline at end of file
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AcceptsParticularTopologyEvent.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AssertingTopologyEventListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AssertingTopologyEventListener.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AssertingTopologyEventListener.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AssertingTopologyEventListener.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,160 @@
+/*
+ * 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.base.its.setup.mock;
+
+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.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEvent.Type;
+import org.apache.sling.discovery.TopologyEventListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AssertingTopologyEventListener implements TopologyEventListener {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private final List<TopologyEventAsserter> expectedEvents = new LinkedList<TopologyEventAsserter>();
+
+ private String debugInfo = null;
+
+ private String errorMsg = null;
+
+ public AssertingTopologyEventListener() {
+ }
+
+ public AssertingTopologyEventListener(String debugInfo) {
+ this.debugInfo = debugInfo;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString()+"-[debugInfo="+debugInfo+"]";
+ }
+
+ private List<TopologyEvent> events_ = new LinkedList<TopologyEvent>();
+
+ private List<TopologyEvent> unexpectedEvents_ = new LinkedList<TopologyEvent>();
+
+ public void handleTopologyEvent(TopologyEvent event) {
+ final String logPrefix = "handleTopologyEvent["+(debugInfo!=null ? debugInfo : "this="+this) +"] ";
+ logger.info(logPrefix + "got event=" + event);
+ TopologyEventAsserter asserter = null;
+ synchronized (expectedEvents) {
+ if (expectedEvents.size() == 0) {
+ unexpectedEvents_.add(event);
+ throw new IllegalStateException(
+ "no expected events anymore. But got: " + event);
+ }
+ asserter = expectedEvents.remove(0);
+ }
+ if (asserter == null) {
+ throw new IllegalStateException("this should not occur");
+ }
+ try{
+ asserter.assertOk(event);
+ logger.info(logPrefix + "event matched expectations (" + event+")");
+ } catch(RuntimeException re) {
+ synchronized(expectedEvents) {
+ unexpectedEvents_.add(event);
+ }
+ throw re;
+ } catch(Error er) {
+ synchronized(expectedEvents) {
+ unexpectedEvents_.add(event);
+ }
+ throw er;
+ }
+ try{
+ switch(event.getType()) {
+ case PROPERTIES_CHANGED: {
+ assertNotNull(event.getOldView());
+ assertNotNull(event.getNewView());
+ assertTrue(event.getNewView().isCurrent());
+ assertFalse(event.getOldView().isCurrent());
+ break;
+ }
+ case TOPOLOGY_CHANGED: {
+ assertNotNull(event.getOldView());
+ assertNotNull(event.getNewView());
+ assertTrue(event.getNewView().isCurrent());
+ assertFalse(event.getOldView().isCurrent());
+ break;
+ }
+ case TOPOLOGY_CHANGING: {
+ assertNotNull(event.getOldView());
+ assertNull(event.getNewView());
+ assertFalse(event.getOldView().isCurrent());
+ break;
+ }
+ case TOPOLOGY_INIT: {
+ assertNull(event.getOldView());
+ assertNotNull(event.getNewView());
+ // cannot make any assertions on event.getNewView().isCurrent()
+ // as that can be true or false
+ break;
+ }
+ }
+ } catch(RuntimeException re) {
+ logger.error("RuntimeException: "+re, re);
+ throw re;
+ } catch(AssertionError e) {
+ logger.error("AssertionError: "+e, e);
+ throw e;
+ }
+ events_.add(event);
+ }
+
+ public List<TopologyEvent> getEvents() {
+ return events_;
+ }
+
+ public void addExpected(Type expectedType) {
+ addExpected(new AcceptsParticularTopologyEvent(expectedType));
+ }
+
+ public void addExpected(TopologyEventAsserter topologyEventAsserter) {
+ expectedEvents.add(topologyEventAsserter);
+ }
+
+ public int getRemainingExpectedCount() {
+ return expectedEvents.size();
+ }
+
+ public int getUnexpectedCount() {
+ return unexpectedEvents_.size();
+ }
+
+ public void dump() {
+ StringBuffer ue = new StringBuffer();
+ if (unexpectedEvents_.size()>0) {
+ for (Iterator<TopologyEvent> it = unexpectedEvents_.iterator(); it.hasNext();) {
+ TopologyEvent topologyEvent = it.next();
+ ue.append(topologyEvent+", ");
+ }
+ unexpectedEvents_.iterator();
+ }
+ logger.info("dump: got "+events_.size()+" events, "+unexpectedEvents_.size()+" (details: "+ue+") thereof unexpected. My list of expected events contains "+expectedEvents.size());
+ }
+}
\ No newline at end of file
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/AssertingTopologyEventListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/DummyViewChecker.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/DummyViewChecker.java?rev=1709601&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/DummyViewChecker.java (added)
+++ sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/DummyViewChecker.java Tue Oct 20 14:12:31 2015
@@ -0,0 +1,48 @@
+/*
+ * 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.base.its.setup.mock;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.commons.scheduler.Scheduler;
+import org.apache.sling.discovery.base.commons.BaseViewChecker;
+import org.apache.sling.discovery.base.connectors.BaseConfig;
+import org.apache.sling.discovery.base.connectors.announcement.AnnouncementRegistry;
+import org.apache.sling.discovery.base.connectors.ping.ConnectorRegistry;
+import org.apache.sling.settings.SlingSettingsService;
+
+public class DummyViewChecker extends BaseViewChecker {
+
+ public static DummyViewChecker testConstructor(
+ SlingSettingsService slingSettingsService,
+ ResourceResolverFactory resourceResolverFactory,
+ ConnectorRegistry connectorRegistry,
+ AnnouncementRegistry announcementRegistry,
+ Scheduler scheduler,
+ BaseConfig connectorConfig) {
+ DummyViewChecker pinger = new DummyViewChecker();
+ pinger.slingSettingsService = slingSettingsService;
+ pinger.resourceResolverFactory = resourceResolverFactory;
+ pinger.connectorRegistry = connectorRegistry;
+ pinger.announcementRegistry = announcementRegistry;
+ pinger.scheduler = scheduler;
+ pinger.connectorConfig = connectorConfig;
+ return pinger;
+ }
+
+}
Propchange: sling/trunk/bundles/extensions/discovery/base/src/test/java/org/apache/sling/discovery/base/its/setup/mock/DummyViewChecker.java
------------------------------------------------------------------------------
svn:eol-style = native