/* * Copyright (c) 2009-2012, 2014, 2015 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: * Simon McDuff - 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.config.IModelConfig; import org.eclipse.emf.cdo.tests.model4.GenRefMultiNonContained; import org.eclipse.emf.cdo.tests.model4.GenRefSingleContained; import org.eclipse.emf.cdo.tests.model4.GenRefSingleNonContained; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.util.ObjectNotFoundException; import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; /** * Deadlock in CDOView * <p> * See bug 279982 * * @author Simon McDuff */ public class Bugzilla_279982_Test extends AbstractCDOTest { // As log as there is no getter interception, stale reference cannot be detected for legacy @Skips(IModelConfig.CAPABILITY_LEGACY) public void testBugzilla_279982_Single() throws Exception { CDOSession session = openSession(); CDOTransaction tx = session.openTransaction(); CDOResource res = tx.getOrCreateResource(getResourcePath("/resource1")); tx.options().setStaleReferencePolicy(CDOStaleReferencePolicy.PROXY); GenRefSingleContained container = getModel4Factory().createGenRefSingleContained(); GenRefSingleNonContained referencer = getModel4Factory().createGenRefSingleNonContained(); GenRefSingleNonContained contained = getModel4Factory().createGenRefSingleNonContained(); container.setElement(contained); referencer.setElement(contained); res.getContents().add(container); res.getContents().add(referencer); tx.commit(); container.setElement(null); tx.commit(); assertNull(container.getElement()); EObject element = referencer.getElement(); assertNotNull(element); assertEquals(true, CDOUtil.isStaleObject(element)); // As of 4.4 should not fail anymore. CDOStaleReferencePolicy.PROXY is more tolerant now. element.eContainer(); tx.options().setStaleReferencePolicy(CDOStaleReferencePolicy.EXCEPTION); try { referencer.getElement(); fail("Should fail"); } catch (ObjectNotFoundException ex) { // ignore } catch (Exception ex) { fail("Should have an ObjectNotFoundException"); } CDOUtil.cleanStaleReference(referencer, getModel4Package().getGenRefSingleNonContained_Element()); assertNull(referencer.getElement()); tx.commit(); clearCache(session.getRevisionManager()); // Verification that the commit is good tx = session.openTransaction(); res = tx.getOrCreateResource(getResourcePath("/resource1")); referencer = (GenRefSingleNonContained)res.getContents().get(1); assertNull(referencer.getElement()); } // As long as there is no getter interception, stale reference cannot be detected for legacy @Skips(IModelConfig.CAPABILITY_LEGACY) public void testBugzilla_279982_Multi() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource = transaction.getOrCreateResource(getResourcePath("/resource1")); transaction.options().setStaleReferencePolicy(CDOStaleReferencePolicy.PROXY); GenRefSingleContained container = getModel4Factory().createGenRefSingleContained(); GenRefMultiNonContained referencer = getModel4Factory().createGenRefMultiNonContained(); GenRefSingleNonContained contained = getModel4Factory().createGenRefSingleNonContained(); container.setElement(contained); referencer.getElements().add(contained); resource.getContents().add(container); resource.getContents().add(referencer); transaction.commit(); container.setElement(null); transaction.commit(); assertNull(container.getElement()); EObject proxy = referencer.getElements().get(0); assertNotNull(proxy); assertEquals(true, CDOUtil.isStaleObject(proxy)); transaction.options().setStaleReferencePolicy(CDOStaleReferencePolicy.EXCEPTION); try { referencer.getElements().get(0); fail("Should fail"); } catch (ObjectNotFoundException ex) { // Success } EReference genRefMultiNonContained_Elements = getModel4Package().getGenRefMultiNonContained_Elements(); CDOUtil.cleanStaleReference(referencer, genRefMultiNonContained_Elements, 0); assertEquals(0, referencer.getElements().size()); transaction.commit(); clearCache(session.getRevisionManager()); // Verification that the commit is good transaction = session.openTransaction(); resource = transaction.getOrCreateResource(getResourcePath("/resource1")); referencer = (GenRefMultiNonContained)resource.getContents().get(1); assertEquals(0, referencer.getElements().size()); } // As log as there is no getter interception, stale reference cannot be detected for legacy @Skips(IModelConfig.CAPABILITY_LEGACY) public void testBugzilla_279982_Multi_RevisionPrefetchingPolicy() throws Exception { CDOSession session = openSession(); { CDOTransaction tx = session.openTransaction(); CDOResource res = tx.getOrCreateResource(getResourcePath("/resource1")); // tx.options().setUnresolveableObjectToNullEnabled(true); GenRefSingleContained container = getModel4Factory().createGenRefSingleContained(); GenRefMultiNonContained referencer = getModel4Factory().createGenRefMultiNonContained(); GenRefSingleNonContained contained = getModel4Factory().createGenRefSingleNonContained(); GenRefSingleNonContained contained2 = getModel4Factory().createGenRefSingleNonContained(); container.setElement(contained); referencer.getElements().add(contained); referencer.getElements().add(contained2); res.getContents().add(container); res.getContents().add(referencer); res.getContents().add(contained2); tx.commit(); res.getContents().remove(contained2); tx.commit(); } clearCache(session.getRevisionManager()); CDOTransaction tx = session.openTransaction(); CDOResource res = tx.getOrCreateResource(getResourcePath("/resource1")); tx.options().setRevisionPrefetchingPolicy(CDOUtil.createRevisionPrefetchingPolicy(100)); tx.options().setStaleReferencePolicy(CDOStaleReferencePolicy.EXCEPTION); GenRefMultiNonContained reference = (GenRefMultiNonContained)res.getContents().get(1); assertNotNull(reference.getElements().get(0)); try { assertNotNull(reference.getElements().get(1)); fail("Should fail"); } catch (ObjectNotFoundException ex) { // ignore } catch (Exception ex) { fail("Should have an ObjectNotFoundException"); } CDOUtil.cleanStaleReference(reference, getModel4Package().getGenRefMultiNonContained_Elements(), 0); assertEquals(1, reference.getElements().size()); tx.commit(); clearCache(session.getRevisionManager()); // Verification that the commit is good tx = session.openTransaction(); res = tx.getOrCreateResource(getResourcePath("/resource1")); reference = (GenRefMultiNonContained)res.getContents().get(1); assertEquals(1, reference.getElements().size()); } }