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 2013/12/03 09:37:58 UTC
svn commit: r1547314 - in
/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr:
ConcurrentAddNodesClusterIT.java OakMongoMKRepositoryStub.java
Author: mreutegg
Date: Tue Dec 3 08:37:58 2013
New Revision: 1547314
URL: http://svn.apache.org/r1547314
Log:
OAK-1254: Parallel execution of SimpleSearchTest fails with MongoMK
- add standalone test to reproduce exception
Added:
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java (with props)
Modified:
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/OakMongoMKRepositoryStub.java
Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java?rev=1547314&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java Tue Dec 3 08:37:58 2013
@@ -0,0 +1,182 @@
+/*
+ * 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.jcr;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
+import org.apache.jackrabbit.oak.plugins.mongomk.MongoMK;
+import org.apache.jackrabbit.oak.plugins.mongomk.util.MongoConnection;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Concurrently add nodes with multiple sessions on multiple cluster nodes.
+ */
+@Ignore("OAK-1254")
+public class ConcurrentAddNodesClusterIT {
+
+ private static final int NUM_CLUSTER_NODES = 3;
+ private static final int NODE_COUNT = 100;
+ private static final String PROP_NAME = "testcount";
+
+ private List<MongoMK> mks = new ArrayList<MongoMK>();
+ private List<Thread> workers = new ArrayList<Thread>();
+
+ @BeforeClass
+ public static void mongoDBAvailable() {
+ Assume.assumeTrue(OakMongoMKRepositoryStub.isMongoDBAvailable());
+ }
+
+ @Before
+ public void before() throws Exception {
+ dropDB();
+ initRepository();
+ for (int i = 0; i < NUM_CLUSTER_NODES; i++) {
+ MongoMK mk = new MongoMK.Builder()
+ .setMongoDB(createConnection().getDB())
+ .setClusterId(i + 1).open();
+ mks.add(mk);
+ }
+ }
+
+ @After
+ public void after() throws Exception {
+ for (MongoMK mk : mks) {
+ mk.dispose();
+ }
+ dropDB();
+ }
+
+ @Test
+ public void addNodes() throws Exception {
+ Map<String, Exception> exceptions = Collections.synchronizedMap(new HashMap<String, Exception>());
+ for (int i = 0; i < mks.size(); i++) {
+ MongoMK mk = mks.get(i);
+ Repository repo = new Jcr(mk).createRepository();
+ workers.add(new Thread(new Worker(repo, exceptions), "Worker-" + (i + 1)));
+ }
+ for (Thread t : workers) {
+ t.start();
+ }
+ for (Thread t : workers) {
+ t.join();
+ }
+ for (Map.Entry<String, Exception> entry : exceptions.entrySet()) {
+ // System.out.println("exception in thread " + entry.getKey());
+ throw entry.getValue();
+ }
+ }
+
+ private static MongoConnection createConnection() throws Exception {
+ return OakMongoMKRepositoryStub.createConnection(
+ ConcurrentAddNodesClusterIT.class.getSimpleName());
+ }
+
+ private static void dropDB() throws Exception {
+ MongoConnection con = createConnection();
+ try {
+ con.getDB().dropDatabase();
+ } finally {
+ con.close();
+ }
+ }
+
+ private static void initRepository() throws Exception {
+ MongoConnection con = createConnection();
+ MongoMK mk = new MongoMK.Builder()
+ .setMongoDB(con.getDB())
+ .setClusterId(1).open();
+ Session session = new Jcr(mk).createRepository().login(
+ new SimpleCredentials("admin", "admin".toCharArray()));
+ session.logout();
+ mk.dispose(); // closes connection as well
+ }
+
+
+ private static void ensureIndex(Node root, String propertyName)
+ throws RepositoryException {
+ Node indexDef = root.getNode(IndexConstants.INDEX_DEFINITIONS_NAME);
+ if (indexDef.hasNode(propertyName)) {
+ return;
+ }
+ Node index = indexDef.addNode(propertyName, IndexConstants.INDEX_DEFINITIONS_NODE_TYPE);
+ index.setProperty(IndexConstants.TYPE_PROPERTY_NAME,
+ PropertyIndexEditorProvider.TYPE);
+ index.setProperty(IndexConstants.REINDEX_PROPERTY_NAME,
+ true);
+ index.setProperty(IndexConstants.PROPERTY_NAMES,
+ new String[] { propertyName }, PropertyType.NAME);
+ try {
+ root.getSession().save();
+ } catch (RepositoryException e) {
+ // created by other thread -> ignore
+ }
+ }
+
+ private static final class Worker implements Runnable {
+
+ private final Repository repo;
+ private final Map<String, Exception> exceptions;
+
+ Worker(Repository repo, Map<String, Exception> exceptions) {
+ this.repo = repo;
+ this.exceptions = exceptions;
+ }
+
+ @Override
+ public void run() {
+ try {
+ Session session = repo.login(new SimpleCredentials(
+ "admin", "admin".toCharArray()));
+ ensureIndex(session.getRootNode(), PROP_NAME);
+
+ String nodeName = "testroot-" + Thread.currentThread().getName();
+ Node root = session.getRootNode().addNode(nodeName, "nt:unstructured");
+ for (int i = 0; i < NODE_COUNT; i++) {
+ Node node = root.addNode(PROP_NAME + i, "nt:unstructured");
+ for (int j = 0; j < NODE_COUNT; j++) {
+ Node child = node.addNode("node" + j, "nt:unstructured");
+ child.setProperty(PROP_NAME, j);
+ }
+ if (!exceptions.isEmpty()) {
+ break;
+ }
+ session.save();
+ }
+ } catch (Exception e) {
+ exceptions.put(Thread.currentThread().getName(), e);
+ }
+ }
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConcurrentAddNodesClusterIT.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/OakMongoMKRepositoryStub.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/OakMongoMKRepositoryStub.java?rev=1547314&r1=1547313&r2=1547314&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/OakMongoMKRepositoryStub.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/OakMongoMKRepositoryStub.java Tue Dec 3 08:37:58 2013
@@ -117,8 +117,7 @@ public class OakMongoMKRepositoryStub ex
public static boolean isMongoDBAvailable() {
MongoConnection connection = null;
try {
- connection = new MongoConnection(HOST, PORT, DB);
- connection.getDB().command(new BasicDBObject("ping", 1));
+ connection = createConnection(DB);
return true;
} catch (Exception e) {
return false;
@@ -129,6 +128,20 @@ public class OakMongoMKRepositoryStub ex
}
}
+ static MongoConnection createConnection(String db) throws Exception {
+ boolean success = false;
+ MongoConnection con = new MongoConnection(HOST, PORT, db);
+ try {
+ con.getDB().command(new BasicDBObject("ping", 1));
+ success = true;
+ } finally {
+ if (!success) {
+ con.close();
+ }
+ }
+ return con;
+ }
+
/**
* Returns the configured repository instance.
*