blob: a650f61275ecdeaea7078a51705cdb037f4ddc79 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2016 Broadcom Corporation 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:
* Broadcom Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.testplugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.core.testplugin.ResourceHelper;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.jobs.Job;
/**
* Abstract builder test which provides utility methods for:
* <ul>
* <li>Importing projects into the workspace</li>
* <li>Adding expected resources to the delta verifier</li>
* <li>Verifying the delta</li>
* <li>Printing markers</li>
* <li>Cleaning up the workspace at the end</li>
* </ul>
*/
public abstract class AbstractBuilderTest extends TestCase {
private static final boolean WINDOWS = java.io.File.separatorChar == '\\';
static final String PATH = "builderTests";
private String workspace;
private List<IProject> projects;
@Override
protected void setUp() throws Exception {
super.setUp();
setAutoBuilding(false);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
ResourceHelper.cleanUp(getName());
// Bug 327126 Stop the indexer before tearing down so we don't deadlock
Job.getJobManager().cancel(CCorePlugin.getPDOMManager());
Job.getJobManager().join(CCorePlugin.getPDOMManager(), null);
if (projects != null) {
// Clean-up any projects we were using
for (IProject project : projects) {
project.delete(true, null);
}
projects.clear();
}
}
/**
* Run a build of the specified kind, and verify that the resource changes that
* result match the expectations of the given verifier.
*/
protected void verifyBuild(final IProject project, final int kind, ResourceDeltaVerifier verifier) throws CoreException {
verifyBuild(new IBuildConfiguration[]{project.getActiveBuildConfig()}, kind, verifier);
}
/**
* Build the specified configurations, and verify that the resource changes that
* result match the expectations of the given verifier.
*/
protected void verifyBuild(final IBuildConfiguration[] configs, final int kind, ResourceDeltaVerifier verifier) throws CoreException {
getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, null);
getWorkspace().addResourceChangeListener(verifier);
try {
// batch changes
IWorkspaceRunnable body = new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
getWorkspace().build(configs, kind, true, monitor);
}
};
getWorkspace().run(body, null);
} finally {
assertTrue(verifier.getMessage(), verifier.isDeltaValid());
getWorkspace().removeResourceChangeListener(verifier);
printAllMarkers();
}
}
/**
* Set the active configuration of a project by configuration name
*/
protected void setActiveConfigurationByName(IProject project, String cfgName) throws CoreException {
ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager();
ICProjectDescription desc = mngr.getProjectDescription(project, true);
ICConfigurationDescription cfg = desc.getConfigurationByName(cfgName);
assertNotNull(cfg);
desc.setActiveConfiguration(cfg);
mngr.setProjectDescription(project, desc);
// FIXME: enable when cdt.core knows about core.resources build configurations
// assertTrue(project.getActiveBuildConfig().getName().equals(cfg.getName()));
}
protected Collection<IResource> getProjectBuildExeResources(String projectName, String cfgName, String obj) throws CoreException {
return getProjectBuildExeResources(projectName, cfgName, obj, true);
}
/**
* The externalBuilder is true for when makefiles are generated, or false for internal builder
*/
protected Collection<IResource> getProjectBuildExeResources(String projectName, String cfgName, String obj, boolean externalBuilder) throws CoreException {
return getProjectBuildExeResources(projectName, cfgName, new String[]{obj}, externalBuilder);
}
protected Collection<IResource> getProjectBuildLibResources(String projectName, String cfgName, String obj) throws CoreException {
return getProjectBuildLibResources(projectName, cfgName, new String[]{obj});
}
protected Collection<IResource> getProjectBuildSharedLibResources(String projectName, String cfgName, String obj) throws CoreException {
return getProjectBuildSharedLibResources(projectName, cfgName, new String[]{obj});
}
protected IFile getProjectExe(String projectName, String cfgName) throws CoreException {
IProject project = getWorkspace().getRoot().getProject(projectName);
IFolder buildDir = project.getFolder(cfgName);
return buildDir.getFile(projectName + (WINDOWS ? ".exe" : ""));
}
protected Collection<IResource> getProjectBuildExeResources(String projectName, String cfgName, String[] objs) throws CoreException {
return getProjectBuildExeResources(projectName, cfgName, objs, true);
}
/**
* The externalBuilder is true for when makefiles are generated, or false for internal builder
*/
protected Collection<IResource> getProjectBuildExeResources(String projectName, String cfgName, String[] objs, boolean externalBuilder) throws CoreException {
Collection<IResource> resources = getProjectBuildResources(projectName, cfgName, objs, externalBuilder);
resources.add(getProjectExe(projectName, cfgName));
return resources;
}
protected Collection<IResource> getProjectBuildLibResources(String projectName, String cfgName, String[] objs) throws CoreException {
Collection<IResource> resources = getProjectBuildResources(projectName, cfgName, objs);
IProject project = getWorkspace().getRoot().getProject(projectName);
IFolder buildDir = project.getFolder(cfgName);
resources.add(buildDir.getFile("lib" + projectName + ".a"));
return resources;
}
protected Collection<IResource> getProjectBuildSharedLibResources(String projectName, String cfgName, String[] objs) throws CoreException {
Collection<IResource> resources = getProjectBuildResources(projectName, cfgName, objs);
IProject project = getWorkspace().getRoot().getProject(projectName);
IFolder buildDir = project.getFolder(cfgName);
resources.add(buildDir.getFile("lib" + projectName + ".so"));
return resources;
}
/**
* Returns an array of resources expected to be generated by building a project configuration.
* The object files expected to be output can also be specified.
*/
protected Collection<IResource> getProjectBuildResources(String projectName, String cfgName, String[] objs) throws CoreException {
return getProjectBuildResources(projectName, cfgName, objs, true);
}
/**
* Returns an array of resources expected to be generated by building a project configuration.
* The object files expected to be output can also be specified.
* The externalBuilder is true for when makefiles are generated, or false for internal builder
*/
protected Collection<IResource> getProjectBuildResources(String projectName, String cfgName, String[] objs, boolean externalBuilder) throws CoreException {
IProject project = getWorkspace().getRoot().getProject(projectName);
IFolder buildDir = project.getFolder(cfgName);
Collection<IResource> resources = new LinkedHashSet<IResource>();
resources.add(buildDir);
if (externalBuilder) {
resources.add(buildDir.getFile("makefile"));
resources.add(buildDir.getFile("objects.mk"));
resources.add(buildDir.getFile("sources.mk"));
}
for (String obj : objs) {
if (externalBuilder) {
resources.add(buildDir.getFile(obj + ".d"));
}
resources.add(buildDir.getFile(obj + ".o"));
// Add subdir.mk in the same directory
if (externalBuilder) {
resources.add(buildDir.getFile(new Path(obj).removeLastSegments(1).append("subdir.mk")));
}
// If the parent of the obj doesn't exist, then ensure we're expecting that too...
IPath p = new Path(obj).removeLastSegments(1);
while (p.segmentCount() > 0) {
IFolder folder = buildDir.getFolder(p);
resources.add(folder);
p = p.removeLastSegments(1);
}
}
return resources;
}
public AbstractBuilderTest() {
super();
}
public AbstractBuilderTest(String name) {
super(name);
}
protected void setWorkspace(String name) {
workspace = name;
projects = new ArrayList<IProject>();
}
protected IProject loadProject(String name) throws CoreException {
ManagedBuildTestHelper.loadProject(name, PATH + "/" + workspace);
IProject project = getWorkspace().getRoot().getProject(name);
assertTrue(project.exists());
projects.add(project);
project.refreshLocal(IResource.DEPTH_INFINITE, null);
return project;
}
private List<IMarker> getAllMarkers() throws CoreException {
List<IMarker> markers = new ArrayList<IMarker>();
for (IProject project : projects)
markers.addAll(Arrays.asList(project.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE)));
return markers;
}
protected void printAllMarkers() throws CoreException {
List<IMarker> markers = getAllMarkers();
String[] attributes = new String[] {IMarker.LINE_NUMBER, IMarker.SEVERITY, IMarker.MESSAGE, IMarker.LOCATION /*, ICModelMarker.C_MODEL_MARKER_CONFIGURATION_NAME*/};
StringBuilder sb = new StringBuilder();
for (IMarker m : markers) {
// Project
if (m.getResource().getProject() == null)
sb.append("?");
else
sb.append(m.getResource().getProject().getName());
// Resource workspace path
sb.append(", "); //$NON-NLS-1$
sb.append(m.getResource().getFullPath());
Object[] attrs = m.getAttributes(attributes);
sb.append(":"); //$NON-NLS-1$
int i = 0;
// line number
if (attrs[i] != null)
sb.append(" line ").append(attrs[i]); //$NON-NLS-1$
// severity
if (attrs[++i] != null) {
switch ((Integer)attrs[i++]) {
case IMarker.SEVERITY_ERROR:
sb.append(" ERROR");
break;
case IMarker.SEVERITY_WARNING:
sb.append(" WARNING");
break;
case IMarker.SEVERITY_INFO:
sb.append(" INFO");
break;
}
}
// append the rest of the string fields
do {
if (attrs[i] != null)
sb.append(' ').append(attrs[i]);
} while (++i < attrs.length);
// Finally print the string
System.err.println(sb.toString());
sb.setLength(0);
}
}
protected void setAutoBuilding(boolean value) throws CoreException {
IWorkspace workspace = getWorkspace();
if (workspace.isAutoBuilding() == value)
return;
IWorkspaceDescription desc = workspace.getDescription();
desc.setAutoBuilding(value);
workspace.setDescription(desc);
}
protected IWorkspace getWorkspace() throws CoreException {
return ResourcesPlugin.getWorkspace();
}
}