From 9bd8b7f6aa55394955b168e8db3546a13193619a Mon Sep 17 00:00:00 2001 From: Philip Langer Date: Tue, 29 Jul 2014 20:15:46 +0200 Subject: [440679] Avoids NPE when performing a move We now make sure that the correct feature (i.e., the target feature of the target container) is used when obtaining the target value list (current list of values in the target container's feature) for finding the insertion index. Signed-off-by: Philip Langer Bug: 440679 Change-Id: I02798dc702c3a17c49ae63d80cf6a099858b7d89--- .../tests/merge/TwoWayBatchMergingTest.java | 101 +++++++++++++++++++++ .../tests/merge/data/TwoWayMergeInputData.java | 35 +++++++ .../movedifferentcontainmentfeature/ltr/left.nodes | 15 +++ .../ltr/right.nodes | 15 +++ .../movedifferentcontainmentfeature/rtl/left.nodes | 17 ++++ .../rtl/right.nodes | 11 +++ .../eclipse/emf/compare/tests/suite/AllTests.java | 3 +- 7 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java create mode 100644 plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java create mode 100644 plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/left.nodes create mode 100644 plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/right.nodes create mode 100644 plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/left.nodes create mode 100644 plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/right.nodes (limited to 'plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare') diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java new file mode 100644 index 000000000..5a1279b54 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) EclipseSource Muenchen GmbH 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: + * Philip Langer - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.tests.merge; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.eclipse.emf.common.util.BasicMonitor; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.EMFCompare; +import org.eclipse.emf.compare.internal.utils.DiffUtil; +import org.eclipse.emf.compare.merge.BatchMerger; +import org.eclipse.emf.compare.merge.IBatchMerger; +import org.eclipse.emf.compare.merge.IMerger; +import org.eclipse.emf.compare.scope.DefaultComparisonScope; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.emf.compare.tests.merge.data.TwoWayMergeInputData; +import org.eclipse.emf.compare.tests.nodes.Node; +import org.eclipse.emf.compare.tests.nodes.NodeMultipleContainment; +import org.eclipse.emf.compare.tests.nodes.NodesPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.junit.Test; + +/** + * Tests two-way comparison of {@link NodesPackage nodes models} with XMI IDs and subsequent merging using the + * {@link BatchMerger}. + * + * @author Philip Langer + */ +public class TwoWayBatchMergingTest { + + private TwoWayMergeInputData input = new TwoWayMergeInputData(); + + private IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance(); + + /** + * Tests a scenario in which an element is moved from one container to another, whereas the containment + * reference in the original container (left) is not available in the target container (right). This lead + * to a NPE in {@link DiffUtil#findInsertionIndex(Comparison, org.eclipse.emf.compare.Diff, boolean)} (cf. + * Bug #440679). In particular, we have two differences: (1) Deletion of {@link NodeMultipleContainment} + * "A" and (2) Move of {@link Node} "B" from {@link NodeMultipleContainment} "A" (reference + * "containmentRef2") to {@link Node} "Root" into reference "containmentRef1". As a result, we move node + * "B" originally contained through "containmentRef2" into a {@link Node}, which does not have the feature + * "containmentRef2". + * + * @throws IOException + * if {@link TwoWayMergeInputData} fails to load the test models. + */ + @Test + public void mergingMoveToDifferentContainmentFeatureR2L() throws IOException { + final Resource left = input.getMoveToDifferentContainmentFeatureRTLLeft(); + final Resource right = input.getMoveToDifferentContainmentFeatureRTLRight(); + + // perform comparison + final IComparisonScope scope = new DefaultComparisonScope(left, right, null); + Comparison comparison = EMFCompare.builder().build().compare(scope); + + // batch merging of all detected differences: + final IBatchMerger merger = new BatchMerger(mergerRegistry); + merger.copyAllRightToLeft(comparison.getDifferences(), new BasicMonitor()); + + // check that models are equal after batch merging + Comparison assertionComparison = EMFCompare.builder().build().compare(scope); + assertEquals(0, assertionComparison.getDifferences().size()); + } + + /** + * This test is the reverse of the test ({@link #mergingMoveToDifferentContainmentFeatureR2L() above} to + * make sure, this issue is not appearing in the other direction as well. + * + * @throws IOException + * if {@link TwoWayMergeInputData} fails to load the test models. + */ + @Test + public void mergingMoveToDifferentContainmentFeatureL2R() throws IOException { + final Resource left = input.getMoveToDifferentContainmentFeatureL2RLeft(); + final Resource right = input.getMoveToDifferentContainmentFeatureL2RRight(); + + // perform comparison + final IComparisonScope scope = new DefaultComparisonScope(left, right, null); + Comparison comparison = EMFCompare.builder().build().compare(scope); + + // batch merging of all detected differences: + final IBatchMerger merger = new BatchMerger(mergerRegistry); + merger.copyAllLeftToRight(comparison.getDifferences(), new BasicMonitor()); + + // check that models are equal after batch merging + Comparison assertionComparison = EMFCompare.builder().build().compare(scope); + assertEquals(0, assertionComparison.getDifferences().size()); + } + +} diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java new file mode 100644 index 000000000..b56de0640 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) EclipseSource Muenchen GmbH 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: + * Philip Langer - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.tests.merge.data; + +import java.io.IOException; + +import org.eclipse.emf.compare.tests.framework.AbstractInputData; +import org.eclipse.emf.ecore.resource.Resource; + +@SuppressWarnings("nls") +public class TwoWayMergeInputData extends AbstractInputData { + public Resource getMoveToDifferentContainmentFeatureRTLLeft() throws IOException { + return loadFromClassLoader("twoway/movedifferentcontainmentfeature/rtl/left.nodes"); + } + + public Resource getMoveToDifferentContainmentFeatureRTLRight() throws IOException { + return loadFromClassLoader("twoway/movedifferentcontainmentfeature/rtl/right.nodes"); + } + + public Resource getMoveToDifferentContainmentFeatureL2RLeft() throws IOException { + return loadFromClassLoader("twoway/movedifferentcontainmentfeature/ltr/left.nodes"); + } + + public Resource getMoveToDifferentContainmentFeatureL2RRight() throws IOException { + return loadFromClassLoader("twoway/movedifferentcontainmentfeature/ltr/right.nodes"); + } +} diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/left.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/left.nodes new file mode 100644 index 000000000..4acfc2460 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/left.nodes @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/right.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/right.nodes new file mode 100644 index 000000000..533e34d50 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/ltr/right.nodes @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/left.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/left.nodes new file mode 100644 index 000000000..5f91348a2 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/left.nodes @@ -0,0 +1,17 @@ + + + + + + diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/right.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/right.nodes new file mode 100644 index 000000000..3e949b46c --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/movedifferentcontainmentfeature/rtl/right.nodes @@ -0,0 +1,11 @@ + + + + diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java index ca965c0ea..c3f00530f 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java @@ -40,6 +40,7 @@ import org.eclipse.emf.compare.tests.merge.IndividualMergeOutOfScopeValuesTest; import org.eclipse.emf.compare.tests.merge.IndividualMergeTest; import org.eclipse.emf.compare.tests.merge.MultipleMergeTest; import org.eclipse.emf.compare.tests.merge.PseudoConflictMergeTest; +import org.eclipse.emf.compare.tests.merge.TwoWayBatchMergingTest; import org.eclipse.emf.compare.tests.nodes.NodesPackage; import org.eclipse.emf.compare.tests.nodes.util.NodesResourceFactoryImpl; import org.eclipse.emf.compare.tests.postprocess.PostProcessorTest; @@ -68,7 +69,7 @@ import org.junit.runners.Suite.SuiteClasses; AllEditTests.class, CommandStackTestSuite.class, MatchEngineFactoryRegistryTest.class, ConflictMergeTest.class, PseudoConflictMergeTest.class, ProximityIndexTest.class, AllRCPTests.class, FeatureMaps2wayMergeTest.class, FeatureMaps3wayMergeTest.class, FeatureMapsConflictsMergeTest.class, - FeatureMapsPseudoConflictsMergeTest.class }) + FeatureMapsPseudoConflictsMergeTest.class, TwoWayBatchMergingTest.class }) public class AllTests { /** * Standalone launcher for all of compare's tests. -- cgit v1.2.3