This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.discovery.base-1.0.2
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-discovery-base.git

commit 65362f2aeb7305a363db7afdb6b7454a2cd04420
Author: Stefan Egli <[email protected]>
AuthorDate: Thu Oct 29 19:03:04 2015 +0000

    SLING-5216 / SLING-5195 : more test cases added
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/discovery/base@1711331
 13f79535-47bb-0310-9956-ffa450edef68
---
 .../base/its/AbstractDiscoveryServiceTest.java     | 375 +++++++++++++++++++++
 .../base/its/setup/mock/MockedResource.java        |   2 +-
 2 files changed, 376 insertions(+), 1 deletion(-)

diff --git 
a/src/test/java/org/apache/sling/discovery/base/its/AbstractDiscoveryServiceTest.java
 
b/src/test/java/org/apache/sling/discovery/base/its/AbstractDiscoveryServiceTest.java
new file mode 100644
index 0000000..c2142f1
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/discovery/base/its/AbstractDiscoveryServiceTest.java
@@ -0,0 +1,375 @@
+/*
+ * 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.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.sling.discovery.InstanceDescription;
+import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEvent.Type;
+import org.apache.sling.discovery.TopologyEventListener;
+import org.apache.sling.discovery.TopologyView;
+import org.apache.sling.discovery.base.its.setup.VirtualInstance;
+import org.apache.sling.discovery.base.its.setup.VirtualInstanceBuilder;
+import org.apache.sling.testing.tools.retry.RetryLoop;
+import org.apache.sling.testing.tools.retry.RetryLoop.Condition;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+    this is to get more assurance that things work:
+        
+        * have an agent that periodically scans getTopology and makes 
assumptions
+        * have a listener that makes assumptions too
+        * these two might be able to communicate with each other to make even 
more assumptions..
+        * combine the above with coming and going instances, with slow ones 
etc etc
+ */
+public abstract class AbstractDiscoveryServiceTest {
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    class Tester implements TopologyEventListener, Runnable {
+        
+        private final VirtualInstance instance;
+        private final Thread thread;
+
+        private TopologyEvent previousEvent;
+        
+        private List<String> failures = new LinkedList<String>();
+        
+        private volatile boolean stopped = false;
+        private final long pollingSleep;
+        
+        private boolean running = true;
+        
+        Tester(VirtualInstance instance, long pollingSleep) throws Throwable {
+            this.instance = instance;
+            this.pollingSleep = pollingSleep;
+            instance.bindTopologyEventListener(this);
+            thread = new Thread(this);
+            thread.setName("Tester-"+instance.getDebugName()+"-thread");
+            thread.setDaemon(true);
+            thread.start();
+        }
+
+        private synchronized void assertNoFailures() {
+            if (failures.size()==0) {
+                return;
+            }
+            fail("got "+failures.size()+" failures, the first one thereof: 
"+failures.get(0));
+        }
+        
+        private synchronized boolean hasFailures() {
+            return failures.size()!=0;
+        }
+        
+        private synchronized void asyncFail(String msg) {
+            failures.add(msg);
+        }
+
+        @Override
+        public void run() {
+            while(!stopped) {
+                try{
+                    TopologyView topo = 
instance.getDiscoveryService().getTopology();
+                    Thread.sleep(pollingSleep);
+                } catch(Throwable th) {
+                    asyncFail("Got a Throwable: "+th);
+                    return;
+                }
+            }
+        }
+
+        @Override
+        public void handleTopologyEvent(TopologyEvent event) {
+            if (hasFailures()) {
+                // then stop
+                return;
+            }
+            logger.info("handleTopologyEvent["+instance.getDebugName()+"]: 
"+event);
+            if (previousEvent == null) {
+                // then we're expecting a TOPOLOGY_INIT
+                if (event.getType()!=Type.TOPOLOGY_INIT) {
+                    asyncFail("expected an INIT as the first, but got: 
"+event);
+                    return;
+                }
+            } else if (previousEvent.getType() == Type.TOPOLOGY_CHANGED
+                    || previousEvent.getType() == Type.PROPERTIES_CHANGED) {
+                // then expecting a TOPOLOGY_CHANGING or PROPERTIES_CHANGED
+                if (event.getType()==Type.TOPOLOGY_CHANGING) {
+                    // perfect
+                } else if (event.getType()==Type.PROPERTIES_CHANGED) {
+                    // perfect
+                } else {
+                    asyncFail("expected a CHANGING or PROPERTIES_CHANGED, but 
got: "+event);
+                    return;
+                }
+            } else if (previousEvent.getType() == Type.TOPOLOGY_CHANGING) {
+                // then expecting a TOPOLOGY_CHANGED
+                if (event.getType()!=Type.TOPOLOGY_CHANGED) {
+                    asyncFail("expected a CHANGED after CHANGING, but got: 
"+event);
+                    return;
+                }
+            }
+            previousEvent = event;
+        }
+
+        public void shutdown() throws Exception {
+            stopped = true;
+            instance.stop();
+            running = false;
+        }
+
+        public void restart() throws Exception {
+            instance.startViewChecker((int) 
instance.getConfig().getConnectorPingInterval());
+            running = true;
+        }
+
+        public void pause() throws Throwable {
+            instance.stopViewChecker();
+            running = false;
+        }
+        
+    }
+    
+    List<Tester> testers = new LinkedList<Tester>();
+    
+    public abstract VirtualInstanceBuilder newBuilder();
+    
+    @Before
+    public void setUp() throws Exception {
+        testers.clear();
+    }
+    
+    @After
+    public void tearDown() throws Exception {
+        for (Tester tester : testers) {
+            tester.shutdown();
+        }
+    }
+    
+    Tester newInstance(String debugName, int interval, int timeout, long 
pollingSleep, VirtualInstance base) throws Throwable {
+        VirtualInstanceBuilder builder = newBuilder();
+        builder.setDebugName(debugName);
+        if (base == null) {
+            builder.newRepository("/var/discovery/testing/", true);
+        } else {
+            builder.useRepositoryOf(base);
+        }
+        builder.setConnectorPingInterval(interval);
+        builder.setConnectorPingTimeout(timeout);
+        builder.setMinEventDelay(1);
+        VirtualInstance instance = builder.build();
+        Tester t = new Tester(instance, pollingSleep);
+        testers.add(t);
+        instance.startViewChecker(interval);
+        return t;
+    }
+    
+    private void assertStableTopology(Tester... instances) {
+        for (Tester tester : instances) {
+            logger.info("asserting tester: "+tester.instance.getDebugName());
+            TopologyEvent lastEvent = tester.previousEvent;
+            Type type = lastEvent.getType();
+            if (type == Type.TOPOLOGY_CHANGED || type == Type.TOPOLOGY_INIT) {
+                // fine
+            } else {
+                fail("wrong type, expected CHANGED or INIT, got: "+type);
+            }
+            assertNotNull(lastEvent.getNewView());
+            assertEquals(instances.length, 
lastEvent.getNewView().getInstances().size());
+            TopologyView t = 
tester.instance.getDiscoveryService().getTopology();
+            assertTrue(t.isCurrent());
+            assertEquals(instances.length, t.getInstances().size());
+        }
+    }
+
+    private boolean isStableTopology(Tester... instances) {
+        for (Tester tester : instances) {
+            TopologyEvent lastEvent = tester.previousEvent;
+            if (lastEvent == null) {
+                return false;
+            }
+            Type type = lastEvent.getType();
+            if (type == Type.TOPOLOGY_CHANGED || type == Type.TOPOLOGY_INIT) {
+                // fine
+            } else {
+                return false;
+            }
+            TopologyView newView = lastEvent.getNewView();
+            if (newView == null) {
+                return false;
+            }
+            if (instances.length != newView.getInstances().size()) {
+                return false;
+            }
+            TopologyView t = 
tester.instance.getDiscoveryService().getTopology();
+            if (!t.isCurrent()) {
+                return false;
+            }
+            if (instances.length != t.getInstances().size()) {
+                return false;
+            }
+            for (Tester t2 : instances) {
+                boolean foundMatch = false;
+                for (InstanceDescription id : t.getInstances()) {
+                    if (t2.instance.getSlingId().equals(id.getSlingId())) {
+                        foundMatch = true;
+                        break;
+                    }
+                }
+                if (!foundMatch) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Test
+    public void testSingleInstance() throws Throwable {
+        Tester single = newInstance("single", 1, 4, 50, null);
+        single.instance.dumpRepo();
+        startRetryLoop(testers, 10);
+        single.assertNoFailures();
+        assertStableTopology(single);
+    }
+    
+    @Test
+    public void testTwoInstances() throws Throwable {
+        Tester i1 = newInstance("i1", 1, 4, 100, null);
+        Tester i2 = newInstance("i2", 1, 4, 100, i1.instance);
+        startRetryLoop(testers, 10);
+        i1.instance.dumpRepo();
+        i1.assertNoFailures();
+        i2.assertNoFailures();
+        assertStableTopology(i1, i2);
+    }
+
+    @Test
+    public void testTenInstances() throws Throwable {
+        Tester i1 = newInstance("i1", 1, 6, 250, null);
+        for(int i=2; i<=10; i++) {
+            Tester in = newInstance("i"+i, 1, 6, 250, i1.instance);
+        }
+        startRetryLoop(testers, 10);
+        i1.instance.dumpRepo();
+        i1.assertNoFailures();
+        assertStableTopology(testers.toArray(new Tester[0]));
+    }
+
+    @Test
+    public void testTwentyInstances() throws Throwable {
+        Tester i1 = newInstance("i1", 1, 20, 1000, null);
+        for(int i=2; i<=20; i++) {
+            Tester in = newInstance("i"+i, 1, 20, 1000, i1.instance);
+        }
+        startRetryLoop(testers, 40);
+        i1.instance.dumpRepo();
+        i1.assertNoFailures();
+        assertStableTopology(testers.toArray(new Tester[0]));
+    }
+
+    @Test
+    public void testThirtyInstances() throws Throwable {
+        Tester i1 = newInstance("i1", 4, 60, 1000, null);
+        for(int i=2; i<=30; i++) {
+            Tester in = newInstance("i"+i, 4, 60, 2000, i1.instance);
+            Thread.sleep(1000);
+        }
+        startRetryLoop(testers, 100);
+        i1.instance.dumpRepo();
+        i1.assertNoFailures();
+        assertStableTopology(testers.toArray(new Tester[0]));
+    }
+    
+    private void startRetryLoop(final List<Tester> testers, int 
retryTimeoutSeconds) {
+        startRetryLoop(retryTimeoutSeconds, testers.toArray(new Tester[0]));
+    }
+    
+    private void startRetryLoop(int retryTimeoutSeconds, final Tester... 
testers) {
+        new RetryLoop(new Condition() {
+
+            @Override
+            public String getDescription() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public boolean isTrue() throws Exception {
+                if (!isStableTopology(testers)) {
+                    return false;
+                }
+                for (Tester tester : testers) {
+                    tester.assertNoFailures();
+                }
+                logger.info("retryLoop: declaring stable topology with 
"+testers.length);
+                return true;
+            }
+            
+        }, retryTimeoutSeconds /*seconds*/, 1000/*millis*/);        
+    }
+    
+    @Test
+    public void testStartStopFiesta() throws Throwable {
+        final Tester[] instances = new Tester[8];
+        instances[0] = newInstance("i1", 1, 10, 1000, null);
+        for(int i=2; i<=8; i++) {
+            instances[i-1] = newInstance("i"+i, 1, 10, 1000, 
instances[0].instance);
+            Thread.sleep(600);
+        }
+        startRetryLoop(15, instances);
+        for (Tester tester : instances) {
+            tester.assertNoFailures();
+        }
+        assertStableTopology(testers.toArray(new Tester[0]));
+        Random r = new Random(123432141);
+        for(int i=0; i<10; i++) {
+            logger.info("testStartStopFiesta : loop "+i);
+            final List<Tester> alive = new LinkedList<Tester>();
+            int keepAlive = r.nextInt(instances.length);
+            for(int j=0; j<instances.length; j++) {
+                if (j == keepAlive || r.nextBoolean()) {
+                    instances[j].restart();
+                    alive.add(instances[j]);
+                } else {
+                    instances[j].pause();
+                }
+            }
+            logger.info("testStartStopFiesta : loop "+i+", alive-cnt: 
"+alive.size());
+            startRetryLoop(alive, 30);
+            for (Tester tester : instances) {
+                tester.assertNoFailures();
+            }
+            
+            assertStableTopology(alive.toArray(new Tester[0]));
+        }
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/discovery/base/its/setup/mock/MockedResource.java
 
b/src/test/java/org/apache/sling/discovery/base/its/setup/mock/MockedResource.java
index b71cc23..a0b5efe 100644
--- 
a/src/test/java/org/apache/sling/discovery/base/its/setup/mock/MockedResource.java
+++ 
b/src/test/java/org/apache/sling/discovery/base/its/setup/mock/MockedResource.java
@@ -123,7 +123,7 @@ public class MockedResource extends SyntheticResource {
                 ValueMap valueMap = new ValueMapDecorator(map);
                 return (AdapterType) valueMap;
             } catch (Exception e) {
-                logger.error("adaptTo failed with : "+e, e);
+                logger.error("adaptTo failed with : "+e);
                 return null;
             }
         } else if (type.equals(ModifiableValueMap.class)) {

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to