• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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