Skip to content

Commit

Permalink
Combine BaseImportTestCase subclasses into a parameterized test
Browse files Browse the repository at this point in the history
and make it work in verification tests and fix source-attachment
assertion.

Add Plug-ins to import from the runtime as dependencies of the
Test-Plugin in order to ensure they are available in the test-runtime.
  • Loading branch information
HannesWell committed Sep 17, 2023
1 parent fb20b26 commit faa7acd
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 304 deletions.
12 changes: 11 additions & 1 deletion ui/org.eclipse.pde.ui.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,17 @@ Require-Bundle: org.eclipse.pde.ui,
org.eclipse.equinox.simpleconfigurator.manipulator;bundle-version="2.1.300",
org.eclipse.platform,
org.eclipse.ui.ide.application,
org.eclipse.pde.api.tools
org.eclipse.pde.api.tools,
org.eclipse.jsch.core,
org.eclipse.jdt.doc.user,
org.junit.source;resolution:=optional,
org.eclipse.pde.ui.source;resolution:=optional,
org.apache.ant.source;resolution:=optional,
org.eclipse.jdt.debug.source;resolution:=optional,
org.eclipse.jsch.core.source;resolution:=optional,
org.eclipse.core.filebuffers.source;resolution:=optional,
org.eclipse.jdt.doc.user;resolution:=optional,
org.eclipse.pde.build.source;resolution:=optional
Import-Package: javax.annotation;version="[1.3.0,2.0.0)",
javax.inject;version="[1.0.0,2.0.0)",
org.assertj.core.api;version="3.14.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation and others.
* Copyright (c) 2005, 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -17,9 +17,9 @@
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;


@RunWith(Suite.class)
@SuiteClasses({ ImportWithLinksTestCase.class, ImportAsBinaryTestCase.class, ImportAsSourceTestCase.class,
@SuiteClasses({ //
BaseImportTestCase.class, //

// Temporarily disabled until git migration is complete and we have access to a
// stable cvs repo (bug 355873)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2015 IBM Corporation and others.
* Copyright (c) 2006, 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -10,74 +10,122 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
* Hannes Wellmann - Combine BaseImportTestCase subclasses into a parameterized test and make it succeed in verifiation builds
*******************************************************************************/
package org.eclipse.pde.ui.tests.imports;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.ModelEntry;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.pde.internal.core.BinaryRepositoryProvider;
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.natures.PDE;
import org.eclipse.pde.internal.ui.wizards.imports.PluginImportOperation;
import org.eclipse.pde.ui.tests.PDETestCase;
import org.eclipse.team.core.RepositoryProvider;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.Version;

public abstract class BaseImportTestCase extends PDETestCase {
@RunWith(Parameterized.class)
public class BaseImportTestCase extends PDETestCase {

@Parameters(name = "{0}")
public static Object[][] importTypes() {
return new Object[][] { //
{ "Import binary", PluginImportOperation.IMPORT_BINARY }, //
{ "Import with source", PluginImportOperation.IMPORT_WITH_SOURCE }, //
{ "Import with links", PluginImportOperation.IMPORT_BINARY_WITH_LINKS }, //
};
}

protected abstract int getType();
protected abstract void verifyProject(String projectName, boolean isJava);
@Parameter(0)
public String importTypeName;
@Parameter(1)
public int importType;

@Test
public void testImportJAR() {
public void testImportJAR() throws Exception {
doSingleImport("org.eclipse.jsch.core", true);
}

@Test
public void testImportFlat() {
public void testImportFlat() throws Exception {
doSingleImport("org.eclipse.jdt.debug", true);
}

@Test
public void testImportNotJavaFlat() {
public void testImportNotJavaFlat() throws Exception {
doSingleImport("org.junit.source", false);
}

@Test
public void testImportNotJavaJARd() {
public void testImportNotJavaJARd() throws Exception {
doSingleImport("org.eclipse.jdt.doc.user", false);
doSingleImport("org.eclipse.pde.ui.source", false);
}

@Test
public void testImportJUnit4() {
public void testImportAnt() throws Exception {
Assume.assumeFalse(importType == PluginImportOperation.IMPORT_WITH_SOURCE);
// Note: Ant is exempt from importing as source
doSingleImport("org.apache.ant", true);
}

@Test
public void testImportJUnit4() throws Exception {
doSingleImport("org.junit", 4, true);
}

@Test
public void testImportLinksMultiple() {
IPluginModelBase[] modelsToImport = getModels(new String[] {"org.eclipse.core.filebuffers", "org.eclipse.jdt.doc.user", "org.eclipse.pde.build"});
runOperation(modelsToImport, getType());
for (int i = 0; i < modelsToImport.length; i++) {
verifyProject(modelsToImport[i], i != 1);
public void testImportLinksMultiple() throws Exception {
List<IPluginModelBase> modelsToImport = Stream
.of("org.eclipse.core.filebuffers", "org.eclipse.jdt.doc.user", "org.eclipse.pde.build").map(name -> {
IPluginModelBase model = PluginRegistry.findModel(name);
assertNotNull("No model found with name'" + name + "'", model);
assertNull("Workspace resource already exists for: " + name, model.getUnderlyingResource());
return model;
}).toList();
runOperation(modelsToImport, importType);
for (int i = 0; i < modelsToImport.size(); i++) {
verifyProject(modelsToImport.get(i), i != 1);
}
}

protected void doSingleImport(String bundleSymbolicName, boolean isJava) {
protected void doSingleImport(String bundleSymbolicName, boolean isJava) throws Exception {
IPluginModelBase modelToImport = PluginRegistry.findModel(bundleSymbolicName);
assertNotNull("No model found with name'" + name + "'", modelToImport);
assertNull(modelToImport.getUnderlyingResource());
runOperation(new IPluginModelBase[] {modelToImport}, getType());
runOperation(List.of(modelToImport), importType);
verifyProject(modelToImport, isJava);
}

Expand All @@ -90,73 +138,78 @@ protected void doSingleImport(String bundleSymbolicName, boolean isJava) {
* @param majorVersion the major version that the imported plug-in must have
* @param isJava whether the imported plug-in should have a java nature
*/
protected void doSingleImport(String bundleSymbolicName, int majorVersion, boolean isJava) {
protected void doSingleImport(String bundleSymbolicName, int majorVersion, boolean isJava) throws Exception {
ModelEntry entry = PluginRegistry.findEntry(bundleSymbolicName);
IPluginModelBase models[] = entry.getExternalModels();
assertTrue("No models for " + bundleSymbolicName + " could be found", models.length > 0);
IPluginModelBase modelToImport = null;

for (IPluginModelBase model : models) {
Version version = new Version(model.getPluginBase().getVersion());
if (version.getMajor() == majorVersion){
modelToImport = model;
break;
}
}

assertNull("Model with correct major version " + majorVersion + " could not be found", modelToImport.getUnderlyingResource());
runOperation(new IPluginModelBase[] {modelToImport}, getType());
assertTrue("No external models for with name '" + bundleSymbolicName + "'", models.length > 0);
IPluginModelBase modelToImport = Arrays.stream(models)
.filter(m -> new Version(m.getPluginBase().getVersion()).getMajor() == majorVersion).findFirst()
.orElse(null);

assertNull("Model for " + bundleSymbolicName + " with major version " + majorVersion + " not be found",
modelToImport.getUnderlyingResource());
runOperation(List.of(modelToImport), importType);
verifyProject(modelToImport, isJava);
}

protected void runOperation(IPluginModelBase[] models, int type) {
PluginImportOperation job = new PluginImportOperation(models, type, false);
protected void runOperation(List<IPluginModelBase> models, int type) throws InterruptedException {
PluginImportOperation job = new PluginImportOperation(models.toArray(IPluginModelBase[]::new), type, false);
job.setRule(ResourcesPlugin.getWorkspace().getRoot());
job.setSystem(true);
job.schedule();
try{
job.join();
} catch (InterruptedException e){
fail("Job interupted: " + e.getMessage());
}
job.join();
IStatus status = job.getResult();
if (!status.isOK()){
fail("Import Operation failed: " + status.toString());
}
assertTrue("Import Operation failed: " + status.toString(), status.isOK());
}

protected IPluginModelBase[] getModels(String[] symbolicNames) {
IPluginModelBase[] models = new IPluginModelBase[symbolicNames.length];
for (int i = 0; i < symbolicNames.length; i++) {
IPluginModelBase model = PluginRegistry.findModel(symbolicNames[i]);
assertNull(model.getUnderlyingResource());
models[i] = model;
}
return models;
}

protected void verifyProject(IPluginModelBase modelImported, boolean isJava) {
private void verifyProject(IPluginModelBase modelImported, boolean isJava) throws CoreException {
String id = modelImported.getPluginBase().getId();
verifyProject(id, isJava);
}

protected IProject verifyProject(String projectName) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject(projectName);
assertTrue("Project " + projectName + " does not exist", project.exists());
return project;
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(id);
assertTrue("Project " + id + " does not exist", project.exists());

// When self hosting the tests, import tests may fail if you have the
// imported project in the host
boolean isFromSelfHostedTestRuntime = Platform.inDevelopmentMode()
&& Path.of(modelImported.getInstallLocation()).getParent().getParent()
.equals(FileLocator.getBundleFileLocation(FrameworkUtil.getBundle(BaseImportTestCase.class))
.get().toPath().getParent().getParent());

if (!isFromSelfHostedTestRuntime) {
if (importType == PluginImportOperation.IMPORT_BINARY_WITH_LINKS) {
assertThat(RepositoryProvider.getProvider(project), is(instanceOf(BinaryRepositoryProvider.class)));
} else if (importType == PluginImportOperation.IMPORT_BINARY) {
assertEquals(PDECore.BINARY_PROJECT_VALUE,
project.getPersistentProperty(PDECore.EXTERNAL_PROJECT_PROPERTY));
}
}
assertTrue(project.hasNature(PDE.PLUGIN_NATURE));
assertEquals(isJava, project.hasNature(JavaCore.NATURE_ID));
if (isJava) {
IJavaProject jProject = JavaCore.create(project);
assertSourceAttached(jProject);
if (importType == PluginImportOperation.IMPORT_WITH_SOURCE) {
assertAnyClasspathEntryOfKind(jProject, IClasspathEntry.CPE_SOURCE);
} else {
if (!isFromSelfHostedTestRuntime) {
assertAnyClasspathEntryOfKind(jProject, IClasspathEntry.CPE_LIBRARY);
}
}
}
}

protected boolean checkSourceAttached(IJavaProject jProject) throws CoreException {
IPackageFragmentRoot[] roots = jProject.getPackageFragmentRoots();
for (IPackageFragmentRoot root : roots) {
private void assertSourceAttached(IJavaProject jProject) throws CoreException {
for (IPackageFragmentRoot root : jProject.getPackageFragmentRoots()) {
IClasspathEntry entry = root.getRawClasspathEntry();
if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() != IClasspathEntry.CPE_CONTAINER || !entry.getPath().equals(PDECore.REQUIRED_PLUGINS_CONTAINER_PATH))
continue;
if (root.getSourceAttachmentPath() == null)
return false;
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY
|| (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER)
&& !entry.getPath().equals(PDECore.REQUIRED_PLUGINS_CONTAINER_PATH)) {
assertNotNull("Missing source attachement for entry " + entry, root.getSourceAttachmentPath());
}
}
return true;
}

private static void assertAnyClasspathEntryOfKind(IJavaProject project, int entryKind) throws JavaModelException {
assertTrue(Arrays.stream(project.getRawClasspath()).anyMatch(e -> e.getEntryKind() == entryKind));
}

}
Loading

0 comments on commit faa7acd

Please sign in to comment.