You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/04/09 11:41:01 UTC
svn commit: r932318 -
/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java
Author: jukka
Date: Fri Apr 9 09:41:00 2010
New Revision: 932318
URL: http://svn.apache.org/viewvc?rev=932318&view=rev
Log:
JCR-2579: InvalidItemStateException when attempting concurrent, non conflicting writes
Improve the concurrent node modification test case
Modified:
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java?rev=932318&r1=932317&r2=932318&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java Fri Apr 9 09:41:00 2010
@@ -17,13 +17,13 @@
package org.apache.jackrabbit.core;
import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.jcr.Node;
+import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
-import java.util.Random;
-import java.util.ArrayList;
-import java.util.Iterator;
/**
* Performs a test with n sessions concurrently performing non-conflicting
@@ -33,118 +33,100 @@ import java.util.Iterator;
*/
public class ConcurrentNodeModificationTest extends AbstractJCRTest {
- private static final int NUM_ITERATIONS = 1;
- private static final int NUM_SESSIONS = 10;
- private static final int NUM_NODES = 100;
+ /**
+ * Logger instance.
+ */
+ private static final Logger log =
+ LoggerFactory.getLogger(ConcurrentNodeModificationTest.class);
- final ArrayList exceptions = new ArrayList();
+ private static final int NUM_SESSIONS = 100;
+ private static final int NUM_ITERATIONS = 10;
+ private static final int NUM_NODES = 10;
+
+ private volatile boolean success;
/**
* Runs the test.
*/
public void testConcurrentNodeModificationSessions() throws Exception {
- int n = NUM_ITERATIONS;
- while (n-- > 0) {
- Thread[] threads = new Thread[NUM_SESSIONS];
- for (int i = 0; i < threads.length; i++) {
- // create new session
- Session session = getHelper().getSuperuserSession();
- TestSession ts = new TestSession("s" + i, session);
- Thread t = new Thread(ts);
- t.setName((NUM_ITERATIONS - n) + "-s" + i);
- t.start();
- log.println("Thread#" + i + " started");
- threads[i] = t;
- Thread.sleep(100);
- }
- for (int i = 0; i < threads.length; i++) {
- threads[i].join();
- }
- }
+ success = true;
- if (!exceptions.isEmpty()) {
- Exception e = null;
- for (Iterator it = exceptions.iterator(); it.hasNext();) {
- e = (Exception) it.next();
- e.printStackTrace(log);
- }
- throw e;
- //fail();
+ Thread[] threads = new Thread[NUM_SESSIONS];
+ for (int i = 0; i < threads.length; i++) {
+ TestSession ts = new TestSession("s" + i);
+ threads[i] = new Thread(ts, "CNMT " + i);
+ }
+ for (Thread thread : threads) {
+ thread.start();
}
+ for (Thread thread : threads) {
+ thread.join();
+ }
+
+ assertTrue("Unexpected exceptions during test, see the log file for details", success);
}
//--------------------------------------------------------< inner classes >
class TestSession implements Runnable {
- Session session;
- String identity;
- Random r;
+ private final Session session;
+ private final String identity;
- TestSession(String identity, Session s) {
- session = s;
+ TestSession(String identity) throws RepositoryException {
+ this.session = getHelper().getSuperuserSession();
this.identity = identity;
- r = new Random();
}
- private void randomSleep() {
- long l = r.nextInt(90) + 20;
+ public void run() {
+ log.debug("started.");
try {
- Thread.sleep(l);
- } catch (InterruptedException ie) {
+ for (int i = 0; success && i < NUM_ITERATIONS; i++) {
+ runIteration();
+ }
+ } catch (Exception e) {
+ log.error("Operation failed", e);
+ success = false;
+ } finally {
+ session.logout();
}
- }
- public void run() {
+ log.info("ended.");
+ }
- log.println("started.");
- String state = "";
- try {
- Node n = session.getRootNode().getNode(testPath);
+ private void runIteration() throws RepositoryException {
+ Node n = session.getRootNode().getNode(testPath);
- String propName = "testprop" + Math.random();
+ String propName = "prop_" + identity;
- state = "setting property " + propName;
- n.setProperty(propName, "Hello World!");
+ log.info("setting property {}", propName);
+ n.setProperty(propName, "Hello World!");
+ Thread.yield(); // maximize chances of interference
+ session.save();
+
+ log.info("removing property {}", propName);
+ n.setProperty(propName, (Value) null);
+ Thread.yield(); // maximize chances of interference
+ session.save();
+
+ for (int i = 0; i < NUM_NODES; i++) {
+ String name = "x_" + identity + "_" + i;
+ log.info("adding subnode {}", name);
+ //Node n1 = n.addNode("x" + i, "nt:unstructured");
+ Node n1 = n.addNode(name, "nt:unstructured");
+ n1.setProperty("testprop", "xxx");
+ Thread.yield(); // maximize chances of interference
session.save();
- randomSleep();
+ }
- state = "removing property " + propName;
- n.setProperty(propName, (Value) null);
+ for (int i = 0; i < NUM_NODES; i++) {
+ String name = "x_" + identity + "_" + i;
+ log.info("removing subnode {}", name);
+ n.getNode(name).remove();
+ Thread.yield(); // maximize chances of interference
session.save();
- randomSleep();
-
- for (int i = 0; i < NUM_NODES; i++) {
- state = "adding subnode " + i;
- //Node n1 = n.addNode("x" + i, "nt:unstructured");
- Node n1 = n.addNode("x" + identity + i, "nt:unstructured");
- state = "adding property to subnode " + i;
- n1.setProperty("testprop", "xxx");
- if (i % 10 == 0) {
- state = "saving pending (added) subnodes";
- session.save();
- }
- randomSleep();
- }
-
- for (int i = 0; i < NUM_NODES; i++) {
- state = "removing subnode " + i;
- n.getNode("x" + identity + i).remove();
- if (i % 10 == 0) {
- state = "saving pending (removed) subnodes";
- session.save();
- }
- randomSleep();
- }
- session.save();
- } catch (Exception e) {
- log.println("Exception while " + state + ": " + e.getMessage());
- //e.printStackTrace();
- exceptions.add(e);
- } finally {
- session.logout();
}
-
- log.println("ended.");
}
+
}
+
}