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