/******************************************************************************* * Copyright (c) 2008, 2016 Red Hat, Inc. * 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: * Elliott Baron <ebaron@redhat.com> - initial API and implementation * Intel Corporation - build job code *******************************************************************************/ package org.eclipse.linuxtools.profiling.tests; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import org.eclipse.cdt.build.core.scannerconfig.ScannerConfigNature; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature; import org.eclipse.cdt.utils.EFSExtensionManager; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.internal.filesystem.local.LocalFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceDescription; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.linuxtools.internal.profiling.tests.CProjectHelper; import org.eclipse.osgi.util.NLS; import org.eclipse.ui.dialogs.IOverwriteQuery; import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; import org.eclipse.ui.wizards.datatransfer.ImportOperation; import org.osgi.framework.Bundle; @SuppressWarnings("restriction") public abstract class AbstractTest { private static final String BIN_DIR = "Debug"; //$NON-NLS-1$ private static final String IMPORTED_SOURCE_FILE = "primeTest.c"; //$NON-NLS-1$ protected ICProject proj; protected ILaunchManager getLaunchManager() { return DebugPlugin.getDefault().getLaunchManager(); } /** * Create a CDT project outside the default workspace. * * @param bundle * The plug-in bundle. * @param projname * The name of the project. * @param absProjectPath * Absolute path to the directory to which the project should be * mapped outside the workspace. * @return A new external CDT project. * @throws CoreException * @throws URISyntaxException * @throws IOException * @throws InvocationTargetException * @throws InterruptedException */ protected IProject createExternalProject(Bundle bundle, final String projname, final Path absProjectPath) throws CoreException, URISyntaxException, IOException, InvocationTargetException, InterruptedException { IProject externalProject; // Turn off auto-building IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceDescription wspDesc = workspace.getDescription(); wspDesc.setAutoBuilding(false); workspace.setDescription(wspDesc); // Create external project IWorkspaceRoot root = workspace.getRoot(); externalProject = root.getProject(projname); IProjectDescription description = workspace .newProjectDescription(projname); URI fileProjectURL = new URI("file://" + absProjectPath.toString()); description.setLocationURI(fileProjectURL); externalProject = CCorePlugin.getDefault().createCDTProject( description, externalProject, new NullProgressMonitor()); assertNotNull(externalProject); externalProject.open(null); try { // CDT opens the Project with BACKGROUND_REFRESH enabled which // causes the // refresh manager to refresh the project 200ms later. This Job // interferes // with the resource change handler firing see: bug 271264 Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, null); } catch (Exception e) { // Ignore } assertTrue(externalProject.isOpen()); // Import boiler-plate files which can then be built and profiled URL location = FileLocator.find(bundle, new Path( "resources/" + projname), null); //$NON-NLS-1$ File testDir = new File(FileLocator.toFileURL(location).toURI()); ImportOperation op = new ImportOperation(externalProject.getFullPath(), testDir, FileSystemStructureProvider.INSTANCE, new IOverwriteQuery() { @Override public String queryOverwrite(String pathString) { return ALL; } }); op.setCreateContainerStructure(false); op.run(null); IStatus status = op.getStatus(); if (!status.isOK()) { throw new CoreException(status); } // Make sure import went well assertNotNull(externalProject .findMember(new Path(IMPORTED_SOURCE_FILE))); // Index the project IIndexManager indexMgr = CCorePlugin.getIndexManager(); indexMgr.joinIndexer(IIndexManager.FOREVER, new NullProgressMonitor()); // These natures must be enabled at this point to continue assertTrue(externalProject .isNatureEnabled(ScannerConfigNature.NATURE_ID)); assertTrue(externalProject .isNatureEnabled(ManagedCProjectNature.MNG_NATURE_ID)); return externalProject; } /** * Create and build a project outside the default workspace * * @param bundle * The plug-in bundle. * @param projname * The name of the project. * @param absProjectPath * Absolute path to the directory to which the project should be * mapped outside the workspace. * @return A new external CDT project with binaries built. * @throws CoreException * @throws URISyntaxException * @throws IOException * @throws InvocationTargetException * @throws InterruptedException */ protected IProject createExternalProjectAndBuild(Bundle bundle, String projname, Path absProjectPath) throws CoreException, URISyntaxException, InvocationTargetException, InterruptedException, IOException { IProject proj = createExternalProject(bundle, projname, absProjectPath); buildProject(proj); return proj; } protected ICProject createProjectAndBuild(Bundle bundle, String projname) throws CoreException, URISyntaxException, InvocationTargetException, InterruptedException, IOException { ICProject proj = createProject(bundle, projname); buildProject(proj); IBinary[] binaries = null; do { Thread.sleep(500) ; binaries = proj.getBinaryContainer().getBinaries(); } while (binaries == null || binaries.length < 1); return proj; } // Wrapper to allow ICProject parameters, since buildProject doesn't really // use // ICProject specifics. protected void buildProject(ICProject project) throws CoreException { buildProject(project.getProject()); } protected void buildProject(IProject proj) throws CoreException { IWorkspace wsp = ResourcesPlugin.getWorkspace(); final IProject curProject = proj; ISchedulingRule rule = wsp.getRuleFactory().buildRule(); Job buildJob = new Job("project build job") { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { try { curProject.build(IncrementalProjectBuilder.FULL_BUILD, null); } catch (CoreException e) { fail(e.getStatus().getMessage()); } catch (OperationCanceledException e) { fail(NLS.bind( Messages.getString("AbstractTest.Build_cancelled"), curProject.getName(), e.getMessage())); //$NON-NLS-1$ } return Status.OK_STATUS; } }; buildJob.setRule(rule); buildJob.schedule(); try { buildJob.join(); } catch (InterruptedException e) { fail(NLS.bind( Messages.getString("AbstractTest.Build_interrupted"), curProject.getName(), e.getMessage())); //$NON-NLS-1$ } IStatus status = buildJob.getResult(); if (status.getCode() != IStatus.OK) { fail(NLS.bind( Messages.getString("AbstractTest.Build_failed"), curProject.getName(), status.getMessage())); //$NON-NLS-1$ } IWorkspaceRunnable runnable = monitor -> curProject.refreshLocal(IResource.DEPTH_INFINITE, null); wsp.run(runnable, wsp.getRoot(), IWorkspace.AVOID_UPDATE, null); } protected ICProject createProject(Bundle bundle, String projname) throws CoreException, URISyntaxException, IOException, InvocationTargetException, InterruptedException { // Turn off auto-building IWorkspace wsp = ResourcesPlugin.getWorkspace(); IWorkspaceDescription desc = wsp.getDescription(); desc.setAutoBuilding(false); wsp.setDescription(desc); ICProject proj = CProjectHelper.createCProject(projname, BIN_DIR); URL location = FileLocator.find(bundle, new Path( "resources/" + projname), null); //$NON-NLS-1$ File testDir = new File(FileLocator.toFileURL(location).toURI()); IProject project = proj.getProject(); // Add these natures before project is imported due to #273079 ManagedCProjectNature.addManagedNature(project, null); ScannerConfigNature.addScannerConfigNature(project); ImportOperation op = new ImportOperation(project.getFullPath(), testDir, FileSystemStructureProvider.INSTANCE, pathString -> IOverwriteQuery.ALL); op.setCreateContainerStructure(false); op.run(null); IStatus status = op.getStatus(); if (!status.isOK()) { throw new CoreException(status); } // Index the project IIndexManager indexManager = CCorePlugin.getIndexManager(); indexManager.reindex(proj); indexManager.joinIndexer(IIndexManager.FOREVER, new NullProgressMonitor()); // These natures must be enabled at this point to continue assertTrue(project.isNatureEnabled(ScannerConfigNature.NATURE_ID)); assertTrue(project.isNatureEnabled(ManagedCProjectNature.MNG_NATURE_ID)); return proj; } protected void deleteProject(final ICProject cproject) throws CoreException { ResourcesPlugin.getWorkspace().run((IWorkspaceRunnable) monitor -> CProjectHelper.delete(cproject), null); } protected ILaunchConfiguration createConfiguration(IProject proj) throws CoreException { String projectName = proj.getName(); String binPath = ""; ILaunchConfigurationType configType = getLaunchConfigType(); ILaunchConfigurationWorkingCopy wc = configType .newInstance(null, getLaunchManager() .generateLaunchConfigurationName(projectName)); if (proj.getLocation() == null) { IFileStore fileStore = null; try { fileStore = EFS.getStore(new URI(proj.getLocationURI() + BIN_DIR + IPath.SEPARATOR + projectName)); } catch (URISyntaxException e) { fail(NLS.bind( Messages.getString("AbstractTest.No_binary"), projectName)); //$NON-NLS-1$ } if ((fileStore instanceof LocalFile)) { fail(NLS.bind( Messages.getString("AbstractTest.No_binary"), projectName)); //$NON-NLS-1$ } binPath = EFSExtensionManager.getDefault().getPathFromURI( proj.getLocationURI()) + BIN_DIR + IPath.SEPARATOR + proj.getName(); } else { IResource bin = proj.findMember(new Path(BIN_DIR) .append(projectName)); if (bin == null) { fail(NLS.bind( Messages.getString("AbstractTest.No_binary"), projectName)); //$NON-NLS-1$ } binPath = bin.getProjectRelativePath().toString(); wc.setMappedResources(new IResource[] { bin, proj }); } wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, binPath); wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, projectName); wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, (String) null); // Make launch run in foreground wc.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, false); setProfileAttributes(wc); return wc.doSave(); } protected abstract ILaunchConfigurationType getLaunchConfigType(); protected abstract void setProfileAttributes( ILaunchConfigurationWorkingCopy wc) throws CoreException; }