Automated import from //branches/master/...@141783,141783
This commit is contained in:
committed by
The Android Open Source Project
parent
3e6efddf28
commit
6dc9883c6e
@@ -32,23 +32,21 @@ import org.eclipse.core.runtime.CoreException;
|
|||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||||
import org.eclipse.jdt.core.IJavaProject;
|
|
||||||
import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
|
import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
|
||||||
import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
|
import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run configuration that can execute JUnit tests on an Android platform
|
* Run configuration that can execute JUnit tests on an Android platform.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Will deploy apps on target Android platform by reusing functionality from ADT
|
* Will deploy apps on target Android platform by reusing functionality from ADT
|
||||||
* LaunchConfigDelegate, and then run JUnits tests by reusing functionality from JDT
|
* LaunchConfigDelegate, and then run JUnits tests by reusing functionality from JDT
|
||||||
* JUnitLaunchConfigDelegate.
|
* JUnitLaunchConfigDelegate.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("restriction") //$NON-NLS-1$
|
@SuppressWarnings("restriction")
|
||||||
public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
|
public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
|
||||||
|
|
||||||
/** Launch config attribute that stores instrumentation runner */
|
/** Launch config attribute that stores instrumentation runner. */
|
||||||
static final String ATTR_INSTR_NAME = AdtPlugin.PLUGIN_ID + ".instrumentation"; //$NON-NLS-1$
|
static final String ATTR_INSTR_NAME = AdtPlugin.PLUGIN_ID + ".instrumentation"; //$NON-NLS-1$
|
||||||
static final String INSTRUMENTATION_OK = null;
|
|
||||||
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,7 +56,7 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
|
|||||||
IFile applicationPackage, AndroidManifestParser manifestParser) {
|
IFile applicationPackage, AndroidManifestParser manifestParser) {
|
||||||
|
|
||||||
String testPackage = manifestParser.getPackage();
|
String testPackage = manifestParser.getPackage();
|
||||||
String runner = getRunnerFromConfig(configuration);
|
String runner = getRunner(project, configuration, manifestParser);
|
||||||
if (runner == null) {
|
if (runner == null) {
|
||||||
AdtPlugin.displayError("Android Launch",
|
AdtPlugin.displayError("Android Launch",
|
||||||
"An instrumention test runner is not specified!");
|
"An instrumention test runner is not specified!");
|
||||||
@@ -73,44 +71,56 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
|
|||||||
junitLaunch, config, androidLaunch, monitor);
|
junitLaunch, config, androidLaunch, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRunnerFromConfig(ILaunchConfiguration configuration) {
|
/**
|
||||||
String runner = EMPTY_STRING;
|
* Gets a instrumentation runner for the launch.
|
||||||
|
* <p/>
|
||||||
|
* If a runner is stored in the given <code>configuration</code>, will return that.
|
||||||
|
* Otherwise, will try to find the first valid runner for the project.
|
||||||
|
* If a runner can still not be found, will return <code>null</code>.
|
||||||
|
*
|
||||||
|
* @param project the {@link IProject} for the app
|
||||||
|
* @param configuration the {@link ILaunchConfiguration} for the launch
|
||||||
|
* @param manifestParser the {@link AndroidManifestParser} for the project
|
||||||
|
*
|
||||||
|
* @return <code>null</code> if no instrumentation runner can be found, otherwise return
|
||||||
|
* the fully qualified runner name.
|
||||||
|
*/
|
||||||
|
private String getRunner(IProject project, ILaunchConfiguration configuration,
|
||||||
|
AndroidManifestParser manifestParser) {
|
||||||
try {
|
try {
|
||||||
runner = configuration.getAttribute(ATTR_INSTR_NAME, EMPTY_STRING);
|
String runner = getRunnerFromConfig(configuration);
|
||||||
} catch (CoreException e) {
|
if (runner != null) {
|
||||||
AdtPlugin.log(e, "Error when retrieving instrumentation info from launch config"); //$NON-NLS-1$
|
return runner;
|
||||||
}
|
}
|
||||||
|
final InstrumentationRunnerValidator instrFinder = new InstrumentationRunnerValidator(
|
||||||
|
BaseProjectHelper.getJavaProject(project), manifestParser);
|
||||||
|
runner = instrFinder.getValidInstrumentationTestRunner();
|
||||||
|
if (runner != null) {
|
||||||
|
AdtPlugin.printErrorToConsole(project,
|
||||||
|
String.format("Warning: No instrumentation runner found for the launch, " +
|
||||||
|
"using %1$s", runner));
|
||||||
|
return runner;
|
||||||
|
}
|
||||||
|
AdtPlugin.printErrorToConsole(project,
|
||||||
|
String.format("ERROR: Application does not specify a %1$s instrumentation or does not declare uses-library %2$s",
|
||||||
|
AndroidConstants.CLASS_INSTRUMENTATION_RUNNER,
|
||||||
|
AndroidConstants.LIBRARY_TEST_RUNNER));
|
||||||
|
return null;
|
||||||
|
} catch (CoreException e) {
|
||||||
|
AdtPlugin.log(e, "Error when retrieving instrumentation info"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRunnerFromConfig(ILaunchConfiguration configuration) throws CoreException {
|
||||||
|
String runner = configuration.getAttribute(ATTR_INSTR_NAME, EMPTY_STRING);
|
||||||
if (runner.length() < 1) {
|
if (runner.length() < 1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return runner;
|
return runner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to return the set of instrumentations for the Android project
|
|
||||||
*
|
|
||||||
* @param project the {@link IProject} to get instrumentations for
|
|
||||||
* @return null if error occurred parsing instrumentations, otherwise returns array of
|
|
||||||
* instrumentation class names
|
|
||||||
*/
|
|
||||||
static String[] getInstrumentationsForProject(IProject project) {
|
|
||||||
if (project != null) {
|
|
||||||
try {
|
|
||||||
// parse the manifest for the list of instrumentations
|
|
||||||
AndroidManifestParser manifestParser = AndroidManifestParser.parse(
|
|
||||||
BaseProjectHelper.getJavaProject(project), null /* errorListener */,
|
|
||||||
true /* gatherData */, false /* markErrors */);
|
|
||||||
if (manifestParser != null) {
|
|
||||||
return manifestParser.getInstrumentations();
|
|
||||||
}
|
|
||||||
} catch (CoreException e) {
|
|
||||||
AdtPlugin.log(e, "%s: Error parsing AndroidManifest.xml", //$NON-NLS-1$
|
|
||||||
project.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to set JUnit-related attributes expected by JDT JUnit runner
|
* Helper method to set JUnit-related attributes expected by JDT JUnit runner
|
||||||
*
|
*
|
||||||
@@ -121,56 +131,4 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
|
|||||||
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND,
|
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND,
|
||||||
TestKindRegistry.JUNIT3_TEST_KIND_ID);
|
TestKindRegistry.JUNIT3_TEST_KIND_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to determine if specified instrumentation can be used as a test runner
|
|
||||||
*
|
|
||||||
* @param project the {@link IJavaProject} to validate
|
|
||||||
* @param instrumentation the instrumentation class name to validate
|
|
||||||
* @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message
|
|
||||||
*/
|
|
||||||
static String validateInstrumentationRunner(IJavaProject project, String instrumentation) {
|
|
||||||
AndroidManifestParser manifestParser;
|
|
||||||
try {
|
|
||||||
manifestParser = AndroidManifestParser.parse(
|
|
||||||
project, null /* errorListener */,
|
|
||||||
true /* gatherData */, false /* markErrors */);
|
|
||||||
// check if this instrumentation is the standard test runner
|
|
||||||
if (!instrumentation.equals(AndroidConstants.CLASS_INSTRUMENTATION_RUNNER)) {
|
|
||||||
// check if it extends the standard test runner
|
|
||||||
String result = BaseProjectHelper.testClassForManifest(project,
|
|
||||||
instrumentation, AndroidConstants.CLASS_INSTRUMENTATION_RUNNER, true);
|
|
||||||
if (result != BaseProjectHelper.TEST_CLASS_OK) {
|
|
||||||
return String.format("The instrumentation runner must be of type %s",
|
|
||||||
AndroidConstants.CLASS_INSTRUMENTATION_RUNNER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasTestRunnerLibrary(manifestParser)) {
|
|
||||||
return String.format("%s does not not use the %s library",
|
|
||||||
project.getProject().getName(), AndroidConstants.LIBRARY_TEST_RUNNER);
|
|
||||||
}
|
|
||||||
} catch (CoreException e) {
|
|
||||||
String err = String.format("Error parsing AndroidManifest for %s",
|
|
||||||
project.getProject().getName());
|
|
||||||
AdtPlugin.log(e, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
return INSTRUMENTATION_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to determine if given manifest has a <code>AndroidConstants.LIBRARY_TEST_RUNNER
|
|
||||||
* </code> library reference
|
|
||||||
*
|
|
||||||
* @param manifestParser the {@link AndroidManifestParser} to search
|
|
||||||
* @return true if test runner library found, false otherwise
|
|
||||||
*/
|
|
||||||
static boolean hasTestRunnerLibrary(AndroidManifestParser manifestParser) {
|
|
||||||
for (String lib : manifestParser.getUsesLibraries()) {
|
|
||||||
if (lib.equals(AndroidConstants.LIBRARY_TEST_RUNNER)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,9 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
private Image mTabIcon = null;
|
private Image mTabIcon = null;
|
||||||
private Combo mInstrumentationCombo;
|
private Combo mInstrumentationCombo;
|
||||||
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||||
|
private static final String TAG = "AndroidJUnitLaunchConfigurationTab"; //$NON-NLS-1$
|
||||||
private String[] mInstrumentations = null;
|
private String[] mInstrumentations = null;
|
||||||
|
private InstrumentationRunnerValidator mInstrValidator = null;
|
||||||
private ProjectChooserHelper mProjectChooserHelper;
|
private ProjectChooserHelper mProjectChooserHelper;
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -454,7 +456,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
mapResources(config);
|
mapResources(config);
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
// TODO: does the real error need to be extracted out of CoreException
|
// TODO: does the real error need to be extracted out of CoreException
|
||||||
AdtPlugin.log(e, "Error occurred saving configuration");
|
AdtPlugin.log(e, "Error occurred saving configuration"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
AndroidJUnitLaunchConfigDelegate.setJUnitDefaults(config);
|
AndroidJUnitLaunchConfigDelegate.setJUnitDefaults(config);
|
||||||
|
|
||||||
@@ -486,7 +488,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
public Image getImage() {
|
public Image getImage() {
|
||||||
// reuse icon from the Android App Launch config tab
|
// reuse icon from the Android App Launch config tab
|
||||||
if (mTabIcon == null) {
|
if (mTabIcon == null) {
|
||||||
mTabIcon= AdtPlugin.getImageLoader().loadImage(MainLaunchConfigTab.LAUNCH_TAB_IMAGE,
|
mTabIcon = AdtPlugin.getImageLoader().loadImage(MainLaunchConfigTab.LAUNCH_TAB_IMAGE,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
return mTabIcon;
|
return mTabIcon;
|
||||||
@@ -514,7 +516,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
setErrorMessage(e.getMessage());
|
setErrorMessage(e.getMessage());
|
||||||
return;
|
return;
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
AdtPlugin.log(e.getTargetException(), "Error finding test types");
|
AdtPlugin.log(e.getTargetException(), "Error finding test types"); //$NON-NLS-1$
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
mTestRadioButton.setSelection(radioSetting[0]);
|
mTestRadioButton.setSelection(radioSetting[0]);
|
||||||
@@ -675,10 +677,10 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
AdtPlugin.log(e, "validatePage failed");
|
AdtPlugin.log(e, "validatePage failed"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
validateInstrumentation(javaProject);
|
validateInstrumentation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateJavaProject(IJavaProject javaProject) {
|
private void validateJavaProject(IJavaProject javaProject) {
|
||||||
@@ -688,19 +690,14 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateInstrumentation(IJavaProject javaProject) {
|
private void validateInstrumentation() {
|
||||||
if (mInstrumentations == null || mInstrumentations.length < 1) {
|
|
||||||
setErrorMessage("Specified project has no defined instrumentations");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String instrumentation = getSelectedInstrumentation();
|
String instrumentation = getSelectedInstrumentation();
|
||||||
if (instrumentation == null) {
|
if (instrumentation == null) {
|
||||||
setErrorMessage("Instrumentation not specified");
|
setErrorMessage("Instrumentation runner not specified");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String result = AndroidJUnitLaunchConfigDelegate.validateInstrumentationRunner(
|
String result = mInstrValidator.validateInstrumentationRunner(instrumentation);
|
||||||
javaProject, instrumentation);
|
if (result != InstrumentationRunnerValidator.INSTRUMENTATION_OK) {
|
||||||
if (result != AndroidJUnitLaunchConfigDelegate.INSTRUMENTATION_OK) {
|
|
||||||
setErrorMessage(result);
|
setErrorMessage(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -949,14 +946,15 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the UI with the instrumentations of the specified project, and stores the
|
* Loads the UI with the instrumentations of the specified project, and stores the
|
||||||
* activities in <code>mActivities</code>.
|
* instrumentations in <code>mInstrumentations</code>.
|
||||||
* <p/>
|
|
||||||
* First activity is selected by default if present.
|
|
||||||
*
|
*
|
||||||
* @param project the {@link IProject} to load the instrumentations from.
|
* @param project the {@link IProject} to load the instrumentations from.
|
||||||
*/
|
*/
|
||||||
private void loadInstrumentations(IProject project) {
|
private void loadInstrumentations(IProject project) {
|
||||||
mInstrumentations = AndroidJUnitLaunchConfigDelegate.getInstrumentationsForProject(project);
|
try {
|
||||||
|
mInstrValidator = new InstrumentationRunnerValidator(project);
|
||||||
|
mInstrumentations = (mInstrValidator == null ? null :
|
||||||
|
mInstrValidator.getInstrumentations());
|
||||||
if (mInstrumentations != null) {
|
if (mInstrumentations != null) {
|
||||||
mInstrumentationCombo.removeAll();
|
mInstrumentationCombo.removeAll();
|
||||||
for (String instrumentation : mInstrumentations) {
|
for (String instrumentation : mInstrumentations) {
|
||||||
@@ -966,9 +964,13 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
|
|||||||
// config object.
|
// config object.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
AdtPlugin.logAndPrintError(e, TAG, "ERROR: Failed to get instrumentations for %1$s",
|
||||||
|
project.getName());
|
||||||
|
}
|
||||||
// if we reach this point, either project is null, or we got an exception during
|
// if we reach this point, either project is null, or we got an exception during
|
||||||
// the parsing. In either case, we empty the instrumentation list.
|
// the parsing. In either case, we empty the instrumentation list.
|
||||||
|
mInstrValidator = null;
|
||||||
mInstrumentations = null;
|
mInstrumentations = null;
|
||||||
mInstrumentationCombo.removeAll();
|
mInstrumentationCombo.removeAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
package com.android.ide.eclipse.adt.launch.junit;
|
package com.android.ide.eclipse.adt.launch.junit;
|
||||||
|
|
||||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
|
||||||
|
|
||||||
import org.eclipse.core.resources.IProject;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||||
import org.eclipse.jdt.core.IJavaElement;
|
import org.eclipse.jdt.core.IJavaElement;
|
||||||
@@ -43,33 +39,18 @@ public class AndroidJUnitLaunchShortcut extends JUnitLaunchShortcut {
|
|||||||
protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(IJavaElement element)
|
protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(IJavaElement element)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
ILaunchConfigurationWorkingCopy config = super.createLaunchConfiguration(element);
|
ILaunchConfigurationWorkingCopy config = super.createLaunchConfiguration(element);
|
||||||
IProject project = element.getResource().getProject();
|
// just get first valid instrumentation runner
|
||||||
String[] instrumentations =
|
String instrumentation = new InstrumentationRunnerValidator(element.getJavaProject()).
|
||||||
AndroidJUnitLaunchConfigDelegate.getInstrumentationsForProject(project);
|
getValidInstrumentationTestRunner();
|
||||||
boolean runnerFound = false;
|
if (instrumentation != null) {
|
||||||
if (instrumentations != null) {
|
|
||||||
// just pick the first valid runner
|
|
||||||
for (String instr : instrumentations) {
|
|
||||||
if (AndroidJUnitLaunchConfigDelegate.validateInstrumentationRunner(
|
|
||||||
element.getJavaProject(), instr) ==
|
|
||||||
AndroidJUnitLaunchConfigDelegate.INSTRUMENTATION_OK) {
|
|
||||||
|
|
||||||
config.setAttribute(AndroidJUnitLaunchConfigDelegate.ATTR_INSTR_NAME,
|
config.setAttribute(AndroidJUnitLaunchConfigDelegate.ATTR_INSTR_NAME,
|
||||||
instr);
|
instrumentation);
|
||||||
runnerFound = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
// if a valid runner is not found, rely on launch delegate to log error.
|
||||||
}
|
// This method is called without explicit user action to launch Android JUnit, so avoid
|
||||||
if (!runnerFound) {
|
// logging an error here.
|
||||||
// TODO: put this in a string properties
|
|
||||||
String msg = String.format("ERROR: Application does not specify a %s instrumentation or does not declare uses-library %s",
|
|
||||||
AndroidConstants.CLASS_INSTRUMENTATION_RUNNER,
|
|
||||||
AndroidConstants.LIBRARY_TEST_RUNNER);
|
|
||||||
AdtPlugin.printErrorToConsole(project, msg);
|
|
||||||
}
|
|
||||||
AndroidJUnitLaunchConfigDelegate.setJUnitDefaults(config);
|
|
||||||
|
|
||||||
|
AndroidJUnitLaunchConfigDelegate.setJUnitDefaults(config);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.eclipse.org/org/documents/epl-v10.php
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.ide.eclipse.adt.launch.junit;
|
||||||
|
|
||||||
|
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||||
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
|
import com.android.ide.eclipse.common.project.BaseProjectHelper;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.jdt.core.IJavaProject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides validation for Android instrumentation test runner
|
||||||
|
*/
|
||||||
|
class InstrumentationRunnerValidator {
|
||||||
|
private final IJavaProject mJavaProject;
|
||||||
|
private String[] mInstrumentations = null;
|
||||||
|
private boolean mHasRunnerLibrary = false;
|
||||||
|
|
||||||
|
static final String INSTRUMENTATION_OK = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the InstrumentationRunnerValidator.
|
||||||
|
*
|
||||||
|
* @param javaProject the {@link IJavaProject} for the Android project to validate
|
||||||
|
*/
|
||||||
|
InstrumentationRunnerValidator(IJavaProject javaProject) {
|
||||||
|
mJavaProject = javaProject;
|
||||||
|
try {
|
||||||
|
AndroidManifestParser manifestParser = AndroidManifestParser.parse(javaProject,
|
||||||
|
null /* errorListener */, true /* gatherData */, false /* markErrors */);
|
||||||
|
init(manifestParser);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
AdtPlugin.printErrorToConsole(javaProject.getProject(), "ERROR: Failed to parse %1$s",
|
||||||
|
AndroidConstants.FN_ANDROID_MANIFEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the InstrumentationRunnerValidator.
|
||||||
|
*
|
||||||
|
* @param project the {@link IProject} for the Android project to validate
|
||||||
|
* @throws CoreException if a fatal error occurred in initialization
|
||||||
|
*/
|
||||||
|
InstrumentationRunnerValidator(IProject project) throws CoreException {
|
||||||
|
this(BaseProjectHelper.getJavaProject(project));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the InstrumentationRunnerValidator with an existing {@link AndroidManifestParser}
|
||||||
|
*
|
||||||
|
* @param javaProject the {@link IJavaProject} for the Android project to validate
|
||||||
|
* @param manifestParser the {@link AndroidManifestParser} for the Android project
|
||||||
|
*/
|
||||||
|
InstrumentationRunnerValidator(IJavaProject javaProject, AndroidManifestParser manifestParser) {
|
||||||
|
mJavaProject = javaProject;
|
||||||
|
init(manifestParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(AndroidManifestParser manifestParser) {
|
||||||
|
mInstrumentations = manifestParser.getInstrumentations();
|
||||||
|
mHasRunnerLibrary = hasTestRunnerLibrary(manifestParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to determine if given manifest has a <code>AndroidConstants.LIBRARY_TEST_RUNNER
|
||||||
|
* </code> library reference
|
||||||
|
*
|
||||||
|
* @param manifestParser the {@link AndroidManifestParser} to search
|
||||||
|
* @return true if test runner library found, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean hasTestRunnerLibrary(AndroidManifestParser manifestParser) {
|
||||||
|
for (String lib : manifestParser.getUsesLibraries()) {
|
||||||
|
if (lib.equals(AndroidConstants.LIBRARY_TEST_RUNNER)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the set of instrumentations for the Android project.
|
||||||
|
*
|
||||||
|
* @return <code>null</code if error occurred parsing instrumentations, otherwise returns array
|
||||||
|
* of instrumentation class names
|
||||||
|
*/
|
||||||
|
String[] getInstrumentations() {
|
||||||
|
return mInstrumentations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get the first instrumentation that can be used as a test runner.
|
||||||
|
*
|
||||||
|
* @return fully qualified instrumentation class name. <code>null</code> if no valid
|
||||||
|
* instrumentation can be found.
|
||||||
|
*/
|
||||||
|
String getValidInstrumentationTestRunner() {
|
||||||
|
for (String instrumentation : getInstrumentations()) {
|
||||||
|
if (validateInstrumentationRunner(instrumentation) == INSTRUMENTATION_OK) {
|
||||||
|
return instrumentation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to determine if specified instrumentation can be used as a test runner
|
||||||
|
*
|
||||||
|
* @param instrumentation the instrumentation class name to validate. Assumes this
|
||||||
|
* instrumentation is one of {@link #getInstrumentations()}
|
||||||
|
* @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message
|
||||||
|
*/
|
||||||
|
String validateInstrumentationRunner(String instrumentation) {
|
||||||
|
if (!mHasRunnerLibrary) {
|
||||||
|
return String.format("The application does not declare uses-library %1$s",
|
||||||
|
AndroidConstants.LIBRARY_TEST_RUNNER);
|
||||||
|
}
|
||||||
|
// check if this instrumentation is the standard test runner
|
||||||
|
if (!instrumentation.equals(AndroidConstants.CLASS_INSTRUMENTATION_RUNNER)) {
|
||||||
|
// check if it extends the standard test runner
|
||||||
|
String result = BaseProjectHelper.testClassForManifest(mJavaProject,
|
||||||
|
instrumentation, AndroidConstants.CLASS_INSTRUMENTATION_RUNNER, true);
|
||||||
|
if (result != BaseProjectHelper.TEST_CLASS_OK) {
|
||||||
|
return String.format("The instrumentation runner must be of type %s",
|
||||||
|
AndroidConstants.CLASS_INSTRUMENTATION_RUNNER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INSTRUMENTATION_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user