/* * Copyright (c) 2014, 2016 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: * Eike Stepper - initial API and implementation */ package org.eclipse.emf.cdo.tests.bugzilla; 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.model6.ContainmentObject; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.ecore.resource.Resource; import org.junit.Assert; import java.util.Collections; /** * @author Esteban Dugueperoux * * Test about remote detachment. */ public class Bugzilla_363355_Test extends AbstractCDOTest { private static final String RESOURCE_PATH = "/test1"; private CDOSession sessionOfUser1; private CDOTransaction transactionOfUser1; private ContainmentObject co1; private ContainmentObject co2; private ContainmentObject co3; @Override public void setUp() throws Exception { super.setUp(); sessionOfUser1 = openSession(); transactionOfUser1 = sessionOfUser1.openTransaction(); CDOResource resourceOfUser1 = transactionOfUser1.createResource(getResourcePath(RESOURCE_PATH)); co1 = getModel6Factory().createContainmentObject(); co2 = getModel6Factory().createContainmentObject(); co1.setContainmentOptional(co2); co3 = getModel6Factory().createContainmentObject(); co2.setContainmentOptional(co3); resourceOfUser1.getContents().add(co1); resourceOfUser1.save(Collections.emptyMap()); } /** * Test about remotely detached object make CDOTransaction dirty * in invalidation while it shouldn't. * * @throws Exception */ public void testCDOTransactionDirtyOnInvalidation() throws Exception { // User 2 do changes CDOSession sessionOfUser2 = openSession(); CDOTransaction transactionOfUser2 = sessionOfUser2.openTransaction(); transactionOfUser2.options().setAutoReleaseLocksEnabled(false); Resource resourceOfUser2 = transactionOfUser2.getResource(getResourcePath(RESOURCE_PATH)); ContainmentObject co1_OfUser2 = (ContainmentObject)resourceOfUser2.getContents().get(0); ContainmentObject co2_OfUser2 = (ContainmentObject)co1_OfUser2.getContainmentOptional(); ContainmentObject newCO3FromUser2 = getModel6Factory().createContainmentObject(); co2_OfUser2.setContainmentOptional(newCO3FromUser2); commitAndSync(transactionOfUser2, transactionOfUser1); // User 1 checks that its transaction is not dirty Assert.assertFalse("Receiving remote changes shouldn't set local CDOTransaction dirty", transactionOfUser1.isDirty()); commitAndSync(transactionOfUser1, transactionOfUser2); transactionOfUser2.close(); sessionOfUser2.close(); } /** * Because we have found a scenario for which the initial * fix, i.e. manage detached objects before changed objects in invalidation, * cause a regression "Cannot modify a frozen revisison" in invalidation in * legacy. * <p> * Scenario : * <ol> * <li>User1 have a ContainmentObject co1 containing a ContainmentObject co2 and this last contains a ContainmentObject co3</li> * <li>User1 set a new co2 having a its own co3 to co1 and move * the original co3 of the old co2 to the new co2 and commit</li> * <li>User2 get a "Cannot modify a frozen revision" exception in * invalidation</li> * </ol> * </p> * * @throws Exception */ public void testCannotModifyFrozenRevisionOnInvalidation() throws Exception { // User 2 do changes CDOSession sessionOfUser2 = openSession(); CDOTransaction transactionOfUser2 = sessionOfUser2.openTransaction(); transactionOfUser2.options().setAutoReleaseLocksEnabled(false); Resource resourceOfUser2 = transactionOfUser2.getResource(getResourcePath(RESOURCE_PATH)); ContainmentObject co1_OfUser2 = (ContainmentObject)resourceOfUser2.getContents().get(0); ContainmentObject co2_OfUser2 = (ContainmentObject)co1_OfUser2.getContainmentOptional(); co2_OfUser2.getContainmentOptional(); ContainmentObject newCO2 = getModel6Factory().createContainmentObject(); ContainmentObject newCO3 = getModel6Factory().createContainmentObject(); newCO2.setContainmentOptional(newCO3); co1_OfUser2.setContainmentOptional(newCO2); ContainmentObject oldCO3 = (ContainmentObject)co2_OfUser2.getContainmentOptional(); newCO2.setContainmentOptional(oldCO3); commitAndSync(transactionOfUser2, transactionOfUser1); // Asserts on user1 transaction, receiving the changes committed by // user2 Assert.assertNotSame(co2, co3.eContainer()); Assert.assertSame(co1.getContainmentOptional(), co3.eContainer()); Assert.assertNull(co2.eContainer()); Assert.assertFalse("Receiving remote changes shouldn't set local CDOTransaction dirty", transactionOfUser2.isDirty()); transactionOfUser2.close(); sessionOfUser2.close(); } @Override public void tearDown() throws Exception { transactionOfUser1.close(); transactionOfUser1 = null; sessionOfUser1.close(); sessionOfUser1 = null; co1 = null; co2 = null; co3 = null; super.tearDown(); } }