diff options
4 files changed, 189 insertions, 2 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java index 707776c5a5..5ee103a7fe 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java @@ -223,6 +223,7 @@ public abstract class AllConfigs extends ConfigTestSuite testClasses.add(Bugzilla_339908_Test.class); testClasses.add(Bugzilla_340961_Test.class); testClasses.add(Bugzilla_341875_Test.class); + testClasses.add(Bugzilla_341995_Test.class); testClasses.add(Bugzilla_342130_Test.class); testClasses.add(Bugzilla_342135_Test.class); testClasses.add(Bugzilla_343332_Test.class); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java new file mode 100644 index 0000000000..97af85d0da --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java @@ -0,0 +1,103 @@ +/** + * 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: + * Caspar De Groot - initial API and implementation + */ +package org.eclipse.emf.cdo.tests.bugzilla; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; +import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.session.CDOSession; +import org.eclipse.emf.cdo.tests.AbstractCDOTest; +import org.eclipse.emf.cdo.tests.model1.Category; +import org.eclipse.emf.cdo.tests.model1.Model1Factory; +import org.eclipse.emf.cdo.tests.util.TestSessionManager; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.cdo.util.CommitException; + +/** + * @author Caspar De Groot + */ +public class Bugzilla_341995_Test extends AbstractCDOTest +{ + public void test() throws CommitException, InterruptedException + { + CDOSession session = openSession(); + CDOTransaction tx = session.openTransaction(); + CDOResource resource = tx.createResource(getResourcePath("test")); + + Model1Factory factory = getModel1Factory(); + Category cat = factory.createCategory(); + resource.getContents().add(cat); + tx.commit(); + + CDOObject cdoCat = CDOUtil.getCDOObject(cat); + msg(cdoCat.cdoRevision().getVersion()); + + long delay = 2000L; + TestSessionManager sessionManager = (TestSessionManager)getRepository().getSessionManager(); + sessionManager.setCommitNotificationDelay(delay); + try + { + doSecondSessionAsync(); + sessionManager.getDelayLatch().await(); // Wait until the delay commences + + long time1 = System.currentTimeMillis(); + + // Attempt the lock; this must block for a while, because it needs to receive + // the commitNotification from the commit in the other session, which we are + // artificially delaying + cdoCat.cdoWriteLock().lock(); + + long timeTaken = System.currentTimeMillis() - time1; + + // We verify that there really was a delay + assertEquals("timeTaken == " + timeTaken, true, timeTaken >= delay); + + tx.close(); + session.close(); + } + finally + { + sessionManager.setCommitNotificationDelay(0L); + } + } + + private void doSecondSessionAsync() throws CommitException + { + Runnable r = new Runnable() + { + public void run() + { + CDOSession session = openSession(); + CDOTransaction tx = session.openTransaction(); + CDOResource resource = tx.getResource(getResourcePath("test")); + + Category cat = (Category)resource.getContents().get(0); + cat.setName("dirty"); + CDOCommitInfo info; + try + { + info = tx.commit(); + } + catch (CommitException ex) + { + throw new RuntimeException(ex); + } + + msg(info.getTimeStamp()); + + tx.close(); + session.close(); + } + }; + new Thread(r).start(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java index e1ca2660f2..43cfde0c74 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java @@ -46,6 +46,7 @@ import org.eclipse.emf.cdo.tests.config.IRepositoryConfig; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesAfter; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore; import org.eclipse.emf.cdo.tests.util.TestRevisionManager; +import org.eclipse.emf.cdo.tests.util.TestSessionManager; import org.eclipse.net4j.Net4jUtil; import org.eclipse.net4j.acceptor.IAcceptor; @@ -82,6 +83,8 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf public static final String PROP_TEST_REVISION_MANAGER = "test.repository.RevisionManager"; + public static final String PROP_TEST_SESSION_MANAGER = "test.repository.SessionManager"; + public static final String PROP_TEST_USER_MANAGER = "test.repository.UserManager"; public static final String PROP_TEST_QUERY_HANDLER_PROVIDER = "test.repository.QueryHandlerProvider"; @@ -389,13 +392,18 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf { revisionManager = new TestRevisionManager(); } - repository.setRevisionManager(revisionManager); + InternalSessionManager sessionManager = getTestSessionManager(); + if (sessionManager == null) + { + sessionManager = new TestSessionManager(); + } + repository.setSessionManager(sessionManager); + IUserManager userManager = getTestUserManager(); if (userManager != null) { - InternalSessionManager sessionManager = (InternalSessionManager)CDOServerUtil.createSessionManager(); sessionManager.setUserManager(userManager); repository.setSessionManager(sessionManager); } @@ -421,6 +429,11 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf return (InternalCDORevisionManager)getTestProperty(PROP_TEST_REVISION_MANAGER); } + protected InternalSessionManager getTestSessionManager() + { + return (InternalSessionManager)getTestProperty(PROP_TEST_SESSION_MANAGER); + } + protected IUserManager getTestUserManager() { return (IUserManager)getTestProperty(PROP_TEST_USER_MANAGER); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionManager.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionManager.java new file mode 100644 index 0000000000..0e32332718 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionManager.java @@ -0,0 +1,70 @@ +/** + * 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: + * Caspar De Groot - initial API and implementation + */ +package org.eclipse.emf.cdo.tests.util; + +import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; +import org.eclipse.emf.cdo.internal.server.SessionManager; +import org.eclipse.emf.cdo.spi.server.InternalSession; + +import org.eclipse.net4j.util.concurrent.ConcurrencyUtil; + +import java.util.concurrent.CountDownLatch; + +/** + * @author Caspar De Groot + */ +public class TestSessionManager extends SessionManager +{ + /** + * Prevents other threads from changing/resetting the commitNotificationDelay while we are just about to execute the + * delay. + */ + private Object lock = new Object(); + + private long commitNotificationDelay; + + /** + * Allows tests to wait until the delay is about to commence + */ + private CountDownLatch delayLatch; + + public void setCommitNotificationDelay(long millis) + { + synchronized (lock) + { + commitNotificationDelay = millis; + if (commitNotificationDelay > 0) + { + delayLatch = new CountDownLatch(1); + } + } + } + + public CountDownLatch getDelayLatch() + { + return delayLatch; + } + + @Override + public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo) + { + synchronized (lock) + { + if (commitNotificationDelay != 0) + { + delayLatch.countDown(); + ConcurrencyUtil.sleep(commitNotificationDelay); + } + } + + super.sendCommitNotification(sender, commitInfo); + } +} |