blob: f2eba5cbe8d1bdc7808308503a1d4c458f5e4c4f [file] [log] [blame]
/*
* Copyright (c) 2010-2013 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;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.Product1;
import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
import org.eclipse.emf.cdo.tests.model1.Supplier;
import org.eclipse.emf.cdo.tests.model4.ContainedElementNoOpposite;
import org.eclipse.emf.cdo.tests.model4.MultiNonContainedElement;
import org.eclipse.emf.cdo.tests.model4.RefMultiNonContained;
import org.eclipse.emf.cdo.tests.model4.RefSingleContainedNPL;
import org.eclipse.emf.cdo.tests.model4.RefSingleNonContained;
import org.eclipse.emf.cdo.tests.model4.SingleNonContainedElement;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.util.CommitIntegrityException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.internal.cdo.util.CommitIntegrityCheck;
import org.eclipse.emf.internal.cdo.util.CommitIntegrityCheck.Style;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction.InternalCDOCommitContext;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @author Eike Stepper
*/
public class PartialCommitTest extends AbstractCDOTest
{
private static String RESOURCENAME = "/r1";
private CDOSession session;
private InternalCDOTransaction tx;
private CDOResource resource1;
/* ---- Model 1 stuff ---- */
private Company company1, company2, company3, company99;
private PurchaseOrder purchaseOrder;
private Supplier supplier1;
/* ---- Model 4 stuff ---- */
private RefSingleContainedNPL refSingleContained1, refSingleContained2;
private ContainedElementNoOpposite singleContainedElement1;
private RefSingleNonContained refSingleNonContained1, refSingleNonContained2;
private SingleNonContainedElement singleNonContainedElement1, singleNonContainedElement2;
private RefMultiNonContained refMultiNonContained1, refMultiNonContained2;
private MultiNonContainedElement multiNonContainedElement1, multiNonContainedElement2;
@Override
public synchronized Map<String, Object> getTestProperties()
{
Map<String, Object> map = super.getTestProperties();
map.put(IRepository.Props.ENSURE_REFERENTIAL_INTEGRITY, "true");
return map;
}
@Override
protected void doSetUp() throws Exception
{
super.doSetUp();
session = openSession();
session.options().setPassiveUpdateEnabled(false);
tx = (InternalCDOTransaction)session.openTransaction();
}
@Override
protected void doTearDown() throws Exception
{
tx.close();
tx = null;
session.close();
session = null;
resource1 = null;
company1 = null;
company2 = null;
company3 = null;
company99 = null;
purchaseOrder = null;
supplier1 = null;
refSingleContained1 = null;
refSingleContained2 = null;
singleContainedElement1 = null;
refSingleNonContained1 = null;
refSingleNonContained2 = null;
singleNonContainedElement1 = null;
singleNonContainedElement2 = null;
refMultiNonContained1 = null;
refMultiNonContained2 = null;
multiNonContainedElement1 = null;
multiNonContainedElement2 = null;
super.doTearDown();
}
@CleanRepositoriesBefore(reason = "Root resource access")
public void testNewTopLevelResource() throws CommitException
{
CDOResource topResource1 = tx.createResource("/top1");
tx.commit();
topResource1.setName("top1_newname"); // Make dirty but don't include; this causes partial commit
CDOResource topResource2 = tx.createResource("/top2");
tx.setCommittables(createSet(topResource2, tx.getRootResource()));
goodAll();
}
@CleanRepositoriesBefore(reason = "Root resource access")
public void testNewTopLevelResource_rootResourceNotIncluded() throws CommitException
{
CDOResource topResource1 = tx.createResource("/top1");
tx.commit();
topResource1.setName("top1_newname"); // Make dirty but don't include; this causes partial commit
CDOResource topResource2 = tx.createResource("/top2");
tx.setCommittables(createSet(topResource2));
badAll(createSet(tx.getRootResource()));
}
@CleanRepositoriesBefore(reason = "Root resource access")
public void testNewNestedResource() throws CommitException
{
CDOResource topResource1 = tx.createResource("/top1");
tx.commit();
topResource1.setName("top1_newname"); // Make dirty but don't include; this causes partial commit
CDOResource nestedResource = tx.createResource("/folder/nested");
tx.setCommittables(createSet(nestedResource, nestedResource.getFolder(), tx.getRootResource()));
goodAll();
}
@CleanRepositoriesBefore(reason = "Root resource access")
public void testNewNestedResource_rootResourceNotIncluded() throws CommitException
{
CDOResource topResource1 = tx.createResource("/top1");
tx.commit();
topResource1.setName("top1_newname"); // Make dirty but don't include; this causes partial commit
CDOResource nestedResource = tx.createResource("/folder/nested");
tx.setCommittables(createSet(nestedResource, nestedResource.getFolder()));
badAll(createSet(tx.getRootResource()));
}
@CleanRepositoriesBefore(reason = "Root resource access")
public void testNewNestedResource_resourceFolderNotIncluded() throws CommitException
{
CDOResource topResource1 = tx.createResource("/top1");
tx.commit();
topResource1.setName("top1_newname"); // Make dirty but don't include; this causes partial commit
CDOResource nestedResource = tx.createResource("/folder/nested");
tx.setCommittables(createSet(nestedResource, tx.getRootResource()));
badAll(createSet(nestedResource.getFolder()));
}
public void testPartialCleanUp_dirtyObjects() throws CommitException
{
simpleModel1Setup();
company1.setName("Company1");
company2.setName("Company2");
company3.setName("Company3");
tx.setCommittables(createSet(company1));
tx.commit();
assertClean(company1, tx);
assertDirty(company2, tx);
assertDirty(company3, tx);
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(company2));
tx.commit();
assertClean(company1, tx);
assertClean(company2, tx);
assertDirty(company3, tx);
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(company3));
tx.commit();
assertClean(company1, tx);
assertClean(company2, tx);
assertClean(company3, tx);
assertEquals(false, tx.isDirty());
}
public void testPartialCleanUp_newObjects() throws CommitException
{
simpleModel1Setup();
Category cat = getModel1Factory().createCategory();
resource1.getContents().add(cat);
tx.commit();
company1.setName("Zzz"); // Make dirty but don't include; so as to force partial commit
// Make some new objects; but with different containers
Company company4 = getModel1Factory().createCompany();
resource1.getContents().add(company4);
PurchaseOrder po = getModel1Factory().createPurchaseOrder();
company2.getPurchaseOrders().add(po);
Product1 product = getModel1Factory().createProduct1();
product.setName("product1");
cat.getProducts().add(product);
tx.setCommittables(createSet(company4, resource1));
tx.commit();
assertClean(company4, tx);
assertNew(po, tx);
assertNew(product, tx);
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(po, company2));
tx.commit();
assertClean(company4, tx);
assertClean(po, tx);
assertNew(product, tx);
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(product, cat));
tx.commit();
assertClean(company4, tx);
assertClean(po, tx);
assertClean(product, tx);
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(company1));
tx.commit();
assertEquals(false, tx.isDirty());
}
public void testPartialCleanUp_detachedObjects() throws CommitException
{
skipStoreWithoutQueryXRefs();
simpleModel1Setup();
Category cat = getModel1Factory().createCategory();
resource1.getContents().add(cat);
// Make some new objects; but with different containers
Company company4 = getModel1Factory().createCompany();
resource1.getContents().add(company4);
PurchaseOrder po = getModel1Factory().createPurchaseOrder();
company2.getPurchaseOrders().add(po);
Product1 product = getModel1Factory().createProduct1();
product.setName("product1");
cat.getProducts().add(product);
tx.commit();
company1.setName("Zzz"); // Make dirty but don't include; so as to force partial commit
resource1.getContents().remove(company4);
company2.getPurchaseOrders().remove(po);
cat.getProducts().remove(product);
assertEquals(true, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(company4)));
assertEquals(true, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(company4)));
assertEquals(true, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(po)));
assertEquals(true, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(company4)));
assertEquals(true, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(product)));
assertEquals(true, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(company4)));
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(company4, resource1));
tx.commit();
assertEquals(false, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(company4)));
assertEquals(false, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(company4)));
assertEquals(true, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(po)));
assertEquals(true, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(po)));
assertEquals(true, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(product)));
assertEquals(true, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(product)));
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(po, company2));
tx.commit();
assertEquals(false, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(company4)));
assertEquals(false, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(company4)));
assertEquals(false, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(po)));
assertEquals(false, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(po)));
assertEquals(true, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(product)));
assertEquals(true, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(product)));
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(product, cat));
tx.commit();
assertEquals(false, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(company4)));
assertEquals(false, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(company4)));
assertEquals(false, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(po)));
assertEquals(false, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(po)));
assertEquals(false, tx.getDetachedObjects().containsValue(CDOUtil.getCDOObject(product)));
assertEquals(false, tx.getCleanRevisions().containsKey(CDOUtil.getCDOObject(product)));
assertEquals(true, tx.isDirty());
tx.setCommittables(createSet(company1));
tx.commit();
assertEquals(false, tx.isDirty());
}
public void testDirty() throws CommitException
{
simpleModel1Setup();
supplier1.setName("Supplier");
company1.setName("Company");
tx.setCommittables(createSet(supplier1));
tx.commit();
assertDirty(company1, tx);
assertEquals(company1.getName(), "Company");
assertClean(supplier1, tx);
assertEquals(supplier1.getName(), "Supplier");
}
public void testNew() throws CommitException
{
simpleModel1Setup();
PurchaseOrder po = getModel1Factory().createPurchaseOrder();
company2.getPurchaseOrders().add(po);
// Include both the new object and its container
tx.setCommittables(createSet(company2, po));
goodAll();
}
public void testNew_containerOfNewObjectNotIncluded() throws CommitException
{
simpleModel1Setup();
PurchaseOrder po = getModel1Factory().createPurchaseOrder();
company2.getPurchaseOrders().add(po);
// Include only the new object
tx.setCommittables(createSet(po));
badAll(createSet(company2));
}
public void testNew_newObjectNotIncluded() throws CommitException
{
simpleModel1Setup();
PurchaseOrder po = getModel1Factory().createPurchaseOrder();
company2.getPurchaseOrders().add(po);
// Include only the new object's container
tx.setCommittables(createSet(company2));
badAll(createSet(po));
}
public void testDetach() throws CommitException
{
skipStoreWithoutQueryXRefs();
simpleModel1Setup();
EcoreUtil.delete(purchaseOrder);
// Include the detached object and its old container
tx.setCommittables(createSet(company1, purchaseOrder));
goodAll();
}
public void testDetach_containerOfDetachedObjectNotIncluded() throws CommitException
{
simpleModel1Setup();
EcoreUtil.delete(purchaseOrder);
// Include only the detached object
tx.setCommittables(createSet(purchaseOrder));
badAll(createSet(company1));
}
public void testDetach_detachedObjectNotIncluded() throws CommitException
{
simpleModel1Setup();
EcoreUtil.delete(purchaseOrder);
// Include only the detached object's old container
tx.setCommittables(createSet(company1));
badAll(createSet(purchaseOrder));
}
public void testMove() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
supplier1.setName("Supplier");
// Include the old and new containers as well as the object that was moved
tx.setCommittables(createSet(purchaseOrder, company1, company2));
goodAll();
assertClean(company1, tx);
assertClean(company2, tx);
assertClean(purchaseOrder, tx);
assertDirty(supplier1, tx);
assertEquals(false, company1.getPurchaseOrders().contains(purchaseOrder));
assertEquals(true, company2.getPurchaseOrders().contains(purchaseOrder));
assertEquals("Supplier", supplier1.getName());
assertSame(company2, purchaseOrder.eContainer());
}
public void testMove_newContainerNotIncluded() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
// Include only the object that was moved and its old container
tx.setCommittables(createSet(purchaseOrder, company1));
badAll(createSet(company2));
}
public void testMove_oldContainerNotIncluded() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
// Include only the object that was moved and its new container
tx.setCommittables(createSet(purchaseOrder, company2));
badAll(createSet(company1));
}
public void testMove_movedObjectNotIncluded() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
// Include only the old and new containers
tx.setCommittables(createSet(company1, company2));
badAll(createSet(purchaseOrder));
}
public void testMove_onlyOldContainerIncluded() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
// Include only the old container
tx.setCommittables(createSet(company1));
badAll(createSet(company2, purchaseOrder));
}
public void testMove_onlyNewContainerIncluded() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
// Include only the new container
tx.setCommittables(createSet(company2));
badAll(createSet(company1, purchaseOrder));
}
public void testMove_onlyMovedObjectIncluded() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
// Include only the moved object
tx.setCommittables(createSet(purchaseOrder));
badAll(createSet(company1, company2));
}
public void testDoubleMove() throws CommitException
{
simpleModel1Setup();
company2.getPurchaseOrders().add(purchaseOrder);
company3.getPurchaseOrders().add(purchaseOrder);
// Include the old and new containers as well as the object that was moved
// (The point here is that company2 does NOT have to be included.)
tx.setCommittables(createSet(purchaseOrder, company1, company3));
System.out.printf("---> purchaseOrder=%s company1=%s company2=%s company3=%s\n", purchaseOrder, company1, company2,
company3);
goodAll();
}
public void test_noCommittablesAfterCommit() throws CommitException
{
simpleModel1Setup();
company1.setName("zzz");
tx.setCommittables(createSet(company1));
tx.commit();
assertNull(tx.getCommittables());
}
public void testNewSingle() throws CommitException
{
simpleModel4ContainmentSetup();
ContainedElementNoOpposite singleContainedElement = getModel4Factory().createContainedElementNoOpposite();
refSingleContained2.setElement(singleContainedElement);
// Include both the new object and its container
tx.setCommittables(createSet(refSingleContained2, singleContainedElement));
goodAll();
}
public void testNewSingle_containerOfNewObjectNotIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
ContainedElementNoOpposite singleContainedElement = getModel4Factory().createContainedElementNoOpposite();
refSingleContained2.setElement(singleContainedElement);
// Include only the new object
tx.setCommittables(createSet(singleContainedElement));
badAll(createSet(refSingleContained2));
}
public void testNewSingle_newObjectNotIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
ContainedElementNoOpposite singleContainedElement = getModel4Factory().createContainedElementNoOpposite();
refSingleContained2.setElement(singleContainedElement);
// Include only the new object's container
tx.setCommittables(createSet(refSingleContained2));
badAll(createSet(singleContainedElement));
}
public void testDetachSingleRef() throws CommitException
{
skipStoreWithoutQueryXRefs();
simpleModel4ContainmentSetup();
refSingleContained1.setElement(null);
// Include the detached object and its old container
tx.setCommittables(createSet(refSingleContained1, singleContainedElement1));
goodAll();
}
public void testDetachSingleRef_containerOfDetachedObjectNotIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained1.setElement(null);
// Include only the detached object
tx.setCommittables(createSet(singleContainedElement1));
badAll(createSet(refSingleContained1));
}
public void testDetachSingleRef_detachedObjectNotIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained1.setElement(null);
// Include only the detached object's old container
tx.setCommittables(createSet(refSingleContained1));
badAll(createSet(singleContainedElement1));
}
public void testMoveSingleRef() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained2.setElement(singleContainedElement1);
// Include the old and new containers as well as the object that was moved
tx.setCommittables(createSet(refSingleContained1, refSingleContained2, singleContainedElement1));
goodAll();
}
public void testMoveSingleRef_newContainerNotIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained2.setElement(singleContainedElement1);
// Include only the object that was moved and its old container
tx.setCommittables(createSet(refSingleContained1, singleContainedElement1));
badAll(createSet(refSingleContained2));
}
public void testMoveSingleRef_oldContainerNotIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained2.setElement(singleContainedElement1);
// Include only the object that was moved and its new container
tx.setCommittables(createSet(refSingleContained2, singleContainedElement1));
badAll(createSet(refSingleContained1));
}
public void testMoveSingleRef_movedObjectNotIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained2.setElement(singleContainedElement1);
// Include only the old and new containers
tx.setCommittables(createSet(refSingleContained1, refSingleContained2));
badAll(createSet(singleContainedElement1));
}
public void testMoveSingleRef_onlyOldContainerIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained2.setElement(singleContainedElement1);
// Include only the old container
tx.setCommittables(createSet(refSingleContained1));
badAll(createSet(singleContainedElement1, refSingleContained2));
}
public void testMoveSingleRef_onlyNewContainerIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained2.setElement(singleContainedElement1);
// Include only the new container
tx.setCommittables(createSet(refSingleContained2));
badAll(createSet(singleContainedElement1, refSingleContained1));
}
public void testMoveSingleRef_onlyMovedObjectIncluded() throws CommitException
{
simpleModel4ContainmentSetup();
refSingleContained2.setElement(singleContainedElement1);
// Include only the moved object
tx.setCommittables(createSet(singleContainedElement1));
badAll(createSet(refSingleContained1, refSingleContained2));
}
public void testNewTopLevel() throws CommitException
{
simpleModel1Setup();
Company company = getModel1Factory().createCompany();
resource1.getContents().add(company);
// Include both the resource and the new object
tx.setCommittables(createSet(resource1, company));
goodAll();
}
public void testNewTopLevel_newObjectNotIncluded() throws CommitException
{
simpleModel1Setup();
Company company = getModel1Factory().createCompany();
resource1.getContents().add(company);
// Include only the resource
tx.setCommittables(createSet(resource1));
badAll(createSet(company));
}
public void testNewTopLevel_resourceNotIncluded() throws CommitException
{
simpleModel1Setup();
Company company = getModel1Factory().createCompany();
resource1.getContents().add(company);
// Include only the new object
tx.setCommittables(createSet(company));
badAll(createSet(resource1));
}
public void _testNewTopLevel_resourceNotIncluded() throws CommitException
{
simpleModel1Setup();
CDOID companyID = null;
{
Company company = getModel1Factory().createCompany();
resource1.getContents().add(company);
// Include only the new object
tx.setCommittables(createSet(company));
tx.commit();
companyID = CDOUtil.getCDOObject(company).cdoID();
}
System.out.println("---> companyID = " + companyID);
System.out.println("---> " + CDOUtil.getCDOObject(resource1).cdoState());
{
CDOSession session2 = openSession();
CDOView view = session2.openView();
CDOResource resource = view.getResource(getResourcePath(resource1.getPath()));
// We want to know if the new company that was committed, is an element
// in the getContents() collection of the Resource. We cannot just call
// getContents().contains(), because of the odd implementation of
// CDOResourceImpl.contains: it actually asks the element, rather than
// checking its own collection. So, we have to do this the hard way:
//
boolean found = false;
Iterator<EObject> iter = resource.getContents().iterator();
while (!found && iter.hasNext())
{
CDOObject o = CDOUtil.getCDOObject(iter.next());
if (o.cdoID().equals(companyID))
{
found = true;
}
}
assertEquals(true, found);
view.close();
session2.close();
}
}
// -------- Tests concerning bi-di references ----------
//
// Cases to test:
// Bi-di refs are analogous to containment, the only difference being that
// bi-di refs are symmetrical, whereas containment/container is not.
//
// So:
//
// For DIRTY objects, the cases are:
// 1. Setting a bidi ref to null where it was previously non-null
// Must check that object owning opposite feature is included
// 2. Setting a bidi ref to non-null where it was previously null
// Must check that object owning opposite feature is included
// 3. Changing a bidi ref from one non-null value to another
// Must check that both the object owning the NEW opposite feature,
// as well as the OLD one, are included
//
// For NEW objects, the
// If the detached object had any non-null bidi refs, we must check
// whether the bidi target is included.
//
// For DETACHED objects:
// If the detached object had any non-null bidi refs, we must check
// whether the bidi target is included.
public void testDirtySingleBidiNew() throws CommitException
{
simpleModel4SingleBidiSetup();
singleNonContainedElement2.setParent(refSingleNonContained2);
tx.setCommittables(createSet(singleNonContainedElement2, refSingleNonContained2));
goodAll();
}
public void testDirtySingleBidiNew_newtargetNotIncluded() throws CommitException
{
simpleModel4SingleBidiSetup();
singleNonContainedElement2.setParent(refSingleNonContained2);
tx.setCommittables(createSet(singleNonContainedElement2));
badAll(createSet(refSingleNonContained2));
}
public void testDirtySingleBidiChanged() throws CommitException
{
simpleModel4SingleBidiSetup();
// We "reparent" the singleNonContainedElement1
singleNonContainedElement1.setParent(refSingleNonContained2);
tx.setCommittables(createSet(singleNonContainedElement1, refSingleNonContained1, refSingleNonContained2));
goodAll();
}
public void testDirtySingleBidiChanged_newTargetNotIncluded() throws CommitException
{
simpleModel4SingleBidiSetup();
// We "reparent" the singleNonContainedElement1
singleNonContainedElement1.setParent(refSingleNonContained2);
tx.setCommittables(createSet(singleNonContainedElement1, refSingleNonContained1));
badAll(createSet(refSingleNonContained2));
}
public void testDirtySingleBidiChanged_oldTargetNotIncluded() throws CommitException
{
simpleModel4SingleBidiSetup();
// We "reparent" the singleNonContainedElement1
singleNonContainedElement1.setParent(refSingleNonContained2);
tx.setCommittables(createSet(singleNonContainedElement1, refSingleNonContained2));
badAll(createSet(refSingleNonContained1));
}
public void testDirtySingleBidiRemoved() throws CommitException
{
simpleModel4SingleBidiSetup();
singleNonContainedElement1.setParent(null);
tx.setCommittables(createSet(singleNonContainedElement1, refSingleNonContained1));
goodAll();
}
public void testDirtySingleBidiRemoved_oldTargetNotIncluded() throws CommitException
{
simpleModel4SingleBidiSetup();
singleNonContainedElement1.setParent(null);
tx.setCommittables(createSet(singleNonContainedElement1));
badAll(createSet(refSingleNonContained1));
}
public void testSingleBidiOnNewObject() throws CommitException
{
simpleModel4SingleBidiSetup();
SingleNonContainedElement newNonContainedElement = getModel4Factory().createSingleNonContainedElement();
resource1.getContents().add(newNonContainedElement);
newNonContainedElement.setParent(refSingleNonContained2);
tx.setCommittables(createSet(newNonContainedElement, resource1, refSingleNonContained2));
goodAll();
}
public void testSingleBidiOnNewObject_targetNotIncluded() throws CommitException
{
simpleModel4SingleBidiSetup();
SingleNonContainedElement newNonContainedElement = getModel4Factory().createSingleNonContainedElement();
resource1.getContents().add(newNonContainedElement);
newNonContainedElement.setParent(refSingleNonContained2);
tx.setCommittables(createSet(newNonContainedElement, resource1));
badAll(createSet(refSingleNonContained2));
}
public void testSingleBidiOnRemovedObject() throws CommitException
{
skipStoreWithoutQueryXRefs();
simpleModel4SingleBidiSetup();
EcoreUtil.delete(singleNonContainedElement1);
tx.setCommittables(createSet(singleNonContainedElement1, resource1, refSingleNonContained1));
goodAll();
}
public void testSingleBidiOnRemovedObject_targetNotIncluded() throws CommitException
{
simpleModel4SingleBidiSetup();
EcoreUtil.delete(singleNonContainedElement1);
tx.setCommittables(createSet(singleNonContainedElement1, resource1));
badAll(createSet(refSingleNonContained1));
}
public void testDirtyMultiBidiNew() throws CommitException
{
simpleModel4MultiBidiSetup();
multiNonContainedElement2.setParent(refMultiNonContained2);
tx.setCommittables(createSet(multiNonContainedElement2, refMultiNonContained2));
goodAll();
}
public void testDirtyMultiBidiNew_newtargetNotIncluded() throws CommitException
{
simpleModel4MultiBidiSetup();
multiNonContainedElement2.setParent(refMultiNonContained2);
tx.setCommittables(createSet(multiNonContainedElement2));
badAll(createSet(refMultiNonContained2));
}
public void testDirtyMultiBidiChanged() throws CommitException
{
simpleModel4MultiBidiSetup();
// We "reparent" the multiNonContainedElement1
multiNonContainedElement1.setParent(refMultiNonContained2);
tx.setCommittables(createSet(multiNonContainedElement1, refMultiNonContained1, refMultiNonContained2));
goodAll();
}
public void testDirtyMultiBidiChanged_newTargetNotIncluded() throws CommitException
{
simpleModel4MultiBidiSetup();
// We "reparent" the multiNonContainedElement1
multiNonContainedElement1.setParent(refMultiNonContained2);
tx.setCommittables(createSet(multiNonContainedElement1, refMultiNonContained1));
badAll(createSet(refMultiNonContained2));
}
public void testDirtyMultiBidiChanged_oldTargetNotIncluded() throws CommitException
{
simpleModel4MultiBidiSetup();
// We "reparent" the multiNonContainedElement1
multiNonContainedElement1.setParent(refMultiNonContained2);
tx.setCommittables(createSet(multiNonContainedElement1, refMultiNonContained2));
badAll(createSet(refMultiNonContained1));
}
public void testDirtyMultiBidiRemoved() throws CommitException
{
simpleModel4MultiBidiSetup();
multiNonContainedElement1.setParent(null);
tx.setCommittables(createSet(multiNonContainedElement1, refMultiNonContained1));
goodAll();
}
public void testDirtyMultiBidiRemoved_oldTargetNotIncluded() throws CommitException
{
simpleModel4MultiBidiSetup();
multiNonContainedElement1.setParent(null);
tx.setCommittables(createSet(multiNonContainedElement1));
badAll(createSet(refMultiNonContained1));
}
public void testMultiBidiOnNewObject() throws CommitException
{
simpleModel4MultiBidiSetup();
MultiNonContainedElement newNonContainedElement = getModel4Factory().createMultiNonContainedElement();
resource1.getContents().add(newNonContainedElement);
newNonContainedElement.setParent(refMultiNonContained2);
tx.setCommittables(createSet(newNonContainedElement, resource1, refMultiNonContained2));
goodAll();
}
public void testMultiBidiOnNewObject_targetNotIncluded() throws CommitException
{
simpleModel4MultiBidiSetup();
MultiNonContainedElement newNonContainedElement = getModel4Factory().createMultiNonContainedElement();
resource1.getContents().add(newNonContainedElement);
newNonContainedElement.setParent(refMultiNonContained2);
tx.setCommittables(createSet(newNonContainedElement, resource1));
badAll(createSet(refMultiNonContained2));
}
public void testMultiBidiOnRemovedObject() throws CommitException
{
skipStoreWithoutQueryXRefs();
simpleModel4MultiBidiSetup();
EcoreUtil.delete(multiNonContainedElement1);
tx.setCommittables(createSet(multiNonContainedElement1, resource1, refMultiNonContained1));
goodAll();
}
public void testMultiBidiOnRemovedObject_targetNotIncluded() throws CommitException
{
simpleModel4MultiBidiSetup();
EcoreUtil.delete(multiNonContainedElement1);
tx.setCommittables(createSet(multiNonContainedElement1, resource1));
badAll(createSet(refMultiNonContained1));
}
/* --------- DANGLING REFERENCE PROBLEMS: Single refs ---------- */
public void testIgnoreDanglingSingleRef_newToDetached() throws CommitException
{
simpleModel4SingleBidiSetup();
RefSingleNonContained refSingleNonContained3 = getModel4Factory().createRefSingleNonContained();
resource1.getContents().add(refSingleNonContained3);
EcoreUtil.delete(singleNonContainedElement2);
refSingleNonContained3.setElement(singleNonContainedElement2);
tx.setCommittables(createSet(refSingleNonContained3, singleNonContainedElement2, resource1));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingSingleRef_newToTransient() throws CommitException
{
simpleModel4SingleBidiSetup();
RefSingleNonContained refSingleNonContained3 = getModel4Factory().createRefSingleNonContained();
resource1.getContents().add(refSingleNonContained3);
SingleNonContainedElement singleNonContainedElement3 = getModel4Factory().createSingleNonContainedElement();
refSingleNonContained3.setElement(singleNonContainedElement3);
tx.setCommittables(createSet(refSingleNonContained3, singleNonContainedElement3, resource1));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingSingleRef_dirtyToDetached() throws CommitException
{
simpleModel4SingleBidiSetup();
EcoreUtil.delete(singleNonContainedElement2);
refSingleNonContained2.setElement(singleNonContainedElement2);
tx.setCommittables(createSet(refSingleNonContained2, singleNonContainedElement2, resource1));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingSingleRef_dirtyToTransient() throws CommitException
{
simpleModel4SingleBidiSetup();
SingleNonContainedElement singleNonContainedElement3 = getModel4Factory().createSingleNonContainedElement();
refSingleNonContained2.setElement(singleNonContainedElement3);
tx.setCommittables(createSet(refSingleNonContained2));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingSingleRef_dirtyToTransient2() throws CommitException
{
simpleModel4SingleBidiSetup();
SingleNonContainedElement singleNonContainedElement3 = getModel4Factory().createSingleNonContainedElement();
refSingleNonContained1.setElement(singleNonContainedElement3);
tx.setCommittables(createSet(refSingleNonContained1, singleNonContainedElement1));
good(Style.EXCEPTION);
}
/* --------- DANGLING REFERENCE PROBLEMS: Multi refs ---------- */
public void testIgnoreDanglingMultiRef_newToDetached() throws CommitException
{
simpleModel4MultiBidiSetup();
RefMultiNonContained refMultiNonContained3 = getModel4Factory().createRefMultiNonContained();
resource1.getContents().add(refMultiNonContained3);
EcoreUtil.delete(multiNonContainedElement2);
refMultiNonContained3.getElements().add(multiNonContainedElement2);
tx.setCommittables(createSet(refMultiNonContained3, multiNonContainedElement2, resource1));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingMultiRef_newToTransient() throws CommitException
{
simpleModel4SingleBidiSetup();
RefMultiNonContained refMultiNonContained3 = getModel4Factory().createRefMultiNonContained();
resource1.getContents().add(refMultiNonContained3);
MultiNonContainedElement multiNonContainedElement3 = getModel4Factory().createMultiNonContainedElement();
refMultiNonContained3.getElements().add(multiNonContainedElement3);
tx.setCommittables(createSet(refMultiNonContained3, multiNonContainedElement3, resource1));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingMultiRef_dirtyToDetached() throws CommitException
{
simpleModel4MultiBidiSetup();
EcoreUtil.delete(multiNonContainedElement2);
refMultiNonContained2.getElements().add(multiNonContainedElement2);
tx.setCommittables(createSet(refMultiNonContained2, multiNonContainedElement2, resource1));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingMultiRef_dirtyToTransient() throws CommitException
{
simpleModel4MultiBidiSetup();
MultiNonContainedElement multiNonContainedElement3 = getModel4Factory().createMultiNonContainedElement();
refMultiNonContained2.getElements().add(multiNonContainedElement3);
tx.setCommittables(createSet(refMultiNonContained2, resource1));
good(Style.EXCEPTION);
}
public void testIgnoreDanglingMultiRef_dirtyToTransient2() throws CommitException
{
simpleModel4MultiBidiSetup();
MultiNonContainedElement multiNonContainedElement3 = getModel4Factory().createMultiNonContainedElement();
refMultiNonContained1.getElements().add(multiNonContainedElement3);
tx.setCommittables(createSet(refMultiNonContained1, multiNonContainedElement1));
good(Style.EXCEPTION);
}
/* --------- END OF DANGLING REFERENCE PROBLEMS ---------- */
public void testCheckWithoutCommit_exceptionFast() throws CommitException
{
simpleModel1Setup();
PurchaseOrder po = getModel1Factory().createPurchaseOrder();
company2.getPurchaseOrders().add(po);
// Include only the new object
tx.setCommittables(createSet(po));
InternalCDOCommitContext ctx = tx.createCommitContext();
try
{
new CommitIntegrityCheck(ctx, CommitIntegrityCheck.Style.EXCEPTION_FAST).check();
}
catch (CommitIntegrityException e)
{
// Good
}
}
public void testCheckWithoutCommit_exception() throws CommitException
{
simpleModel1Setup();
PurchaseOrder po = getModel1Factory().createPurchaseOrder();
company2.getPurchaseOrders().add(po);
// Include only the new object
tx.setCommittables(createSet(po));
InternalCDOCommitContext ctx = tx.createCommitContext();
try
{
new CommitIntegrityCheck(ctx, CommitIntegrityCheck.Style.EXCEPTION_FAST).check();
}
catch (CommitIntegrityException e)
{
// Good
}
}
public void testCommittablesContainUncommittableObjects()
{
// Idea here is to include some objects in the committables, that exist, but
// are neither dirty nor detached nor new.
//
// Actually, one could wonder what the desirable behavior is in this case.
// Should there be a failure? Or should the "committables" be considered more like
// a filter; i.e. it's ok for the filter to cover more than what can actually be committed.
// Hmm... *ponder* *ponder*.
//
}
/**
* Test the commit integrity, assuming that it is good, using all possible checking styles.
*/
private void goodAll() throws CommitException
{
good(Style.NO_EXCEPTION);
good(Style.EXCEPTION_FAST);
good(Style.EXCEPTION);
good(null);
}
/**
* Test the commit integrity, assuming that it is good.
*
* @param style
* - the checking style to be used; if null, just commit. In that case, the commit logic will choose the
* checking style.
*/
private void good(Style style) throws CommitException
{
if (style != null)
{
InternalCDOCommitContext ctx = tx.createCommitContext();
CommitIntegrityCheck check = new CommitIntegrityCheck(ctx, style);
try
{
check.check();
assertEquals("check.getMissingObjects() should have been empty", true, check.getMissingObjects().isEmpty());
}
catch (CommitIntegrityException e)
{
fail("Should not have thrown " + CommitIntegrityException.class.getName());
}
}
else
{
// We always make company99 dirty if it's present
// (This is just a control object to verify that some stuff does NOT get
// committed.)
if (company99 != null)
{
company99.setName("000");
}
tx.commit();
// And we verify that it didn't get included in the commit
if (company99 != null)
{
assertDirty(company99, tx);
assertEquals("Transaction should still have been dirty", true, tx.isDirty());
}
}
}
/**
* Test the commit integrity, assuming that it is bad, using all possible checking styles.
*/
private void badAll(Set<EObject> expectedMissingObjects) throws CommitException
{
bad(Style.NO_EXCEPTION, expectedMissingObjects);
bad(Style.EXCEPTION_FAST, expectedMissingObjects);
bad(Style.EXCEPTION, expectedMissingObjects);
bad(null, expectedMissingObjects);
}
/**
* Test the commit integrity, assuming that it is bad.
*
* @param style
* - the checking style to be used; if null, just commit. In that case, the commit logic will choose the
* checking style.
*/
private void bad(Style style, Set<EObject> expectedMissingObjects) throws CommitException
{
CommitIntegrityException commitIntegrityEx = null;
Set<? extends EObject> missingObjects = null;
CommitIntegrityCheck check = null;
if (style != null)
{
InternalCDOCommitContext ctx = tx.createCommitContext();
check = new CommitIntegrityCheck(ctx, style);
}
if (style == Style.NO_EXCEPTION)
{
try
{
check.check();
}
catch (CommitIntegrityException e)
{
fail("Should not have thrown " + CommitIntegrityException.class.getName());
}
}
else if (style == CommitIntegrityCheck.Style.EXCEPTION || style == CommitIntegrityCheck.Style.EXCEPTION_FAST)
{
try
{
check.check();
fail("Should have thrown " + CommitIntegrityException.class.getName());
}
catch (CommitIntegrityException e)
{
commitIntegrityEx = e;
}
}
else if (style == null)
{
try
{
tx.commit();
fail("Should have thrown " + CommitException.class.getName());
}
catch (CommitException e)
{
Throwable cause = e.getCause().getCause();
if (cause instanceof CommitIntegrityException)
{
// Good
commitIntegrityEx = (CommitIntegrityException)cause;
System.out.println("---> Failed properly: " + e.getCause().getMessage());
}
else
{
throw e;
}
}
}
else
{
fail("Unknown style");
}
if (commitIntegrityEx != null)
{
missingObjects = commitIntegrityEx.getMissingObjects();
}
else
{
missingObjects = check.getMissingObjects();
}
if (style == Style.EXCEPTION_FAST)
{
assertEquals(1, missingObjects.size());
}
else
{
// We cannot use == here, because it isn't (always) possible for the logic to
// find all missing objects
assertEquals(true, missingObjects.size() <= expectedMissingObjects.size());
}
for (EObject missingObject : missingObjects)
{
assertEquals(true, expectedMissingObjects.contains(missingObject));
}
}
private void simpleModel1Setup() throws CommitException
{
EReference ref = getModel1Package().getCompany_PurchaseOrders();
boolean preconditions = ref.isContainment() && ref.getEOpposite() == null && ref.isMany();
if (!preconditions)
{
throw new RuntimeException("Model1 does not meet prerequirements for this test");
}
resource1 = tx.createResource(getResourcePath(RESOURCENAME));
company1 = getModel1Factory().createCompany();
company2 = getModel1Factory().createCompany();
company3 = getModel1Factory().createCompany();
company99 = getModel1Factory().createCompany();
supplier1 = getModel1Factory().createSupplier();
purchaseOrder = getModel1Factory().createPurchaseOrder();
company1.getPurchaseOrders().add(purchaseOrder);
resource1.getContents().add(company1);
resource1.getContents().add(company2);
resource1.getContents().add(company3);
resource1.getContents().add(company99);
resource1.getContents().add(supplier1);
tx.commit();
}
private void simpleModel4ContainmentSetup() throws CommitException
{
EReference ref = getModel4Package().getRefSingleContainedNPL_Element();
boolean preconditions = ref.isContainment() && ref.getEOpposite() == null && !ref.isMany();
if (!preconditions)
{
throw new RuntimeException("Model4 does not meet prerequirements for this test");
}
resource1 = tx.createResource(getResourcePath(RESOURCENAME));
refSingleContained1 = getModel4Factory().createRefSingleContainedNPL();
refSingleContained2 = getModel4Factory().createRefSingleContainedNPL();
singleContainedElement1 = getModel4Factory().createContainedElementNoOpposite();
refSingleContained1.setElement(singleContainedElement1);
resource1.getContents().add(refSingleContained1);
resource1.getContents().add(refSingleContained2);
tx.commit();
}
private void simpleModel4SingleBidiSetup() throws CommitException
{
EReference ref = getModel4Package().getRefSingleNonContained_Element();
boolean preconditions = !ref.isContainment() && ref.getEOpposite() != null && !ref.isMany();
if (!preconditions)
{
throw new RuntimeException("Model4 does not meet prerequirements for this test");
}
resource1 = tx.createResource(getResourcePath(RESOURCENAME));
refSingleNonContained1 = getModel4Factory().createRefSingleNonContained();
refSingleNonContained2 = getModel4Factory().createRefSingleNonContained();
singleNonContainedElement1 = getModel4Factory().createSingleNonContainedElement();
singleNonContainedElement2 = getModel4Factory().createSingleNonContainedElement();
refSingleNonContained1.setElement(singleNonContainedElement1);
resource1.getContents().add(refSingleNonContained1);
resource1.getContents().add(refSingleNonContained2);
resource1.getContents().add(singleNonContainedElement1);
resource1.getContents().add(singleNonContainedElement2);
tx.commit();
}
private void simpleModel4MultiBidiSetup() throws CommitException
{
EReference ref = getModel4Package().getRefMultiNonContained_Elements();
boolean preconditions = !ref.isContainment() && ref.getEOpposite() != null && ref.isMany();
if (!preconditions)
{
throw new RuntimeException("Model4 does not meet prerequirements for this test");
}
resource1 = tx.createResource(getResourcePath(RESOURCENAME));
refMultiNonContained1 = getModel4Factory().createRefMultiNonContained();
refMultiNonContained2 = getModel4Factory().createRefMultiNonContained();
multiNonContainedElement1 = getModel4Factory().createMultiNonContainedElement();
multiNonContainedElement2 = getModel4Factory().createMultiNonContainedElement();
refMultiNonContained1.getElements().add(multiNonContainedElement1);
resource1.getContents().add(refMultiNonContained1);
resource1.getContents().add(refMultiNonContained2);
resource1.getContents().add(multiNonContainedElement1);
resource1.getContents().add(multiNonContainedElement2);
tx.commit();
}
private Set<EObject> createSet(EObject... objects)
{
Set<EObject> committables = new HashSet<EObject>();
for (EObject o : objects)
{
if (o == null)
{
throw new NullPointerException();
}
committables.add(o);
}
return committables;
}
}