blob: 2024af1d7a1b9e79ed05906503f092d7eb2d6e78 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2017 IBM Corporation and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which accompanies this distribution,
* and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors: IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.build.tests;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;
import junit.framework.TestCase;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.helper.AntXMLContext;
import org.apache.tools.ant.helper.ProjectHelper2;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.eclipse.ant.core.AntRunner;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
import org.eclipse.osgi.signedcontent.*;
import org.eclipse.pde.build.internal.tests.ant.AntUtils;
import org.eclipse.pde.internal.build.AbstractScriptGenerator;
import org.eclipse.pde.internal.build.Utils;
import org.eclipse.pde.internal.build.builder.BuildDirector;
import org.eclipse.pde.internal.build.site.BuildTimeSiteFactory;
import org.eclipse.pde.internal.build.site.QualifierReplacer;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public abstract class PDETestCase extends TestCase {
public static final String PROJECT_NAME = "pde.build";
public static final String EQUINOX_COMMON = "org.eclipse.equinox.common";
public static final String SIMPLE_CONFIGURATOR = "org.eclipse.equinox.simpleconfigurator";
public static final String EQUINOX_EXECUTABLE = "org.eclipse.equinox.executable";
public static final String EQUINOX_LAUNCHER = "org.eclipse.equinox.launcher";
public static final String EQUINOX_APP = "org.eclipse.equinox.app";
public static final String EQUINOX_REGISTRY = "org.eclipse.equinox.registry";
public static final String EQUINOX_PREFERENCES = "org.eclipse.equinox.preferences";
public static final String CORE_JOBS = "org.eclipse.core.jobs";
public static final String CORE_RUNTIME = "org.eclipse.core.runtime";
public static final String OSGI = "org.eclipse.osgi";
private IFolder buildFolder = null;
protected void clearStatics() throws Exception {
AbstractScriptGenerator.getConfigInfos().clear();
BuildTimeSiteFactory.setInstalledBaseSite(null);
AbstractScriptGenerator.setForceUpdateJar(false);
QualifierReplacer.setGlobalQualifier(null);
BuildDirector.p2Gathering = false;
}
@Override
protected void runTest() throws Throwable {
super.runTest();
// clean up after success
if (buildFolder != null && buildFolder.exists() && !Boolean.getBoolean("pde.build.noCleanup")) {
try {
buildFolder.delete(true, null);
} catch (CoreException e) {
}
}
}
protected IProject newTest() throws Exception {
IProject builderProject = ResourcesPlugin.getWorkspace().getRoot().getProject(PROJECT_NAME);
if (!builderProject.exists()) {
builderProject.create(null);
}
if (!builderProject.isOpen())
builderProject.open(null);
return builderProject;
}
protected IFolder newTest(String folderName, String resources) throws Exception {
clearStatics();
IProject builderProject = newTest();
// create build folder for this test
buildFolder = builderProject.getFolder(folderName);
if (buildFolder.exists()) {
try {
buildFolder.delete(true, null);
buildFolder.create(true, true, null);
} catch (CoreException e) {
}
} else {
buildFolder.create(true, true, null);
}
URL resource = FileLocator.find(Platform.getBundle(Activator.PLUGIN_ID), new Path("/resources/" + resources),
null);
if (resource != null) {
String path = FileLocator.toFileURL(resource).getPath();
Utils.copyFiles(path, buildFolder.getLocation().toOSString());
buildFolder.refreshLocal(IResource.DEPTH_INFINITE, null);
}
return buildFolder;
}
protected IFolder newTest(String resources) throws Exception {
return newTest(resources, resources);
}
protected void runBuild(IFolder buildFolder) throws Exception {
URL resource = FileLocator.find(Platform.getBundle("org.eclipse.pde.build"), new Path("/scripts/build.xml"),
null);
String buildXMLPath = FileLocator.toFileURL(resource).getPath();
runAntScript(buildXMLPath, new String[] { "main" }, buildFolder.getLocation().toOSString(), null);
}
protected void runProductBuild(IFolder buildFolder) throws Exception {
URL resource = FileLocator.find(Platform.getBundle("org.eclipse.pde.build"),
new Path("/scripts/productBuild/productBuild.xml"), null);
String buildXMLPath = FileLocator.toFileURL(resource).getPath();
runAntScript(buildXMLPath, new String[] { "main" }, buildFolder.getLocation().toOSString(), null);
}
protected void generateScripts(IFolder buildFolder, Properties generateProperties) throws Exception {
URL resource = FileLocator.find(Platform.getBundle("org.eclipse.pde.build"),
new Path("/scripts/genericTargets.xml"), null);
String buildXMLPath = FileLocator.toFileURL(resource).getPath();
runAntScript(buildXMLPath, new String[] { "generateScript" }, buildFolder.getLocation().toOSString(),
generateProperties);
}
protected void runAntScript(String script, String[] targets, String antHome, Properties additionalProperties)
throws Exception {
runAntScript(script, targets, antHome, additionalProperties, null, null);
}
protected void runAntScript(String script, String[] targets, String antHome, Properties additionalProperties,
String listener, String logger) throws Exception {
String[] args = createAntRunnerArgs(script, targets, antHome, additionalProperties, listener, logger);
try {
AntRunner runner = new AntRunner();
runner.run(args);
} catch (InvocationTargetException e) {
Throwable target = e.getTargetException();
if (target instanceof Exception)
throw (Exception) target;
throw e;
}
}
protected String[] createAntRunnerArgs(String script, String[] targets, String antHome,
Properties additionalProperties, String listener, String logger) {
int numArgs = 5 + targets.length + (additionalProperties != null ? additionalProperties.size() : 0);
if (listener != null)
numArgs += 2;
if (logger != null)
numArgs += 2;
String[] args = new String[numArgs];
int idx = 0;
args[idx++] = "-buildfile";
args[idx++] = script;
args[idx++] = "-logfile";
args[idx++] = antHome + "/log.log";
args[idx++] = "-Dbuilder=" + antHome;
if (listener != null) {
args[idx++] = "-listener";
args[idx++] = listener;
}
if (logger != null) {
args[idx++] = "-logger";
args[idx++] = logger;
}
if (additionalProperties != null && additionalProperties.size() > 0) {
Enumeration<Object> e = additionalProperties.keys();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = additionalProperties.getProperty(key);
if (value.length() > 0)
args[idx++] = "-D" + key + "=" + additionalProperties.getProperty(key);
else
args[idx++] = "";
}
}
for (int i = 0; i < targets.length; i++) {
args[idx++] = targets[i];
}
return args;
}
/**
* Assert that the zip file contains at least the given entries
*
* @param buildFolder
* @param archive
* @param entries
* @throws Exception
*/
public static void assertZipContents(IFolder buildFolder, String archive, Set<String> entries) throws Exception {
assertZipContents(buildFolder, archive, entries, true);
}
public static void assertZipContents(File archiveFile, Set<String> entries) throws Exception {
assertZipContents(archiveFile, entries, true);
}
public static void assertZipContents(File archiveFile, Set<String> entries, boolean assertEmpty) throws Exception {
assertTrue(archiveFile.exists());
try (ZipFile zip = new ZipFile(archiveFile)) {
Enumeration<ZipEntry> e = zip.getEntries();
while (e.hasMoreElements() && entries.size() > 0) {
ZipEntry entry = e.nextElement();
String name = entry.getName();
if (entries.contains(name)) {
if (!entry.isDirectory())
assertTrue(entry.getSize() > 0);
entries.remove(name);
}
}
}
if (assertEmpty)
assertTrue("Missing entry in archive: " + entries, entries.size() == 0);
}
public static void assertZipContents(IFolder buildFolder, String archive, Set<String> entries, boolean assertEmpty)
throws Exception {
File folder = new File(buildFolder.getLocation().toOSString());
File archiveFile = new File(folder, archive);
assertZipContents(archiveFile, entries, assertEmpty);
}
/**
* Assert that the given resource exists and has size > 0
*
* @param buildFolder
* @param fileName
* @throws Exception
*/
public static void assertResourceFile(IFolder buildFolder, String fileName) throws Exception {
buildFolder.refreshLocal(IResource.DEPTH_INFINITE, null);
IFile file = buildFolder.getFile(fileName);
assertTrue(file.exists());
File ioFile = file.getLocation().toFile();
assertTrue(ioFile.length() > 0);
}
public static void assertResourceFile(IFile file) throws Exception {
file.getParent().refreshLocal(IResource.DEPTH_INFINITE, null);
assertTrue(file.exists());
File ioFile = file.getLocation().toFile();
assertTrue(ioFile.length() > 0);
}
/**
* Assert that the given log file contains the given message The message is
* expected to be contained on a single line
*
* @param log
* @param msg
* @throws Exception
*/
public static void assertLogContainsLine(IFile log, String msg) throws Exception {
assertLogContainsLines(log, new String[] { msg });
}
/**
* Assert that the given log file contains the given lines Lines are expected to
* appear in order
*
* @param log
* @param lines
* @throws Exception
*/
public static void assertLogContainsLines(IFile log, String[] lines) throws Exception {
log.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
assertNotNull(log);
assertTrue(log.exists());
File logFile = log.getLocation().toFile();
assertTrue(logFile.length() > 0);
int idx = 0;
try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) {
while (reader.ready()) {
String line = reader.readLine();
if (line.indexOf(lines[idx]) >= 0) {
if (++idx >= lines.length) {
reader.close();
return;
}
}
}
}
fail();
}
/**
* assert that the given xml file exists, has size > 0 and is a valid ant script
*
* @param buildXML
* @throws Exception
*/
public static Project assertValidAntScript(IFile buildXML) throws Exception {
return assertValidAntScript(buildXML, null);
}
public static Project assertValidAntScript(IFile buildXML, Map<String, String> alternateTasks) throws Exception {
assertResourceFile((IFolder) buildXML.getParent(), buildXML.getName());
// Parse the build file using ant
ProjectHelper2 helper = new ProjectHelper2();
Project project = new Project();
project.addReference("ant.projectHelper", helper); //$NON-NLS-1$
AntXMLContext context = new AntXMLContext(project);
project.addReference("ant.parsing.context", context);
project.addReference("ant.targets", context.getTargets());
context.setCurrentTargets(new HashMap<>());
AntUtils.setupProject(project, alternateTasks);
project.init();
// this will throw an exception if it is not a valid ant script
helper.parse(project, buildXML.getLocation().toFile(),
new ProjectHelper2.RootHandler(context, new ProjectHelper2.MainHandler()));
return project;
}
public static void assertJarVerifies(File jarFile) throws Exception {
assertJarVerifies(jarFile, false);
}
public static void assertJarVerifies(File jarFile, boolean throwIfNotSigned) throws Exception {
BundleContext context = Activator.getDefault().getContext();
ServiceReference<SignedContentFactory> certRef = context.getServiceReference(SignedContentFactory.class);
if (certRef == null)
throw new IllegalStateException("The SignedContentFactory service is not available");
SignedContentFactory certFactory = context.getService(certRef);
try {
SignedContent content = certFactory.getSignedContent(jarFile);
if (content.isSigned()) {
SignedContentEntry[] entries = content.getSignedEntries();
for (int i = 0; i < entries.length; i++) {
entries[i].verify();
}
} else if (throwIfNotSigned)
throw new AssertionFailedException(jarFile.toString() + " is not signed.");
} finally {
context.ungetService(certRef);
}
}
public void assertZipPermissions(IFile zip, String file, String permissions) throws Exception {
if (Platform.getOS().equals("linux")) {
IFolder tempFolder = org.eclipse.pde.build.internal.tests.Utils.createFolder(buildFolder,
"permissions" + String.valueOf(Math.random()).substring(2, 7));
try {
String[] command = new String[] { "unzip", "-qq", zip.getLocation().toOSString(), file, "-d",
tempFolder.getLocation().toOSString() };
Process proc = Runtime.getRuntime().exec(command);
proc.waitFor();
IFile extractedFile = tempFolder.getFile(file);
assertResourceFile(extractedFile);
command = new String[] { "ls", "-la", extractedFile.getLocation().toOSString() };
proc = Runtime.getRuntime().exec(command);
Utils.transferStreams(proc.getInputStream(),
new FileOutputStream(tempFolder.getFile("ls.out").getLocation().toFile()));
proc.waitFor();
assertLogContainsLine(tempFolder.getFile("ls.out"), permissions);
} finally {
FileUtils.deleteAll(tempFolder.getLocation().toFile());
}
}
}
}