blob: 96796ecfcf8307ef18a90a3735413ff0c5b110f9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.junit.launcher;
import java.io.File;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.junit.ui.JUnitMessages;
import org.eclipse.jdt.internal.junit.ui.JUnitPlugin;
import org.eclipse.jdt.internal.junit.util.IJUnitStatusConstants;
import org.eclipse.jdt.internal.junit.util.TestSearchEngine;
import org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate;
import org.eclipse.jdt.launching.ExecutionArguments;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.SocketUtil;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
/**
* Abstract launch configuration delegate for a JUnit test.
*/
public abstract class JUnitBaseLaunchConfiguration extends AbstractJavaLaunchConfigurationDelegate {
public static final String PORT_ATTR= JUnitPlugin.PLUGIN_ID+".PORT"; //$NON-NLS-1$
/**
* The single test type, or "" iff running a launch container.
*/
public static final String TESTTYPE_ATTR= JUnitPlugin.PLUGIN_ID+".TESTTYPE"; //$NON-NLS-1$
/**
* The test method, or "" iff running the whole test type.
*/
public static final String TESTNAME_ATTR= JUnitPlugin.PLUGIN_ID+".TESTNAME"; //$NON-NLS-1$
public static final String ATTR_KEEPRUNNING = JUnitPlugin.PLUGIN_ID+ ".KEEPRUNNING_ATTR"; //$NON-NLS-1$
/**
* The launch container, or "" iff running a single test type.
*/
public static final String LAUNCH_CONTAINER_ATTR= JUnitPlugin.PLUGIN_ID+".CONTAINER"; //$NON-NLS-1$
/**
* The name of the prioritized tests
*/
public static final String FAILURES_FILENAME_ATTR= JUnitPlugin.PLUGIN_ID+".FAILURENAMES"; //$NON-NLS-1$
public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor pm) throws CoreException {
IType[] testTypes = getTestTypes(configuration, pm);
IVMInstall install= getVMInstall(configuration);
IVMRunner runner = install.getVMRunner(mode);
if (runner == null) {
abort(MessageFormat.format(JUnitMessages.JUnitBaseLaunchConfiguration_error_novmrunner, new String[]{install.getId()}), null, IJavaLaunchConfigurationConstants.ERR_VM_RUNNER_DOES_NOT_EXIST);
}
int port= SocketUtil.findFreePort();
VMRunnerConfiguration runConfig= launchTypes(configuration, mode, testTypes, port);
setDefaultSourceLocator(launch, configuration);
launch.setAttribute(PORT_ATTR, Integer.toString(port));
launch.setAttribute(TESTTYPE_ATTR, testTypes[0].getHandleIdentifier());
runner.run(runConfig, launch, pm);
}
/**
* @param configuration
* @param pm
* @return The types representing tests to be launched for this
* configuration
* @throws CoreException
*/
protected IType[] getTestTypes(ILaunchConfiguration configuration, IProgressMonitor pm) throws CoreException {
IJavaProject javaProject= getJavaProject(configuration);
if ((javaProject == null) || !javaProject.exists()) {
abort(JUnitMessages.JUnitBaseLaunchConfiguration_error_invalidproject, null, IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT);
}
if (!TestSearchEngine.hasTestCaseType(javaProject)) {
abort(JUnitMessages.JUnitBaseLaunchConfiguration_error_junitnotonpath, null, IJUnitStatusConstants.ERR_JUNIT_NOT_ON_PATH);
}
IType[] testTypes = getTestTypes(configuration, javaProject, pm);
if (testTypes.length == 0) {
abort(JUnitMessages.JUnitBaseLaunchConfiguration_error_notests, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
}
return testTypes;
}
protected VMRunnerConfiguration launchTypes(ILaunchConfiguration configuration,
String mode, IType[] tests, int port) throws CoreException {
File workingDir = verifyWorkingDirectory(configuration);
String workingDirName = null;
if (workingDir != null)
workingDirName = workingDir.getAbsolutePath();
// Program & VM args
String vmArgs= getVMArguments(configuration);
ExecutionArguments execArgs = new ExecutionArguments(vmArgs, ""); //$NON-NLS-1$
String[] envp= DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);
VMRunnerConfiguration runConfig= createVMRunner(configuration, tests, port, mode);
runConfig.setVMArguments(execArgs.getVMArgumentsArray());
runConfig.setWorkingDirectory(workingDirName);
runConfig.setEnvironment(envp);
Map vmAttributesMap = getVMSpecificAttributesMap(configuration);
runConfig.setVMSpecificAttributesMap(vmAttributesMap);
String[] bootpath = getBootpath(configuration);
runConfig.setBootClassPath(bootpath);
return runConfig;
}
public IType[] getTestTypes(ILaunchConfiguration configuration, IJavaProject javaProject, IProgressMonitor pm) throws CoreException {
String testTypeName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String)null);
testTypeName= VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(testTypeName);
if (pm == null)
pm= new NullProgressMonitor();
String containerHandle = configuration.getAttribute(LAUNCH_CONTAINER_ATTR, ""); //$NON-NLS-1$
if (containerHandle.length() == 0) {
return findSingleTest(javaProject, testTypeName);
}
return findTestsInContainer(containerHandle, pm);
}
/**
* @inheritdoc
* @param containerHandle
* @param pm
* @return
*/
private IType[] findTestsInContainer(String containerHandle, IProgressMonitor pm) {
IJavaElement container= JavaCore.create(containerHandle);
Set result= new HashSet();
try {
TestSearchEngine.doFindTests(new Object[]{container}, result, pm);
} catch (InterruptedException e) {
}
return (IType[]) result.toArray(new IType[result.size()]) ;
}
public IType[] findSingleTest(IJavaProject javaProject, String testName) throws CoreException {
IType type = null;
try {
type = findType(javaProject, testName);
} catch (JavaModelException jme) {
abort("Test type does not exist", null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); //$NON-NLS-1$
}
if (type == null) {
abort("Test type does not exist", null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); //$NON-NLS-1$
}
return new IType[]{type};
}
/**
* Throws a core exception with the given message and optional
* exception. The exception's status code will indicate an error.
*
* @param message error message
* @param exception cause of the error, or <code>null</code>
* @exception CoreException with the given message and underlying
* exception
*/
protected void abort(String message, Throwable exception, int code) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, JUnitPlugin.PLUGIN_ID, code, message, exception));
}
/**
* Find the specified (fully-qualified) type name in the specified java project.
*/
private IType findType(IJavaProject javaProject, String mainTypeName) throws JavaModelException {
return javaProject.findType(mainTypeName);
}
/**
* Override to create a custom VMRunnerConfiguration for a launch configuration.
*/
protected abstract VMRunnerConfiguration createVMRunner(ILaunchConfiguration configuration, IType[] testTypes, int port, String runMode) throws CoreException;
protected boolean keepAlive(ILaunchConfiguration config) {
try {
return config.getAttribute(ATTR_KEEPRUNNING, false);
} catch(CoreException e) {
}
return false;
}
}