/**
* Test case for
* JCR-2908.
*/
public void testAddNodeInMultipleThreads() throws Exception {
Session session = getHelper().getSuperuserSession();
// make sure that 'testNode' does not exist at the beginning
// of the test
while (session.nodeExists("/testNode")) {
session.getNode("/testNode").remove();
session.save();
}
// create 'testNode' that has two child
Node node = session.getRootNode().addNode("testNode");
Node child1 = node.addNode("child1");
String child1Path = child1.getPath();
Node child2 = node.addNode("child2");
String child2Path = child2.getPath();
session.save();
session.logout();
//create versionable nodes under child1 and child2
//repeat several times
for(int i=0; i<5; ++i){
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch endSignal = new CountDownLatch(2);
AddNodeThread t1 = new AddNodeThread(child1Path, 20, startSignal, endSignal);
t1.start();
AddNodeThread t2 = new AddNodeThread(child2Path, 20, startSignal, endSignal);
t2.start();
startSignal.countDown();
endSignal.await();
assertTrue(t1.isSuccess());
assertTrue(t2.isSuccess());
}
}
class AddNodeThread extends Thread {
private String parentPath;
private int childCount=0;
private boolean success = false;
private CountDownLatch startSignal;
private CountDownLatch endSignal;
AddNodeThread(String parentPath, int childCount, CountDownLatch startSignal, CountDownLatch endSignal) {
this.parentPath = parentPath;
this.childCount = childCount;
this.startSignal = startSignal;
this.endSignal = endSignal;
}
public void run() {
Session session = null;
try {
startSignal.await();
session = getHelper().getSuperuserSession();
UserTransaction utx = new UserTransactionImpl(session);
utx.begin();
Node parent = session.getNode(parentPath);
for(int i=0; i