blob: 8cccab01ad251a62473c21e1fa9f2ba16048dd2a [file] [log] [blame]
Brett Chabot3add9162010-09-12 17:23:05 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 */
Brett Chabot13638ab2011-10-16 13:59:03 -070016
Brett Chabot3add9162010-09-12 17:23:05 -070017package com.android.cts.tradefed.testtype;
18
Brett Chabot82d9daf2010-10-20 20:07:14 -070019import com.android.ddmlib.testrunner.TestIdentifier;
Brett Chabot58c43a82011-09-13 14:13:57 -070020import com.android.tradefed.log.LogUtil.CLog;
Brett Chabot3add9162010-09-12 17:23:05 -070021import com.android.tradefed.testtype.IRemoteTest;
22import com.android.tradefed.testtype.InstrumentationTest;
Brett Chabot58c43a82011-09-13 14:13:57 -070023import com.android.tradefed.util.StreamUtil;
Brett Chabot3add9162010-09-12 17:23:05 -070024
Brett Chabot58c43a82011-09-13 14:13:57 -070025import java.io.BufferedInputStream;
Brett Chabot3add9162010-09-12 17:23:05 -070026import java.io.File;
Brett Chabot58c43a82011-09-13 14:13:57 -070027import java.io.FileInputStream;
28import java.io.FileNotFoundException;
29import java.io.IOException;
30import java.io.InputStream;
31import java.security.DigestInputStream;
32import java.security.MessageDigest;
33import java.security.NoSuchAlgorithmException;
Brett Chabot82d9daf2010-10-20 20:07:14 -070034import java.util.Collection;
Brett Chabotef5a6042011-01-19 19:54:14 -080035import java.util.LinkedHashSet;
Brett Chabot3add9162010-09-12 17:23:05 -070036
37/**
38 * Container for CTS test info.
39 * <p/>
40 * Knows how to translate this info into a runnable {@link IRemoteTest}.
41 */
Brett Chabot4f8143c2010-12-14 18:29:44 -080042class TestPackageDef implements ITestPackageDef {
Brett Chabot3add9162010-09-12 17:23:05 -070043
Brett Chabot584d2b92011-02-03 17:56:49 -080044 private static final String SIGNATURE_TEST_METHOD = "testSignature";
45 private static final String SIGNATURE_TEST_CLASS = "android.tests.sigtest.SimpleSignatureTest";
Brett Chabot3add9162010-09-12 17:23:05 -070046
47 private String mUri = null;
48 private String mAppNameSpace = null;
49 private String mName = null;
50 private String mRunner = null;
51 private boolean mIsHostSideTest = false;
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -070052 private boolean mIsVMHostTest = false;
Brian Muramatsu88d32a82011-12-02 10:55:12 -080053 private String mTestType = null;
Brett Chabot3add9162010-09-12 17:23:05 -070054 private String mJarPath = null;
55 private boolean mIsSignatureTest = false;
56 private boolean mIsReferenceAppTest = false;
Brett Chabota0f443c2011-02-04 13:57:55 -080057 private String mPackageToTest = null;
58 private String mApkToTestName = null;
Brian Carlstrom022aff42011-05-17 23:16:51 -070059 private String mTestPackageName = null;
Brett Chabot58c43a82011-09-13 14:13:57 -070060 private String mDigest = null;
Brett Chabot3add9162010-09-12 17:23:05 -070061
Brett Chabot13638ab2011-10-16 13:59:03 -070062 // use a LinkedHashSet for predictable iteration insertion-order, and fast
63 // lookups
Brett Chabotef5a6042011-01-19 19:54:14 -080064 private Collection<TestIdentifier> mTests = new LinkedHashSet<TestIdentifier>();
65 // also maintain an index of known test classes
66 private Collection<String> mTestClasses = new LinkedHashSet<String>();
Brett Chabot4f8143c2010-12-14 18:29:44 -080067
Brett Chabot53e68a32011-10-05 14:14:55 -070068 // dynamic options, not parsed from package xml
69 private String mClassName;
70 private String mMethodName;
71 private TestFilter mExcludedTestFilter = new TestFilter();
Brett Chabot358dc562011-10-25 15:46:48 -070072 private String mTargetBinaryName;
73 private String mTargetNameSpace;
Brett Chabot53e68a32011-10-05 14:14:55 -070074
Brett Chabot3add9162010-09-12 17:23:05 -070075 void setUri(String uri) {
76 mUri = uri;
77 }
78
79 /**
Brett Chabot4f8143c2010-12-14 18:29:44 -080080 * {@inheritDoc}
Brett Chabot3add9162010-09-12 17:23:05 -070081 */
Brian Muramatsu88d32a82011-12-02 10:55:12 -080082 @Override
Brett Chabot3add9162010-09-12 17:23:05 -070083 public String getUri() {
84 return mUri;
85 }
86
87 void setAppNameSpace(String appNameSpace) {
88 mAppNameSpace = appNameSpace;
89 }
90
91 String getAppNameSpace() {
92 return mAppNameSpace;
93 }
94
95 void setName(String name) {
96 mName = name;
97 }
98
Brett Chabot58c43a82011-09-13 14:13:57 -070099 /**
100 * {@inheritDoc}
101 */
102 @Override
103 public String getName() {
Brett Chabot3add9162010-09-12 17:23:05 -0700104 return mName;
105 }
106
107 void setRunner(String runnerName) {
108 mRunner = runnerName;
109 }
110
111 String getRunner() {
112 return mRunner;
113 }
114
115 void setIsHostSideTest(boolean hostSideTest) {
116 mIsHostSideTest = hostSideTest;
117
118 }
119
120 boolean isHostSideTest() {
121 return mIsHostSideTest;
122 }
123
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700124 void setIsVMHostTest(boolean vmHostTest) {
125 mIsVMHostTest = vmHostTest;
126
127 }
128
129 boolean isVMHostTest() {
130 return mIsVMHostTest;
131 }
Brett Chabot13638ab2011-10-16 13:59:03 -0700132
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800133 void setTestType(String testType) {
134 mTestType = testType;
135 }
136
Brett Chabot3add9162010-09-12 17:23:05 -0700137 void setJarPath(String jarPath) {
138 mJarPath = jarPath;
139 }
140
141 String getJarPath() {
142 return mJarPath;
143 }
144
145 void setIsSignatureCheck(boolean isSignatureCheckTest) {
146 mIsSignatureTest = isSignatureCheckTest;
147 }
148
149 boolean isSignatureCheck() {
150 return mIsSignatureTest;
151 }
152
153 void setIsReferenceApp(boolean isReferenceApp) {
154 mIsReferenceAppTest = isReferenceApp;
155 }
156
157 boolean isReferenceApp() {
158 return mIsReferenceAppTest;
159 }
160
Brett Chabota0f443c2011-02-04 13:57:55 -0800161 void setPackageToTest(String packageName) {
162 mPackageToTest = packageName;
163 }
164
Brian Carlstrom022aff42011-05-17 23:16:51 -0700165 void setTestPackageName(String testPackageName) {
166 mTestPackageName = testPackageName;
167 }
168
Brett Chabota0f443c2011-02-04 13:57:55 -0800169 void setApkToTest(String apkName) {
170 mApkToTestName = apkName;
171 }
172
Brett Chabot358dc562011-10-25 15:46:48 -0700173 void setTargetBinaryName(String targetBinaryName) {
174 mTargetBinaryName = targetBinaryName;
175 }
176
177 void setTargetNameSpace(String targetNameSpace) {
178 mTargetNameSpace = targetNameSpace;
179 }
180
181 @Override
182 public String getTargetApkName() {
183 if (mTargetBinaryName != null && !mTargetBinaryName.isEmpty()) {
184 return String.format("%s.apk", mTargetBinaryName);
185 }
186 return null;
187 }
188
189 @Override
190 public String getTargetPackageName() {
191 if (mTargetNameSpace != null && mTargetNameSpace.isEmpty()) {
192 return null;
193 }
194 return mTargetNameSpace;
195 }
196
Brett Chabot3add9162010-09-12 17:23:05 -0700197 /**
Brett Chabot4f8143c2010-12-14 18:29:44 -0800198 * {@inheritDoc}
Brett Chabot3add9162010-09-12 17:23:05 -0700199 */
Brett Chabot53e68a32011-10-05 14:14:55 -0700200 @Override
201 public void setExcludedTestFilter(TestFilter excludeFilter) {
202 mExcludedTestFilter = excludeFilter;
203 }
204
205 /**
206 * {@inheritDoc}
207 */
208 @Override
209 public void setClassName(String className, String methodName) {
210 mClassName = className;
211 mMethodName = methodName;
212 }
213
214 /**
215 * {@inheritDoc}
216 */
217 @Override
218 public IRemoteTest createTest(File testCaseDir) {
219 mExcludedTestFilter.setTestInclusion(mClassName, mMethodName);
220 mTests = filterTests();
221
Brett Chabot3add9162010-09-12 17:23:05 -0700222 if (mIsHostSideTest) {
Brett Chabot13638ab2011-10-16 13:59:03 -0700223 CLog.d("Creating host test for %s", mName);
Brett Chabot82d9daf2010-10-20 20:07:14 -0700224 JarHostTest hostTest = new JarHostTest();
Brett Chabot58c43a82011-09-13 14:13:57 -0700225 hostTest.setRunName(getUri());
Brett Chabotf4bec732011-04-19 17:31:06 -0700226 hostTest.setJarFileName(mJarPath);
Brett Chabot53e68a32011-10-05 14:14:55 -0700227 hostTest.setTests(mTests);
Brett Chabot58c43a82011-09-13 14:13:57 -0700228 mDigest = generateDigest(testCaseDir, mJarPath);
Brett Chabot82d9daf2010-10-20 20:07:14 -0700229 return hostTest;
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700230 } else if (mIsVMHostTest) {
Brett Chabot13638ab2011-10-16 13:59:03 -0700231 CLog.d("Creating vm host test for %s", mName);
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700232 VMHostTest vmHostTest = new VMHostTest();
Brett Chabot58c43a82011-09-13 14:13:57 -0700233 vmHostTest.setRunName(getUri());
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700234 vmHostTest.setJarFileName(mJarPath);
Brett Chabot53e68a32011-10-05 14:14:55 -0700235 vmHostTest.setTests(mTests);
Brett Chabot58c43a82011-09-13 14:13:57 -0700236 mDigest = generateDigest(testCaseDir, mJarPath);
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700237 return vmHostTest;
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800238 } else if ("native".equals(mTestType)) {
239 return new GeeTest(mUri, mName);
Brett Chabot3add9162010-09-12 17:23:05 -0700240 } else if (mIsSignatureTest) {
Brett Chabot13638ab2011-10-16 13:59:03 -0700241 // TODO: hardcode the runner/class/method for now, since current package xml points to
242 // specialized instrumentation. Eventually this special case for signatureTest can be
243 // removed, and it can be treated just like a normal InstrumentationTest
244 CLog.d("Creating signature test %s", mName);
Brett Chabotf4bec732011-04-19 17:31:06 -0700245 InstrumentationApkTest instrTest = new InstrumentationApkTest();
Brett Chabot584d2b92011-02-03 17:56:49 -0800246 instrTest.setPackageName(mAppNameSpace);
247 instrTest.setRunnerName("android.test.InstrumentationTestRunner");
248 instrTest.setClassName(SIGNATURE_TEST_CLASS);
249 instrTest.setMethodName(SIGNATURE_TEST_METHOD);
Brett Chabot13638ab2011-10-16 13:59:03 -0700250 // set expected tests to the single signature test
251 TestIdentifier t = new TestIdentifier(SIGNATURE_TEST_CLASS, SIGNATURE_TEST_METHOD);
252 mTests.clear();
253 mTests.add(t);
Brett Chabot584d2b92011-02-03 17:56:49 -0800254 // mName means 'apk file name' for instrumentation tests
Brett Chabotf4bec732011-04-19 17:31:06 -0700255 instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
Brett Chabot58c43a82011-09-13 14:13:57 -0700256 mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
Brett Chabot584d2b92011-02-03 17:56:49 -0800257 return instrTest;
Brett Chabot3add9162010-09-12 17:23:05 -0700258 } else if (mIsReferenceAppTest) {
Brett Chabota0f443c2011-02-04 13:57:55 -0800259 // a reference app test is just a InstrumentationTest with one extra apk to install
Brett Chabot4263db42011-04-15 13:51:48 -0700260 InstrumentationApkTest instrTest = new InstrumentationApkTest();
261 instrTest.addInstallApk(String.format("%s.apk", mApkToTestName), mPackageToTest);
Brett Chabot53e68a32011-10-05 14:14:55 -0700262 return setInstrumentationTest(instrTest, testCaseDir);
Brett Chabota0f443c2011-02-04 13:57:55 -0800263 } else {
Brett Chabot13638ab2011-10-16 13:59:03 -0700264 CLog.d("Creating instrumentation test for %s", mName);
Brett Chabot4263db42011-04-15 13:51:48 -0700265 InstrumentationApkTest instrTest = new InstrumentationApkTest();
Brett Chabot53e68a32011-10-05 14:14:55 -0700266 return setInstrumentationTest(instrTest, testCaseDir);
Brett Chabot3add9162010-09-12 17:23:05 -0700267 }
268 }
Brett Chabot82d9daf2010-10-20 20:07:14 -0700269
270 /**
Brett Chabot13638ab2011-10-16 13:59:03 -0700271 * Populates given {@link InstrumentationApkTest} with data from the package xml.
Brett Chabota0f443c2011-02-04 13:57:55 -0800272 *
273 * @param testCaseDir
274 * @param className
275 * @param methodName
276 * @param instrTest
277 * @return the populated {@link InstrumentationTest} or <code>null</code>
278 */
Brett Chabot53e68a32011-10-05 14:14:55 -0700279 private InstrumentationTest setInstrumentationTest(InstrumentationApkTest instrTest,
280 File testCaseDir) {
Brett Chabot58c43a82011-09-13 14:13:57 -0700281 instrTest.setRunName(getUri());
Brett Chabota0f443c2011-02-04 13:57:55 -0800282 instrTest.setPackageName(mAppNameSpace);
283 instrTest.setRunnerName(mRunner);
Brian Carlstrom022aff42011-05-17 23:16:51 -0700284 instrTest.setTestPackageName(mTestPackageName);
Brett Chabot53e68a32011-10-05 14:14:55 -0700285 instrTest.setClassName(mClassName);
286 instrTest.setMethodName(mMethodName);
287 instrTest.setTestsToRun(mTests,
288 !mExcludedTestFilter.hasExclusion()
289 /* only force batch mode if no tests are excluded */);
Brett Chabota0f443c2011-02-04 13:57:55 -0800290 // mName means 'apk file name' for instrumentation tests
Brett Chabot4263db42011-04-15 13:51:48 -0700291 instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
Brett Chabot58c43a82011-09-13 14:13:57 -0700292 mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
Brett Chabot4263db42011-04-15 13:51:48 -0700293 if (mTests.size() > 1000) {
294 // TODO: hack, large test suites can take longer to collect tests, increase timeout
Brett Chabot13638ab2011-10-16 13:59:03 -0700295 instrTest.setCollectsTestsShellTimeout(10 * 60 * 1000);
Brett Chabota0f443c2011-02-04 13:57:55 -0800296 }
Brett Chabota0f443c2011-02-04 13:57:55 -0800297 return instrTest;
298 }
299
300 /**
Brett Chabot13638ab2011-10-16 13:59:03 -0700301 * Filter the tests to run based on list of excluded tests, class and method name.
Brett Chabotef5a6042011-01-19 19:54:14 -0800302 *
Brett Chabotef5a6042011-01-19 19:54:14 -0800303 * @return the filtered collection of tests
304 */
Brett Chabot53e68a32011-10-05 14:14:55 -0700305 private Collection<TestIdentifier> filterTests() {
306 mExcludedTestFilter.setTestInclusion(mClassName, mMethodName);
307 return mExcludedTestFilter.filter(mTests);
Brett Chabotef5a6042011-01-19 19:54:14 -0800308 }
309
310 /**
Brett Chabot4f8143c2010-12-14 18:29:44 -0800311 * {@inheritDoc}
312 */
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800313 @Override
Brett Chabot4f8143c2010-12-14 18:29:44 -0800314 public boolean isKnownTest(TestIdentifier testDef) {
315 return mTests.contains(testDef);
316 }
317
318 /**
Brett Chabotef5a6042011-01-19 19:54:14 -0800319 * {@inheritDoc}
320 */
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800321 @Override
Brett Chabotef5a6042011-01-19 19:54:14 -0800322 public boolean isKnownTestClass(String className) {
323 return mTestClasses.contains(className);
324 }
325
326 /**
Brett Chabot82d9daf2010-10-20 20:07:14 -0700327 * Add a {@link TestDef} to the list of tests in this package.
328 *
329 * @param testdef
330 */
331 void addTest(TestIdentifier testDef) {
332 mTests.add(testDef);
Brett Chabotef5a6042011-01-19 19:54:14 -0800333 mTestClasses.add(testDef.getClassName());
Brett Chabot82d9daf2010-10-20 20:07:14 -0700334 }
335
336 /**
337 * Get the collection of tests in this test package.
Brett Chabot82d9daf2010-10-20 20:07:14 -0700338 */
Brett Chabot1dcb9a52011-02-10 20:26:57 -0800339 @Override
340 public Collection<TestIdentifier> getTests() {
Brett Chabot82d9daf2010-10-20 20:07:14 -0700341 return mTests;
342 }
Brett Chabot58c43a82011-09-13 14:13:57 -0700343
344 /**
345 * {@inheritDoc}
346 */
347 @Override
348 public String getDigest() {
349 return mDigest;
350 }
351
352 /**
353 * Generate a sha1sum digest for a file.
354 * <p/>
355 * Exposed for unit testing.
356 *
357 * @param fileDir the directory of the file
358 * @param fileName the name of the file
359 * @return a hex {@link String} of the digest
360 */
Brett Chabot13638ab2011-10-16 13:59:03 -0700361 String generateDigest(File fileDir, String fileName) {
Brett Chabot58c43a82011-09-13 14:13:57 -0700362 final String algorithm = "SHA-1";
363 InputStream fileStream = null;
Brett Chabot13638ab2011-10-16 13:59:03 -0700364 DigestInputStream d = null;
Brett Chabot58c43a82011-09-13 14:13:57 -0700365 try {
366 fileStream = getFileStream(fileDir, fileName);
367 MessageDigest md = MessageDigest.getInstance(algorithm);
368 d = new DigestInputStream(fileStream, md);
369 byte[] buffer = new byte[8196];
370 while (d.read(buffer) != -1);
371 return toHexString(md.digest());
372 } catch (NoSuchAlgorithmException e) {
373 return algorithm + " not found";
374 } catch (IOException e) {
375 CLog.e(e);
376 } finally {
377 StreamUtil.closeStream(d);
378 StreamUtil.closeStream(fileStream);
379 }
380 return "failed to generate digest";
381 }
382
383 /**
384 * Retrieve an input stream for given file
385 * <p/>
386 * Exposed so unit tests can mock.
387 */
388 InputStream getFileStream(File fileDir, String fileName) throws FileNotFoundException {
389 InputStream fileStream;
390 fileStream = new BufferedInputStream(new FileInputStream(new File(fileDir, fileName)));
391 return fileStream;
392 }
393
394 /**
395 * Convert the given byte array into a lowercase hex string.
396 *
397 * @param arr The array to convert.
398 * @return The hex encoded string.
399 */
400 private String toHexString(byte[] arr) {
401 StringBuffer buf = new StringBuffer(arr.length * 2);
402 for (byte b : arr) {
403 buf.append(String.format("%02x", b & 0xFF));
404 }
405 return buf.toString();
406 }
Brett Chabot3add9162010-09-12 17:23:05 -0700407}