blob: 3732d92dbb1ae196ad495d1fb5dc61d8f9a5edc0 [file] [log] [blame]
/*
* Copyright (c) 2013, 2014 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:
* Esteban Dugueperoux - initial API and implementation
*/
package org.eclipse.emf.cdo.tests.bugzilla;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
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.model3.NodeA;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
/**
* Bug 415415: Stale reference not removed between locally detached object and remotely changed ones
*
* @author Esteban Dugueperoux
*/
public class Bugzilla_415415_Test extends AbstractCDOTest
{
private static final String RESOURCE_NAME = "res1";
private CDOTransaction transaction;
private NodeA root;
private NodeA child1;
private NodeA child2;
private CDOObject rootCDO;
private CDOObject child1CDO;
private CDOObject child2CDO;
private CDOID rootID;
private CDOID child1ID;
private CDOID child2ID;
private RemoteUser remoteUser;
@Override
public void setUp() throws Exception
{
super.setUp();
root = getModel3Factory().createNodeA();
root.setName("root");
child1 = getModel3Factory().createNodeA();
child1.setName("child1");
root.getChildren().add(child1);
child2 = getModel3Factory().createNodeA();
child2.setName("child2");
root.getChildren().add(child2);
CDOSession session = openSession();
session.options().setPassiveUpdateEnabled(true);
session.options().setPassiveUpdateMode(PassiveUpdateMode.ADDITIONS);
transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath(RESOURCE_NAME));
resource.getContents().add(root);
transaction.commit();
rootCDO = CDOUtil.getCDOObject(root);
rootID = rootCDO.cdoID();
child1CDO = CDOUtil.getCDOObject(child1);
child1ID = child1CDO.cdoID();
child2CDO = CDOUtil.getCDOObject(child2);
child2ID = child2CDO.cdoID();
remoteUser = new RemoteUser();
}
@Override
public void tearDown() throws Exception
{
root = null;
child1 = null;
child2 = null;
rootCDO = null;
child1CDO = null;
child2CDO = null;
rootID = null;
child1ID = null;
child2ID = null;
remoteUser = null;
super.tearDown();
}
public void testStaleReferenceRemove_FromLocallyDirtyObjectToRemotelyDetachedObject() throws Exception
{
child2.getOtherNodes().add(child1);
remoteUser.removeNodeA1ChildToNodeAroot();
CDOCommitInfo commit = remoteUser.commit();
transaction.waitForUpdate(commit.getTimeStamp(), DEFAULT_TIMEOUT);
assertEquals("As child1 is remotelly detached, the stale reference child2.otherNodes:child1 should be removed", 0,
child2.getOtherNodes().size());
String assertMessage = "As the stale reference child2.otherNodes:child1 has been removed the transaction should be clean";
assertEquals(assertMessage, false, transaction.isDirty());
assertEquals(assertMessage, 0, transaction.getDirtyObjects().size());
transaction.commit();
remoteUser.assertNotStaleReference();
}
public void testStaleReferenceRemove_FromRemotelyDirtyObjectToLocallyDetachedObject() throws Exception
{
root.getChildren().remove(child1);
remoteUser.createReferenceFromNodeA2ToNodeA1();
CDOCommitInfo commit = remoteUser.commit();
transaction.waitForUpdate(commit.getTimeStamp(), DEFAULT_TIMEOUT);
assertEquals(1, transaction.getDetachedObjects().size());
assertEquals(child1CDO, transaction.getDetachedObjects().get(child1ID));
assertEquals("As child1 is locally detached, the stale reference child2.otherNodes:child1 should be removed", 0,
child2.getOtherNodes().size());
String assertMessage = "As the stale reference child2.otherNodes:child1 has been removed, child2 and nodeARoot should be the only dirty objects";
assertEquals(assertMessage, 2, transaction.getDirtyObjects().size());
assertEquals(assertMessage, child2CDO, transaction.getDirtyObjects().get(child2ID));
assertEquals(assertMessage, rootCDO, transaction.getDirtyObjects().get(rootID));
commit = transaction.commit();
remoteUser.waitForUpdate(commit.getTimeStamp(), DEFAULT_TIMEOUT);
remoteUser.assertNotStaleReference();
}
/**
* @author Esteban Dugueperoux
*/
private final class RemoteUser
{
private CDOTransaction transaction;
private NodeA root;
private NodeA child1;
private NodeA child2;
public RemoteUser()
{
CDOSession session = openSession();
session.options().setPassiveUpdateEnabled(true);
session.options().setPassiveUpdateMode(PassiveUpdateMode.ADDITIONS);
transaction = session.openTransaction();
CDOResource resource = transaction.getResource(getResourcePath(RESOURCE_NAME));
root = (NodeA)resource.getContents().get(0);
child1 = root.getChildren().get(0);
child2 = root.getChildren().get(1);
}
public void removeNodeA1ChildToNodeAroot()
{
root.getChildren().remove(child1);
}
public void createReferenceFromNodeA2ToNodeA1()
{
child2.getOtherNodes().add(child1);
}
public CDOCommitInfo commit() throws Exception
{
return transaction.commit();
}
public void waitForUpdate(long timeStamp, long defaultTimeout)
{
transaction.waitForUpdate(timeStamp, defaultTimeout);
}
public void assertNotStaleReference()
{
assertEquals(0, transaction.getDetachedObjects().size());
assertEquals(0, transaction.getDirtyObjects().size());
assertEquals(0, child2.getOtherNodes().size());
}
}
}