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/08 16:31:46 UTC

svn commit: r1707548 [3/4] - in /sling/trunk/bundles/extensions/discovery/commons: ./ src/main/java/org/apache/sling/discovery/commons/providers/ src/main/java/org/apache/sling/discovery/commons/providers/impl/ src/main/java/org/apache/sling/discovery/...

Copied: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/impl/TestViewStateManager.java (from r1706814, sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/TestViewStateManager.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/impl/TestViewStateManager.java?p2=sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/impl/TestViewStateManager.java&p1=sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/TestViewStateManager.java&r1=1706814&r2=1707548&rev=1707548&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/TestViewStateManager.java (original)
+++ sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/impl/TestViewStateManager.java Thu Oct  8 14:31:45 2015
@@ -16,146 +16,72 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.discovery.commons.providers;
+package org.apache.sling.discovery.commons.providers.impl;
 
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Random;
-import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
-import org.apache.sling.discovery.ClusterView;
-import org.apache.sling.discovery.InstanceDescription;
-import org.apache.sling.discovery.InstanceFilter;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
 import org.apache.sling.discovery.TopologyEvent;
-import org.apache.sling.discovery.TopologyEventListener;
 import org.apache.sling.discovery.commons.providers.BaseTopologyView;
-import org.apache.sling.discovery.commons.providers.ViewStateManager;
+import org.apache.sling.discovery.commons.providers.EventFactory;
+import org.apache.sling.discovery.commons.providers.spi.ConsistencyService;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class TestViewStateManager {
 
-    private class Listener implements TopologyEventListener {
-
-        private List<TopologyEvent> events = new LinkedList<TopologyEvent>();
-        private TopologyEvent lastEvent;
-        
-        public synchronized void handleTopologyEvent(TopologyEvent event) {
-            events.add(event);
-            lastEvent = event;
-        }
-        
-        public synchronized List<TopologyEvent> getEvents() {
-            return Collections.unmodifiableList(events);
-        }
-
-        public synchronized int countEvents() {
-            return events.size();
-        }
-        
-        public synchronized TopologyEvent getLastEvent() {
-            return lastEvent;
-        }
+    private static final Logger logger = LoggerFactory.getLogger(TestViewStateManager.class);
 
-        public synchronized void clearEvents() {
-            events.clear();
-        }
+    private class ConsistencyServiceWithSemaphore implements ConsistencyService {
 
-        public BaseTopologyView getLastView() {
-            if (lastEvent==null) {
-                return null;
-            } else {
-                switch(lastEvent.getType()) {
-                case TOPOLOGY_INIT:
-                case PROPERTIES_CHANGED:
-                case TOPOLOGY_CHANGED: {
-                    return (BaseTopologyView) lastEvent.getNewView();
-                }
-                case TOPOLOGY_CHANGING:{
-                    return (BaseTopologyView) lastEvent.getOldView();
-                }
-                default: {
-                    fail("no other types supported yet");
-                }
-                }
-            }
-            return null;
-        }
-        
-    }
-    
-    private class View extends BaseTopologyView {
-        
-        private final BaseTopologyView clonedView;
+        private final Semaphore semaphore;
+        private final Lock lock;
 
-        public View() {
-            clonedView = null;
+        public ConsistencyServiceWithSemaphore(Lock lock, Semaphore semaphore) {
+            this.lock = lock;
+            this.semaphore = semaphore;
         }
         
-        public View(BaseTopologyView clonedView) {
-            this.clonedView = clonedView;
-        }
-        
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof View)) {
-                return false;
-            }
-            final View other = (View) obj;
-            if (clonedView!=null) {
-                if (obj==clonedView) {
-                    return true;
+        public void sync(BaseTopologyView view, Runnable callback) {
+            try {
+                lock.unlock();
+                try{
+                    semaphore.acquire();
+                } finally {
+                    lock.lock();
                 }
-            } else if (other.clonedView==this) {
-                return true;
+                callback.run();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
             }
-            return super.equals(obj);
         }
         
-        @Override
-        public int hashCode() {
-            if (clonedView!=null) {
-                return clonedView.hashCode();
-            }
-            return super.hashCode();
-        }
-
-        public View addInstance() {
-            return this;
-        }
-
-        public InstanceDescription getLocalInstance() {
-            throw new IllegalStateException("not yet implemented");
-        }
-
-        public Set<InstanceDescription> getInstances() {
-            throw new IllegalStateException("not yet implemented");
-        }
-
-        public Set<InstanceDescription> findInstances(InstanceFilter filter) {
-            throw new IllegalStateException("not yet implemented");
-        }
-
-        public Set<ClusterView> getClusterViews() {
-            throw new IllegalStateException("not yet implemented");
-        }
     }
     
-    private ViewStateManager mgr;
+    private ViewStateManagerImpl mgr;
     
     private Random defaultRandom;
 
     @Before
     public void setup() throws Exception {
-        mgr = new ViewStateManager();
+        mgr = new ViewStateManagerImpl(new ReentrantLock(), new ConsistencyService() {
+            
+            public void sync(BaseTopologyView view, Runnable callback) {
+                callback.run();
+            }
+        });
         defaultRandom = new Random(1234123412); // I want randomness yes, but deterministic, for some methods at least
     }
     
@@ -165,73 +91,15 @@ public class TestViewStateManager {
         defaultRandom= null;
     }
     
-    private void assertNoEvents(Listener listener) {
-        assertEquals(0, listener.countEvents());
+    void assertEvents(Listener listener, TopologyEvent... events) {
+        TestHelper.assertEvents(mgr, listener, events);
     }
     
-    private void assertEvents(Listener listener, TopologyEvent... events) {
-        assertEquals(events.length, listener.countEvents());
-        for (int i = 0; i < events.length; i++) {
-            TopologyEvent e = events[i];
-            assertEquals(e.getType(), listener.getEvents().get(i).getType());
-            switch(e.getType()) {
-            case TOPOLOGY_INIT: {
-                assertNull(listener.getEvents().get(i).getOldView());
-                assertEquals(e.getNewView(), listener.getEvents().get(i).getNewView());
-                break;
-            }
-            case TOPOLOGY_CHANGING: {
-                assertEquals(e.getOldView(), listener.getEvents().get(i).getOldView());
-                assertNull(listener.getEvents().get(i).getNewView());
-                break;
-            }
-            case PROPERTIES_CHANGED:
-            case TOPOLOGY_CHANGED: {
-                assertEquals(e.getOldView(), listener.getEvents().get(i).getOldView());
-                assertEquals(e.getNewView(), listener.getEvents().get(i).getNewView());
-                break;
-            }
-            default: {
-                fail("no other type supported yet");
-            }
-            }
-        }
-        listener.clearEvents();
-    }
-
     /** does couple loops randomly calling handleChanging() (or not) and then handleNewView().
-     * Note: random is passed to allow customizing and not hardcoding this method to a particular random **/
-    private void randomEventLoop(final Random random, Listener... listeners) {
-        for(int i=0; i<100; i++) {
-            final boolean shouldCallChanging = random.nextBoolean();
-            if (shouldCallChanging) {
-                // dont always do a changing
-                mgr.handleChanging();
-                for(int j=0; j<listeners.length; j++) {
-                    assertEvents(listeners[j], ViewStateManager.newChangingEvent(listeners[j].getLastView()));
-                }
-            } else {
-                for(int j=0; j<listeners.length; j++) {
-                    assertNoEvents(listeners[j]);
-                }
-            }
-            final BaseTopologyView view = new View().addInstance();
-            BaseTopologyView[] lastViews = new BaseTopologyView[listeners.length];
-            for(int j=0; j<listeners.length; j++) {
-                lastViews[j] = listeners[j].getLastView();
-            }
-            mgr.handleNewView(view);
-            if (!shouldCallChanging) {
-                // in that case I should still get a CHANGING - by contract
-                for(int j=0; j<listeners.length; j++) {
-                    assertEvents(listeners[j], ViewStateManager.newChangingEvent(lastViews[j]), ViewStateManager.newChangedEvent(lastViews[j], view));
-                }
-            } else {
-                for(int j=0; j<listeners.length; j++) {
-                    assertEvents(listeners[j], ViewStateManager.newChangedEvent(lastViews[j], view));
-                }
-            }
-        }
+     * Note: random is passed to allow customizing and not hardcoding this method to a particular random 
+     * @throws InterruptedException **/
+    private void randomEventLoop(final Random random, Listener... listeners) throws InterruptedException {
+        TestHelper.randomEventLoop(mgr, null, 100, -1, random, listeners);
     }
     
     @Test
@@ -254,14 +122,14 @@ public class TestViewStateManager {
     public void testBindActivateChangingChanged() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
+        assertEvents(listener, EventFactory.newInitEvent(view));
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -269,14 +137,14 @@ public class TestViewStateManager {
     public void testBindChangingActivateChanged() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
+        assertEvents(listener, EventFactory.newInitEvent(view));
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -284,14 +152,14 @@ public class TestViewStateManager {
     public void testBindChangingChangedActivate() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
+        assertEvents(listener, EventFactory.newInitEvent(view));
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -299,19 +167,19 @@ public class TestViewStateManager {
     public void testBindChangingChangedChangingActivate() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view2 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view2 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view2);
-        assertEvents(listener, ViewStateManager.newInitEvent(view2));
+        assertEvents(listener, EventFactory.newInitEvent(view2));
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -319,17 +187,17 @@ public class TestViewStateManager {
     public void testBindChangedChangingActivate() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view2 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view2 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view2);
-        assertEvents(listener, ViewStateManager.newInitEvent(view2));
+        assertEvents(listener, EventFactory.newInitEvent(view2));
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -338,15 +206,15 @@ public class TestViewStateManager {
         final Listener listener = new Listener();
         // first activate
         mgr.handleActivated();
-        assertNoEvents(listener); // paranoia
+        TestHelper.assertNoEvents(listener); // paranoia
         // then bind
         mgr.bind(listener);
-        assertNoEvents(listener); // there was no changing or changed yet
+        TestHelper.assertNoEvents(listener); // there was no changing or changed yet
         mgr.handleChanging();
-        assertNoEvents(listener);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
+        assertEvents(listener, EventFactory.newInitEvent(view));
         randomEventLoop(defaultRandom, listener);
     }
 
@@ -355,15 +223,15 @@ public class TestViewStateManager {
         final Listener listener = new Listener();
         // first activate
         mgr.handleActivated();
-        assertNoEvents(listener); // paranoia
+        TestHelper.assertNoEvents(listener); // paranoia
         mgr.handleChanging();
-        assertNoEvents(listener); // no listener yet
+        TestHelper.assertNoEvents(listener); // no listener yet
         // then bind
         mgr.bind(listener);
-        assertNoEvents(listener); // no changed event yet
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener); // no changed event yet
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
+        assertEvents(listener, EventFactory.newInitEvent(view));
         randomEventLoop(defaultRandom, listener);
     }
 
@@ -372,15 +240,15 @@ public class TestViewStateManager {
         final Listener listener = new Listener();
         // first activate
         mgr.handleActivated();
-        assertNoEvents(listener); // paranoia
+        TestHelper.assertNoEvents(listener); // paranoia
         mgr.handleChanging();
-        assertNoEvents(listener); // no listener yet
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener); // no listener yet
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertNoEvents(listener); // no listener yet
+        TestHelper.assertNoEvents(listener); // no listener yet
         // then bind
         mgr.bind(listener);
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
+        assertEvents(listener, EventFactory.newInitEvent(view));
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -390,19 +258,19 @@ public class TestViewStateManager {
         final Listener listener2 = new Listener();
         
         mgr.bind(listener1);
-        assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener1);
         mgr.handleActivated();
-        assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener1);
         mgr.bind(listener2);
-        assertNoEvents(listener1);
-        assertNoEvents(listener2);
+        TestHelper.assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener2);
         mgr.handleChanging();
-        assertNoEvents(listener1);
-        assertNoEvents(listener2);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener2);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener1, ViewStateManager.newInitEvent(view));
-        assertEvents(listener2, ViewStateManager.newInitEvent(view));
+        assertEvents(listener1, EventFactory.newInitEvent(view));
+        assertEvents(listener2, EventFactory.newInitEvent(view));
         
         randomEventLoop(defaultRandom, listener1, listener2);
     }
@@ -413,18 +281,18 @@ public class TestViewStateManager {
         final Listener listener2 = new Listener();
         
         mgr.bind(listener1);
-        assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener1);
         mgr.handleActivated();
-        assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener1);
         mgr.handleChanging();
-        assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener1);
         mgr.bind(listener2);
-        assertNoEvents(listener1);
-        assertNoEvents(listener2);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener1);
+        TestHelper.assertNoEvents(listener2);
+        final BaseTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener1, ViewStateManager.newInitEvent(view));
-        assertEvents(listener2, ViewStateManager.newInitEvent(view));
+        assertEvents(listener1, EventFactory.newInitEvent(view));
+        assertEvents(listener2, EventFactory.newInitEvent(view));
 
         randomEventLoop(defaultRandom, listener1, listener2);
     }
@@ -435,11 +303,11 @@ public class TestViewStateManager {
         mgr.handleActivated();
         mgr.bind(listener);
         mgr.handleChanging();
-        final BaseTopologyView view = new View().addInstance();
+        final SimpleTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
-        mgr.handleNewView(clone(view));
-        assertNoEvents(listener);
+        assertEvents(listener, EventFactory.newInitEvent(view));
+        mgr.handleNewView(SimpleTopologyView.clone(view));
+        TestHelper.assertNoEvents(listener);
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -449,15 +317,15 @@ public class TestViewStateManager {
         mgr.handleActivated();
         mgr.bind(listener1);
         mgr.handleChanging();
-        final BaseTopologyView view = new View().addInstance();
+        final SimpleTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertEvents(listener1, ViewStateManager.newInitEvent(view));
+        assertEvents(listener1, EventFactory.newInitEvent(view));
         
         final Listener listener2 = new Listener();
         mgr.bind(listener2);
-        mgr.handleNewView(clone(view));
-        assertNoEvents(listener1);
-        assertEvents(listener2, ViewStateManager.newInitEvent(view));
+        mgr.handleNewView(SimpleTopologyView.clone(view));
+        TestHelper.assertNoEvents(listener1);
+        assertEvents(listener2, EventFactory.newInitEvent(view));
         randomEventLoop(defaultRandom, listener1, listener2);
     }
     
@@ -465,14 +333,14 @@ public class TestViewStateManager {
     public void testActivateChangedBindDuplicateHandleNewView() throws Exception {
         final Listener listener = new Listener();
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final SimpleTopologyView view = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.bind(listener);
-        assertEvents(listener, ViewStateManager.newInitEvent(view));
-        mgr.handleNewView(clone(view));
-        assertNoEvents(listener);
+        assertEvents(listener, EventFactory.newInitEvent(view));
+        mgr.handleNewView(SimpleTopologyView.clone(view));
+        TestHelper.assertNoEvents(listener);
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -480,17 +348,17 @@ public class TestViewStateManager {
     public void testBindActivateChangedChanged() throws Exception {
         final Listener listener = new Listener();
         mgr.handleActivated();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
-        final BaseTopologyView view1 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view1 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view1);
-        assertEvents(listener, ViewStateManager.newInitEvent(view1));
-        final BaseTopologyView view2 = new View().addInstance();
+        assertEvents(listener, EventFactory.newInitEvent(view1));
+        final BaseTopologyView view2 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view2);
-        assertEvents(listener, ViewStateManager.newChangingEvent(view1), ViewStateManager.newChangedEvent(view1, view2));
+        assertEvents(listener, EventFactory.newChangingEvent(view1), EventFactory.newChangedEvent(view1, view2));
         randomEventLoop(defaultRandom, listener);
     }
     
@@ -498,72 +366,225 @@ public class TestViewStateManager {
     public void testBindActivateChangedDeactivateChangingActivateChanged() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view1 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view1 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view1);
-        assertEvents(listener, ViewStateManager.newInitEvent(view1));
+        assertEvents(listener, EventFactory.newInitEvent(view1));
         mgr.handleDeactivated();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.bind(listener); // need to bind again after deactivate
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view2 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view2 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view2);
-        assertEvents(listener, ViewStateManager.newInitEvent(view2));
+        assertEvents(listener, EventFactory.newInitEvent(view2));
     }
 
     @Test
     public void testBindActivateChangedDeactivateChangedActivateChanged() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view1 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view1 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view1);
-        assertEvents(listener, ViewStateManager.newInitEvent(view1));
+        assertEvents(listener, EventFactory.newInitEvent(view1));
         mgr.handleDeactivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view2 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view2 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view2);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.bind(listener); // need to bind again after deactivate
         mgr.handleActivated();
-        assertEvents(listener, ViewStateManager.newInitEvent(view2));
-        final BaseTopologyView view3 = new View().addInstance();
+        assertEvents(listener, EventFactory.newInitEvent(view2));
+        final BaseTopologyView view3 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view3);
-        assertEvents(listener, ViewStateManager.newChangingEvent(view2), ViewStateManager.newChangedEvent(view2, view3));
+        assertEvents(listener, EventFactory.newChangingEvent(view2), EventFactory.newChangedEvent(view2, view3));
     }
 
     @Test
     public void testBindActivateChangedChangingDeactivateActivateChangingChanged() throws Exception {
         final Listener listener = new Listener();
         mgr.bind(listener);
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleActivated();
-        assertNoEvents(listener);
-        final BaseTopologyView view1 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view1 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view1);
-        assertEvents(listener, ViewStateManager.newInitEvent(view1));
+        assertEvents(listener, EventFactory.newInitEvent(view1));
         mgr.handleChanging();
-        assertEvents(listener, ViewStateManager.newChangingEvent(view1));
+        assertEvents(listener, EventFactory.newChangingEvent(view1));
         mgr.handleDeactivated();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.bind(listener); // need to bind again after deactivate
         mgr.handleActivated();
-        assertNoEvents(listener);
+        TestHelper.assertNoEvents(listener);
         mgr.handleChanging();
-        assertNoEvents(listener);
-        final BaseTopologyView view2 = new View().addInstance();
+        TestHelper.assertNoEvents(listener);
+        final BaseTopologyView view2 = new SimpleTopologyView().addInstance();
         mgr.handleNewView(view2);
-        assertEvents(listener, ViewStateManager.newInitEvent(view2));
+        assertEvents(listener, EventFactory.newInitEvent(view2));
     }
+    
+    @Test
+    public void testConsistencyService_noConcurrency() throws Exception {
+        final org.apache.log4j.Logger commonsLogger = LogManager.getRootLogger().getLogger("org.apache.sling.discovery.commons.providers");
+        final org.apache.log4j.Level logLevel = commonsLogger.getLevel();
+        commonsLogger.setLevel(Level.INFO); // change here to DEBUG in case of issues with this test
+        final Semaphore serviceSemaphore = new Semaphore(0);
+        final ReentrantLock lock = new ReentrantLock();
+        final ConsistencyServiceWithSemaphore cs = new ConsistencyServiceWithSemaphore(lock, serviceSemaphore );
+        mgr = new ViewStateManagerImpl(lock, cs);
+        final Listener listener = new Listener();
+        mgr.bind(listener);
+        TestHelper.assertNoEvents(listener);
+        mgr.handleActivated();
+        TestHelper.assertNoEvents(listener);
+        final String slingId1 = UUID.randomUUID().toString();
+        final String slingId2 = UUID.randomUUID().toString();
+        final String clusterId = UUID.randomUUID().toString();
+        final SimpleClusterView cluster = new SimpleClusterView(clusterId);
+        final SimpleTopologyView view1 = new SimpleTopologyView()
+                .addInstance(slingId1, cluster, true, true)
+                .addInstance(slingId2, cluster, false, false);
+        async(new Runnable() {
+
+            public void run() {
+                mgr.handleNewView(view1);
+            }
+            
+        });
+        Thread.sleep(1000);
+        TestHelper.assertNoEvents(listener);
+        serviceSemaphore.release(1);
+        Thread.sleep(1000);
+        assertEvents(listener, EventFactory.newInitEvent(view1));
+        mgr.handleChanging();
+        assertEvents(listener, EventFactory.newChangingEvent(view1));
+        final SimpleTopologyView view2 = SimpleTopologyView.clone(view1).removeInstance(slingId2);
+        async(new Runnable() {
+
+            public void run() {
+                mgr.handleNewView(view2);
+            }
+            
+        });
+        logger.debug("run: waiting for 1sec");
+        Thread.sleep(1000);
+        logger.debug("run: asserting no events");
+        TestHelper.assertNoEvents(listener);
+        logger.debug("run: releasing consistencyService");
+        serviceSemaphore.release(1);
+        logger.debug("run: waiting 1sec");
+        Thread.sleep(1000);
+        logger.debug("run: asserting 1 event");
+        assertEvents(listener, EventFactory.newChangedEvent(view1, view2));
+        commonsLogger.setLevel(Level.INFO); // back to default
+    }
+
+    private void async(Runnable runnable) {
+        new Thread(runnable).start();
+    }
+
+    @Test
+    public void testConsistencyService_withConcurrency() throws Exception {
+        final org.apache.log4j.Logger commonsLogger = LogManager.getRootLogger().getLogger("org.apache.sling.discovery.commons.providers");
+        final org.apache.log4j.Level logLevel = commonsLogger.getLevel();
+        commonsLogger.setLevel(Level.INFO); // change here to DEBUG in case of issues with this test
+        final Semaphore serviceSemaphore = new Semaphore(0);
+        final Semaphore testSemaphore = new Semaphore(0);
+        final ReentrantLock lock = new ReentrantLock();
+        final ConsistencyServiceWithSemaphore cs = new ConsistencyServiceWithSemaphore(lock, serviceSemaphore );
+        mgr = new ViewStateManagerImpl(lock, cs);
+        final Listener listener = new Listener();
+        mgr.bind(listener);
+        TestHelper.assertNoEvents(listener);
+        mgr.handleActivated();
+        TestHelper.assertNoEvents(listener);
+        final String slingId1 = UUID.randomUUID().toString();
+        final String slingId2 = UUID.randomUUID().toString();
+        final String slingId3 = UUID.randomUUID().toString();
+        final String clusterId = UUID.randomUUID().toString();
+        final SimpleClusterView cluster = new SimpleClusterView(clusterId);
+        final SimpleTopologyView view1 = new SimpleTopologyView()
+                .addInstance(slingId1, cluster, true, true)
+                .addInstance(slingId2, cluster, false, false)
+                .addInstance(slingId3, cluster, false, false);
+        final SimpleTopologyView view2 = SimpleTopologyView.clone(view1).removeInstance(slingId2);
+        final SimpleTopologyView view3 = SimpleTopologyView.clone(view1).removeInstance(slingId2).removeInstance(slingId3);
+        async(new Runnable() {
+
+            public void run() {
+                mgr.handleNewView(view1);
+            }
+            
+        });
+        Thread.sleep(1000);
+        TestHelper.assertNoEvents(listener);
+        serviceSemaphore.release(1); // release the first one only
+        Thread.sleep(1000);
+        assertEvents(listener, EventFactory.newInitEvent(view1));
+        mgr.handleChanging();
+        assertEvents(listener, EventFactory.newChangingEvent(view1));
+        async(new Runnable() {
+
+            public void run() {
+                mgr.handleNewView(view2);
+            }
+            
+        });
+        logger.debug("run: waiting 1sec");
+        Thread.sleep(1000);
+        logger.debug("run: asserting no events");
+        TestHelper.assertNoEvents(listener);
+        assertFalse("should not be locked", lock.isLocked());
+
+        logger.debug("run: issuing a second event");
+        // before releasing, issue another event, lets do a combination of changing/changed
+        async(new Runnable() {
 
-    private BaseTopologyView clone(final BaseTopologyView view) {
-        return new View(view);
+            public void run() {
+                logger.debug("run2: calling handleChanging...");
+                mgr.handleChanging();
+                try {
+                    logger.debug("run2: done with handleChanging, acquiring testSemaphore...");
+                    testSemaphore.acquire();
+                    logger.debug("run2: calling handleNewView...");
+                    mgr.handleNewView(view3);
+                    logger.debug("run2: done with handleNewView...");
+                } catch (InterruptedException e) {
+                    // fail
+                    logger.error("interrupted: "+e, e);
+                }
+            }
+            
+        });
+        logger.debug("run: waiting 1sec");
+        Thread.sleep(1000);
+        assertEquals("should be acquiring (by thread2)", 1, testSemaphore.getQueueLength());
+        // releasing the testSemaphore
+        testSemaphore.release();
+        logger.debug("run: waiting 1sec");
+        Thread.sleep(1000);
+        assertEquals("should have both threads now waiting", 2, serviceSemaphore.getQueueLength());
+        logger.debug("run: releasing consistencyService");
+        serviceSemaphore.release(1); // release the first one only
+        logger.debug("run: waiting 1sec");
+        Thread.sleep(1000);
+        assertFalse("should not be locked", lock.isLocked());
+        TestHelper.assertNoEvents(listener); // this should not have triggered any event 
+        serviceSemaphore.release(1); // then release the 2nd one
+        logger.debug("run: waiting 1sec");
+        Thread.sleep(1000);
+        logger.debug("run: asserting 1 event");
+        final TopologyEvent changedEvent = EventFactory.newChangedEvent(view1, view3);
+        assertEvents(listener, changedEvent);
+        commonsLogger.setLevel(Level.INFO); // back to default
     }
+
 }

Added: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/DiscoLite.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/DiscoLite.java?rev=1707548&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/DiscoLite.java (added)
+++ sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/DiscoLite.java Thu Oct  8 14:31:45 2015
@@ -0,0 +1,74 @@
+/*
+ * 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.commons.providers.spi.impl;
+
+import java.util.Arrays;
+
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+
+// {"seq":8,"final":true,"id":"aae34e9a-b08d-409e-be10-9ff4106e5387","me":4,"active":[4],"deactivating":[],"inactive":[1,2,3]}
+public class DiscoLite {
+    
+    private int seqNum;
+    private int me;
+    private Integer[] activeIds = new Integer[0];
+    private Integer[] inactiveIds = new Integer[0];
+    private Integer[] deactivating = new Integer[0];
+
+    public DiscoLite() {
+        // nothing here
+    }
+    
+    public DiscoLite seq(int seqNum) {
+        this.seqNum = seqNum;
+        return this;
+    }
+
+    public DiscoLite me(int me) {
+        this.me = me;
+        return this;
+    }
+
+    public DiscoLite activeIds(Integer... activeIds) {
+        this.activeIds = activeIds;
+        return this;
+    }
+
+    public DiscoLite inactiveIds(Integer... inactiveIds) {
+        this.inactiveIds = inactiveIds;
+        return this;
+    }
+
+    public DiscoLite deactivatingIds(Integer... deactivating) {
+        this.deactivating = deactivating;
+        return this;
+    }
+    
+    public String asJson() throws JSONException {
+        JSONObject json = new JSONObject();
+        json.put("me", me);
+        json.put("seq", seqNum);
+        json.put("active", new JSONArray(Arrays.asList(activeIds)));
+        json.put("inactive", new JSONArray(Arrays.asList(inactiveIds)));
+        json.put("deactivating", new JSONArray(Arrays.asList(deactivating)));
+        return json.toString();
+    }
+}

Propchange: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/DiscoLite.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockFactory.java?rev=1707548&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockFactory.java (added)
+++ sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockFactory.java Thu Oct  8 14:31:45 2015
@@ -0,0 +1,85 @@
+/*
+ * 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.commons.providers.spi.impl;
+
+import javax.jcr.Session;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.commons.testing.jcr.RepositoryProvider;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.hamcrest.Description;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.api.Action;
+import org.jmock.api.Invocation;
+import org.jmock.integration.junit4.JUnit4Mockery;
+
+public class MockFactory {
+
+    public final Mockery context = new JUnit4Mockery();
+
+    public static ResourceResolverFactory mockResourceResolverFactory()
+            throws Exception {
+    	return mockResourceResolverFactory(null);
+    }
+
+    public static ResourceResolverFactory mockResourceResolverFactory(final SlingRepository repositoryOrNull)
+            throws Exception {
+        Mockery context = new JUnit4Mockery();
+
+        final ResourceResolverFactory resourceResolverFactory = context
+                .mock(ResourceResolverFactory.class);
+        // final ResourceResolver resourceResolver = new MockResourceResolver();
+        // final ResourceResolver resourceResolver = new
+        // MockedResourceResolver();
+
+        context.checking(new Expectations() {
+            {
+                allowing(resourceResolverFactory)
+                        .getAdministrativeResourceResolver(null);
+                will(new Action() {
+
+                    public Object invoke(Invocation invocation)
+                            throws Throwable {
+                    	return new MockedResourceResolver(repositoryOrNull);
+                    }
+
+                    public void describeTo(Description arg0) {
+                        arg0.appendText("whateva - im going to create a new mockedresourceresolver");
+                    }
+                });
+            }
+        });
+        return resourceResolverFactory;
+    }
+
+    public static void resetRepo() throws Exception {
+        Session l = RepositoryProvider.instance().getRepository()
+                .loginAdministrative(null);
+        try {
+            l.removeItem("/var");
+            l.save();
+            l.logout();
+        } catch (Exception e) {
+            l.refresh(false);
+            l.logout();
+        }
+    }
+    
+}

Propchange: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResource.java?rev=1707548&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResource.java (added)
+++ sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResource.java Thu Oct  8 14:31:45 2015
@@ -0,0 +1,296 @@
+/*
+ * 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.commons.providers.spi.impl;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+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.ModifiableValueMap;
+import org.apache.sling.api.resource.SyntheticResource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MockedResource extends SyntheticResource {
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private final MockedResourceResolver mockedResourceResolver;
+    private Session session;
+
+    public MockedResource(MockedResourceResolver resourceResolver, String path,
+            String resourceType) {
+        super(resourceResolver, path, resourceType);
+        mockedResourceResolver = resourceResolver;
+
+        resourceResolver.register(this);
+    }
+
+    private Session getSession() {
+        synchronized (this) {
+            if (session == null) {
+                try {
+                    session = mockedResourceResolver.getSession();
+                } catch (RepositoryException e) {
+                    throw new RuntimeException("RepositoryException: " + e, e);
+                }
+            }
+            return session;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+//        close();
+        super.finalize();
+    }
+
+    public void close() {
+        synchronized (this) {
+            if (session != null) {
+                if (session.isLive()) {
+                    session.logout();
+                }
+                session = null;
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type.equals(Node.class)) {
+            try {
+                return (AdapterType) getSession().getNode(getPath());
+            } catch (Exception e) {
+                logger.error("Exception occurred: "+e, e);
+                throw new RuntimeException("Exception occurred: " + e, e);
+            }
+        } else if (type.equals(ValueMap.class)) {
+            try {
+                Session session = getSession();
+                Node node = session.getNode(getPath());
+                HashMap<String, Object> map = new HashMap<String, Object>();
+
+                PropertyIterator properties = node.getProperties();
+                while (properties.hasNext()) {
+                    Property p = properties.nextProperty();
+                    if (p.getType() == PropertyType.BOOLEAN) {
+                        map.put(p.getName(), p.getBoolean());
+                    } else if (p.getType() == PropertyType.STRING) {
+                        map.put(p.getName(), p.getString());
+                    } else if (p.getType() == PropertyType.DATE) {
+                        map.put(p.getName(), p.getDate().getTime());
+                    } else if (p.getType() == PropertyType.NAME) {
+                        map.put(p.getName(), p.getName());
+                    } else if (p.getType() == PropertyType.LONG) {
+                        map.put(p.getName(), p.getLong());
+                    } else {
+                        throw new RuntimeException(
+                                "Unsupported property type: " + p.getType());
+                    }
+                }
+                ValueMap valueMap = new ValueMapDecorator(map);
+                return (AdapterType) valueMap;
+            } catch (Exception e) {
+                e.printStackTrace();
+                return null;
+            }
+        } else if (type.equals(ModifiableValueMap.class)) {
+            return (AdapterType) new ModifiableValueMap() {
+                
+                public Collection<Object> values() {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public int size() {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public Object remove(Object arg0) {
+                    Session session = getSession();
+                    try{
+                        final Node node = session.getNode(getPath());
+                        final Property p = node.getProperty(String.valueOf(arg0));
+                        if (p!=null) {
+                        	p.remove();
+                        }
+                        // this is not according to the spec - but OK for tests since
+                        // the return value is never used
+                        return null;
+                    } catch(PathNotFoundException pnfe) {
+                    	// perfectly fine
+                    	return null;
+                    } catch(RepositoryException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                
+                public void putAll(Map<? extends String, ? extends Object> arg0) {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public Object put(String arg0, Object arg1) {
+                    Session session = getSession();
+                    try{
+                        final Node node = session.getNode(getPath());
+                        Object result = null;
+                        if (node.hasProperty(arg0)) {
+                            final Property previous = node.getProperty(arg0);
+                            if (previous==null) {
+                                // null
+                            } else if (previous.getType() == PropertyType.STRING) {
+                                result = previous.getString();
+                            } else if (previous.getType() == PropertyType.DATE) {
+                                result = previous.getDate();
+                            } else if (previous.getType() == PropertyType.BOOLEAN) {
+                                result = previous.getBoolean();
+                            } else {
+                                throw new UnsupportedOperationException();
+                            }
+                        }
+                        if (arg1 instanceof String) {
+                            node.setProperty(arg0, (String)arg1);
+                        } else if (arg1 instanceof Calendar) {
+                            node.setProperty(arg0, (Calendar)arg1);
+                        } else if (arg1 instanceof Boolean) {
+                            node.setProperty(arg0, (Boolean)arg1);
+                        } else if (arg1 instanceof Date) {
+                            final Calendar c = Calendar.getInstance();
+                            c.setTime((Date)arg1);
+                            node.setProperty(arg0, c);
+                        } else if (arg1 instanceof Number) {
+                            Number n = (Number)arg1;
+                            node.setProperty(arg0, n.longValue());
+                        } else {
+                            throw new UnsupportedOperationException();
+                        }
+                        return result;
+                    } catch(RepositoryException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                
+                public Set<String> keySet() {
+                    Session session = getSession();
+                    try {
+                        final Node node = session.getNode(getPath());
+                        final PropertyIterator pi = node.getProperties();
+                        final Set<String> result = new HashSet<String>();
+                        while(pi.hasNext()) {
+                            final Property p = pi.nextProperty();
+                            result.add(p.getName());
+                        }
+                        return result;
+                    } catch (RepositoryException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                
+                public boolean isEmpty() {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public Object get(Object arg0) {
+                    Session session = getSession();
+                    try{
+                        final Node node = session.getNode(getPath());
+                        final String key = String.valueOf(arg0);
+                        if (node.hasProperty(key)) {
+                            return node.getProperty(key);
+                        } else {
+                            return null;
+                        }
+                    } catch(RepositoryException re) {
+                        throw new RuntimeException(re);
+                    }
+                }
+                
+                public Set<Entry<String, Object>> entrySet() {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public boolean containsValue(Object arg0) {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public boolean containsKey(Object arg0) {
+                    Session session = getSession();
+                    try{
+                        final Node node = session.getNode(getPath());
+                        return node.hasProperty(String.valueOf(arg0));
+                    } catch(RepositoryException re) {
+                        throw new RuntimeException(re);
+                    }
+                }
+                
+                public void clear() {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public <T> T get(String name, T defaultValue) {
+                    throw new UnsupportedOperationException();
+                }
+                
+                public <T> T get(String name, Class<T> type) {
+                    Session session = getSession();
+                    try{
+                        final Node node = session.getNode(getPath());
+                        if (node==null) {
+                        	return null;
+                        }
+                        if (!node.hasProperty(name)) {
+                            return null;
+                        }
+                        Property p = node.getProperty(name);
+                        if (p==null) {
+                        	return null;
+                        }
+                        if (type.equals(Calendar.class)) {
+                        	return (T) p.getDate();
+                        } else if (type.equals(String.class)) {
+                        	return (T) p.getString();
+                        } else {
+                            throw new UnsupportedOperationException();
+                        }
+                    } catch(RepositoryException e) {
+                    	throw new RuntimeException(e);
+                    }
+                }
+            };
+        } else {
+            return super.adaptTo(type);
+        }
+    }
+
+}

Propchange: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResourceResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResourceResolver.java?rev=1707548&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResourceResolver.java (added)
+++ sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResourceResolver.java Thu Oct  8 14:31:45 2015
@@ -0,0 +1,329 @@
+/*
+ * 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.commons.providers.spi.impl;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.testing.jcr.RepositoryProvider;
+import org.apache.sling.commons.testing.jcr.RepositoryUtil;
+import org.apache.sling.jcr.api.SlingRepository;
+
+public class MockedResourceResolver implements ResourceResolver {
+
+	private final SlingRepository repository;
+
+	private Session session;
+
+    private List<MockedResource> resources = new LinkedList<MockedResource>();
+
+    public MockedResourceResolver() throws RepositoryException {
+    	this(null);
+    }
+
+    public MockedResourceResolver(SlingRepository repositoryOrNull) throws RepositoryException {
+    	if (repositoryOrNull==null) {
+    		this.repository = RepositoryProvider.instance().getRepository();
+    		Session adminSession = null;
+    		try {
+    		    adminSession = this.repository.loginAdministrative(null);
+                RepositoryUtil.registerSlingNodeTypes(adminSession);
+    		} catch ( final IOException ioe ) {
+    		    throw new RepositoryException(ioe);
+    		} finally {
+    		    if ( adminSession != null ) {
+    		        adminSession.logout();
+    		    }
+    		}
+    	} else {
+    		this.repository = repositoryOrNull;
+    	}
+    }
+
+    public Session getSession() throws RepositoryException {
+        synchronized (this) {
+            if (session != null) {
+                return session;
+            }
+            session = createSession();
+            return session;
+        }
+    }
+
+    private Repository getRepository() {
+    	return repository;
+    }
+
+    private Session createSession() throws RepositoryException {
+        final Credentials credentials = new SimpleCredentials("admin",
+                "admin".toCharArray());
+        return repository.login(credentials, "default");
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type.equals(Session.class)) {
+            try {
+                return (AdapterType) getSession();
+            } catch (RepositoryException e) {
+                throw new RuntimeException("RepositoryException: " + e, e);
+            }
+        } else if (type.equals(Repository.class)) {
+        	return (AdapterType) getRepository();
+        }
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Resource resolve(HttpServletRequest request, String absPath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Resource resolve(String absPath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    @Deprecated
+    public Resource resolve(HttpServletRequest request) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public String map(String resourcePath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public String map(HttpServletRequest request, String resourcePath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Resource getResource(String path) {
+        Session session;
+        try {
+            session = getSession();
+            session.getNode(path);
+        } catch (PathNotFoundException e) {
+            return null;
+        } catch (RepositoryException e) {
+            throw new RuntimeException("RepositoryException: " + e, e);
+        }
+        return new MockedResource(this, path, "nt:unstructured");
+    }
+
+    public Resource getResource(Resource base, String path) {
+        if (base.getPath().equals("/")) {
+            return getResource("/" + path);
+        } else {
+            return getResource(base.getPath() + "/" + path);
+        }
+    }
+
+    public String[] getSearchPath() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<Resource> listChildren(Resource parent) {
+        try {
+            Node node = parent.adaptTo(Node.class);
+            final NodeIterator nodes = node.getNodes();
+            return new Iterator<Resource>() {
+
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+
+                public Resource next() {
+                    Node next = nodes.nextNode();
+                    try {
+                        return new MockedResource(MockedResourceResolver.this,
+                                next.getPath(), "nt:unstructured");
+                    } catch (RepositoryException e) {
+                        throw new RuntimeException("RepositoryException: " + e,
+                                e);
+                    }
+                }
+
+                public boolean hasNext() {
+                    return nodes.hasNext();
+                }
+            };
+        } catch (RepositoryException e) {
+            throw new RuntimeException("RepositoryException: " + e, e);
+        }
+    }
+
+    public Iterable<Resource> getChildren(Resource parent) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<Resource> findResources(String query, String language) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<Map<String, Object>> queryResources(String query,
+            String language) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public ResourceResolver clone(Map<String, Object> authenticationInfo)
+            throws LoginException {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public boolean isLive() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public void close() {
+        Iterator<MockedResource> it = resources.iterator();
+        while (it.hasNext()) {
+            MockedResource r = it.next();
+            r.close();
+        }
+        if (session != null) {
+            if (session.isLive()) {
+                session.logout();
+            }
+            session = null;
+        }
+    }
+
+    public void register(MockedResource mockedResource) {
+        resources.add(mockedResource);
+    }
+
+    public String getUserID() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<String> getAttributeNames() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Object getAttribute(String name) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public void delete(Resource resource) throws PersistenceException {
+        if (resources.contains(resource)) {
+            resources.remove(resource);
+            Node node = resource.adaptTo(Node.class);
+            try {
+                node.remove();
+            } catch (RepositoryException e) {
+                throw new PersistenceException("RepositoryException: "+e, e);
+            }
+        } else {
+            throw new UnsupportedOperationException("Not implemented");
+        }
+    }
+
+    public Resource create(Resource parent, String name,
+            Map<String, Object> properties) throws PersistenceException {
+        final Node parentNode = parent.adaptTo(Node.class);
+        try {
+            final Node child;
+            if (properties!=null && properties.containsKey("jcr:primaryType")) {
+                child = parentNode.addNode(name, (String) properties.get("jcr:primaryType"));
+            } else {
+                child = parentNode.addNode(name);
+            }
+            if (properties!=null) {
+                final Iterator<Entry<String, Object>> it = properties.entrySet().iterator();
+                while(it.hasNext()) {
+                    final Entry<String, Object> entry = it.next();
+                    if (entry.getKey().equals("jcr:primaryType")) {
+                        continue;
+                    }
+                    if (entry.getValue() instanceof String) {
+                        child.setProperty(entry.getKey(), (String)entry.getValue());
+                    } else if (entry.getValue() instanceof Boolean) {
+                        child.setProperty(entry.getKey(), (Boolean)entry.getValue());
+                    } else if (entry.getValue() instanceof Calendar) {
+                        child.setProperty(entry.getKey(), (Calendar)entry.getValue());
+                    } else {
+                        throw new UnsupportedOperationException("Not implemented (entry.getValue(): "+entry.getValue()+")");
+                    }
+                }
+            }
+            return getResource(parent, name);
+        } catch (RepositoryException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void revert() {
+        try {
+            this.session.refresh(false);
+        } catch (final RepositoryException re) {
+            throw new RuntimeException("Unable to commit changes.", re);
+        }
+    }
+
+    public void commit() throws PersistenceException {
+        try {
+            this.session.save();
+        } catch (final RepositoryException re) {
+            throw new PersistenceException("Unable to commit changes.", re);
+        }
+    }
+
+    public boolean hasChanges() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public String getParentResourceType(Resource resource) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getParentResourceType(String resourceType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public boolean isResourceType(Resource resource, String resourceType) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public void refresh() {
+        // TODO Auto-generated method stub
+
+    }
+
+}

Propchange: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/MockedResourceResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/RepositoryHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/RepositoryHelper.java?rev=1707548&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/RepositoryHelper.java (added)
+++ sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/RepositoryHelper.java Thu Oct  8 14:31:45 2015
@@ -0,0 +1,281 @@
+/*
+ * 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.commons.providers.spi.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.naming.NamingException;
+
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl;
+import org.apache.jackrabbit.oak.plugins.commit.ConflictValidatorProvider;
+import org.apache.jackrabbit.oak.plugins.commit.JcrConflictHandler;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
+import org.apache.jackrabbit.oak.plugins.name.NamespaceEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.plugins.version.VersionEditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.spi.whiteboard.DefaultWhiteboard;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.commons.testing.jcr.RepositoryUtil;
+import org.apache.sling.commons.testing.jcr.RepositoryUtil.RepositoryWrapper;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RepositoryHelper {
+
+    private static class ShutdownThread extends Thread {
+        
+        private SlingRepository repository;
+        
+        public ShutdownThread(SlingRepository repository) {
+            this.repository = repository;
+        }
+        @Override
+        public void run() {
+            try {
+                stopRepository(repository);
+            } catch(Exception e) {
+                System.out.println("Exception in ShutdownThread:" + e);
+            }
+        }
+        
+    }
+
+    private final static Logger logger = LoggerFactory.getLogger(RepositoryHelper.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 if (p.getType() == PropertyType.LONG) {
+                sb.append(p.getLong());
+            } 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);
+        }
+    }
+
+    static Map<SlingRepository,Session> adminSessions = new HashMap<SlingRepository, Session>();
+    /** from commons.testing.jcr **/
+    public static final String CONFIG_FILE = "jackrabbit-test-config.xml";
+
+    public static SlingRepository newRepository(String homeDir) throws RepositoryException {
+        SlingRepository repository = startRepository(homeDir);
+        Runtime.getRuntime().addShutdownHook(new ShutdownThread(repository));
+        return repository;
+    }
+
+    public static SlingRepository newOakRepository(NodeStore nodeStore) throws RepositoryException {
+            SlingRepository repository = new RepositoryWrapper(createOakRepository(nodeStore));
+    //        Runtime.getRuntime().addShutdownHook(new ShutdownThread(repository));
+            return repository;
+        }
+
+    public static void initSlingNodeTypes(SlingRepository repository) throws RepositoryException {
+        Session adminSession = null;
+        try {
+            adminSession = repository.loginAdministrative(null);
+            RepositoryUtil.registerSlingNodeTypes(adminSession);
+        } catch ( final IOException ioe ) {
+            throw new RepositoryException(ioe);
+        } finally {
+            if ( adminSession != null ) {
+                adminSession.logout();
+            }
+        }
+    }
+
+    /**
+     * Start a new repository
+     * @return 
+     *
+     * @throws RepositoryException when it is not possible to start the
+     *             repository.
+     */
+    private static RepositoryWrapper startRepository(String homeDir) throws RepositoryException {
+        // copy the repository configuration file to the repository HOME_DIR
+        InputStream ins = RepositoryUtil.class.getClassLoader().getResourceAsStream(
+            CONFIG_FILE);
+        if (ins == null) {
+            throw new RepositoryException("Cannot get " + CONFIG_FILE);
+        }
+    
+        File configFile = new File(homeDir, "repository.xml");
+        configFile.getParentFile().mkdirs();
+    
+        FileOutputStream out = null;
+        try {
+            out = new FileOutputStream(configFile);
+            byte[] buf = new byte[1024];
+            int rd;
+            while ((rd = ins.read(buf)) >= 0) {
+                out.write(buf, 0, rd);
+            }
+        } catch (IOException ioe) {
+            throw new RepositoryException("Cannot copy configuration file to "
+                + configFile);
+        } finally {
+            try {
+                ins.close();
+            } catch (IOException ignore) {
+            }
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    
+        // somewhat dirty hack to have the derby.log file in a sensible
+        // location, but don't overwrite anything already set
+        if (System.getProperty("derby.stream.error.file") == null) {
+            String derbyLog = homeDir + "/derby.log";
+            System.setProperty("derby.stream.error.file", derbyLog);
+        }
+    
+        final File f = new File(homeDir);
+        RepositoryWrapper repository = new RepositoryWrapper(JcrUtils.getRepository(f.toURI().toString()));
+        Session adminSession = repository.loginAdministrative(null);
+        adminSessions.put(repository, adminSession);
+        return repository;
+    }
+
+    /**
+     * Stop a repository.
+     */
+    public static void stopRepository(SlingRepository repository) throws NamingException {
+        Session adminSession = adminSessions.remove(repository);
+        if ( adminSession != null ) {
+            adminSession.logout();
+        }
+    }
+
+    public static Repository createOakRepository() {
+        return createOakRepository(new MemoryNodeStore());
+    }
+    
+    public static Repository createOakRepository(NodeStore nodeStore) {
+        DefaultWhiteboard whiteboard = new DefaultWhiteboard();
+        final Oak oak = new Oak(nodeStore)
+        .with(new InitialContent())
+//        .with(new ExtraSlingContent())
+
+        .with(JcrConflictHandler.createJcrConflictHandler())
+        .with(new EditorHook(new VersionEditorProvider()))
+
+        .with(new OpenSecurityProvider())
+
+//        .with(new ValidatorProvider() {
+//
+//            @Override
+//            public Validator getRootValidator(
+//                    NodeState before, NodeState after, CommitInfo info) {
+//                HashSet<String> set = newHashSet(after
+//                                .getChildNode(JCR_SYSTEM)
+//                                .getChildNode(REP_NAMESPACES)
+//                                .getChildNode(REP_NSDATA)
+//                                .getStrings(REP_PREFIXES));
+//                set.add("sling");
+//                return new NameValidator(set);
+//            }
+//        })
+        .with(new NamespaceEditorProvider())
+        .with(new TypeEditorProvider())
+//        .with(new RegistrationEditorProvider())
+        .with(new ConflictValidatorProvider())
+
+        // index stuff
+//        .with(indexProvider)
+//        .with(indexEditorProvider)
+        .with("default")//getDefaultWorkspace())
+//        .withAsyncIndexing()
+        .with(whiteboard)
+        ;
+        
+//        if (commitRateLimiter != null) {
+//            oak.with(commitRateLimiter);
+//        }
+
+        final ContentRepository contentRepository = oak.createContentRepository();
+        return new RepositoryImpl(contentRepository, whiteboard, new OpenSecurityProvider(), 1000, null);
+    }
+
+
+}

Propchange: sling/trunk/bundles/extensions/discovery/commons/src/test/java/org/apache/sling/discovery/commons/providers/spi/impl/RepositoryHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native