Home | History | Annotate | Download | only in cts
      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 com.android.cts.TestSession.ResultObserver;
     20 
     21 import java.util.TimerTask;
     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 
     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      */
     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      */
     71     public String getKnownFailure() {
     72         return mKnownFailure;
     73     }
     74 
     75     /**
     76      * Set the test controller.
     77      *
     78      * @param testController The test controller.
     79      */
     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      */
     89     public TestController getTestController() {
     90         return mTestController;
     91     }
     92 
     93     /**
     94      * Get the instrumentation runner.
     95      *
     96      * @return The instrumentation runner.
     97      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    212     public CtsTestResult getResult() {
    213         return mResult;
    214     }
    215 
    216     /**
    217      * Set start Test time.
    218      *
    219      * @param time The start time.
    220      */
    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      */
    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      */
    239     public long getStartTime() {
    240         return mStartTime;
    241     }
    242 
    243     /**
    244      * Get Test end time.
    245      *
    246      * @return The end time.
    247      */
    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      */
    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 
    273         public TimeOutTask(final Test testResult) {
    274             mTest = testResult;
    275         }
    276 
    277         /** {@inheritDoc} */
    278         @Override
    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      */
    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      */
    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      */
    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      */
    372     protected void runImpl() throws DeviceDisconnectedException {
    373         mDevice.runTest(this);
    374     }
    375 
    376     /**
    377      * Notify the result.
    378      *
    379      * @param result The result.
    380      */
    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} */
    398     public void notifyInstallingComplete(final int resultCode) {
    399     }
    400 
    401     /** {@inheritDoc} */
    402     public void notifyUninstallingComplete(final int resultCode) {
    403     }
    404 
    405     /** {@inheritDoc} */
    406     public void notifyInstallingTimeout(final TestDevice testDevice) {
    407     }
    408 
    409     /** {@inheritDoc} */
    410     public void notifyUninstallingTimeout(final TestDevice testDevice) {
    411     }
    412 
    413     /** {@inheritDoc} */
    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