diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_316444_Test.java')
-rw-r--r-- | plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_316444_Test.java | 1274 |
1 files changed, 637 insertions, 637 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_316444_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_316444_Test.java index 9d2e1af4c5..cab930e8b0 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_316444_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_316444_Test.java @@ -1,637 +1,637 @@ -/* - * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Martin Fluegge - initial API and implementation - */ -package org.eclipse.emf.cdo.tests.bugzilla; - -import org.eclipse.emf.cdo.internal.server.Repository; -import org.eclipse.emf.cdo.internal.server.TransactionCommitContext; -import org.eclipse.emf.cdo.net4j.CDONet4jSession; -import org.eclipse.emf.cdo.server.IRepository; -import org.eclipse.emf.cdo.spi.server.InternalCommitContext; -import org.eclipse.emf.cdo.spi.server.InternalRepository; -import org.eclipse.emf.cdo.spi.server.InternalTransaction; -import org.eclipse.emf.cdo.tests.AbstractCDOTest; -import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig; -import org.eclipse.emf.cdo.tests.model3.NodeA; -import org.eclipse.emf.cdo.tests.model3.NodeB; -import org.eclipse.emf.cdo.transaction.CDOTransaction; -import org.eclipse.emf.cdo.util.CommitException; - -import org.eclipse.net4j.util.WrappedException; - -import org.eclipse.emf.ecore.resource.Resource; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * @author Martin Fluegge - * @since 4.0 - */ -public class Bugzilla_316444_Test extends AbstractCDOTest -{ - private static final String REPOSITORY_NAME = "repo1"; - - private static final String RESOURCE_PATH = "/my/resource"; - - public int idSessionA; - - public int idSessionB; - - private int idInitSession; - - private Object monitor = new Object(); - - private CountDownLatch latch = new CountDownLatch(2); - - private boolean finishedSessionA = false; - - private List<Exception> exceptions = new ArrayList<Exception>(); - - @Override - public synchronized Map<String, Object> getTestProperties() - { - Map<String, Object> map = super.getTestProperties(); - map.put(IRepository.Props.ENSURE_REFERENTIAL_INTEGRITY, "true"); - return map; - } - - @Override - protected void doSetUp() throws Exception - { - createRepository(); - super.doSetUp(); - } - - private void createRepository() - { - Repository repository = new Repository.Default() - { - @Override - public InternalCommitContext createCommitContext(InternalTransaction transaction) - { - return new TransactionCommitContext(transaction) - { - @Override - protected void lockObjects() throws InterruptedException - { - int sessionID = getTransaction().getSession().getSessionID(); - if (sessionID == idSessionB) - { - synchronized (monitor) - { - // Only wait if Session A has not passed the lockObjects - if (!finishedSessionA) - { - msg("Session B is waiting for Session A"); - monitor.wait(DEFAULT_TIMEOUT); - msg("Session B stopped waiting"); - } - else - { - msg("Session B - no need to wait. A has already passed lockObjects()"); - } - } - } - - msg("Passing lockObjects() " + getTransaction().getSession()); - - try - { - super.lockObjects(); - } - catch (RuntimeException ex) - { - latch.countDown(); - throw ex; - } - catch (Exception ex) - { - latch.countDown(); - throw WrappedException.wrap(ex); - } - - msg("Passed lockObjects() " + getTransaction().getSession()); - - if (sessionID == idSessionA) - { - synchronized (monitor) - { - finishedSessionA = true; - monitor.notifyAll(); - msg("Session A notified others not to wait anymore."); - } - } - - // Do nothing for inital session. Otherwise the test will block too early - if (sessionID != idInitSession) - { - latch.countDown(); - - try - { - assertEquals(true, latch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)); - } - catch (InterruptedException ex) - { - throw WrappedException.wrap(ex); - } - } - } - }; - } - }; - - Map<String, String> props = getRepositoryProperties(); - ((InternalRepository)repository).setProperties(props); - - repository.setName(REPOSITORY_NAME); - - Map<String, Object> map = getTestProperties(); - map.put(RepositoryConfig.PROP_TEST_REPOSITORY, repository); - } - - @CleanRepositoriesBefore - public void testMovingSubtree() throws Exception - { - exceptions.clear(); - - { - CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idInitSession = session.getSessionID(); - CDOTransaction transaction = session.openTransaction(); - - Resource resource = transaction.createResource(getResourcePath(RESOURCE_PATH)); - - // -------------- create graph begin ------------------------ - NodeB root = createSimpleNode("root"); - - NodeB A = createSimpleNode("A"); - NodeB B = createSimpleNode("B"); - NodeB C = createSimpleNode("C"); - NodeB D = createSimpleNode("D"); - NodeB E = createSimpleNode("E"); - - root.getChildren().add(A); - root.getChildren().add(D); - - A.getChildren().add(B); - B.getChildren().add(C); - - D.getChildren().add(E); - - resource.getContents().add(root); - transaction.commit(); - - // -------- check for consistency ----------- - - checkInitialGraph(root, A, B, C, D, E); - - transaction.close(); - session.close(); - } - - // if (!(isConfig(MEM) || isConfig(MEM_AUDITS) || isConfig(MEM_BRANCHES) || isConfig(MEM_OFFLINE))) - // { - // // do not restart the repository on MEM store - // restartRepository(); - // } - - { - // Just an additional check to make sure that the graph is stored correctly even after repository restart - CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idInitSession = session.getSessionID(); - CDOTransaction transaction = session.openTransaction(); - Resource resource = transaction.getResource(getResourcePath(RESOURCE_PATH), true); - - NodeB root = (NodeB)resource.getContents().get(0); - assertEquals("root", root.getName()); - - NodeB A = getElementFromGraphNodeB(root, "A"); - NodeB B = getElementFromGraphNodeB(root, "B"); - NodeB C = getElementFromGraphNodeB(root, "C"); - NodeB D = getElementFromGraphNodeB(root, "D"); - NodeB E = getElementFromGraphNodeB(root, "E"); - - assertNotNull(A); - assertNotNull(B); - assertNotNull(C); - assertNotNull(D); - assertNotNull(E); - - checkInitialGraph(root, A, B, C, D, E); - } - - { - CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idInitSession = session.getSessionID(); - - // ----- start threads ----- - ThreadA threadA = new ThreadA(RESOURCE_PATH); - ThreadB threadB = new ThreadB(RESOURCE_PATH); - - threadA.start(); - sleepIfNeeded(); - threadB.start(); - - threadA.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - threadB.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - // threadA.join(DEFAULT_TIMEOUT); - // threadB.join(DEFAULT_TIMEOUT); - - if (exceptions.size() > 0) - { - Exception exception = exceptions.get(0); - if (exception instanceof ThreadBShouldHaveThrownAnExceptionException) - { - fail(exception.getMessage()); - } - else - { - throw exception; - } - } - - session.close(); - msg("finished"); - } - } - - public void testLockParentWithEAttributeChange() throws Exception - { - String resourcePath = RESOURCE_PATH + "1"; - { - CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idInitSession = session.getSessionID(); - CDOTransaction transaction = session.openTransaction(); - - Resource resource = transaction.createResource(getResourcePath(resourcePath)); - - // -------------- create graph begin ------------------------ - NodeB root = createSimpleNode("root"); - - NodeB A = createSimpleNode("A"); - NodeB B = createSimpleNode("B"); - NodeB C = createSimpleNode("C"); - NodeB D = createSimpleNode("D"); - NodeB E = createSimpleNode("E"); - - root.getChildren().add(A); - root.getChildren().add(D); - - A.getChildren().add(B); - B.getChildren().add(C); - - D.getChildren().add(E); - - resource.getContents().add(root); - transaction.commit(); - - // -------- check for consistency ----------- - - checkInitialGraph(root, A, B, C, D, E); - - transaction.close(); - session.close(); - } - - // restartRepository(); - - { - CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idInitSession = session.getSessionID(); - - // ----- start threads ----- - ThreadX threadX = new ThreadX(resourcePath); - ThreadA threadA = new ThreadA(resourcePath); - - threadA.start(); - sleepIfNeeded(); - threadX.start(); - - threadA.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - threadX.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - // threadX.join(DEFAULT_TIMEOUT); - // threadA.join(DEFAULT_TIMEOUT); - - if (exceptions.size() > 0) - { - throw exceptions.get(0); - } - } - } - - private void sleepIfNeeded() - { - if (isConfig(LEGACY)) - { - // sleep in legacy while Bug 318816 is not solved - sleep(1000); - } - } - - private void checkInitialGraph(NodeB root, NodeB A, NodeB B, NodeB C, NodeB D, NodeB E) - { - assertEquals("A", A.getName()); - assertEquals("B", B.getName()); - assertEquals("C", C.getName()); - assertEquals("D", D.getName()); - assertEquals("E", E.getName()); - - assertEquals(root, A.getParent()); - assertEquals(root, A.eContainer()); - - assertEquals(root, D.getParent()); - assertEquals(root, D.eContainer()); - - assertEquals(A, B.getParent()); - assertEquals(A, B.eContainer()); - - assertEquals(B, C.getParent()); - assertEquals(B, C.eContainer()); - - assertEquals(D, E.getParent()); - assertEquals(D, E.eContainer()); - } - - private abstract class AbstactTestThread extends Thread - { - public CountDownLatch done = new CountDownLatch(1); - - protected final String resourcePath; - - public AbstactTestThread(String resourcePath) - { - this.resourcePath = resourcePath; - } - - @Override - public final void run() - { - try - { - doRun(); - } - finally - { - done.countDown(); - } - } - - protected abstract void doRun(); - } - - /** - * @author Martin Fluegge - */ - private class ThreadA extends AbstactTestThread - { - private CDONet4jSession session; - - public ThreadA(String resourcePath) - { - super(resourcePath); - setName("ThreadA"); - - msg("Starting Thread A"); - session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idSessionA = session.getSessionID(); - } - - @Override - protected void doRun() - { - try - { - msg("Started Thread A " + session); - CDOTransaction transaction = session.openTransaction(); - Resource resource = transaction.getResource(getResourcePath(resourcePath), true); - - NodeB root = (NodeB)resource.getContents().get(0); - assertEquals("root", root.getName()); - - NodeB B = getElementFromGraphNodeB(root, "B"); - NodeB E = getElementFromGraphNodeB(root, "E"); - - assertEquals("B", B.getName()); - assertEquals("E", E.getName()); - - E.getChildren().add(B); - - try - { - transaction.commit(); - } - catch (CommitException ex) - { - exceptions.add(ex); - } - - session.close(); - msg("Finished Thread A " + session); - } - catch (Exception e) - { - exceptions.add(e); - } - } - } - - /** - * @author Martin Fluegge - */ - private class ThreadB extends AbstactTestThread - { - private CDONet4jSession session; - - public ThreadB(String resourcePath) - { - super(resourcePath); - setName("ThreadB"); - - msg("Starting Thread B"); - session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idSessionB = session.getSessionID(); - } - - @Override - protected void doRun() - { - try - { - msg("Started Thread B " + session); - CDOTransaction transaction = session.openTransaction(); - - Resource resource = transaction.getResource(getResourcePath(resourcePath), true); - - NodeB root = (NodeB)resource.getContents().get(0); - assertEquals("root", root.getName()); - NodeB C = getElementFromGraphNodeB(root, "C"); - NodeB D = getElementFromGraphNodeB(root, "D"); - - assertEquals("C", C.getName()); - assertEquals("D", D.getName()); - - C.getChildren().add(D); - - try - { - transaction.commit(); - } - catch (CommitException ex) - { - try - { - String message = ex.getMessage(); - if (message == null || !message.contains("ContainmentCycleDetectedException")) - { - throw ex; - } - - msg("Finished (Passed) Thread B " + session); - return; - } - catch (Exception exx) - { - throw new RuntimeException(exx); - } - } - - exceptions.add(new ThreadBShouldHaveThrownAnExceptionException("Thread B should have thrown an exception")); - session.close(); - } - catch (Exception e) - { - exceptions.add(e); - msg("Finished Thread B " + session); - } - } - } - - /** - * @author Martin Fluegge - */ - private class ThreadX extends AbstactTestThread - { - private CDONet4jSession session; - - public ThreadX(String resourcePath) - { - super(resourcePath); - setName("ThreadX"); - - msg("Starting Thread X"); - session = (CDONet4jSession)openSession(REPOSITORY_NAME); - idSessionB = session.getSessionID(); - } - - @Override - protected void doRun() - { - try - { - msg("Started Thread X" + session); - CDOTransaction transaction = session.openTransaction(); - Resource resource = transaction.getResource(getResourcePath(resourcePath), true); - - NodeB root = (NodeB)resource.getContents().get(0); - assertEquals("root", root.getName()); - - NodeB D = getElementFromGraphNodeB(root, "D"); - - assertEquals("D", D.getName()); - D.setName("DD"); - - try - { - transaction.commit(); - } - catch (CommitException ex) - { - exceptions.add(ex); - } - - session.close(); - msg("Finished Thread X"); - } - catch (Exception e) - { - exceptions.add(e); - } - } - } - - private NodeB createSimpleNode(String name) - { - NodeB y = getModel3Factory().createNodeB(); - y.setName(name); - return y; - } - - private NodeB getElementFromGraphNodeB(NodeB node, String name) - { - if (node.getName().equals(name)) - { - return node; - } - - for (NodeB child : node.getChildren()) - { - NodeB elementFromGraph = getElementFromGraphNodeB(child, name); - if (elementFromGraph != null) - { - return elementFromGraph; - } - } - - return null; - } - - @SuppressWarnings("unused") - private NodeA getElementFromGraphNodeA(NodeA node, String name) - { - if (node.getName().equals(name)) - { - return node; - } - - for (NodeA child : node.getChildren()) - { - NodeA elementFromGraph = getElementFromGraphNodeA(child, name); - if (elementFromGraph != null) - { - return elementFromGraph; - } - } - - return null; - } - - /* - * @SuppressWarnings("unused") private void restartRepository() { LifecycleUtil.deactivate(getRepository()); - * createRepository(); getRepository(); } - */ - - /** - * @author Martin Fluegge - */ - private static class ThreadBShouldHaveThrownAnExceptionException extends Exception - { - private static final long serialVersionUID = 1L; - - public ThreadBShouldHaveThrownAnExceptionException(String s) - { - super(s); - } - } -} +/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Fluegge - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.internal.server.Repository;
+import org.eclipse.emf.cdo.internal.server.TransactionCommitContext;
+import org.eclipse.emf.cdo.net4j.CDONet4jSession;
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig;
+import org.eclipse.emf.cdo.tests.model3.NodeA;
+import org.eclipse.emf.cdo.tests.model3.NodeB;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CommitException;
+
+import org.eclipse.net4j.util.WrappedException;
+
+import org.eclipse.emf.ecore.resource.Resource;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Martin Fluegge
+ * @since 4.0
+ */
+public class Bugzilla_316444_Test extends AbstractCDOTest
+{
+ private static final String REPOSITORY_NAME = "repo1";
+
+ private static final String RESOURCE_PATH = "/my/resource";
+
+ public int idSessionA;
+
+ public int idSessionB;
+
+ private int idInitSession;
+
+ private Object monitor = new Object();
+
+ private CountDownLatch latch = new CountDownLatch(2);
+
+ private boolean finishedSessionA = false;
+
+ private List<Exception> exceptions = new ArrayList<Exception>();
+
+ @Override
+ public synchronized Map<String, Object> getTestProperties()
+ {
+ Map<String, Object> map = super.getTestProperties();
+ map.put(IRepository.Props.ENSURE_REFERENTIAL_INTEGRITY, "true");
+ return map;
+ }
+
+ @Override
+ protected void doSetUp() throws Exception
+ {
+ createRepository();
+ super.doSetUp();
+ }
+
+ private void createRepository()
+ {
+ Repository repository = new Repository.Default()
+ {
+ @Override
+ public InternalCommitContext createCommitContext(InternalTransaction transaction)
+ {
+ return new TransactionCommitContext(transaction)
+ {
+ @Override
+ protected void lockObjects() throws InterruptedException
+ {
+ int sessionID = getTransaction().getSession().getSessionID();
+ if (sessionID == idSessionB)
+ {
+ synchronized (monitor)
+ {
+ // Only wait if Session A has not passed the lockObjects
+ if (!finishedSessionA)
+ {
+ msg("Session B is waiting for Session A");
+ monitor.wait(DEFAULT_TIMEOUT);
+ msg("Session B stopped waiting");
+ }
+ else
+ {
+ msg("Session B - no need to wait. A has already passed lockObjects()");
+ }
+ }
+ }
+
+ msg("Passing lockObjects() " + getTransaction().getSession());
+
+ try
+ {
+ super.lockObjects();
+ }
+ catch (RuntimeException ex)
+ {
+ latch.countDown();
+ throw ex;
+ }
+ catch (Exception ex)
+ {
+ latch.countDown();
+ throw WrappedException.wrap(ex);
+ }
+
+ msg("Passed lockObjects() " + getTransaction().getSession());
+
+ if (sessionID == idSessionA)
+ {
+ synchronized (monitor)
+ {
+ finishedSessionA = true;
+ monitor.notifyAll();
+ msg("Session A notified others not to wait anymore.");
+ }
+ }
+
+ // Do nothing for inital session. Otherwise the test will block too early
+ if (sessionID != idInitSession)
+ {
+ latch.countDown();
+
+ try
+ {
+ assertEquals(true, latch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS));
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ }
+ }
+ };
+ }
+ };
+
+ Map<String, String> props = getRepositoryProperties();
+ ((InternalRepository)repository).setProperties(props);
+
+ repository.setName(REPOSITORY_NAME);
+
+ Map<String, Object> map = getTestProperties();
+ map.put(RepositoryConfig.PROP_TEST_REPOSITORY, repository);
+ }
+
+ @CleanRepositoriesBefore
+ public void testMovingSubtree() throws Exception
+ {
+ exceptions.clear();
+
+ {
+ CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idInitSession = session.getSessionID();
+ CDOTransaction transaction = session.openTransaction();
+
+ Resource resource = transaction.createResource(getResourcePath(RESOURCE_PATH));
+
+ // -------------- create graph begin ------------------------
+ NodeB root = createSimpleNode("root");
+
+ NodeB A = createSimpleNode("A");
+ NodeB B = createSimpleNode("B");
+ NodeB C = createSimpleNode("C");
+ NodeB D = createSimpleNode("D");
+ NodeB E = createSimpleNode("E");
+
+ root.getChildren().add(A);
+ root.getChildren().add(D);
+
+ A.getChildren().add(B);
+ B.getChildren().add(C);
+
+ D.getChildren().add(E);
+
+ resource.getContents().add(root);
+ transaction.commit();
+
+ // -------- check for consistency -----------
+
+ checkInitialGraph(root, A, B, C, D, E);
+
+ transaction.close();
+ session.close();
+ }
+
+ // if (!(isConfig(MEM) || isConfig(MEM_AUDITS) || isConfig(MEM_BRANCHES) || isConfig(MEM_OFFLINE)))
+ // {
+ // // do not restart the repository on MEM store
+ // restartRepository();
+ // }
+
+ {
+ // Just an additional check to make sure that the graph is stored correctly even after repository restart
+ CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idInitSession = session.getSessionID();
+ CDOTransaction transaction = session.openTransaction();
+ Resource resource = transaction.getResource(getResourcePath(RESOURCE_PATH), true);
+
+ NodeB root = (NodeB)resource.getContents().get(0);
+ assertEquals("root", root.getName());
+
+ NodeB A = getElementFromGraphNodeB(root, "A");
+ NodeB B = getElementFromGraphNodeB(root, "B");
+ NodeB C = getElementFromGraphNodeB(root, "C");
+ NodeB D = getElementFromGraphNodeB(root, "D");
+ NodeB E = getElementFromGraphNodeB(root, "E");
+
+ assertNotNull(A);
+ assertNotNull(B);
+ assertNotNull(C);
+ assertNotNull(D);
+ assertNotNull(E);
+
+ checkInitialGraph(root, A, B, C, D, E);
+ }
+
+ {
+ CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idInitSession = session.getSessionID();
+
+ // ----- start threads -----
+ ThreadA threadA = new ThreadA(RESOURCE_PATH);
+ ThreadB threadB = new ThreadB(RESOURCE_PATH);
+
+ threadA.start();
+ sleepIfNeeded();
+ threadB.start();
+
+ threadA.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ threadB.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ // threadA.join(DEFAULT_TIMEOUT);
+ // threadB.join(DEFAULT_TIMEOUT);
+
+ if (exceptions.size() > 0)
+ {
+ Exception exception = exceptions.get(0);
+ if (exception instanceof ThreadBShouldHaveThrownAnExceptionException)
+ {
+ fail(exception.getMessage());
+ }
+ else
+ {
+ throw exception;
+ }
+ }
+
+ session.close();
+ msg("finished");
+ }
+ }
+
+ public void testLockParentWithEAttributeChange() throws Exception
+ {
+ String resourcePath = RESOURCE_PATH + "1";
+ {
+ CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idInitSession = session.getSessionID();
+ CDOTransaction transaction = session.openTransaction();
+
+ Resource resource = transaction.createResource(getResourcePath(resourcePath));
+
+ // -------------- create graph begin ------------------------
+ NodeB root = createSimpleNode("root");
+
+ NodeB A = createSimpleNode("A");
+ NodeB B = createSimpleNode("B");
+ NodeB C = createSimpleNode("C");
+ NodeB D = createSimpleNode("D");
+ NodeB E = createSimpleNode("E");
+
+ root.getChildren().add(A);
+ root.getChildren().add(D);
+
+ A.getChildren().add(B);
+ B.getChildren().add(C);
+
+ D.getChildren().add(E);
+
+ resource.getContents().add(root);
+ transaction.commit();
+
+ // -------- check for consistency -----------
+
+ checkInitialGraph(root, A, B, C, D, E);
+
+ transaction.close();
+ session.close();
+ }
+
+ // restartRepository();
+
+ {
+ CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idInitSession = session.getSessionID();
+
+ // ----- start threads -----
+ ThreadX threadX = new ThreadX(resourcePath);
+ ThreadA threadA = new ThreadA(resourcePath);
+
+ threadA.start();
+ sleepIfNeeded();
+ threadX.start();
+
+ threadA.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ threadX.done.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ // threadX.join(DEFAULT_TIMEOUT);
+ // threadA.join(DEFAULT_TIMEOUT);
+
+ if (exceptions.size() > 0)
+ {
+ throw exceptions.get(0);
+ }
+ }
+ }
+
+ private void sleepIfNeeded()
+ {
+ if (isConfig(LEGACY))
+ {
+ // sleep in legacy while Bug 318816 is not solved
+ sleep(1000);
+ }
+ }
+
+ private void checkInitialGraph(NodeB root, NodeB A, NodeB B, NodeB C, NodeB D, NodeB E)
+ {
+ assertEquals("A", A.getName());
+ assertEquals("B", B.getName());
+ assertEquals("C", C.getName());
+ assertEquals("D", D.getName());
+ assertEquals("E", E.getName());
+
+ assertEquals(root, A.getParent());
+ assertEquals(root, A.eContainer());
+
+ assertEquals(root, D.getParent());
+ assertEquals(root, D.eContainer());
+
+ assertEquals(A, B.getParent());
+ assertEquals(A, B.eContainer());
+
+ assertEquals(B, C.getParent());
+ assertEquals(B, C.eContainer());
+
+ assertEquals(D, E.getParent());
+ assertEquals(D, E.eContainer());
+ }
+
+ private abstract class AbstactTestThread extends Thread
+ {
+ public CountDownLatch done = new CountDownLatch(1);
+
+ protected final String resourcePath;
+
+ public AbstactTestThread(String resourcePath)
+ {
+ this.resourcePath = resourcePath;
+ }
+
+ @Override
+ public final void run()
+ {
+ try
+ {
+ doRun();
+ }
+ finally
+ {
+ done.countDown();
+ }
+ }
+
+ protected abstract void doRun();
+ }
+
+ /**
+ * @author Martin Fluegge
+ */
+ private class ThreadA extends AbstactTestThread
+ {
+ private CDONet4jSession session;
+
+ public ThreadA(String resourcePath)
+ {
+ super(resourcePath);
+ setName("ThreadA");
+
+ msg("Starting Thread A");
+ session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idSessionA = session.getSessionID();
+ }
+
+ @Override
+ protected void doRun()
+ {
+ try
+ {
+ msg("Started Thread A " + session);
+ CDOTransaction transaction = session.openTransaction();
+ Resource resource = transaction.getResource(getResourcePath(resourcePath), true);
+
+ NodeB root = (NodeB)resource.getContents().get(0);
+ assertEquals("root", root.getName());
+
+ NodeB B = getElementFromGraphNodeB(root, "B");
+ NodeB E = getElementFromGraphNodeB(root, "E");
+
+ assertEquals("B", B.getName());
+ assertEquals("E", E.getName());
+
+ E.getChildren().add(B);
+
+ try
+ {
+ transaction.commit();
+ }
+ catch (CommitException ex)
+ {
+ exceptions.add(ex);
+ }
+
+ session.close();
+ msg("Finished Thread A " + session);
+ }
+ catch (Exception e)
+ {
+ exceptions.add(e);
+ }
+ }
+ }
+
+ /**
+ * @author Martin Fluegge
+ */
+ private class ThreadB extends AbstactTestThread
+ {
+ private CDONet4jSession session;
+
+ public ThreadB(String resourcePath)
+ {
+ super(resourcePath);
+ setName("ThreadB");
+
+ msg("Starting Thread B");
+ session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idSessionB = session.getSessionID();
+ }
+
+ @Override
+ protected void doRun()
+ {
+ try
+ {
+ msg("Started Thread B " + session);
+ CDOTransaction transaction = session.openTransaction();
+
+ Resource resource = transaction.getResource(getResourcePath(resourcePath), true);
+
+ NodeB root = (NodeB)resource.getContents().get(0);
+ assertEquals("root", root.getName());
+ NodeB C = getElementFromGraphNodeB(root, "C");
+ NodeB D = getElementFromGraphNodeB(root, "D");
+
+ assertEquals("C", C.getName());
+ assertEquals("D", D.getName());
+
+ C.getChildren().add(D);
+
+ try
+ {
+ transaction.commit();
+ }
+ catch (CommitException ex)
+ {
+ try
+ {
+ String message = ex.getMessage();
+ if (message == null || !message.contains("ContainmentCycleDetectedException"))
+ {
+ throw ex;
+ }
+
+ msg("Finished (Passed) Thread B " + session);
+ return;
+ }
+ catch (Exception exx)
+ {
+ throw new RuntimeException(exx);
+ }
+ }
+
+ exceptions.add(new ThreadBShouldHaveThrownAnExceptionException("Thread B should have thrown an exception"));
+ session.close();
+ }
+ catch (Exception e)
+ {
+ exceptions.add(e);
+ msg("Finished Thread B " + session);
+ }
+ }
+ }
+
+ /**
+ * @author Martin Fluegge
+ */
+ private class ThreadX extends AbstactTestThread
+ {
+ private CDONet4jSession session;
+
+ public ThreadX(String resourcePath)
+ {
+ super(resourcePath);
+ setName("ThreadX");
+
+ msg("Starting Thread X");
+ session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ idSessionB = session.getSessionID();
+ }
+
+ @Override
+ protected void doRun()
+ {
+ try
+ {
+ msg("Started Thread X" + session);
+ CDOTransaction transaction = session.openTransaction();
+ Resource resource = transaction.getResource(getResourcePath(resourcePath), true);
+
+ NodeB root = (NodeB)resource.getContents().get(0);
+ assertEquals("root", root.getName());
+
+ NodeB D = getElementFromGraphNodeB(root, "D");
+
+ assertEquals("D", D.getName());
+ D.setName("DD");
+
+ try
+ {
+ transaction.commit();
+ }
+ catch (CommitException ex)
+ {
+ exceptions.add(ex);
+ }
+
+ session.close();
+ msg("Finished Thread X");
+ }
+ catch (Exception e)
+ {
+ exceptions.add(e);
+ }
+ }
+ }
+
+ private NodeB createSimpleNode(String name)
+ {
+ NodeB y = getModel3Factory().createNodeB();
+ y.setName(name);
+ return y;
+ }
+
+ private NodeB getElementFromGraphNodeB(NodeB node, String name)
+ {
+ if (node.getName().equals(name))
+ {
+ return node;
+ }
+
+ for (NodeB child : node.getChildren())
+ {
+ NodeB elementFromGraph = getElementFromGraphNodeB(child, name);
+ if (elementFromGraph != null)
+ {
+ return elementFromGraph;
+ }
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ private NodeA getElementFromGraphNodeA(NodeA node, String name)
+ {
+ if (node.getName().equals(name))
+ {
+ return node;
+ }
+
+ for (NodeA child : node.getChildren())
+ {
+ NodeA elementFromGraph = getElementFromGraphNodeA(child, name);
+ if (elementFromGraph != null)
+ {
+ return elementFromGraph;
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * @SuppressWarnings("unused") private void restartRepository() { LifecycleUtil.deactivate(getRepository());
+ * createRepository(); getRepository(); }
+ */
+
+ /**
+ * @author Martin Fluegge
+ */
+ private static class ThreadBShouldHaveThrownAnExceptionException extends Exception
+ {
+ private static final long serialVersionUID = 1L;
+
+ public ThreadBShouldHaveThrownAnExceptionException(String s)
+ {
+ super(s);
+ }
+ }
+}
|