1 /* 2 * Copyright (C) 2018 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 package com.android.tradefed.result.suite; 17 18 import com.android.tradefed.config.IConfiguration; 19 import com.android.tradefed.config.IConfigurationReceiver; 20 import com.android.tradefed.error.IHarnessException; 21 import com.android.tradefed.log.LogUtil.CLog; 22 import com.android.tradefed.result.FailureDescription; 23 import com.android.tradefed.targetprep.TargetSetupError; 24 import com.android.tradefed.testtype.IRemoteTest; 25 import com.android.tradefed.testtype.suite.retry.ResultsPlayer; 26 27 import com.google.common.base.Strings; 28 29 /** Reporter that allows to generate reports in a particular format. TODO: fix logged file */ 30 public abstract class FormattedGeneratorReporter extends SuiteResultReporter 31 implements IConfigurationReceiver { 32 33 private Throwable mTestHarnessError = null; 34 private IConfiguration mConfiguration; 35 36 @Override setConfiguration(IConfiguration configuration)37 public final void setConfiguration(IConfiguration configuration) { 38 mConfiguration = configuration; 39 } 40 getConfiguration()41 public final IConfiguration getConfiguration() { 42 return mConfiguration; 43 } 44 45 /** {@inheritDoc} */ 46 @Override invocationEnded(long elapsedTime)47 public final void invocationEnded(long elapsedTime) { 48 // Let the parent create the results structures 49 super.invocationEnded(elapsedTime); 50 51 // If invocation failed due to a test harness error and did not see any tests 52 if (mTestHarnessError != null) { 53 Boolean replaySuccess = null; 54 for (IRemoteTest test : mConfiguration.getTests()) { 55 if (test instanceof ResultsPlayer) { 56 replaySuccess = ((ResultsPlayer) test).completed(); 57 } 58 } 59 60 String replay = 61 getInvocationContext() 62 .getBuildInfos() 63 .get(0) 64 .getBuildAttributes() 65 .get(ResultsPlayer.REPLAY_DONE); 66 if (!Strings.isNullOrEmpty(replay) && "false".equals(replay)) { 67 CLog.e( 68 "Invocation failed and previous session results couldn't be copied, skip " 69 + "generating the formatted report due to:"); 70 CLog.e(mTestHarnessError); 71 return; 72 } 73 74 if (replaySuccess != null && !replaySuccess) { 75 CLog.e( 76 "Invocation failed and previous session results couldn't be copied, skip " 77 + "generating the formatted report due to:"); 78 CLog.e(mTestHarnessError); 79 return; 80 } 81 } 82 83 SuiteResultHolder holder = generateResultHolder(); 84 IFormatterGenerator generator = createFormatter(); 85 finalizeResults(generator, holder); 86 } 87 88 @Override invocationFailed(Throwable cause)89 public void invocationFailed(Throwable cause) { 90 FailureDescription description = 91 FailureDescription.create(cause.getMessage()).setCause(cause); 92 if (cause instanceof IHarnessException) { 93 description.setErrorIdentifier(((IHarnessException) cause).getErrorId()); 94 } 95 invocationFailed(description); 96 } 97 98 @Override invocationFailed(FailureDescription failure)99 public void invocationFailed(FailureDescription failure) { 100 // Some exception indicate a harness level issue, the tests result cannot be trusted at 101 // that point so we should skip the reporting. 102 Throwable cause = failure.getCause(); 103 if (cause != null 104 && (cause instanceof TargetSetupError 105 || cause instanceof RuntimeException 106 || cause instanceof OutOfMemoryError)) { 107 mTestHarnessError = cause; 108 } 109 super.invocationFailed(cause); 110 } 111 112 /** 113 * Step that handles using the {@link IFormatterGenerator} and the {@link SuiteResultHolder} in 114 * order to generate some formatted results. 115 * 116 * @param generator 117 * @param resultHolder 118 */ finalizeResults( IFormatterGenerator generator, SuiteResultHolder resultHolder)119 public abstract void finalizeResults( 120 IFormatterGenerator generator, SuiteResultHolder resultHolder); 121 122 /** Returns a new instance of the {@link IFormatterGenerator} to use. */ createFormatter()123 public abstract IFormatterGenerator createFormatter(); 124 generateResultHolder()125 private SuiteResultHolder generateResultHolder() { 126 final SuiteResultHolder holder = new SuiteResultHolder(); 127 holder.context = getInvocationContext(); 128 129 holder.runResults = getMergedTestRunResults(); 130 //holder.loggedFiles = mLoggedFiles; 131 holder.modulesAbi = getModulesAbi(); 132 133 holder.completeModules = getCompleteModules(); 134 holder.totalModules = getTotalModules(); 135 holder.passedTests = getPassedTests(); 136 holder.failedTests = getFailedTests(); 137 138 holder.startTime = getStartTime(); 139 holder.endTime = getEndTime(); 140 141 return holder; 142 } 143 } 144