1 /*
2  * Copyright (C) 2014 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.tradefed.result;
18 
19 import com.android.cts.tradefed.device.DeviceInfoCollector;
20 import com.android.cts.util.AbiUtils;
21 import com.android.ddmlib.Log;
22 import com.android.ddmlib.Log.LogLevel;
23 import com.android.ddmlib.testrunner.TestIdentifier;
24 import com.android.tradefed.build.IBuildInfo;
25 import com.android.tradefed.config.Option;
26 import com.android.tradefed.config.OptionCopier;
27 import com.android.tradefed.log.LogUtil.CLog;
28 import com.android.tradefed.result.IShardableListener;
29 import com.android.tradefed.result.StubTestInvocationListener;
30 
31 import java.util.Map;
32 
33 /**
34  * Dumps tests in progress to stdout
35  */
36 public class CtsTestLogReporter extends StubTestInvocationListener implements IShardableListener {
37 
38     @Option(name = "quiet-output", description = "Mute display of test results.")
39     private boolean mQuietOutput = false;
40 
41     protected IBuildInfo mBuildInfo;
42     private String mDeviceSerial;
43     private TestResults mResults = new TestResults();
44     private TestPackageResult mCurrentPkgResult = null;
45     private boolean mIsDeviceInfoRun = false;
46     private boolean mIsExtendedDeviceInfoRun = false;
47 
48     @Override
invocationStarted(IBuildInfo buildInfo)49     public void invocationStarted(IBuildInfo buildInfo) {
50         mDeviceSerial = buildInfo.getDeviceSerial() == null ? "unknown_device" : buildInfo.getDeviceSerial();
51     }
52 
53     /**
54      * Reports the start of a test run.
55      *
56      * @param id the unique identifier of this test run, generated by
57      * {@link AbiUtils#createId(String, String)}.
58      * @param numTests total number of tests in test run
59      */
60     @Override
testRunStarted(String id, int numTests)61     public void testRunStarted(String id, int numTests) {
62         if (mCurrentPkgResult != null && !id.equals(mCurrentPkgResult.getId())) {
63             // display results from previous run
64             logCompleteRun(mCurrentPkgResult);
65         }
66         mIsDeviceInfoRun = DeviceInfoCollector.IDS.contains(id);
67         mIsExtendedDeviceInfoRun = DeviceInfoCollector.EXTENDED_IDS.contains(id);
68         if (mIsDeviceInfoRun) {
69             logResult("Collecting device info");
70         } else if (mIsExtendedDeviceInfoRun) {
71             logResult("Collecting extended device info");
72         } else  {
73             if (mCurrentPkgResult == null || !id.equals(mCurrentPkgResult.getId())) {
74                 logResult("-----------------------------------------");
75                 logResult("Test package %s started", id);
76                 logResult("-----------------------------------------");
77             }
78             mCurrentPkgResult = mResults.getOrCreatePackage(id);
79         }
80     }
81 
82     /**
83      * {@inheritDoc}
84      */
85     @Override
testStarted(TestIdentifier test)86     public void testStarted(TestIdentifier test) {
87         mCurrentPkgResult.insertTest(test);
88     }
89 
90     /**
91      * {@inheritDoc}
92      */
93     @Override
testFailed(TestIdentifier test, String trace)94     public void testFailed(TestIdentifier test, String trace) {
95         mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
96     }
97 
98     /**
99      * {@inheritDoc}
100      */
101     @Override
testAssumptionFailure(TestIdentifier test, String trace)102     public void testAssumptionFailure(TestIdentifier test, String trace) {
103         // TODO: do something different here?
104         mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
105     }
106 
107     /**
108      * {@inheritDoc}
109      */
110     @Override
testEnded(TestIdentifier test, Map<String, String> testMetrics)111     public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
112         mCurrentPkgResult.reportTestEnded(test, testMetrics);
113         Test result = mCurrentPkgResult.findTest(test);
114         String stack = result.getStackTrace() == null ? "" : "\n" + result.getStackTrace();
115         logResult("%s#%s %s %s", test.getClassName(), test.getTestName(), result.getResult(),
116                 stack);
117     }
118 
119     /**
120      * {@inheritDoc}
121      */
122     @Override
invocationEnded(long elapsedTime)123     public void invocationEnded(long elapsedTime) {
124         // display the results of the last completed run
125         if (mCurrentPkgResult != null) {
126             logCompleteRun(mCurrentPkgResult);
127         }
128     }
129 
logResult(String format, Object... args)130     private void logResult(String format, Object... args) {
131         if (mQuietOutput) {
132             CLog.i(format, args);
133         } else {
134             Log.logAndDisplay(LogLevel.INFO, mDeviceSerial, String.format(format, args));
135         }
136     }
137 
logCompleteRun(TestPackageResult pkgResult)138     private void logCompleteRun(TestPackageResult pkgResult) {
139         String appPackageName = pkgResult.getAppPackageName();
140         if (appPackageName.equals(DeviceInfoCollector.APP_PACKAGE_NAME)) {
141             logResult("Device info collection complete");
142             return;
143         } else if (appPackageName.equals(DeviceInfoCollector.EXTENDED_APP_PACKAGE_NAME)) {
144             logResult("Extended device info collection complete");
145             return;
146         }
147         logResult("%s package complete: Passed %d, Failed %d, Not Executed %d",
148                 pkgResult.getId(), pkgResult.countTests(CtsTestStatus.PASS),
149                 pkgResult.countTests(CtsTestStatus.FAIL),
150                 pkgResult.countTests(CtsTestStatus.NOT_EXECUTED));
151     }
152 
153     @Override
clone()154     public IShardableListener clone() {
155         CtsTestLogReporter clone = new CtsTestLogReporter();
156         OptionCopier.copyOptionsNoThrow(this, clone);
157         return clone;
158     }
159 }
160