| /******************************************************************************* |
| * Copyright (c) 2015, 2017 Obeo 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: |
| * Obeo - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.papyrus.compare.diagram.tests; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| |
| import org.eclipse.compare.ITypedElement; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.resources.mapping.ModelProvider; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.FileLocator; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.eclipse.egit.core.Activator; |
| import org.eclipse.egit.core.GitCorePreferences; |
| import org.eclipse.egit.core.op.MergeOperation; |
| import org.eclipse.emf.common.util.BasicMonitor; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.compare.Comparison; |
| import org.eclipse.emf.compare.EMFCompare; |
| import org.eclipse.emf.compare.EMFCompare.Builder; |
| import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin; |
| import org.eclipse.emf.compare.ide.ui.internal.logical.ComparisonScopeBuilder; |
| import org.eclipse.emf.compare.ide.ui.internal.logical.EMFModelProvider; |
| import org.eclipse.emf.compare.ide.ui.internal.logical.StorageTypedElement; |
| import org.eclipse.emf.compare.ide.ui.internal.logical.SubscriberStorageAccessor; |
| import org.eclipse.emf.compare.ide.ui.internal.logical.resolver.CrossReferenceResolutionScope; |
| import org.eclipse.emf.compare.ide.ui.internal.logical.resolver.ThreadedModelResolver; |
| import org.eclipse.emf.compare.ide.ui.internal.preferences.EMFCompareUIPreferences; |
| import org.eclipse.emf.compare.ide.ui.logical.IStorageProvider; |
| import org.eclipse.emf.compare.ide.ui.logical.IStorageProviderAccessor; |
| import org.eclipse.emf.compare.ide.ui.tests.CompareTestCase; |
| import org.eclipse.emf.compare.ide.ui.tests.workspace.TestProject; |
| import org.eclipse.emf.compare.internal.utils.Graph; |
| import org.eclipse.emf.compare.rcp.internal.extension.impl.EMFCompareBuilderConfigurator; |
| import org.eclipse.emf.compare.scope.IComparisonScope; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jgit.api.Git; |
| import org.eclipse.jgit.api.Status; |
| import org.eclipse.jgit.lib.Constants; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.util.FileUtils; |
| import org.eclipse.jgit.util.SystemReader; |
| import org.eclipse.papyrus.compare.diagram.tests.egit.fixture.GitTestRepository; |
| import org.eclipse.papyrus.compare.diagram.tests.egit.fixture.MockSystemReader; |
| import org.eclipse.team.core.subscribers.Subscriber; |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.osgi.framework.Bundle; |
| |
| @SuppressWarnings({"restriction", "nls" }) |
| public class AbstractGitTestCase extends CompareTestCase { |
| |
| /** |
| * The bundle containing this test. |
| */ |
| protected static final String TEST_BUNDLE = "org.eclipse.papyrus.compare.diagram.tests.git"; |
| |
| protected static final String MASTER = Constants.R_HEADS + Constants.MASTER; |
| |
| protected static final String BRANCH_1 = Constants.R_HEADS + "branch1"; |
| |
| protected static final String BRANCH_2 = Constants.R_HEADS + "branch2"; |
| |
| protected static final String BRANCH_3 = Constants.R_HEADS + "branch3"; |
| |
| protected GitTestRepository repository; |
| |
| // The ".git" folder of the test repository |
| protected File gitDir; |
| |
| protected static String deafultResolutionScope; |
| |
| @BeforeClass |
| public static void setUpClass() { |
| // suppress auto-ignoring and auto-sharing to avoid interference |
| IEclipsePreferences eGitPreferences = InstanceScope.INSTANCE.getNode(Activator.getPluginId()); |
| eGitPreferences.put(GitCorePreferences.core_preferredMergeStrategy, "model recursive"); |
| eGitPreferences.putBoolean(GitCorePreferences.core_autoShareProjects, false); |
| // This is actually the value of "GitCorePreferences.core_autoIgnoreDerivedResources"... but it was |
| // not in Egit 2.1 |
| eGitPreferences.putBoolean("core_autoIgnoreDerivedResources", false); |
| final IPreferenceStore store = EMFCompareIDEUIPlugin.getDefault().getPreferenceStore(); |
| deafultResolutionScope = store.getString(EMFCompareUIPreferences.RESOLUTION_SCOPE_PREFERENCE); |
| store.setValue(EMFCompareUIPreferences.RESOLUTION_SCOPE_PREFERENCE, |
| CrossReferenceResolutionScope.WORKSPACE.name()); |
| } |
| |
| @AfterClass |
| public static void tearDownClass() { |
| final IPreferenceStore store = EMFCompareIDEUIPlugin.getDefault().getPreferenceStore(); |
| store.setValue(EMFCompareUIPreferences.RESOLUTION_SCOPE_PREFERENCE, deafultResolutionScope); |
| } |
| |
| @Override |
| @Before |
| public void setUp() throws Exception { |
| // ensure there are no shared Repository instances left |
| // when starting a new test |
| Activator.getDefault().getRepositoryCache().clear(); |
| final MockSystemReader mockSystemReader = new MockSystemReader(); |
| SystemReader.setInstance(mockSystemReader); |
| final IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); |
| String gitRepoPath = workspaceRoot.getRawLocation().toFile() + File.separator + "repo"; |
| mockSystemReader.setProperty(Constants.GIT_CEILING_DIRECTORIES_KEY, |
| workspaceRoot.getLocation().toFile().getParentFile().getAbsoluteFile().toString()); |
| gitDir = new File(gitRepoPath, Constants.DOT_GIT); |
| repository = new GitTestRepository(gitDir); |
| repository.ignore(workspaceRoot.getRawLocation().append(".metadata").toFile()); |
| } |
| |
| @Override |
| @After |
| public void tearDown() throws Exception { |
| final EMFModelProvider emfModelProvider = (EMFModelProvider)ModelProvider |
| .getModelProviderDescriptor(EMFModelProvider.PROVIDER_ID).getModelProvider(); |
| emfModelProvider.clear(); |
| repository.dispose(); |
| Activator.getDefault().getRepositoryCache().clear(); |
| if (gitDir.exists()) { |
| File gitRoot = gitDir.getParentFile(); |
| if (gitRoot.exists()) { |
| FileUtils.delete(gitRoot, FileUtils.RECURSIVE | FileUtils.RETRY); |
| } |
| } |
| } |
| |
| /** |
| * Copies the file located in {@link #testDataPath} + {@code filePath} to the given |
| * {@code destinationPath} in {@code iProject}. |
| * |
| * @param iProject |
| * The {@link IProject} to which the file is added. |
| * @param filePath |
| * The path relative to {@link #testDataPath} where the file is originally located. |
| * @param destinationPath |
| * The path in the {@code iProject} to which the file will be copied. |
| * @return The newly created {@link IFile}. |
| */ |
| protected IFile addToProject(String testDataPath, TestProject project, IProject iProject, String filePath, |
| String destinationPath) throws IOException, URISyntaxException, CoreException { |
| final Bundle bundle = Platform.getBundle(TEST_BUNDLE); |
| final URI fileUri = getFileUri(bundle.getEntry(testDataPath + filePath)); |
| |
| final File file = project.getOrCreateFile(iProject, destinationPath + fileUri.lastSegment()); |
| |
| copyFile(toFile(fileUri), file); |
| |
| return project.getIFile(iProject, file); |
| } |
| |
| protected void removeFromProject(IProject iProject, String name) throws CoreException { |
| iProject.getFile(name).delete(true, null); |
| } |
| |
| protected URI getFileUri(final URL bundleUrl) throws IOException { |
| URL fileLocation = FileLocator.toFileURL(bundleUrl); |
| return URI.createFileURI(fileLocation.getPath()); |
| } |
| |
| protected File toFile(final URI fileUri) throws URISyntaxException { |
| return new File(fileUri.toFileString()); |
| } |
| |
| protected Comparison compare(String sourceRev, String targetRev, IFile file) throws Exception { |
| final String fullPath = file.getFullPath().toString(); |
| final Subscriber subscriber = repository.createSubscriberForComparison(sourceRev, targetRev, file, |
| false); |
| final IStorageProviderAccessor accessor = new SubscriberStorageAccessor(subscriber); |
| final IStorageProvider sourceProvider = accessor.getStorageProvider(file, |
| IStorageProviderAccessor.DiffSide.SOURCE); |
| final IStorageProvider remoteProvider = accessor.getStorageProvider(file, |
| IStorageProviderAccessor.DiffSide.REMOTE); |
| final IStorageProvider ancestorProvider = accessor.getStorageProvider(file, |
| IStorageProviderAccessor.DiffSide.ORIGIN); |
| assertNotNull(sourceProvider); |
| assertNotNull(remoteProvider); |
| assertNotNull(ancestorProvider); |
| |
| final IProgressMonitor monitor = new NullProgressMonitor(); |
| // do we really need to create a new one? |
| final IStorageProviderAccessor storageAccessor = new SubscriberStorageAccessor(subscriber); |
| final ITypedElement left = new StorageTypedElement(file, fullPath); |
| final ITypedElement right = new StorageTypedElement(remoteProvider.getStorage(monitor), fullPath); |
| final ITypedElement origin = new StorageTypedElement(ancestorProvider.getStorage(monitor), fullPath); |
| final ThreadedModelResolver resolver = new ThreadedModelResolver(); |
| resolver.setGraph(new Graph<URI>()); |
| resolver.initialize(); |
| final ComparisonScopeBuilder scopeBuilder = new ComparisonScopeBuilder(resolver, |
| EMFCompareIDEUIPlugin.getDefault().getModelMinimizerRegistry().getCompoundMinimizer(), |
| storageAccessor); |
| final IComparisonScope scope = scopeBuilder.build(left, right, origin, monitor); |
| |
| final ResourceSet leftResourceSet = (ResourceSet)scope.getLeft(); |
| final ResourceSet rightResourceSet = (ResourceSet)scope.getRight(); |
| final ResourceSet originResourceSet = (ResourceSet)scope.getOrigin(); |
| |
| assertFalse(leftResourceSet.getResources().isEmpty()); |
| assertFalse(rightResourceSet.getResources().isEmpty()); |
| assertFalse(originResourceSet.getResources().isEmpty()); |
| |
| final Builder comparisonBuilder = EMFCompare.builder(); |
| EMFCompareBuilderConfigurator.createDefault().configure(comparisonBuilder); |
| |
| return comparisonBuilder.build().compare(scope, new BasicMonitor()); |
| } |
| |
| protected void merge(Repository repo, String refName) throws CoreException { |
| new MergeOperation(repo, refName).execute(null); |
| } |
| |
| protected void merge(Repository repo, String refName, String strategyName) throws CoreException { |
| new MergeOperation(repo, refName, strategyName).execute(null); |
| } |
| |
| protected Status status(Repository repo) throws Exception { |
| Git git = new Git(repo); |
| try { |
| return git.status().call(); |
| } finally { |
| git.close(); |
| } |
| } |
| } |