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 2015/09/22 15:54:42 UTC
svn commit: r1704629 - in
/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document:
AbstractMongoConnectionTest.java DocumentMKTestBase.java
mongo/ClusterConflictTest.java
Author: mreutegg
Date: Tue Sep 22 13:54:39 2015
New Revision: 1704629
URL: http://svn.apache.org/viewvc?rev=1704629&view=rev
Log:
OAK-3433: Commit does not detect conflict when background read happens after rebase
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractMongoConnectionTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKTestBase.java
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractMongoConnectionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractMongoConnectionTest.java?rev=1704629&r1=1704628&r2=1704629&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractMongoConnectionTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractMongoConnectionTest.java Tue Sep 22 13:54:39 2015
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.oak.plugins.document;
+import com.mongodb.DB;
+
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
import org.apache.jackrabbit.oak.stats.Clock;
import org.junit.After;
@@ -43,7 +45,11 @@ public abstract class AbstractMongoConne
mongoConnection = MongoUtils.getConnection();
MongoUtils.dropCollections(mongoConnection.getDB());
Revision.setClock(getTestClock());
- mk = new DocumentMK.Builder().clock(getTestClock()).setMongoDB(mongoConnection.getDB()).open();
+ mk = newBuilder(mongoConnection.getDB()).open();
+ }
+
+ protected DocumentMK.Builder newBuilder(DB db) throws Exception {
+ return new DocumentMK.Builder().clock(getTestClock()).setMongoDB(db);
}
protected Clock getTestClock() throws InterruptedException {
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKTestBase.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKTestBase.java?rev=1704629&r1=1704628&r2=1704629&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKTestBase.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKTestBase.java Tue Sep 22 13:54:39 2015
@@ -196,4 +196,12 @@ public abstract class DocumentMKTestBase
}
return rev;
}
+
+ protected void runBackgroundUpdate(DocumentNodeStore store) {
+ store.runBackgroundUpdateOperations();
+ }
+
+ protected void runBackgroundRead(DocumentNodeStore store) {
+ store.runBackgroundReadOperations();
+ }
}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java?rev=1704629&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java Tue Sep 22 13:54:39 2015
@@ -0,0 +1,140 @@
+/*
+ * 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.mongo;
+
+import javax.annotation.Nonnull;
+
+import com.mongodb.DB;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.document.AbstractMongoConnectionTest;
+import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
+import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
+import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+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.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class ClusterConflictTest extends AbstractMongoConnectionTest {
+
+ private DocumentNodeStore ns2;
+
+ @Override
+ public void setUpConnection() throws Exception {
+ super.setUpConnection();
+ ns2 = newBuilder(MongoUtils.getConnection().getDB()).getNodeStore();
+ }
+
+ @Override
+ protected DocumentMK.Builder newBuilder(DB db) throws Exception {
+ return super.newBuilder(db).setAsyncDelay(0).setLeaseCheck(false);
+ }
+
+ @Override
+ public void tearDownConnection() throws Exception {
+ ns2.dispose();
+ super.tearDownConnection();
+ }
+
+ // OAK-3433
+ @Ignore
+ @Test
+ public void mergeRetryWhileBackgroundRead() throws Exception {
+ DocumentNodeStore ns1 = mk.getNodeStore();
+ NodeBuilder b1 = ns1.getRoot().builder();
+ b1.child("a").child("b").child("c").child("foo");
+ merge(ns1, b1);
+ ns1.runBackgroundOperations();
+ ns2.runBackgroundOperations();
+
+ NodeBuilder b2 = ns2.getRoot().builder();
+ // force cache fill
+ assertNodeExists(b2, "/a/b/c/foo");
+
+ // remove /a/b/c on ns1
+ b1 = ns1.getRoot().builder();
+ b1.child("a").child("b").child("c").remove();
+ merge(ns1, b1);
+
+ // perform some change on ns2
+ b2.child("z");
+ merge(ns2, b2);
+ runBackgroundUpdate(ns2);
+
+ // this will pickup changes done by ns2 and update
+ // the head revision
+ runBackgroundRead(ns1);
+ // the next step is where the issue described
+ // in OAK-3433 occurs.
+ // the journal entry with changes done on ns1 is pushed
+ // with the current head revision, which is newer
+ // than the most recent change in the journal entry
+ runBackgroundUpdate(ns1);
+
+ // perform a background read after the rebase
+ // the first merge attempt will fail with a conflict
+ // because /a/b/c is seen as changed in the future
+ // without the fix for OAK-3433:
+ // the second merge attempt succeeds because now the
+ // /a/b/c change is visible and happened before the commit
+ // revision but before the base revision
+ b2 = ns2.getRoot().builder();
+ b2.child("z").setProperty("q", "v");
+ try {
+ ns2.merge(b2, new CommitHook() {
+ @Nonnull
+ @Override
+ public NodeState processCommit(NodeState before,
+ NodeState after,
+ CommitInfo info)
+ throws CommitFailedException {
+ runBackgroundRead(ns2);
+
+ NodeBuilder builder = after.builder();
+ builder.child("a").child("b").child("c").child("bar");
+ return builder.getNodeState();
+ }
+ }, CommitInfo.EMPTY);
+ fail("Merge must fail with CommitFailedException");
+ } catch (CommitFailedException e) {
+ e.printStackTrace();
+ // expected
+ }
+ }
+
+ private void assertNodeExists(NodeBuilder builder, String path) {
+ for (String name : PathUtils.elements(path)) {
+ builder = builder.getChildNode(name);
+ assertTrue("node '" + name + "' does not exist", builder.exists());
+ }
+ }
+
+ private static void merge(NodeStore store,
+ NodeBuilder builder) throws Exception {
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java
------------------------------------------------------------------------------
svn:eol-style = native