diff options
author | Martin Fleck | 2017-03-14 11:53:36 +0000 |
---|---|---|
committer | Laurent Goubet | 2017-06-26 08:50:24 +0000 |
commit | 1bbda312bb6f122b5e02e39ab0a4dcdd2c05733b (patch) | |
tree | 4f372485eb5ce5776ae1fb98ed48a5080d4df94f /plugins | |
parent | 7a23275b0791418731f7b6ab291bac3946239732 (diff) | |
download | org.eclipse.emf.compare-1bbda312bb6f122b5e02e39ab0a4dcdd2c05733b.tar.gz org.eclipse.emf.compare-1bbda312bb6f122b5e02e39ab0a4dcdd2c05733b.tar.xz org.eclipse.emf.compare-1bbda312bb6f122b5e02e39ab0a4dcdd2c05733b.zip |
[514382] Pre-Merge on conflict can lead to data loss
Ensure that pre-merge merges only diffs from the right side and leaves
the diffs from the left side untouched.
Contains tests.
Bug: 514382
Change-Id: Ie24a595dca3da78d2eda7ea32510d3630b8def9a
Also-by: Simon Delisle <simon.delisle@ericsson.com>
Signed-off-by: Martin Fleck <mfleck@eclipsesource.com>
Diffstat (limited to 'plugins')
4 files changed, 175 insertions, 8 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/merge/EMFResourceMappingMergerPreMergeTest.java b/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/merge/EMFResourceMappingMergerPreMergeTest.java new file mode 100644 index 000000000..8e4839ea2 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/merge/EMFResourceMappingMergerPreMergeTest.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2017 EclipseSource Services 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: + * Martin Fleck - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.ide.ui.tests.merge; + +import static org.eclipse.emf.compare.ide.ui.internal.preferences.EMFCompareUIPreferences.PRE_MERGE_MODELS_WHEN_CONFLICT; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin; +import org.eclipse.emf.compare.ide.ui.internal.logical.EMFResourceMappingMerger; +import org.eclipse.emf.compare.ide.ui.tests.git.framework.GitTestRunner; +import org.eclipse.emf.compare.ide.ui.tests.git.framework.annotations.GitInput; +import org.eclipse.emf.compare.ide.ui.tests.git.framework.annotations.GitMerge; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jgit.api.Status; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +/** + * Test cases covering the pre-merge scenario of the {@link EMFResourceMappingMerger}. + * + * @author Martin Fleck <mfleck@eclipsesource.com> + */ +@SuppressWarnings({"restriction", "nls" }) +@RunWith(GitTestRunner.class) +public class EMFResourceMappingMergerPreMergeTest { + + /** Preference store for the pre-merge setting. */ + protected static final IPreferenceStore EMF_COMPARE_PREFS = EMFCompareIDEUIPlugin.getDefault() + .getPreferenceStore(); + + /** Cached pre-merge setting in the preference store. */ + protected static boolean PRE_MERGE_CONFLICT_SETTING; + + @BeforeClass + public static void setupClass() { + // turn pre-merge on + PRE_MERGE_CONFLICT_SETTING = EMF_COMPARE_PREFS.getBoolean(PRE_MERGE_MODELS_WHEN_CONFLICT); + EMF_COMPARE_PREFS.setValue(PRE_MERGE_MODELS_WHEN_CONFLICT, true); + } + + @AfterClass + public static void tearDownClass() { + // restore pre-merge setting + EMFCompareIDEUIPlugin.getDefault().getPreferenceStore().setValue(PRE_MERGE_MODELS_WHEN_CONFLICT, + PRE_MERGE_CONFLICT_SETTING); + } + + /** + * Tests that we have the expected files exist when performing a pre-merge with a real conflict. The test + * model looks as follows: + * <ul> + * <li>master: One class diagram (model) with a single class 'ClassA'</li> + * <li>renameClassA: Rename of existing class to 'ClassB'</li> + * <li>renameClassA_addOtherModel: Rename of existing class to 'ClassC' (REAL conflict) and addition of + * other model (otherModel) which imports ClassC into the diagram (-> part of logical model)</li> + * </ul> + * The expected result is: + * <ul> + * <li>Projects: Only the single project containing the models is involved</li> + * <li>Conflicts: model.uml has a rename conflict of 'ClassA' to 'ClassB' or 'ClassC'</li> + * <li>PreMerge: otherModel can be merged as there is no conflict</li> + * </ul> + * + * @param status + * git status + * @param projects + * list of involved projects + */ + @GitInput("data/premerge/bug_preMergeWithConflict.zip") + @GitMerge(local = "renameClassA", remote = "renameClassA_addOtherModel") + public void testPreMergeWithConflictL2R(Status status, List<IProject> projects) { + IProject project = assertSingleProject(projects); + assertFilesExist(project, "model.uml", "model.notation", "model.di", "otherModel.uml", + "otherModel.notation", "otherModel.di"); + assertFilesConflict(status, "PreMergeWithConflict/model.uml"); + } + + /** + * Tests that we have the expected files exist when performing a pre-merge with a real conflict. The test + * model looks as follows: + * <ul> + * <li>master: One class diagram (model) with a single class 'ClassA'</li> + * <li>renameClassA: Rename of existing class to 'ClassB'</li> + * <li>renameClassA_addOtherModel: Rename of existing class to 'ClassC' (REAL conflict) and addition of + * other model (otherModel) which imports ClassC into the diagram (-> part of logical model)</li> + * </ul> + * The expected result is: + * <ul> + * <li>Projects: Only the single project containing the models is involved</li> + * <li>Conflicts: model.uml has a rename conflict of 'ClassA' to 'ClassB' or 'ClassC'</li> + * <li>PreMerge: otherModel can be merged as there is no conflict</li> + * </ul> + * + * @param status + * git status + * @param projects + * list of involved projects + */ + @GitInput("data/premerge/bug_preMergeWithConflict.zip") + @GitMerge(local = "renameClassA_addOtherModel", remote = "renameClassA") + public void testPreMergeWithConflictR2L(Status status, List<IProject> projects) { + IProject project = assertSingleProject(projects); + assertFilesExist(project, "model.uml", "model.notation", "model.di", "otherModel.uml", + "otherModel.notation", "otherModel.di"); + assertFilesConflict(status, "PreMergeWithConflict/model.uml"); + } + + /** + * Asserts that there is a single project and returns it. + * + * @param projects + * projects + * @return single project + */ + protected IProject assertSingleProject(List<IProject> projects) { + assertEquals(1, projects.size()); + return projects.get(0); + } + + /** + * Asserts that all given files exist in the given project. + * + * @param project + * project + * @param files + * files that need to exist in the project + */ + protected void assertFilesExist(IProject project, String... files) { + for (String file : files) { + assertTrue(file + " does not exist.", project.getFile(file).exists()); + } + } + + /** + * Asserts that the all and only the given files are conflicting. + * + * @param status + * git status + * @param files + * files that should be conflicting + */ + protected void assertFilesConflict(Status status, String... files) { + Set<String> conflicting = status.getConflicting(); + assertEquals(files.length, conflicting.size()); + for (String file : files) { + assertTrue(file + " is not conflicting.", conflicting.contains(file)); + } + } +} diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/merge/data/premerge/bug_preMergeWithConflict.zip b/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/merge/data/premerge/bug_preMergeWithConflict.zip Binary files differnew file mode 100644 index 000000000..aa42f9860 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/merge/data/premerge/bug_preMergeWithConflict.zip diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/suite/GitTests.java b/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/suite/GitTests.java index f4650ca2b..f3bc3d64e 100644 --- a/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/suite/GitTests.java +++ b/plugins/org.eclipse.emf.compare.ide.ui.tests.git/src/org/eclipse/emf/compare/ide/ui/tests/suite/GitTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2015 Obeo. + * Copyright (c) 2012, 2017 Obeo. * 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 @@ -8,16 +8,14 @@ * Contributors: * Obeo - initial API and implementation * Philip Langer - adds further test cases + * Martin Fleck - add EMFResourceMappingMergerPreMergeTest *******************************************************************************/ package org.eclipse.emf.compare.ide.ui.tests.suite; -import junit.framework.JUnit4TestAdapter; -import junit.framework.Test; -import junit.textui.TestRunner; - import org.eclipse.emf.compare.ComparePackage; import org.eclipse.emf.compare.ide.ui.tests.merge.AdditiveMergeTests; import org.eclipse.emf.compare.ide.ui.tests.merge.DirCacheResourceVariantTreeProviderTest; +import org.eclipse.emf.compare.ide.ui.tests.merge.EMFResourceMappingMergerPreMergeTest; import org.eclipse.emf.compare.ide.ui.tests.merge.GitResourceVariantTreeSubscriberTest; import org.eclipse.emf.compare.ide.ui.tests.merge.ResourceVariantTest; import org.eclipse.emf.compare.ide.ui.tests.merge.TreeWalkResourceVariantTreeProviderTest; @@ -40,6 +38,10 @@ import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; +import junit.framework.JUnit4TestAdapter; +import junit.framework.Test; +import junit.textui.TestRunner; + @RunWith(Suite.class) @SuiteClasses({AdditiveMergeTests.class, DirCacheResourceVariantTreeProviderTest.class, // GitLogicalMergeTest.class, @@ -58,7 +60,8 @@ import org.junit.runners.Suite.SuiteClasses; ResourceVariantTest.class, ResourceUtilPathTest.class, RevisionedURIConverterTest.class, // StrategyRecursiveModelTest.class, // StrategyRecursiveModelWithDeepProjectTest.class, - ThreadedModelResolverResolutionTest.class, TreeWalkResourceVariantTreeProviderTest.class, }) + ThreadedModelResolverResolutionTest.class, TreeWalkResourceVariantTreeProviderTest.class, + EMFResourceMappingMergerPreMergeTest.class }) public class GitTests { /** * Launches the test with the given arguments. diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java index 03f3ecd24..788272b53 100644 --- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java +++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java @@ -10,11 +10,12 @@ * Philip Langer - bugs 461713, 465331, 470268, 476363, 476417, 486940, refactorings * Alexandra Buzila - bugs 470332, 478620 * Stefan Dirix - bug 507050 - * Martin Fleck - bug 512562 + * Martin Fleck - bug 512562, 514382 *******************************************************************************/ package org.eclipse.emf.compare.ide.ui.internal.logical; import static com.google.common.base.Predicates.alwaysFalse; +import static com.google.common.collect.Iterables.filter; import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide; import com.google.common.collect.ImmutableMap; @@ -325,7 +326,7 @@ public class EMFResourceMappingMerger implements IResourceMappingMerger { private Set<URI> performPreMerge(Comparison comparison, SubMonitor subMonitor) { final Monitor emfMonitor = BasicMonitor.toMonitor(subMonitor); final Set<URI> conflictingURIs = new LinkedHashSet<URI>(); - for (Diff next : comparison.getDifferences()) { + for (Diff next : filter(comparison.getDifferences(), fromSide(DifferenceSource.RIGHT))) { doMergeForDiff(emfMonitor, conflictingURIs, next); } return conflictingURIs; |