diff options
author | Caspar De Groot | 2011-08-18 02:24:31 +0000 |
---|---|---|
committer | Caspar De Groot | 2011-08-18 02:24:31 +0000 |
commit | b7e84a0e190445f303dc8fa918cd5a7c6c0670f6 (patch) | |
tree | 776782d6099f9228e8764ce57b692914e9b80812 /plugins/org.eclipse.emf.cdo.tests | |
parent | 8c9b3bb2192a53b7ee1eff6035462f04c20ba842 (diff) | |
download | cdo-b7e84a0e190445f303dc8fa918cd5a7c6c0670f6.tar.gz cdo-b7e84a0e190445f303dc8fa918cd5a7c6c0670f6.tar.xz cdo-b7e84a0e190445f303dc8fa918cd5a7c6c0670f6.zip |
[353691] Add lock notifications and lock caching
https://bugs.eclipse.org/bugs/show_bug.cgi?id=353691
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.tests')
4 files changed, 411 insertions, 0 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 7b49bbe8b8..a488d28d6e 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 @@ -74,6 +74,7 @@ public abstract class AllConfigs extends ConfigTestSuite testClasses.add(LockingManagerRestartTransactionTest.class); testClasses.add(LockingManagerRestartSessionTest.class); testClasses.add(LockingManagerRestartRepositoryTest.class); + testClasses.add(LockingNotificationsTest.class); testClasses.add(MultiValuedOfAttributeTest.class); testClasses.add(MapTest.class); testClasses.add(FeatureMapTest.class); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java index 72e59220cb..c67d939679 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java @@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.tests.config.IScenario; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest; import org.eclipse.emf.cdo.tests.offline.FailoverTest; import org.eclipse.emf.cdo.tests.offline.OfflineDelayed2Test; +import org.eclipse.emf.cdo.tests.offline.OfflineLockingTest; import org.eclipse.emf.cdo.tests.offline.OfflineTest; import java.util.List; @@ -43,6 +44,7 @@ public class AllTestsMEMOffline extends AllConfigs // MEM does not support raw replication // testClasses.add(OfflineRawTest.class); + testClasses.add(OfflineLockingTest.class); testClasses.add(OfflineTest.class); testClasses.add(OfflineDelayed2Test.class); testClasses.add(FailoverTest.class); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java new file mode 100644 index 0000000000..f9b8f6e677 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java @@ -0,0 +1,341 @@ +/** + * 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; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.lock.CDOLockOwner; +import org.eclipse.emf.cdo.common.lock.CDOLockState; +import org.eclipse.emf.cdo.common.lock.CDOLockUtil; +import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch; +import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.session.CDOSession; +import org.eclipse.emf.cdo.tests.model1.Company; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.cdo.util.CommitException; +import org.eclipse.emf.cdo.view.CDOLocksChangedEvent; +import org.eclipse.emf.cdo.view.CDOView; + +import org.eclipse.net4j.util.event.IEvent; +import org.eclipse.net4j.util.event.IListener; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author Caspar De Groot + */ +public class LockingNotificationsTest extends AbstractLockingTest +{ + private CDOView openViewWithLockNotifications(CDOSession session, CDOBranch branch) + { + CDOView view = branch != null ? session.openView(branch) : session.openView(); + view.options().setLockNotificationEnabled(true); + return view; + } + + public void testSameBranchDifferentSession() throws CommitException + { + CDOSession session1 = openSession(); + CDOSession session2 = openSession(); + CDOView controlView = openViewWithLockNotifications(session2, null); + test(session1, controlView, true); + session1.close(); + session2.close(); + } + + public void testSameBranchSameSession() throws CommitException + { + CDOSession session1 = openSession(); + CDOView controlView = openViewWithLockNotifications(session1, null); + test(session1, controlView, true); + session1.close(); + } + + public void testDifferentBranchDifferentSession() throws CommitException + { + skipUnlessBranching(); + + CDOSession session1 = openSession(); + CDOBranch subBranch = session1.getBranchManager().getMainBranch().createBranch("sub1"); + CDOSession session2 = openSession(); + CDOView controlView = openViewWithLockNotifications(session2, subBranch); + test(session1, controlView, false); + session1.close(); + session2.close(); + } + + public void testDifferentBranchSameSession() throws CommitException + { + skipUnlessBranching(); + + CDOSession session1 = openSession(); + CDOBranch subBranch = session1.getBranchManager().getMainBranch().createBranch("sub2"); + CDOView controlView = openViewWithLockNotifications(session1, subBranch); + test(session1, controlView, false); + session1.close(); + } + + private void test(CDOSession session1, CDOView controlView, boolean mustReceiveNotifications) throws CommitException + { + CDOTransaction tx1 = session1.openTransaction(); + CDOResource res1 = tx1.getOrCreateResource(getResourcePath("r1")); + LockEventListener listener1 = new LockEventListener(); + tx1.addListener(listener1); + res1.getContents().clear(); + Company company1 = getModel1Factory().createCompany(); + res1.getContents().add(company1); + tx1.commit(); + + LockEventListener listener2 = new LockEventListener(); + controlView.addListener(listener2); + + CDOObject cdoCompany1 = CDOUtil.getCDOObject(company1); + + /* Test write lock */ + + cdoCompany1.cdoWriteLock().lock(); + if (mustReceiveNotifications) + { + listener2.waitFor(1); + assertEquals(1, listener2.getLockEvents().size()); + + CDOLocksChangedEvent event = listener2.getLockEvents().get(0); + assertLockOwner(tx1, event.getLockOwner()); + + CDOLockState[] lockStates = event.getLockStates(); + assertEquals(1, lockStates.length); + assertLockedObject(cdoCompany1, lockStates[0].getLockedObject()); + assertLockOwner(tx1, lockStates[0].getWriteLockOwner()); + } + + cdoCompany1.cdoWriteLock().unlock(); + if (mustReceiveNotifications) + { + listener2.waitFor(2); + + assertEquals(2, listener2.getLockEvents().size()); + + CDOLocksChangedEvent event = listener2.getLockEvents().get(1); + assertLockOwner(tx1, event.getLockOwner()); + + CDOLockState[] lockStates = event.getLockStates(); + assertEquals(1, lockStates.length); + assertLockedObject(cdoCompany1, lockStates[0].getLockedObject()); + assertNull(lockStates[0].getWriteLockOwner()); + } + + /* Test read lock */ + + cdoCompany1.cdoReadLock().lock(); + if (mustReceiveNotifications) + { + listener2.waitFor(3); + assertEquals(3, listener2.getLockEvents().size()); + + CDOLocksChangedEvent event = listener2.getLockEvents().get(2); + assertLockOwner(tx1, event.getLockOwner()); + + CDOLockState[] lockStates = event.getLockStates(); + assertEquals(1, lockStates.length); + assertLockedObject(cdoCompany1, lockStates[0].getLockedObject()); + assertEquals(1, lockStates[0].getReadLockOwners().size()); + CDOLockOwner tx1Lo = CDOLockUtil.createLockOwner(tx1); + assertEquals(true, lockStates[0].getReadLockOwners().contains(tx1Lo)); + } + + cdoCompany1.cdoReadLock().unlock(); + if (mustReceiveNotifications) + { + listener2.waitFor(4); + + assertEquals(4, listener2.getLockEvents().size()); + + CDOLocksChangedEvent event = listener2.getLockEvents().get(3); + assertLockOwner(tx1, event.getLockOwner()); + + CDOLockState[] lockStates = event.getLockStates(); + assertEquals(1, lockStates.length); + assertEquals(0, lockStates[0].getReadLockOwners().size()); + } + + /* Test write option */ + + cdoCompany1.cdoWriteOption().lock(); + if (mustReceiveNotifications) + { + listener2.waitFor(5); + assertEquals(5, listener2.getLockEvents().size()); + + CDOLocksChangedEvent event = listener2.getLockEvents().get(4); + assertLockOwner(tx1, event.getLockOwner()); + + CDOLockState[] lockStates = event.getLockStates(); + assertEquals(1, lockStates.length); + assertLockedObject(cdoCompany1, lockStates[0].getLockedObject()); + assertLockOwner(tx1, lockStates[0].getWriteOptionOwner()); + } + + cdoCompany1.cdoWriteOption().unlock(); + if (mustReceiveNotifications) + { + listener2.waitFor(6); + + assertEquals(6, listener2.getLockEvents().size()); + + CDOLocksChangedEvent event = listener2.getLockEvents().get(5); + assertLockOwner(tx1, event.getLockOwner()); + + CDOLockState[] lockStates = event.getLockStates(); + assertEquals(1, lockStates.length); + assertLockedObject(cdoCompany1, lockStates[0].getLockedObject()); + assertNull(lockStates[0].getWriteOptionOwner()); + } + + assertEquals(0, listener1.getLockEvents().size()); + + if (!mustReceiveNotifications) + { + assertEquals(0, listener2.getLockEvents().size()); + } + } + + private void assertLockedObject(CDOObject obj, Object lockedObject) + { + if (lockedObject instanceof CDOIDAndBranch) + { + CDOIDAndBranch idAndBranch = CDOIDUtil.createIDAndBranch(obj.cdoID(), obj.cdoView().getBranch()); + assertEquals(idAndBranch, lockedObject); + } + else if (lockedObject instanceof CDOID) + { + assertEquals(obj.cdoID(), lockedObject); + } + } + + private void assertLockOwner(CDOView view, CDOLockOwner lockOwner) + { + CDOLockOwner lo = CDOLockUtil.createLockOwner(view); + assertEquals(lo, lockOwner); + } + + /** + * @author Caspar De Groot + */ + private final class LockEventListener implements IListener + { + private List<CDOLocksChangedEvent> lockEvents = new LinkedList<CDOLocksChangedEvent>(); + + public synchronized void notifyEvent(IEvent event) + { + if (event instanceof CDOLocksChangedEvent) + { + lockEvents.add((CDOLocksChangedEvent)event); + notify(); + } + } + + public List<CDOLocksChangedEvent> getLockEvents() + { + return lockEvents; + } + + public synchronized void waitFor(int n) + { + long timeout = 2000; + long t = 0; + while (lockEvents.size() < n) + { + if (timeout <= 0) + { + fail("Timed out"); + } + try + { + t = System.currentTimeMillis(); + wait(timeout); + } + catch (InterruptedException ex) + { + } + timeout -= System.currentTimeMillis() - t; + } + } + } + + public void testEnableDisableNotifications() throws CommitException + { + CDOSession session1 = openSession(); + CDOSession session2 = openSession(); + CDOView controlView = session2.openView(); + test(session1, controlView, false); + + controlView.options().setLockNotificationEnabled(true); + test(session1, controlView, true); + + controlView.options().setLockNotificationEnabled(false); + test(session1, controlView, false); + + session1.close(); + session2.close(); + } + + public void testLockStateHeldByDurableView() throws CommitException + { + { + CDOSession session1 = openSession(); + CDOTransaction tx1 = session1.openTransaction(); + tx1.enableDurableLocking(true); + CDOResource res1 = tx1.createResource(getResourcePath("r1")); + Company company1 = getModel1Factory().createCompany(); + res1.getContents().add(company1); + tx1.commit(); + + CDOUtil.getCDOObject(company1).cdoWriteLock().lock(); + tx1.close(); + session1.close(); + } + + CDOSession session2 = openSession(); + CDOView controlView = session2.openView(); + CDOResource resource = controlView.getResource(getResourcePath("r1")); + Company company1 = (Company)resource.getContents().get(0); + CDOObject cdoObj = CDOUtil.getCDOObject(company1); + assertEquals(true, cdoObj.cdoWriteLock().isLockedByOthers()); + assertSame(CDOLockOwner.UNKNOWN, cdoObj.cdoLockState().getWriteLockOwner()); + session2.close(); + } + + public void testLockStateNewAndTransient() throws CommitException + { + Company company1 = getModel1Factory().createCompany(); + CDOObject cdoObj = CDOUtil.getCDOObject(company1); + assertTransient(cdoObj); + assertNull(cdoObj.cdoLockState()); + + CDOSession session1 = openSession(); + CDOTransaction tx1 = session1.openTransaction(); + CDOResource res1 = tx1.createResource(getResourcePath("r1")); + res1.getContents().add(company1); + assertNew(cdoObj, tx1); + assertNull(cdoObj.cdoLockState()); + + tx1.commit(); + assertClean(cdoObj, tx1); + assertNotNull(cdoObj.cdoLockState()); + + res1.getContents().add(company1); + tx1.commit(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java new file mode 100644 index 0000000000..250fa7cd3b --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java @@ -0,0 +1,67 @@ +/** + * 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.offline; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.session.CDOSession; +import org.eclipse.emf.cdo.tests.AbstractSyncingTest; +import org.eclipse.emf.cdo.tests.model1.Company; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.cdo.view.CDOView; + +/** + * @author Caspar De Groot + */ +public class OfflineLockingTest extends AbstractSyncingTest +{ + public void testLockAndUnlockThrough() throws Exception + { + // InternalRepository clone = getRepository(); + // InternalRepository master = getRepository(clone.getName() + "_master"); + + CDOSession masterSession = openSession(getRepository().getName() + "_master"); + // CDOTransaction masterTx = masterSession.openTransaction(); + + CDOSession cloneSession = openSession(); + waitForOnline(cloneSession.getRepositoryInfo()); + + CDOTransaction cloneTx = cloneSession.openTransaction(); + cloneTx.enableDurableLocking(true); + + CDOResource res = cloneTx.createResource(getResourcePath("test")); + Company company = getModel1Factory().createCompany(); + res.getContents().add(company); + cloneTx.commit(); + + CDOObject cdoCompany = CDOUtil.getCDOObject(company); + cdoCompany.cdoWriteLock().lock(); + + CDOView masterView = masterSession.openView(); + CDOObject cdoCompanyOnMaster = masterView.getObject(cdoCompany.cdoID()); + assertEquals(true, cdoCompanyOnMaster.cdoWriteLock().isLockedByOthers()); + + // int viewID = cloneTx.getViewID(); + // master.getLockManager().hasLock(LockType.WRITE, context, objectToLock); + + cdoCompany.cdoWriteLock().unlock(); + assertEquals(false, cdoCompanyOnMaster.cdoWriteLock().isLockedByOthers()); + + cloneSession.close(); + masterSession.close(); + } + + public void testMasterLocks_ArrivalInClone() throws Exception + { + + } +} |