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.compatibility.common.util.AbiUtils; 20 import com.android.cts.tradefed.device.DeviceInfoCollector; 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 private static final String DEVICE_INFO_ERROR = "DEVICE_INFO_ERROR_"; 39 40 @Option(name = "quiet-output", description = "Mute display of test results.") 41 private boolean mQuietOutput = false; 42 43 protected IBuildInfo mBuildInfo; 44 private String mDeviceSerial; 45 private TestResults mResults = new TestResults(); 46 private TestPackageResult mCurrentPkgResult = null; 47 private boolean mIsDeviceInfoRun = false; 48 private boolean mIsExtendedDeviceInfoRun = false; 49 50 @Override invocationStarted(IBuildInfo buildInfo)51 public void invocationStarted(IBuildInfo buildInfo) { 52 mDeviceSerial = buildInfo.getDeviceSerial() == null ? "unknown_device" : buildInfo.getDeviceSerial(); 53 } 54 55 /** 56 * Reports the start of a test run. 57 * 58 * @param id the unique identifier of this test run, generated by 59 * {@link AbiUtils#createId(String, String)}. 60 * @param numTests total number of tests in test run 61 */ 62 @Override testRunStarted(String id, int numTests)63 public void testRunStarted(String id, int numTests) { 64 if (mCurrentPkgResult != null && !id.equals(mCurrentPkgResult.getId())) { 65 // display results from previous run 66 logCompleteRun(mCurrentPkgResult); 67 } 68 mIsDeviceInfoRun = DeviceInfoCollector.IDS.contains(id); 69 mIsExtendedDeviceInfoRun = DeviceInfoCollector.EXTENDED_IDS.contains(id); 70 if (mIsDeviceInfoRun) { 71 logResult("Collecting device info"); 72 } else if (mIsExtendedDeviceInfoRun) { 73 logResult("Collecting extended device info"); 74 } else { 75 if (mCurrentPkgResult == null || !id.equals(mCurrentPkgResult.getId())) { 76 logResult("-----------------------------------------"); 77 logResult("Test package %s started", id); 78 logResult("-----------------------------------------"); 79 } 80 mCurrentPkgResult = mResults.getOrCreatePackage(id); 81 } 82 } 83 84 /** 85 * {@inheritDoc} 86 */ 87 @Override testStarted(TestIdentifier test)88 public void testStarted(TestIdentifier test) { 89 if (mIsExtendedDeviceInfoRun) { 90 return; 91 } 92 mCurrentPkgResult.insertTest(test); 93 } 94 95 /** 96 * {@inheritDoc} 97 */ 98 @Override testFailed(TestIdentifier test, String trace)99 public void testFailed(TestIdentifier test, String trace) { 100 if (mIsExtendedDeviceInfoRun) { 101 return; 102 } 103 mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace); 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 @Override testAssumptionFailure(TestIdentifier test, String trace)110 public void testAssumptionFailure(TestIdentifier test, String trace) { 111 if (mIsExtendedDeviceInfoRun) { 112 return; 113 } 114 // TODO: do something different here? 115 mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace); 116 } 117 118 /** 119 * {@inheritDoc} 120 */ 121 @Override testEnded(TestIdentifier test, Map<String, String> testMetrics)122 public void testEnded(TestIdentifier test, Map<String, String> testMetrics) { 123 if (mIsExtendedDeviceInfoRun) { 124 for (Map.Entry<String, String> metricsEntry : testMetrics.entrySet()) { 125 String key = metricsEntry.getKey(); 126 String value = metricsEntry.getValue(); 127 if (key.startsWith(DEVICE_INFO_ERROR)) { 128 throw new RuntimeException(String.format( 129 "Error collecting extended device info: %s=%s", key, value)); 130 } 131 } 132 return; 133 } 134 mCurrentPkgResult.reportTestEnded(test, testMetrics); 135 Test result = mCurrentPkgResult.findTest(test); 136 String stack = result.getStackTrace() == null ? "" : "\n" + result.getStackTrace(); 137 logResult("%s#%s %s %s", test.getClassName(), test.getTestName(), result.getResult(), 138 stack); 139 } 140 141 /** 142 * {@inheritDoc} 143 */ 144 @Override invocationEnded(long elapsedTime)145 public void invocationEnded(long elapsedTime) { 146 if (mIsExtendedDeviceInfoRun) { 147 return; 148 } 149 // display the results of the last completed run 150 if (mCurrentPkgResult != null) { 151 logCompleteRun(mCurrentPkgResult); 152 } 153 } 154 logResult(String format, Object... args)155 private void logResult(String format, Object... args) { 156 if (mQuietOutput) { 157 CLog.i(format, args); 158 } else { 159 Log.logAndDisplay(LogLevel.INFO, mDeviceSerial, String.format(format, args)); 160 } 161 } 162 logCompleteRun(TestPackageResult pkgResult)163 private void logCompleteRun(TestPackageResult pkgResult) { 164 String appPackageName = pkgResult.getAppPackageName(); 165 if (appPackageName.equals(DeviceInfoCollector.APP_PACKAGE_NAME)) { 166 logResult("Device info collection complete"); 167 return; 168 } else if (appPackageName.equals(DeviceInfoCollector.EXTENDED_APP_PACKAGE_NAME)) { 169 logResult("Extended device info collection complete"); 170 return; 171 } 172 logResult("%s package complete: Passed %d, Failed %d, Not Executed %d", 173 pkgResult.getId(), pkgResult.countTests(CtsTestStatus.PASS), 174 pkgResult.countTests(CtsTestStatus.FAIL), 175 pkgResult.countTests(CtsTestStatus.NOT_EXECUTED)); 176 } 177 178 @Override clone()179 public IShardableListener clone() { 180 CtsTestLogReporter clone = new CtsTestLogReporter(); 181 OptionCopier.copyOptionsNoThrow(this, clone); 182 return clone; 183 } 184 } 185