| /******************************************************************************* |
| * 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(); |
| } |
| |
| } |