• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.ide.eclipse.adt.internal.launch.junit;
17 
18 import com.android.SdkConstants;
19 import com.android.annotations.NonNull;
20 import com.android.annotations.Nullable;
21 import com.android.ide.common.xml.ManifestData;
22 import com.android.ide.common.xml.ManifestData.Instrumentation;
23 import com.android.ide.common.xml.ManifestData.UsesLibrary;
24 import com.android.ide.eclipse.adt.AdtConstants;
25 import com.android.ide.eclipse.adt.internal.launch.LaunchMessages;
26 import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
27 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
28 
29 import org.eclipse.core.resources.IProject;
30 import org.eclipse.core.runtime.CoreException;
31 import org.eclipse.jdt.core.IJavaProject;
32 
33 /**
34  * Provides validation for Android instrumentation test runner
35  */
36 class InstrumentationRunnerValidator {
37     private final IJavaProject mJavaProject;
38     private String[] mInstrumentationNames = null;
39     private boolean mHasRunnerLibrary = false;
40 
41     static final String INSTRUMENTATION_OK = null;
42 
43     /**
44      * Initializes the InstrumentationRunnerValidator.
45      *
46      * @param javaProject the {@link IJavaProject} for the Android project to validate
47      */
InstrumentationRunnerValidator(IJavaProject javaProject)48     InstrumentationRunnerValidator(IJavaProject javaProject) {
49         mJavaProject = javaProject;
50         ManifestData manifestData = AndroidManifestHelper.parseForData(javaProject.getProject());
51         init(manifestData);
52     }
53 
54     /**
55      * Initializes the InstrumentationRunnerValidator.
56      *
57      * @param project the {@link IProject} for the Android project to validate
58      * @throws CoreException if a fatal error occurred in initialization
59      */
InstrumentationRunnerValidator(IProject project)60     InstrumentationRunnerValidator(IProject project) throws CoreException {
61         this(BaseProjectHelper.getJavaProject(project));
62     }
63 
64     /**
65      * Initializes the InstrumentationRunnerValidator with an existing {@link AndroidManifestHelper}
66      *
67      * @param javaProject the {@link IJavaProject} for the Android project to validate
68      * @param manifestData the {@link ManifestData} for the Android project
69      */
InstrumentationRunnerValidator(IJavaProject javaProject, ManifestData manifestData)70     InstrumentationRunnerValidator(IJavaProject javaProject, ManifestData manifestData) {
71         mJavaProject = javaProject;
72         init(manifestData);
73     }
74 
init(ManifestData manifestData)75     private void init(ManifestData manifestData) {
76         if (manifestData == null) {
77             mInstrumentationNames = new String[0];
78             mHasRunnerLibrary = false;
79             return;
80         }
81 
82         Instrumentation[] instrumentations = manifestData.getInstrumentations();
83         mInstrumentationNames = new String[instrumentations.length];
84         for (int i = 0; i < instrumentations.length; i++) {
85             mInstrumentationNames[i] = instrumentations[i].getName();
86         }
87         mHasRunnerLibrary = hasTestRunnerLibrary(manifestData);
88     }
89 
90     /**
91      * Helper method to determine if given manifest has a <code>SdkConstants.LIBRARY_TEST_RUNNER
92      * </code> library reference
93      *
94      * @param manifestParser the {@link ManifestData} to search
95      * @return true if test runner library found, false otherwise
96      */
hasTestRunnerLibrary(ManifestData manifestData)97     private boolean hasTestRunnerLibrary(ManifestData manifestData) {
98        for (UsesLibrary lib : manifestData.getUsesLibraries()) {
99            if (AdtConstants.LIBRARY_TEST_RUNNER.equals(lib.getName())) {
100                return true;
101            }
102        }
103        return false;
104     }
105 
106     /**
107      * Return the set of instrumentation names for the Android project.
108      *
109      * @return array of instrumentation class names, possibly empty
110      */
111     @NonNull
getInstrumentationNames()112     String[] getInstrumentationNames() {
113         return mInstrumentationNames;
114     }
115 
116     /**
117      * Helper method to get the first instrumentation that can be used as a test runner.
118      *
119      * @return fully qualified instrumentation class name. <code>null</code> if no valid
120      * instrumentation can be found.
121      */
122     @Nullable
getValidInstrumentationTestRunner()123     String getValidInstrumentationTestRunner() {
124         for (String instrumentation : getInstrumentationNames()) {
125             if (validateInstrumentationRunner(instrumentation) == INSTRUMENTATION_OK) {
126                 return instrumentation;
127             }
128         }
129         return null;
130     }
131 
132     /**
133      * Helper method to determine if specified instrumentation can be used as a test runner
134      *
135      * @param instrumentation the instrumentation class name to validate. Assumes this
136      *   instrumentation is one of {@link #getInstrumentationNames()}
137      * @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message
138      */
validateInstrumentationRunner(String instrumentation)139     String validateInstrumentationRunner(String instrumentation) {
140         if (!mHasRunnerLibrary) {
141             return String.format(LaunchMessages.InstrValidator_NoTestLibMsg_s,
142                     AdtConstants.LIBRARY_TEST_RUNNER);
143         }
144         // check if this instrumentation is the standard test runner
145         if (!instrumentation.equals(SdkConstants.CLASS_INSTRUMENTATION_RUNNER)) {
146             // Ideally, we'd check if the class extends instrumentation test runner.
147             // However, the Google Instrumentation Test Runner extends Google Instrumentation, and not a test runner,
148             // so we just check that the super class is Instrumentation.
149             String result = BaseProjectHelper.testClassForManifest(mJavaProject,
150                     instrumentation, SdkConstants.CLASS_INSTRUMENTATION, true);
151              if (result != BaseProjectHelper.TEST_CLASS_OK) {
152                 return String.format(
153                         LaunchMessages.InstrValidator_WrongRunnerTypeMsg_s,
154                         SdkConstants.CLASS_INSTRUMENTATION);
155              }
156         }
157         return INSTRUMENTATION_OK;
158     }
159 }
160