blob: db95aba080e4c25e371d880b50d4e8de5439c518 [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;
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -070051 private boolean mIsVMHostTest = false;
Brian Muramatsu88d32a82011-12-02 10:55:12 -080052 private String mTestType = null;
Brett Chabot3add9162010-09-12 17:23:05 -070053 private String mJarPath = null;
54 private boolean mIsSignatureTest = false;
Brian Carlstrom022aff42011-05-17 23:16:51 -070055 private String mTestPackageName = null;
Brett Chabot58c43a82011-09-13 14:13:57 -070056 private String mDigest = null;
Brett Chabot3add9162010-09-12 17:23:05 -070057
Brett Chabot13638ab2011-10-16 13:59:03 -070058 // use a LinkedHashSet for predictable iteration insertion-order, and fast
59 // lookups
Brett Chabotef5a6042011-01-19 19:54:14 -080060 private Collection<TestIdentifier> mTests = new LinkedHashSet<TestIdentifier>();
61 // also maintain an index of known test classes
62 private Collection<String> mTestClasses = new LinkedHashSet<String>();
Brett Chabot4f8143c2010-12-14 18:29:44 -080063
Brett Chabot53e68a32011-10-05 14:14:55 -070064 // dynamic options, not parsed from package xml
65 private String mClassName;
66 private String mMethodName;
67 private TestFilter mExcludedTestFilter = new TestFilter();
Brett Chabot358dc562011-10-25 15:46:48 -070068 private String mTargetBinaryName;
69 private String mTargetNameSpace;
Brett Chabot53e68a32011-10-05 14:14:55 -070070
Brett Chabot3add9162010-09-12 17:23:05 -070071 void setUri(String uri) {
72 mUri = uri;
73 }
74
75 /**
Brett Chabot4f8143c2010-12-14 18:29:44 -080076 * {@inheritDoc}
Brett Chabot3add9162010-09-12 17:23:05 -070077 */
Brian Muramatsu88d32a82011-12-02 10:55:12 -080078 @Override
Brett Chabot3add9162010-09-12 17:23:05 -070079 public String getUri() {
80 return mUri;
81 }
82
83 void setAppNameSpace(String appNameSpace) {
84 mAppNameSpace = appNameSpace;
85 }
86
87 String getAppNameSpace() {
88 return mAppNameSpace;
89 }
90
91 void setName(String name) {
92 mName = name;
93 }
94
Brett Chabot58c43a82011-09-13 14:13:57 -070095 /**
96 * {@inheritDoc}
97 */
98 @Override
99 public String getName() {
Brett Chabot3add9162010-09-12 17:23:05 -0700100 return mName;
101 }
102
103 void setRunner(String runnerName) {
104 mRunner = runnerName;
105 }
106
107 String getRunner() {
108 return mRunner;
109 }
110
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700111 void setIsVMHostTest(boolean vmHostTest) {
112 mIsVMHostTest = vmHostTest;
113
114 }
115
116 boolean isVMHostTest() {
117 return mIsVMHostTest;
118 }
Brett Chabot13638ab2011-10-16 13:59:03 -0700119
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800120 void setTestType(String testType) {
121 mTestType = testType;
122 }
123
Brett Chabot3add9162010-09-12 17:23:05 -0700124 void setJarPath(String jarPath) {
125 mJarPath = jarPath;
126 }
127
128 String getJarPath() {
129 return mJarPath;
130 }
131
132 void setIsSignatureCheck(boolean isSignatureCheckTest) {
133 mIsSignatureTest = isSignatureCheckTest;
134 }
135
136 boolean isSignatureCheck() {
137 return mIsSignatureTest;
138 }
139
Brian Carlstrom022aff42011-05-17 23:16:51 -0700140 void setTestPackageName(String testPackageName) {
141 mTestPackageName = testPackageName;
142 }
143
Brett Chabot358dc562011-10-25 15:46:48 -0700144 void setTargetBinaryName(String targetBinaryName) {
145 mTargetBinaryName = targetBinaryName;
146 }
147
148 void setTargetNameSpace(String targetNameSpace) {
149 mTargetNameSpace = targetNameSpace;
150 }
151
152 @Override
153 public String getTargetApkName() {
154 if (mTargetBinaryName != null && !mTargetBinaryName.isEmpty()) {
155 return String.format("%s.apk", mTargetBinaryName);
156 }
157 return null;
158 }
159
160 @Override
161 public String getTargetPackageName() {
162 if (mTargetNameSpace != null && mTargetNameSpace.isEmpty()) {
163 return null;
164 }
165 return mTargetNameSpace;
166 }
167
Brett Chabot3add9162010-09-12 17:23:05 -0700168 /**
Brett Chabot4f8143c2010-12-14 18:29:44 -0800169 * {@inheritDoc}
Brett Chabot3add9162010-09-12 17:23:05 -0700170 */
Brett Chabot53e68a32011-10-05 14:14:55 -0700171 @Override
172 public void setExcludedTestFilter(TestFilter excludeFilter) {
173 mExcludedTestFilter = excludeFilter;
174 }
175
176 /**
177 * {@inheritDoc}
178 */
179 @Override
180 public void setClassName(String className, String methodName) {
181 mClassName = className;
182 mMethodName = methodName;
183 }
184
185 /**
186 * {@inheritDoc}
187 */
188 @Override
189 public IRemoteTest createTest(File testCaseDir) {
190 mExcludedTestFilter.setTestInclusion(mClassName, mMethodName);
191 mTests = filterTests();
192
Brian Muramatsu5df641c2011-12-28 15:46:57 -0800193 if ("hostSideOnly".equals(mTestType)) {
Brett Chabot13638ab2011-10-16 13:59:03 -0700194 CLog.d("Creating host test for %s", mName);
Brett Chabot82d9daf2010-10-20 20:07:14 -0700195 JarHostTest hostTest = new JarHostTest();
Brett Chabot58c43a82011-09-13 14:13:57 -0700196 hostTest.setRunName(getUri());
Brett Chabotf4bec732011-04-19 17:31:06 -0700197 hostTest.setJarFileName(mJarPath);
Brett Chabot53e68a32011-10-05 14:14:55 -0700198 hostTest.setTests(mTests);
Brett Chabot58c43a82011-09-13 14:13:57 -0700199 mDigest = generateDigest(testCaseDir, mJarPath);
Brett Chabot82d9daf2010-10-20 20:07:14 -0700200 return hostTest;
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700201 } else if (mIsVMHostTest) {
Brett Chabot13638ab2011-10-16 13:59:03 -0700202 CLog.d("Creating vm host test for %s", mName);
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700203 VMHostTest vmHostTest = new VMHostTest();
Brett Chabot58c43a82011-09-13 14:13:57 -0700204 vmHostTest.setRunName(getUri());
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700205 vmHostTest.setJarFileName(mJarPath);
Brett Chabot53e68a32011-10-05 14:14:55 -0700206 vmHostTest.setTests(mTests);
Brett Chabot58c43a82011-09-13 14:13:57 -0700207 mDigest = generateDigest(testCaseDir, mJarPath);
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700208 return vmHostTest;
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800209 } else if ("native".equals(mTestType)) {
210 return new GeeTest(mUri, mName);
Brett Chabot3add9162010-09-12 17:23:05 -0700211 } else if (mIsSignatureTest) {
Brett Chabot13638ab2011-10-16 13:59:03 -0700212 // TODO: hardcode the runner/class/method for now, since current package xml points to
213 // specialized instrumentation. Eventually this special case for signatureTest can be
214 // removed, and it can be treated just like a normal InstrumentationTest
215 CLog.d("Creating signature test %s", mName);
Brett Chabotf4bec732011-04-19 17:31:06 -0700216 InstrumentationApkTest instrTest = new InstrumentationApkTest();
Brett Chabot584d2b92011-02-03 17:56:49 -0800217 instrTest.setPackageName(mAppNameSpace);
218 instrTest.setRunnerName("android.test.InstrumentationTestRunner");
219 instrTest.setClassName(SIGNATURE_TEST_CLASS);
220 instrTest.setMethodName(SIGNATURE_TEST_METHOD);
Brett Chabot13638ab2011-10-16 13:59:03 -0700221 // set expected tests to the single signature test
222 TestIdentifier t = new TestIdentifier(SIGNATURE_TEST_CLASS, SIGNATURE_TEST_METHOD);
223 mTests.clear();
224 mTests.add(t);
Brett Chabot584d2b92011-02-03 17:56:49 -0800225 // mName means 'apk file name' for instrumentation tests
Brett Chabotf4bec732011-04-19 17:31:06 -0700226 instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
Brett Chabot58c43a82011-09-13 14:13:57 -0700227 mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
Brett Chabot584d2b92011-02-03 17:56:49 -0800228 return instrTest;
Brett Chabota0f443c2011-02-04 13:57:55 -0800229 } else {
Brett Chabot13638ab2011-10-16 13:59:03 -0700230 CLog.d("Creating instrumentation test for %s", mName);
Brett Chabot4263db42011-04-15 13:51:48 -0700231 InstrumentationApkTest instrTest = new InstrumentationApkTest();
Brett Chabot53e68a32011-10-05 14:14:55 -0700232 return setInstrumentationTest(instrTest, testCaseDir);
Brett Chabot3add9162010-09-12 17:23:05 -0700233 }
234 }
Brett Chabot82d9daf2010-10-20 20:07:14 -0700235
236 /**
Brett Chabot13638ab2011-10-16 13:59:03 -0700237 * Populates given {@link InstrumentationApkTest} with data from the package xml.
Brett Chabota0f443c2011-02-04 13:57:55 -0800238 *
239 * @param testCaseDir
Brett Chabota0f443c2011-02-04 13:57:55 -0800240 * @param instrTest
241 * @return the populated {@link InstrumentationTest} or <code>null</code>
242 */
Brett Chabot53e68a32011-10-05 14:14:55 -0700243 private InstrumentationTest setInstrumentationTest(InstrumentationApkTest instrTest,
244 File testCaseDir) {
Brett Chabot58c43a82011-09-13 14:13:57 -0700245 instrTest.setRunName(getUri());
Brett Chabota0f443c2011-02-04 13:57:55 -0800246 instrTest.setPackageName(mAppNameSpace);
247 instrTest.setRunnerName(mRunner);
Brian Carlstrom022aff42011-05-17 23:16:51 -0700248 instrTest.setTestPackageName(mTestPackageName);
Brett Chabot53e68a32011-10-05 14:14:55 -0700249 instrTest.setClassName(mClassName);
250 instrTest.setMethodName(mMethodName);
251 instrTest.setTestsToRun(mTests,
252 !mExcludedTestFilter.hasExclusion()
253 /* only force batch mode if no tests are excluded */);
Brett Chabota0f443c2011-02-04 13:57:55 -0800254 // mName means 'apk file name' for instrumentation tests
Brett Chabot4263db42011-04-15 13:51:48 -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 Chabot4263db42011-04-15 13:51:48 -0700257 if (mTests.size() > 1000) {
258 // TODO: hack, large test suites can take longer to collect tests, increase timeout
Brett Chabot13638ab2011-10-16 13:59:03 -0700259 instrTest.setCollectsTestsShellTimeout(10 * 60 * 1000);
Brett Chabota0f443c2011-02-04 13:57:55 -0800260 }
Brett Chabota0f443c2011-02-04 13:57:55 -0800261 return instrTest;
262 }
263
264 /**
Brett Chabot13638ab2011-10-16 13:59:03 -0700265 * Filter the tests to run based on list of excluded tests, class and method name.
Brett Chabotef5a6042011-01-19 19:54:14 -0800266 *
Brett Chabotef5a6042011-01-19 19:54:14 -0800267 * @return the filtered collection of tests
268 */
Brett Chabot53e68a32011-10-05 14:14:55 -0700269 private Collection<TestIdentifier> filterTests() {
270 mExcludedTestFilter.setTestInclusion(mClassName, mMethodName);
271 return mExcludedTestFilter.filter(mTests);
Brett Chabotef5a6042011-01-19 19:54:14 -0800272 }
273
274 /**
Brett Chabot4f8143c2010-12-14 18:29:44 -0800275 * {@inheritDoc}
276 */
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800277 @Override
Brett Chabot4f8143c2010-12-14 18:29:44 -0800278 public boolean isKnownTest(TestIdentifier testDef) {
279 return mTests.contains(testDef);
280 }
281
282 /**
Brett Chabotef5a6042011-01-19 19:54:14 -0800283 * {@inheritDoc}
284 */
Brian Muramatsu88d32a82011-12-02 10:55:12 -0800285 @Override
Brett Chabotef5a6042011-01-19 19:54:14 -0800286 public boolean isKnownTestClass(String className) {
287 return mTestClasses.contains(className);
288 }
289
290 /**
Brian Muramatsu29d34782012-01-06 18:00:21 -0800291 * Add a {@link TestIdentifier} to the list of tests in this package.
Brett Chabot82d9daf2010-10-20 20:07:14 -0700292 *
Brian Muramatsu29d34782012-01-06 18:00:21 -0800293 * @param testDef
Brett Chabot82d9daf2010-10-20 20:07:14 -0700294 */
295 void addTest(TestIdentifier testDef) {
296 mTests.add(testDef);
Brett Chabotef5a6042011-01-19 19:54:14 -0800297 mTestClasses.add(testDef.getClassName());
Brett Chabot82d9daf2010-10-20 20:07:14 -0700298 }
299
300 /**
301 * Get the collection of tests in this test package.
Brett Chabot82d9daf2010-10-20 20:07:14 -0700302 */
Brett Chabot1dcb9a52011-02-10 20:26:57 -0800303 @Override
304 public Collection<TestIdentifier> getTests() {
Brett Chabot82d9daf2010-10-20 20:07:14 -0700305 return mTests;
306 }
Brett Chabot58c43a82011-09-13 14:13:57 -0700307
308 /**
309 * {@inheritDoc}
310 */
311 @Override
312 public String getDigest() {
313 return mDigest;
314 }
315
316 /**
317 * Generate a sha1sum digest for a file.
318 * <p/>
319 * Exposed for unit testing.
320 *
321 * @param fileDir the directory of the file
322 * @param fileName the name of the file
323 * @return a hex {@link String} of the digest
324 */
Brett Chabot13638ab2011-10-16 13:59:03 -0700325 String generateDigest(File fileDir, String fileName) {
Brett Chabot58c43a82011-09-13 14:13:57 -0700326 final String algorithm = "SHA-1";
327 InputStream fileStream = null;
Brett Chabot13638ab2011-10-16 13:59:03 -0700328 DigestInputStream d = null;
Brett Chabot58c43a82011-09-13 14:13:57 -0700329 try {
330 fileStream = getFileStream(fileDir, fileName);
331 MessageDigest md = MessageDigest.getInstance(algorithm);
332 d = new DigestInputStream(fileStream, md);
333 byte[] buffer = new byte[8196];
Brian Muramatsu29d34782012-01-06 18:00:21 -0800334 while (d.read(buffer) != -1) {
335 }
Brett Chabot58c43a82011-09-13 14:13:57 -0700336 return toHexString(md.digest());
337 } catch (NoSuchAlgorithmException e) {
338 return algorithm + " not found";
339 } catch (IOException e) {
340 CLog.e(e);
341 } finally {
342 StreamUtil.closeStream(d);
343 StreamUtil.closeStream(fileStream);
344 }
345 return "failed to generate digest";
346 }
347
348 /**
349 * Retrieve an input stream for given file
350 * <p/>
351 * Exposed so unit tests can mock.
352 */
353 InputStream getFileStream(File fileDir, String fileName) throws FileNotFoundException {
354 InputStream fileStream;
355 fileStream = new BufferedInputStream(new FileInputStream(new File(fileDir, fileName)));
356 return fileStream;
357 }
358
359 /**
360 * Convert the given byte array into a lowercase hex string.
361 *
362 * @param arr The array to convert.
363 * @return The hex encoded string.
364 */
365 private String toHexString(byte[] arr) {
366 StringBuffer buf = new StringBuffer(arr.length * 2);
367 for (byte b : arr) {
368 buf.append(String.format("%02x", b & 0xFF));
369 }
370 return buf.toString();
371 }
Brett Chabot3add9162010-09-12 17:23:05 -0700372}