aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java')
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java286
1 files changed, 286 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java
new file mode 100755
index 000000000..6e47ce91c
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java
@@ -0,0 +1,286 @@
+/*
+ * 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.internal.launch.junit;
+
+import com.android.SdkConstants;
+import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner.TestSize;
+import com.android.ide.common.xml.ManifestData;
+import com.android.ide.common.xml.ManifestData.Instrumentation;
+import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.internal.launch.AndroidLaunch;
+import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration;
+import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchController;
+import com.android.ide.eclipse.adt.internal.launch.IAndroidLaunchAction;
+import com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate;
+import com.android.ide.eclipse.adt.internal.launch.LaunchMessages;
+import com.android.ide.eclipse.adt.internal.launch.junit.runtime.AndroidJUnitLaunchInfo;
+import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
+import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Run configuration that can execute JUnit tests on an Android platform.
+ * <p/>
+ * Will deploy apps on target Android platform by reusing functionality from ADT
+ * LaunchConfigDelegate, and then run JUnits tests by reusing functionality from JDT
+ * JUnitLaunchConfigDelegate.
+ */
+@SuppressWarnings("restriction")
+public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
+
+ /** Launch config attribute that stores instrumentation runner. */
+ static final String ATTR_INSTR_NAME = AdtPlugin.PLUGIN_ID + ".instrumentation"; //$NON-NLS-1$
+
+ /** Launch config attribute that stores the test size annotation to run. */
+ static final String ATTR_TEST_SIZE = AdtPlugin.PLUGIN_ID + ".testSize"; //$NON-NLS-1$
+
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ @Override
+ protected void doLaunch(final ILaunchConfiguration configuration, final String mode,
+ final IProgressMonitor monitor, final IProject project,
+ final AndroidLaunch androidLaunch, final AndroidLaunchConfiguration config,
+ final AndroidLaunchController controller, final IFile applicationPackage,
+ final ManifestData manifestData) {
+
+ String runner = getRunner(project, configuration, manifestData);
+ if (runner == null) {
+ AdtPlugin.displayError(LaunchMessages.LaunchDialogTitle,
+ String.format(LaunchMessages.AndroidJUnitDelegate_NoRunnerMsg_s,
+ project.getName()));
+ androidLaunch.stopLaunch();
+ return;
+ }
+ // get the target app's package
+ final String targetAppPackage = getTargetPackage(manifestData, runner);
+ if (targetAppPackage == null) {
+ AdtPlugin.displayError(LaunchMessages.LaunchDialogTitle,
+ String.format(LaunchMessages.AndroidJUnitDelegate_NoTargetMsg_3s,
+ project.getName(), runner, SdkConstants.FN_ANDROID_MANIFEST_XML));
+ androidLaunch.stopLaunch();
+ return;
+ }
+ final String testAppPackage = manifestData.getPackage();
+ AndroidJUnitLaunchInfo junitLaunchInfo = new AndroidJUnitLaunchInfo(project,
+ testAppPackage, runner);
+ junitLaunchInfo.setTestClass(getTestClass(configuration));
+ junitLaunchInfo.setTestPackage(getTestPackage(configuration));
+ junitLaunchInfo.setTestMethod(getTestMethod(configuration));
+ junitLaunchInfo.setLaunch(androidLaunch);
+ junitLaunchInfo.setTestSize(getTestSize(configuration));
+ final IAndroidLaunchAction junitLaunch = new AndroidJUnitLaunchAction(junitLaunchInfo);
+
+ // launch on a separate thread if currently on the display thread
+ if (Display.getCurrent() != null) {
+ Job job = new Job("Junit Launch") { //$NON-NLS-1$
+ @Override
+ protected IStatus run(IProgressMonitor m) {
+ controller.launch(project, mode, applicationPackage, testAppPackage,
+ targetAppPackage, manifestData.getDebuggable(),
+ manifestData.getMinSdkVersionString(),
+ junitLaunch, config, androidLaunch, monitor);
+ return Status.OK_STATUS;
+ }
+ };
+ job.setPriority(Job.INTERACTIVE);
+ job.schedule();
+ } else {
+ controller.launch(project, mode, applicationPackage, testAppPackage, targetAppPackage,
+ manifestData.getDebuggable(), manifestData.getMinSdkVersionString(),
+ junitLaunch, config, androidLaunch, monitor);
+ }
+ }
+
+ /**
+ * Get the target Android application's package for the given instrumentation runner, or
+ * <code>null</code> if it could not be found.
+ *
+ * @param manifestParser the {@link ManifestData} for the test project
+ * @param runner the instrumentation runner class name
+ * @return the target package or <code>null</code>
+ */
+ private String getTargetPackage(ManifestData manifestParser, String runner) {
+ for (Instrumentation instr : manifestParser.getInstrumentations()) {
+ if (instr.getName().equals(runner)) {
+ return instr.getTargetPackage();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the test package stored in the launch configuration, or <code>null</code> if not
+ * specified.
+ *
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the test package info from
+ * @return the test package or <code>null</code>.
+ */
+ private String getTestPackage(ILaunchConfiguration configuration) {
+ // try to retrieve a package name from the JUnit container attribute
+ String containerHandle = getStringLaunchAttribute(
+ JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, configuration);
+ if (containerHandle != null && containerHandle.length() > 0) {
+ IJavaElement element = JavaCore.create(containerHandle);
+ // containerHandle could be a IProject, check if its a java package
+ if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+ return element.getElementName();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the test class stored in the launch configuration.
+ *
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the test class info from
+ * @return the test class. <code>null</code> if not specified.
+ */
+ private String getTestClass(ILaunchConfiguration configuration) {
+ return getStringLaunchAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
+ configuration);
+ }
+
+ /**
+ * Returns the test method stored in the launch configuration.
+ *
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the test method info from
+ * @return the test method. <code>null</code> if not specified.
+ */
+ private String getTestMethod(ILaunchConfiguration configuration) {
+ return getStringLaunchAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
+ configuration);
+ }
+
+ /**
+ * Returns the test sizes to run as saved in the launch configuration.
+ * @return {@link TestSize} if only tests of specific sizes should be run,
+ * null if all tests should be run
+ */
+ private TestSize getTestSize(ILaunchConfiguration configuration) {
+ String testSizeAnnotation = getStringLaunchAttribute(
+ AndroidJUnitLaunchConfigDelegate.ATTR_TEST_SIZE,
+ configuration);
+ if (AndroidJUnitLaunchConfigurationTab.SMALL_TEST_ANNOTATION.equals(
+ testSizeAnnotation)){
+ return TestSize.SMALL;
+ } else if (AndroidJUnitLaunchConfigurationTab.MEDIUM_TEST_ANNOTATION.equals(
+ testSizeAnnotation)) {
+ return TestSize.MEDIUM;
+ } else if (AndroidJUnitLaunchConfigurationTab.LARGE_TEST_ANNOTATION.equals(
+ testSizeAnnotation)) {
+ return TestSize.LARGE;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 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>, and will log an error
+ * to the console.
+ *
+ * @param project the {@link IProject} for the app
+ * @param configuration the {@link ILaunchConfiguration} for the launch
+ * @param manifestData the {@link ManifestData} 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,
+ ManifestData manifestData) {
+ try {
+ String runner = getRunnerFromConfig(configuration);
+ if (runner != null) {
+ return runner;
+ }
+ final InstrumentationRunnerValidator instrFinder = new InstrumentationRunnerValidator(
+ BaseProjectHelper.getJavaProject(project), manifestData);
+ runner = instrFinder.getValidInstrumentationTestRunner();
+ if (runner != null) {
+ AdtPlugin.printErrorToConsole(project, String.format(
+ LaunchMessages.AndroidJUnitDelegate_NoRunnerConfigMsg_s, runner));
+ return runner;
+ }
+ AdtPlugin.printErrorToConsole(project, String.format(
+ LaunchMessages.AndroidJUnitDelegate_NoRunnerConsoleMsg_4s,
+ project.getName(),
+ SdkConstants.CLASS_INSTRUMENTATION_RUNNER,
+ AdtConstants.LIBRARY_TEST_RUNNER,
+ SdkConstants.FN_ANDROID_MANIFEST_XML));
+ return null;
+ } catch (CoreException e) {
+ AdtPlugin.log(e, "Error when retrieving instrumentation info"); //$NON-NLS-1$
+ }
+
+ return null;
+ }
+
+ private String getRunnerFromConfig(ILaunchConfiguration configuration) {
+ return getStringLaunchAttribute(ATTR_INSTR_NAME, configuration);
+ }
+
+ /**
+ * Helper method to retrieve a string attribute from the launch configuration
+ *
+ * @param attributeName name of the launch attribute
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the attribute from
+ * @return the attribute's value. <code>null</code> if not found.
+ */
+ private String getStringLaunchAttribute(String attributeName,
+ ILaunchConfiguration configuration) {
+ try {
+ String attrValue = configuration.getAttribute(attributeName, EMPTY_STRING);
+ if (attrValue.length() < 1) {
+ return null;
+ }
+ return attrValue;
+ } catch (CoreException e) {
+ AdtPlugin.log(e, String.format("Error when retrieving launch info %1$s", //$NON-NLS-1$
+ attributeName));
+ }
+ return null;
+ }
+
+ /**
+ * Helper method to set JUnit-related attributes expected by JDT JUnit runner
+ *
+ * @param config the launch configuration to modify
+ */
+ static void setJUnitDefaults(ILaunchConfigurationWorkingCopy config) {
+ // set the test runner to JUnit3 to placate JDT JUnit runner logic
+ config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND,
+ TestKindRegistry.JUNIT3_TEST_KIND_ID);
+ }
+}