You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ch...@apache.org on 2014/08/08 13:19:42 UTC

svn commit: r1616719 - /jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java

Author: chetanm
Date: Fri Aug  8 11:19:42 2014
New Revision: 1616719

URL: http://svn.apache.org/r1616719
Log:
OAK-2020 - NodeState view at given version is not stable with DocumentNodeStore

Adding a testcase

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java   (with props)

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java?rev=1616719&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java Fri Aug  8 11:19:42 2014
@@ -0,0 +1,197 @@
+/*
+ * 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.jackrabbit.oak.plugins.document;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.commit.AnnotatingConflictHandler;
+import org.apache.jackrabbit.oak.plugins.commit.ConflictHook;
+import org.apache.jackrabbit.oak.plugins.commit.ConflictValidatorProvider;
+import org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore;
+import org.apache.jackrabbit.oak.plugins.document.util.Utils;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.CompositeHook;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+
+public class NodeStoreDiffTest {
+    private NodeStore ns;
+    private final TestDocumentStore tds = new TestDocumentStore();
+
+    @Before
+    public void setUp() throws IOException {
+        ns = new DocumentMK.Builder()
+                .setDocumentStore(tds)
+                .setUseSimpleRevision(true) //To simplify debugging
+                .setAsyncDelay(0)
+                .memoryCacheSize(0) //Keep the cache size zero such that nodeCache is not used
+                .getNodeStore();
+    }
+
+    @Ignore("OAK-2020")
+    @Test
+    public void diffWithConflict() throws Exception{
+        //Last rev on /var would be 1-0-1
+        createNodes("/var/a", "/var/b/b1");
+
+        //1. Dummy commits to bump the version no
+        createNodes("/fake/b");
+        createNodes("/fake/c");
+
+        //Root rev = 3-0-1
+        //Root rev = 3-0-1
+
+        //2. Create a node under /var/a but hold on commit
+        NodeBuilder b1 = ns.getRoot().builder();
+        createNodes(b1, "/var/a/a1");
+
+        //3. Remove a node under /var/b and commit it
+        NodeBuilder b2 = ns.getRoot().builder();
+        b2.child("var").child("b").child("b1").remove();
+        merge(b2);
+
+        //4. Now merge and commit the changes in b1 and include conflict hooks
+        //For now exception would be thrown
+        ns.merge(b1,
+                new CompositeHook(
+                        new ConflictHook(new AnnotatingConflictHandler()),
+                        new EditorHook(new ConflictValidatorProvider())
+                ),
+                CommitInfo.EMPTY);
+    }
+
+    /**
+     * This testcase demonstrates that diff logic in merge part traverses node path
+     * which are not affected by the commit
+     * @throws Exception
+     */
+    @Ignore("OAK-2020")
+    @Test
+    public void testDiff() throws Exception{
+        createNodes("/oak:index/prop-a", "/oak:index/prop-b", "/etc/workflow");
+
+        //1. Make some other changes so as to bump root rev=3
+        createNodes("/fake/a");
+        createNodes("/fake/b");
+
+        //2 - Start change
+        NodeBuilder b2 = ns.getRoot().builder();
+        createNodes(b2, "/etc/workflow/instance1");
+
+        tds.reset();
+        //3. Merge which does a rebase
+        ns.merge(b2, new CommitHook() {
+            public NodeState processCommit(NodeState before, NodeState after, CommitInfo info) throws CommitFailedException {
+                NodeBuilder rb = after.builder();
+                createNodes(rb, "/oak:index/prop-a/a1");
+
+                //2.1 Commit some change under prop-
+                //This cause diff in lastRev of base node state in ModifiedNodeState for
+                //oak:index due to which when the base state is compared in ModifiedNodeState
+                //then it fetches the new DocumentNodeState whose lastRev is greater than this.base.lastRev
+                //but less then lastRev of the of readRevision. Where readRevision is the rev of root node when
+                //rebase was performed
+
+                //This is not to be done in actual cases as CommitHooks are invoked in critical sections
+                //and creating nodes from within CommitHooks would cause deadlock. This is done here to ensure
+                //that changes are done when rebase has been performed and merge is about to happen
+                createNodes("/oak:index/prop-b/b1");
+
+                //For now we the cache is disabled (size 0) so this is not required
+                //ns.nodeCache.invalidateAll();
+
+                return rb.getNodeState();
+            }
+        }, CommitInfo.EMPTY);
+
+        //Assert that diff logic does not traverse to /oak:index/prop-b/b1 as
+        //its not part of commit
+        assertFalse(tds.paths.contains("/oak:index/prop-b/b1"));
+    }
+
+    private NodeState merge(NodeBuilder nb) throws CommitFailedException {
+        NodeState result = ns.merge(nb, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        prRev(result);
+        ops();
+        return result;
+    }
+
+    private void ops(){
+        if(ns instanceof DocumentNodeStore) {
+            DocumentNodeStore dns = ((DocumentNodeStore) ns);
+            dns.runBackgroundOperations();
+            //Background ops are disabled for simple revisions
+            dns.backgroundWrite();
+        }
+    }
+
+    private NodeState createNodes(String... paths) throws CommitFailedException {
+        NodeBuilder nb = ns.getRoot().builder();
+        createNodes(nb, paths);
+        NodeState result = merge(nb);
+        return result;
+    }
+
+    private static void createNodes(NodeBuilder builder, String... paths) {
+        for(String path : paths) {
+            NodeBuilder cb = builder;
+            for (String name : PathUtils.elements(path)) {
+                cb = cb.child(name);
+            }
+        }
+    }
+
+    private void prRev(NodeState ns){
+        if(ns instanceof DocumentNodeState){
+            DocumentNodeState dns = ((DocumentNodeState) ns);
+            System.out.printf("Root at %s (%s) %n", dns.getRevision(), dns.getLastRevision());
+        }
+    }
+
+
+    private static class TestDocumentStore extends MemoryDocumentStore {
+        final List<String> paths = Lists.newArrayList();
+
+        @Override
+        public <T extends Document> T find(Collection<T> collection, String key) {
+            if(collection == Collection.NODES){
+                paths.add(Utils.getPathFromId(key));
+            }
+            return super.find(collection, key);
+        }
+
+        void reset(){
+            paths.clear();
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java
------------------------------------------------------------------------------
    svn:eol-style = native