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.ide.eclipse.adt.AdtConstants; 19 import com.android.ide.eclipse.adt.internal.launch.LaunchMessages; 20 import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; 21 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; 22 import com.android.sdklib.SdkConstants; 23 import com.android.sdklib.xml.ManifestData; 24 import com.android.sdklib.xml.ManifestData.Instrumentation; 25 import com.android.sdklib.xml.ManifestData.UsesLibrary; 26 27 import org.eclipse.core.resources.IProject; 28 import org.eclipse.core.runtime.CoreException; 29 import org.eclipse.jdt.core.IJavaProject; 30 31 /** 32 * Provides validation for Android instrumentation test runner 33 */ 34 class InstrumentationRunnerValidator { 35 private final IJavaProject mJavaProject; 36 private String[] mInstrumentationNames = null; 37 private boolean mHasRunnerLibrary = false; 38 39 static final String INSTRUMENTATION_OK = null; 40 41 /** 42 * Initializes the InstrumentationRunnerValidator. 43 * 44 * @param javaProject the {@link IJavaProject} for the Android project to validate 45 */ 46 InstrumentationRunnerValidator(IJavaProject javaProject) { 47 mJavaProject = javaProject; 48 ManifestData manifestData = AndroidManifestHelper.parseForData(javaProject.getProject()); 49 init(manifestData); 50 } 51 52 /** 53 * Initializes the InstrumentationRunnerValidator. 54 * 55 * @param project the {@link IProject} for the Android project to validate 56 * @throws CoreException if a fatal error occurred in initialization 57 */ 58 InstrumentationRunnerValidator(IProject project) throws CoreException { 59 this(BaseProjectHelper.getJavaProject(project)); 60 } 61 62 /** 63 * Initializes the InstrumentationRunnerValidator with an existing {@link AndroidManifestHelper} 64 * 65 * @param javaProject the {@link IJavaProject} for the Android project to validate 66 * @param manifestData the {@link ManifestData} for the Android project 67 */ 68 InstrumentationRunnerValidator(IJavaProject javaProject, ManifestData manifestData) { 69 mJavaProject = javaProject; 70 init(manifestData); 71 } 72 73 private void init(ManifestData manifestData) { 74 Instrumentation[] instrumentations = manifestData.getInstrumentations(); 75 mInstrumentationNames = new String[instrumentations.length]; 76 for (int i = 0; i < instrumentations.length; i++) { 77 mInstrumentationNames[i] = instrumentations[i].getName(); 78 } 79 mHasRunnerLibrary = hasTestRunnerLibrary(manifestData); 80 } 81 82 /** 83 * Helper method to determine if given manifest has a <code>AndroidConstants.LIBRARY_TEST_RUNNER 84 * </code> library reference 85 * 86 * @param manifestParser the {@link ManifestData} to search 87 * @return true if test runner library found, false otherwise 88 */ 89 private boolean hasTestRunnerLibrary(ManifestData manifestData) { 90 for (UsesLibrary lib : manifestData.getUsesLibraries()) { 91 if (AdtConstants.LIBRARY_TEST_RUNNER.equals(lib.getName())) { 92 return true; 93 } 94 } 95 return false; 96 } 97 98 /** 99 * Return the set of instrumentation names for the Android project. 100 * 101 * @return <code>null</code> if error occurred parsing instrumentations, otherwise returns array 102 * of instrumentation class names 103 */ 104 String[] getInstrumentationNames() { 105 return mInstrumentationNames; 106 } 107 108 /** 109 * Helper method to get the first instrumentation that can be used as a test runner. 110 * 111 * @return fully qualified instrumentation class name. <code>null</code> if no valid 112 * instrumentation can be found. 113 */ 114 String getValidInstrumentationTestRunner() { 115 for (String instrumentation : getInstrumentationNames()) { 116 if (validateInstrumentationRunner(instrumentation) == INSTRUMENTATION_OK) { 117 return instrumentation; 118 } 119 } 120 return null; 121 } 122 123 /** 124 * Helper method to determine if specified instrumentation can be used as a test runner 125 * 126 * @param instrumentation the instrumentation class name to validate. Assumes this 127 * instrumentation is one of {@link #getInstrumentationNames()} 128 * @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message 129 */ 130 String validateInstrumentationRunner(String instrumentation) { 131 if (!mHasRunnerLibrary) { 132 return String.format(LaunchMessages.InstrValidator_NoTestLibMsg_s, 133 AdtConstants.LIBRARY_TEST_RUNNER); 134 } 135 // check if this instrumentation is the standard test runner 136 if (!instrumentation.equals(SdkConstants.CLASS_INSTRUMENTATION_RUNNER)) { 137 // check if it extends the standard test runner 138 String result = BaseProjectHelper.testClassForManifest(mJavaProject, 139 instrumentation, SdkConstants.CLASS_INSTRUMENTATION_RUNNER, true); 140 if (result != BaseProjectHelper.TEST_CLASS_OK) { 141 return String.format( 142 LaunchMessages.InstrValidator_WrongRunnerTypeMsg_s, 143 SdkConstants.CLASS_INSTRUMENTATION_RUNNER); 144 } 145 } 146 return INSTRUMENTATION_OK; 147 } 148 } 149