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