1 /* 2 * Copyright (C) 2008 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 */ 16 17 package com.android.cts; 18 19 import java.util.TimerTask; 20 21 import com.android.cts.TestSession.ResultObserver; 22 23 /** 24 * Correspond to junit's test method, provide functions on storing 25 * and executing a test from CTS test harness. 26 */ 27 public class Test implements DeviceObserver { 28 public static final String METHOD_SEPARATOR = "#"; 29 30 private TestController mTestController; 31 private TestCase mParentCase; 32 private String mName; 33 private String mType; 34 private String mKnownFailure; 35 private long mStartTime; 36 private long mEndTime; 37 38 protected boolean mTestStop; 39 protected TestDevice mDevice; 40 protected HostTimer mTimeOutTimer; 41 protected ProgressObserver mProgressObserver; 42 protected CtsTestResult mResult; 43 Test(final TestCase parentCase, final String name, final String type, final String knownFailure, final int resCode)44 public Test(final TestCase parentCase, final String name, 45 final String type, final String knownFailure, final int resCode) { 46 mParentCase = parentCase; 47 mName = name; 48 mType = type; 49 mKnownFailure = knownFailure; 50 mResult = new CtsTestResult(resCode); 51 52 mTestController = null; 53 mProgressObserver = null; 54 mTestStop = false; 55 } 56 57 /** 58 * Check if it's known failure test. 59 * 60 * @return If known failure test, return true; else, return false. 61 */ isKnownFailure()62 public boolean isKnownFailure() { 63 return (mKnownFailure != null); 64 } 65 66 /** 67 * Get the known failure description. 68 * 69 * @return The known failure description. 70 */ getKnownFailure()71 public String getKnownFailure() { 72 return mKnownFailure; 73 } 74 75 /** 76 * Set the test controller. 77 * 78 * @param testController The test controller. 79 */ setTestController(final TestController testController)80 public void setTestController(final TestController testController) { 81 mTestController = testController; 82 } 83 84 /** 85 * Get the test controller. 86 * 87 * @return The test controller. 88 */ getTestController()89 public TestController getTestController() { 90 return mTestController; 91 } 92 93 /** 94 * Get the instrumentation runner. 95 * 96 * @return The instrumentation runner. 97 */ getInstrumentationRunner()98 public String getInstrumentationRunner() { 99 TestPackage pkg = mParentCase.getParent().getParent(); 100 return pkg.getInstrumentationRunner(); 101 } 102 103 /** 104 * Get the test name of this test. 105 * 106 * @return The test name of this test. 107 */ getName()108 public String getName() { 109 return mName; 110 } 111 112 /** 113 * Get the test type of this test. 114 * 115 * @return The test type of this test. 116 */ getType()117 public String getType() { 118 return mType; 119 } 120 121 /** 122 * Get the parent TestCase containing the test. 123 * 124 * @return The parent TestCase. 125 */ getTestCase()126 public TestCase getTestCase() { 127 return mParentCase; 128 } 129 130 /** 131 * Get the parent TestSuite containing the test. 132 * 133 * @return The parent TestSuite. 134 */ getTestSuite()135 public TestSuite getTestSuite() { 136 return mParentCase.getParent(); 137 } 138 139 /** 140 * Get the parent TestPackage containing the test. 141 * 142 * @return The parent TestPackage. 143 */ getTestPackage()144 public TestPackage getTestPackage() { 145 return mParentCase.getParent().getParent(); 146 } 147 148 /** 149 * Get the app package name space of this test. 150 * 151 * @return The app package name space of this test. 152 */ getAppNameSpace()153 public String getAppNameSpace() { 154 TestPackage pkg = mParentCase.getParent().getParent(); 155 return pkg.getAppNameSpace(); 156 } 157 158 /** 159 * Get the full name of this test. 160 * 161 * @return The full name of this test. 162 */ getFullName()163 public String getFullName() { 164 TestSuite suite = mParentCase.getParent(); 165 return suite.getFullName() + "." + mParentCase.getName() 166 + METHOD_SEPARATOR + mName; 167 } 168 169 /** 170 * Set test result. 171 * 172 * @param result The result. 173 */ setResult(CtsTestResult result)174 public void setResult(CtsTestResult result) { 175 if (isKnownFailure()) { 176 result.reverse(); 177 } 178 mResult = result; 179 CUIOutputStream.println("(" + mResult.getResultString() + ")"); 180 if (!mResult.isPass()) { 181 String failedMessage = result.getFailedMessage(); 182 String stackTrace = result.getStackTrace(); 183 if (failedMessage != null) { 184 CUIOutputStream.println(failedMessage); 185 } 186 if (stackTrace != null) { 187 CUIOutputStream.println(stackTrace); 188 } 189 } 190 setEndTime(System.currentTimeMillis()); 191 192 ResultObserver.getInstance().notifyUpdate(); 193 } 194 195 /** 196 * Add test result. 197 * 198 * @param result The result. 199 */ addResult(CtsTestResult result)200 public void addResult(CtsTestResult result) { 201 if (isKnownFailure()) { 202 result.reverse(); 203 } 204 mResult = result; 205 } 206 207 /** 208 * Get the result. 209 * 210 * @return the result. 211 */ getResult()212 public CtsTestResult getResult() { 213 return mResult; 214 } 215 216 /** 217 * Set start Test time. 218 * 219 * @param time The start time. 220 */ setStartTime(final long time)221 public void setStartTime(final long time) { 222 mStartTime = time; 223 } 224 225 /** 226 * Set end Test time. 227 * 228 * @param time The end time. 229 */ setEndTime(final long time)230 public void setEndTime(final long time) { 231 mEndTime = time; 232 } 233 234 /** 235 * Get Test start time. 236 * 237 * @return The start time. 238 */ getStartTime()239 public long getStartTime() { 240 return mStartTime; 241 } 242 243 /** 244 * Get Test end time. 245 * 246 * @return The end time. 247 */ getEndTime()248 public long getEndTime() { 249 return mEndTime; 250 } 251 252 /** 253 * Print the message without appending the new line mark. 254 * 255 * @param msg the message to be print. 256 */ print(final String msg)257 protected void print(final String msg) { 258 if (!mTestStop) { 259 CUIOutputStream.print(msg); 260 } 261 } 262 263 /** 264 * The timer task which aids in guarding the running test 265 * with the guarding timer. If the executing of the test 266 * is not finished, and the guarding timer is expired, 267 * this task will be executed to force the finish of the 268 * running test. 269 */ 270 class TimeOutTask extends TimerTask { 271 private Test mTest; 272 TimeOutTask(final Test testResult)273 public TimeOutTask(final Test testResult) { 274 mTest = testResult; 275 } 276 277 /** {@inheritDoc} */ 278 @Override run()279 public void run() { 280 mProgressObserver.stop(); 281 synchronized (mTimeOutTimer) { 282 mTimeOutTimer.cancel(true); 283 mTimeOutTimer.sendNotify(); 284 } 285 286 Log.d("mTimeOutTimer timed out"); 287 288 if (!mTestStop) { 289 mTest.setResult( 290 new CtsTestResult(CtsTestResult.CODE_TIMEOUT, null, null)); 291 } 292 293 killDeviceProcess(mTest.getAppNameSpace()); 294 } 295 } 296 297 /** 298 * Kill the device process. 299 * 300 * @param packageName The package name. 301 */ killDeviceProcess(final String packageName)302 private void killDeviceProcess(final String packageName) { 303 mDevice.killProcess(packageName); 304 } 305 306 /** 307 * Set test stopped. 308 * 309 * @param testStopped If true, it's stopped. Else, still running. 310 */ setTestStopped(final boolean testStopped)311 public void setTestStopped(final boolean testStopped) { 312 mTestStop = testStopped; 313 } 314 315 /** 316 * Run the test over device given. 317 * 318 * @param device the device to run the test. 319 */ run(final TestDevice device)320 public void run(final TestDevice device) throws DeviceDisconnectedException, 321 ADBServerNeedRestartException { 322 323 if ((getName() == null) || (getName().length() == 0)) { 324 return; 325 } 326 327 if (TestSession.exceedsMaxCount()) { 328 throw new ADBServerNeedRestartException("Test count reached overflow point"); 329 } else { 330 TestSession.incTestCount(); 331 } 332 333 mTestStop = false; 334 mDevice = device; 335 mTimeOutTimer = new HostTimer(new TimeOutTask(this), 336 HostConfig.Ints.individualStartTimeoutMs.value()); 337 mTimeOutTimer.start(); 338 mProgressObserver = new ProgressObserver(); 339 mProgressObserver.start(); 340 341 setStartTime(System.currentTimeMillis()); 342 String testFullName = getFullName(); 343 print(testFullName + "..."); 344 345 runImpl(); 346 347 synchronized (mTimeOutTimer) { 348 if (!mTestStop) { 349 try { 350 mTimeOutTimer.waitOn(); 351 } catch (InterruptedException e) { 352 Log.d("time out object interrupted"); 353 } 354 } 355 356 mProgressObserver.stop(); 357 if (mTimeOutTimer.isTimeOut()) { 358 return; 359 } else { 360 //not caused by timer timing out 361 //need to cancel timer 362 mTimeOutTimer.cancel(false); 363 } 364 } 365 366 setResult(mResult); 367 } 368 369 /** 370 * Implementation of running test. 371 */ runImpl()372 protected void runImpl() throws DeviceDisconnectedException { 373 mDevice.runTest(this); 374 } 375 376 /** 377 * Notify the result. 378 * 379 * @param result The result. 380 */ notifyResult(CtsTestResult result)381 public void notifyResult(CtsTestResult result) { 382 383 Log.d("Test.notifyResult() is called. (Test.getFullName()=" + getFullName()); 384 mResult = result; 385 if (mTimeOutTimer != null) { 386 synchronized (mTimeOutTimer) { 387 // set result again in case timeout just happened 388 mResult = result; 389 Log.d("notifyUpdateResult() detects that it needs to cancel mTimeOutTimer"); 390 if (mTimeOutTimer != null) { 391 mTimeOutTimer.sendNotify(); 392 } 393 } 394 } 395 } 396 397 /** {@inheritDoc} */ notifyInstallingComplete(final int resultCode)398 public void notifyInstallingComplete(final int resultCode) { 399 } 400 401 /** {@inheritDoc} */ notifyUninstallingComplete(final int resultCode)402 public void notifyUninstallingComplete(final int resultCode) { 403 } 404 405 /** {@inheritDoc} */ notifyInstallingTimeout(final TestDevice testDevice)406 public void notifyInstallingTimeout(final TestDevice testDevice) { 407 } 408 409 /** {@inheritDoc} */ notifyUninstallingTimeout(final TestDevice testDevice)410 public void notifyUninstallingTimeout(final TestDevice testDevice) { 411 } 412 413 /** {@inheritDoc} */ notifyTestingDeviceDisconnected()414 public void notifyTestingDeviceDisconnected() { 415 Log.d("Test.notifyTestingDeviceDisconnected() is called"); 416 if (mProgressObserver != null) { 417 mProgressObserver.stop(); 418 } 419 420 if (mTimeOutTimer != null) { 421 synchronized (mTimeOutTimer) { 422 mTimeOutTimer.cancel(false); 423 mTimeOutTimer.sendNotify(); 424 } 425 } 426 } 427 } 428 429