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 mr...@apache.org on 2014/02/25 12:02:32 UTC

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

Author: mreutegg
Date: Tue Feb 25 11:02:31 2014
New Revision: 1571646

URL: http://svn.apache.org/r1571646
Log:
OAK-1467: Commit.rollback() may remove changes from other commit

- add test, currently ignored

Modified:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1571646&r1=1571645&r2=1571646&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java Tue Feb 25 11:02:31 2014
@@ -17,7 +17,10 @@
 package org.apache.jackrabbit.oak.plugins.document;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.concurrent.Semaphore;
@@ -25,20 +28,24 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.annotation.Nonnull;
 
+import org.apache.jackrabbit.mk.api.MicroKernelException;
 import org.apache.jackrabbit.oak.kernel.KernelNodeState;
 import org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore;
 import org.apache.jackrabbit.oak.plugins.document.util.TimingDocumentStoreWrapper;
+import org.apache.jackrabbit.oak.plugins.document.util.Utils;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import com.google.common.collect.Iterables;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 public class DocumentNodeStoreTest {
@@ -164,4 +171,69 @@ public class DocumentNodeStoreTest {
 
         store.dispose();
     }
+
+    @Ignore("OAK-1467")
+    @Test
+    public void rollback() throws Exception {
+        final Map<Thread, Semaphore> locks = Collections.synchronizedMap(
+                new HashMap<Thread, Semaphore>());
+        final Semaphore created = new Semaphore(0);
+        DocumentStore docStore = new MemoryDocumentStore() {
+            @Override
+            public <T extends Document> boolean create(Collection<T> collection,
+                                                       List<UpdateOp> updateOps) {
+                Semaphore semaphore = locks.get(Thread.currentThread());
+                boolean result = super.create(collection, updateOps);
+                if (semaphore != null) {
+                    created.release();
+                    semaphore.acquireUninterruptibly();
+                }
+                return result;
+            }
+        };
+        final List<Exception> exceptions = new ArrayList<Exception>();
+        final DocumentMK mk = new DocumentMK.Builder()
+                .setDocumentStore(docStore).setAsyncDelay(0).open();
+        final DocumentNodeStore store = mk.getNodeStore();
+        final String head = mk.commit("/", "+\"foo\":{}+\"bar\":{}", null, null);
+        Thread writer = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Revision r = store.newRevision();
+                    Commit c = new Commit(store, Revision.fromString(head), r);
+                    c.addNode(new DocumentNodeState(store, "/foo/node", r));
+                    c.addNode(new DocumentNodeState(store, "/bar/node", r));
+                    c.apply();
+                } catch (MicroKernelException e) {
+                    exceptions.add(e);
+                }
+            }
+        });
+        final Semaphore s = new Semaphore(0);
+        locks.put(writer, s);
+        // will block in DocumentStore.create()
+        writer.start();
+        // wait for writer to create nodes
+        created.acquireUninterruptibly();
+        // commit will succeed and add collision marker to writer commit
+        Revision r = store.newRevision();
+        Commit c = new Commit(store, Revision.fromString(head), r);
+        c.addNode(new DocumentNodeState(store, "/foo/node", r));
+        c.addNode(new DocumentNodeState(store, "/bar/node", r));
+        c.apply();
+        // allow writer to continue
+        s.release();
+        writer.join();
+        assertEquals("expected exception", 1, exceptions.size());
+
+        String id = Utils.getIdFromPath("/foo/node");
+        NodeDocument doc = docStore.find(Collection.NODES, id);
+        assertNotNull("document with id " + id + " does not exist", doc);
+        id = Utils.getIdFromPath("/bar/node");
+        doc = docStore.find(Collection.NODES, id);
+        assertNotNull("document with id " + id + " does not exist", doc);
+
+        mk.dispose();
+    }
 }