• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.compatibility.common.tradefed.result;
18 
19 import com.android.ddmlib.Log.LogLevel;
20 import com.android.tradefed.config.Option;
21 import com.android.tradefed.config.OptionCopier;
22 import com.android.tradefed.device.ITestDevice;
23 import com.android.tradefed.invoker.IInvocationContext;
24 import com.android.tradefed.log.LogUtil.CLog;
25 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
26 import com.android.tradefed.result.IShardableListener;
27 import com.android.tradefed.result.TestDescription;
28 import com.android.tradefed.util.TimeUtil;
29 import com.android.tradefed.util.proto.TfMetricProtoUtil;
30 
31 import java.util.HashMap;
32 import java.util.Map;
33 
34 /**
35  * Write test progress to the test console.
36  */
37 public class ConsoleReporter implements IShardableListener {
38 
39     private static final String UNKNOWN_DEVICE = "unknown_device";
40 
41     @Option(name = "quiet-output", description = "Mute display of test results.")
42     private boolean mQuietOutput = false;
43 
44     private String mDeviceSerial = UNKNOWN_DEVICE;
45     private boolean mTestFailed;
46     private boolean mTestSkipped;
47 
48     private String mModuleId;
49     private int mCurrentTestNum;
50     private int mTotalTestsInModule;
51     private int mPassedTests;
52     private int mFailedTests;
53     private int mNotExecutedTests;
54 
55     /**
56      * {@inheritDoc}
57      */
58     @Override
invocationStarted(IInvocationContext context)59     public void invocationStarted(IInvocationContext context) {
60         if (context == null) {
61             CLog.w("InvocationContext should not be null");
62             return;
63         }
64         ITestDevice primaryDevice = context.getDevices().get(0);
65 
66         // Escape any "%" signs in the device serial.
67         mDeviceSerial = primaryDevice.getSerialNumber().replace("%", "%%");
68     }
69 
70     /**
71      * {@inheritDoc}
72      */
73     @Override
testRunStarted(String id, int numTests)74     public void testRunStarted(String id, int numTests) {
75         boolean isRepeatModule = (mModuleId != null && mModuleId.equals(id));
76         mModuleId = id;
77         mTotalTestsInModule = numTests;
78         // Reset counters
79         mCurrentTestNum = 0;
80         mPassedTests = 0;
81         mFailedTests = 0;
82         mNotExecutedTests = 0;
83         mTestFailed = false;
84         logMessage("%s %s with %d test%s", (isRepeatModule) ? "Continuing" : "Starting", id,
85                 mTotalTestsInModule, (mTotalTestsInModule > 1) ? "s" : "");
86     }
87 
88     /**
89      * {@inheritDoc}
90      */
91     @Override
testStarted(TestDescription test)92     public void testStarted(TestDescription test) {
93         mTestFailed = false;
94         mTestSkipped = false;
95         mCurrentTestNum++;
96     }
97 
98     /**
99      * {@inheritDoc}
100      */
101     @Override
testFailed(TestDescription test, String trace)102     public void testFailed(TestDescription test, String trace) {
103         logProgress("%s fail: %s", test, trace);
104         mTestFailed = true;
105         mFailedTests++;
106     }
107 
108     /**
109      * {@inheritDoc}
110      */
111     @Override
testIgnored(TestDescription test)112     public void testIgnored(TestDescription test) {
113         logProgress("%s ignore", test);
114         mTestSkipped = true;
115     }
116 
117     /**
118      * {@inheritDoc}
119      */
120     @Override
testAssumptionFailure(TestDescription test, String trace)121     public void testAssumptionFailure(TestDescription test, String trace) {
122         logProgress("%s skip", test);
123         mTestSkipped = true;
124     }
125 
126     /**
127      * {@inheritDoc}
128      */
129     @Override
testEnded(TestDescription test, HashMap<String, Metric> testMetrics)130     public void testEnded(TestDescription test, HashMap<String, Metric> testMetrics) {
131         if (!mTestFailed && !mTestSkipped) {
132             logProgress("%s pass", test);
133             mPassedTests++;
134         }
135     }
136 
137     /**
138      * {@inheritDoc}
139      */
140     @Override
testRunFailed(String errorMessage)141     public void testRunFailed(String errorMessage) {
142         logMessage(errorMessage);
143     }
144 
145     /**
146      * {@inheritDoc}
147      */
148     @Override
testRunEnded(long elapsedTime, Map<String, String> metrics)149     public void testRunEnded(long elapsedTime, Map<String, String> metrics) {
150         testRunEnded(elapsedTime, TfMetricProtoUtil.upgradeConvert(metrics));
151     }
152 
153     /**
154      * {@inheritDoc}
155      */
156     @Override
testRunEnded(long elapsedTime, HashMap<String, Metric> metrics)157     public void testRunEnded(long elapsedTime, HashMap<String, Metric> metrics) {
158         mNotExecutedTests = Math.max(mTotalTestsInModule - mCurrentTestNum, 0);
159         String status = mNotExecutedTests > 0 ? "failed" : "completed";
160         logMessage("%s %s in %s. %d passed, %d failed, %d not executed",
161             mModuleId,
162             status,
163             TimeUtil.formatElapsedTime(elapsedTime),
164             mPassedTests,
165             mFailedTests,
166             mNotExecutedTests);
167     }
168 
169     /**
170      * {@inheritDoc}
171      */
172     @Override
testRunStopped(long elapsedTime)173     public void testRunStopped(long elapsedTime) {
174         logMessage("%s stopped (%s)", mModuleId, TimeUtil.formatElapsedTime(elapsedTime));
175     }
176 
177     /**
178      * Print out message with test execution status.
179      */
logProgress(String format, Object... args)180     private void logProgress(String format, Object... args) {
181         format = String.format("[%s %s %s] %s", progress(), mModuleId, mDeviceSerial, format);
182         log(format, args);
183     }
184 
185     /**
186      * Print out message to the console
187      */
logMessage(String format, Object... args)188     private void logMessage(String format, Object... args) {
189         format = String.format("[%s] %s", mDeviceSerial, format);
190         log(format, args);
191     }
192 
193     /**
194      * Print out to the console or log silently when mQuietOutput is true.
195      */
log(String format, Object... args)196     private void log(String format, Object... args) {
197         if (mQuietOutput) {
198             CLog.i(format, args);
199         } else {
200             CLog.logAndDisplay(LogLevel.INFO, format, args);
201         }
202     }
203 
204     /**
205      * {@inheritDoc}
206      */
207     @Override
clone()208     public IShardableListener clone() {
209         ConsoleReporter clone = new ConsoleReporter();
210         OptionCopier.copyOptionsNoThrow(this, clone);
211         return clone;
212     }
213 
214     /**
215      * Return a string containing the percentage complete of module test execution.
216      */
progress()217     private String progress() {
218         return String.format("%d/%d", mCurrentTestNum, mTotalTestsInModule);
219     }
220 
getDeviceSerial()221     String getDeviceSerial() {
222         return mDeviceSerial;
223     }
224 
getTestFailed()225     boolean getTestFailed() {
226         return mTestFailed;
227     }
228 
getModuleId()229     String getModuleId() {
230         return mModuleId;
231     }
232 
getCurrentTestNum()233     int getCurrentTestNum() {
234         return mCurrentTestNum;
235     }
236 
getTotalTestsInModule()237     int getTotalTestsInModule() {
238         return mTotalTestsInModule;
239     }
240 
getPassedTests()241     int getPassedTests() {
242         return mPassedTests;
243     }
244 
getFailedTests()245     int getFailedTests() {
246         return mFailedTests;
247     }
248 }
249