| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.compatibility.common.tradefed.result; |
| |
| import com.android.ddmlib.Log; |
| import com.android.ddmlib.Log.LogLevel; |
| import com.android.ddmlib.testrunner.TestIdentifier; |
| import com.android.tradefed.build.IBuildInfo; |
| import com.android.tradefed.config.Option; |
| import com.android.tradefed.config.OptionClass; |
| import com.android.tradefed.config.OptionCopier; |
| import com.android.tradefed.log.LogUtil.CLog; |
| import com.android.tradefed.result.IShardableListener; |
| import com.android.tradefed.result.StubTestInvocationListener; |
| import com.android.tradefed.util.TimeUtil; |
| |
| import java.util.Map; |
| |
| /** |
| * Write test progress to the test console. |
| */ |
| public class ConsoleReporter extends StubTestInvocationListener implements IShardableListener { |
| |
| private static final String UNKNOWN_DEVICE = "unknown_device"; |
| |
| @Option(name = "quiet-output", description = "Mute display of test results.") |
| private boolean mQuietOutput = false; |
| |
| private String mDeviceSerial = UNKNOWN_DEVICE; |
| private boolean mTestFailed; |
| private String mModuleId; |
| private int mCurrentTestNum; |
| private int mTotalTestsInModule; |
| private int mPassedTests; |
| private int mFailedTests; |
| private int mNotExecutedTests; |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void invocationStarted(IBuildInfo buildInfo) { |
| if (buildInfo == null) { |
| CLog.w("buildInfo should not be null"); |
| return; |
| } |
| // Escape any "%" signs in the device serial. |
| mDeviceSerial = buildInfo.getDeviceSerial().replace("%", "%%"); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testRunStarted(String id, int numTests) { |
| if (mModuleId == null || !mModuleId.equals(id)) { |
| mModuleId = id; |
| mTotalTestsInModule = numTests; |
| // Reset counters |
| mCurrentTestNum = 0; |
| mPassedTests = 0; |
| mFailedTests = 0; |
| mNotExecutedTests = 0; |
| mTestFailed = false; |
| logMessage("Starting %s with %d test%s", |
| id, mTotalTestsInModule, (mTotalTestsInModule > 1) ? "s" : ""); |
| } else { |
| if (mNotExecutedTests == 0) { |
| mTotalTestsInModule += numTests; |
| } else { |
| mTotalTestsInModule += Math.max(0, numTests - mNotExecutedTests); |
| } |
| logMessage("Continuing %s with %d test%s", |
| id, mTotalTestsInModule, (mTotalTestsInModule > 1) ? "s" : ""); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testStarted(TestIdentifier test) { |
| mTestFailed = false; |
| mCurrentTestNum++; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testFailed(TestIdentifier test, String trace) { |
| logProgress("%s fail: %s", test, trace); |
| mTestFailed = true; |
| mFailedTests++; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testIgnored(TestIdentifier test) { |
| mCurrentTestNum--; |
| logProgress("%s ignore", test); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testAssumptionFailure(TestIdentifier test, String trace) { |
| logProgress("%s failed assumption: %s", test, trace); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testEnded(TestIdentifier test, Map<String, String> testMetrics) { |
| if (!mTestFailed) { |
| logProgress("%s pass", test); |
| mPassedTests++; |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testRunFailed(String errorMessage) { |
| logMessage(errorMessage); |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testRunEnded(long elapsedTime, Map<String, String> metrics) { |
| mNotExecutedTests = Math.max(mTotalTestsInModule - mCurrentTestNum, 0); |
| String status = mNotExecutedTests > 0 ? "failed" : "completed"; |
| logMessage("%s %s in %s. %d passed, %d failed, %d not executed", |
| mModuleId, |
| status, |
| TimeUtil.formatElapsedTime(elapsedTime), |
| mPassedTests, |
| mFailedTests, |
| mNotExecutedTests); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void testRunStopped(long elapsedTime) { |
| logMessage("%s stopped (%s)", mModuleId, TimeUtil.formatElapsedTime(elapsedTime)); |
| } |
| |
| /** |
| * Print out message with test execution status. |
| */ |
| private void logProgress(String format, Object... args) { |
| format = String.format("[%s %s %s] %s", progress(), mModuleId, mDeviceSerial, format); |
| log(format, args); |
| } |
| |
| /** |
| * Print out message to the console |
| */ |
| private void logMessage(String format, Object... args) { |
| format = String.format("[%s] %s", mDeviceSerial, format); |
| log(format, args); |
| } |
| |
| /** |
| * Print out to the console or log silently when mQuietOutput is true. |
| */ |
| private void log(String format, Object... args) { |
| if (mQuietOutput) { |
| CLog.i(format, args); |
| } else { |
| CLog.logAndDisplay(LogLevel.INFO, format, args); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public IShardableListener clone() { |
| ConsoleReporter clone = new ConsoleReporter(); |
| OptionCopier.copyOptionsNoThrow(this, clone); |
| return clone; |
| } |
| |
| /** |
| * Return a string containing the percentage complete of module test execution. |
| */ |
| private String progress() { |
| return String.format("%d/%d", mCurrentTestNum, mTotalTestsInModule); |
| } |
| |
| String getDeviceSerial() { |
| return mDeviceSerial; |
| } |
| |
| boolean getTestFailed() { |
| return mTestFailed; |
| } |
| |
| String getModuleId() { |
| return mModuleId; |
| } |
| |
| int getCurrentTestNum() { |
| return mCurrentTestNum; |
| } |
| |
| int getTotalTestsInModule() { |
| return mTotalTestsInModule; |
| } |
| |
| int getPassedTests() { |
| return mPassedTests; |
| } |
| |
| int getFailedTests() { |
| return mFailedTests; |
| } |
| } |