/* * Copyright (c) 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.internal.server.syncing.OfflineClone; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.emf.cdo.tests.AbstractSyncingTest; import org.eclipse.emf.cdo.tests.model1.Company; import org.eclipse.emf.cdo.tests.util.TestListener2; 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.CDOViewLocksChangedEvent; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; /** * @author Caspar De Groot */ public class OfflineLockReplicationTest extends AbstractSyncingTest { public void testCloneLocks_replicationToOtherClone_newSession() throws CommitException { testCloneLocks_replicationToOtherClone(false); } public void testCloneLocks_replicationToOtherClone_sameSession() throws CommitException { testCloneLocks_replicationToOtherClone(true); } private void testCloneLocks_replicationToOtherClone(boolean keepSession) throws CommitException { InternalRepository repo1 = getRepository("repo1"); assertEquals(true, repo1 instanceof OfflineClone); InternalRepository repo2 = getRepository("repo2"); assertEquals(true, repo2 instanceof OfflineClone); OfflineClone clone2 = (OfflineClone)repo2; waitForOnline(getRepository("repo1")); waitForOnline(getRepository("repo2")); CDOSession clone1session = openSession("repo1"); // Store 3 objects in repo1 CDOTransaction tx1_sess1 = openTransaction(clone1session); CDOResource resource_tx1_sess1 = tx1_sess1.createResource(getResourcePath("test")); Company companyA = getModel1Factory().createCompany(); Company companyB = getModel1Factory().createCompany(); Company companyC = getModel1Factory().createCompany(); resource_tx1_sess1.getContents().add(companyA); resource_tx1_sess1.getContents().add(companyB); resource_tx1_sess1.getContents().add(companyC); tx1_sess1.commit(); CDOTransaction tx1_sess2; { // Verify that they're visible in repo2 tx1_sess2 = openTransactionWithLockListener("repo2"); CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test")); assertEquals(3, resource_tx1_sess2.getContents().size()); if (!keepSession) { tx1_sess2.getSession().close(); tx1_sess2 = null; } } clone2.goOffline(); waitForOffline(clone2); // Lock the objects in repo1. Since repo1 is ONLINE, this will also lock them // in the master. CDOUtil.getCDOObject(companyA).cdoReadLock().lock(); CDOUtil.getCDOObject(companyB).cdoWriteLock().lock(); CDOUtil.getCDOObject(companyC).cdoWriteOption().lock(); clone2.goOnline(); waitForOnline(clone2); { // Verify that the locks are visible in repo2 if (!keepSession) { tx1_sess2 = openTransactionWithLockListener("repo2"); } else { ((TestListener2)tx1_sess2.getListeners()[0]).waitFor(1); } CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test")); EList<EObject> contents = resource_tx1_sess2.getContents(); CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0)); CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1)); CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2)); assertEquals(true, companyA_in_sess2.cdoReadLock().isLockedByOthers()); assertEquals(true, companyB_in_sess2.cdoWriteLock().isLockedByOthers()); assertEquals(true, companyC_in_sess2.cdoWriteOption().isLockedByOthers()); if (!keepSession) { tx1_sess2.getSession().close(); tx1_sess2 = null; } } clone2.goOffline(); waitForOffline(clone2); // Unlock the objects in repo1. Since repo1 is ONLINE, this will also lock them // in the master. CDOUtil.getCDOObject(companyA).cdoReadLock().unlock(); CDOUtil.getCDOObject(companyB).cdoWriteLock().unlock(); CDOUtil.getCDOObject(companyC).cdoWriteOption().unlock(); clone2.goOnline(); waitForOnline(clone2); { // Verify in repo2 if (!keepSession) { tx1_sess2 = openTransactionWithLockListener("repo2"); } else { ((TestListener2)tx1_sess2.getListeners()[0]).waitFor(2); } CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test")); EList<EObject> contents = resource_tx1_sess2.getContents(); CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0)); CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1)); CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2)); assertEquals(false, companyA_in_sess2.cdoReadLock().isLockedByOthers()); assertEquals(false, companyB_in_sess2.cdoWriteLock().isLockedByOthers()); assertEquals(false, companyC_in_sess2.cdoWriteOption().isLockedByOthers()); tx1_sess2.getSession().close(); } clone1session.close(); } private CDOTransaction openTransactionWithLockListener(String repoName) { CDOSession session = openSession(repoName); CDOTransaction tx = openTransaction(session); tx.addListener(new TestListener2(CDOViewLocksChangedEvent.class)); return tx; } }