1 /* 2 * Copyright (C) 2020 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; 17 18 import com.android.tradefed.result.error.ErrorIdentifier; 19 import com.android.tradefed.result.proto.TestRecordProto; 20 21 import javax.annotation.Nullable; 22 23 /** 24 * The class describing a failure information in Trade Federation. This class contains the debugging 25 * information and context of the failure that helps understanding the issue. 26 */ 27 public class FailureDescription { 28 // The error message generated from the failure 29 private String mErrorMessage; 30 // Optional: The category of the failure 31 private @Nullable TestRecordProto.FailureStatus mFailureStatus = 32 TestRecordProto.FailureStatus.UNSET; 33 // Optional: Context of the action in progress during the failure 34 private @Nullable ActionInProgress mActionInProgress = ActionInProgress.UNSET; 35 // Optional: A free-formed text that help debugging the failure 36 private @Nullable String mDebugHelpMessage = null; 37 // Optional: The exception that triggered the failure 38 private @Nullable Throwable mCause = null; 39 // Whether or not the error is retriable by Tradefed auto-retry. By Default we retry it all. 40 private boolean mRetriable = true; 41 42 // Error identifiers 43 // Optional: The error identifier and its code 44 private @Nullable ErrorIdentifier mErrorId = null; 45 // Optional: The class that raised the error 46 private @Nullable String mOrigin = null; 47 FailureDescription()48 FailureDescription() {} 49 50 /** 51 * Set the {@link com.android.tradefed.result.proto.TestRecordProto.FailureStatus} associated 52 * with the failure. 53 */ setFailureStatus(TestRecordProto.FailureStatus status)54 public FailureDescription setFailureStatus(TestRecordProto.FailureStatus status) { 55 mFailureStatus = status; 56 return this; 57 } 58 59 /** Returns the FailureStatus associated with the failure. Can be null. */ getFailureStatus()60 public @Nullable TestRecordProto.FailureStatus getFailureStatus() { 61 if (TestRecordProto.FailureStatus.UNSET.equals(mFailureStatus)) { 62 return null; 63 } 64 return mFailureStatus; 65 } 66 67 /** Sets the action in progress during the failure. */ setActionInProgress(ActionInProgress action)68 public FailureDescription setActionInProgress(ActionInProgress action) { 69 mActionInProgress = action; 70 return this; 71 } 72 73 /** Returns the action in progress during the failure. Can be null. */ getActionInProgress()74 public @Nullable ActionInProgress getActionInProgress() { 75 return mActionInProgress; 76 } 77 78 /** Sets the debug help message for the failure. */ setDebugHelpMessage(String message)79 public FailureDescription setDebugHelpMessage(String message) { 80 mDebugHelpMessage = message; 81 return this; 82 } 83 84 /** Returns the debug help message. Can be null. */ getDebugHelpMessage()85 public @Nullable String getDebugHelpMessage() { 86 return mDebugHelpMessage; 87 } 88 89 /** Sets the exception that caused the failure if any. */ setCause(Throwable cause)90 public FailureDescription setCause(Throwable cause) { 91 mCause = cause; 92 return this; 93 } 94 95 /** Returns the exception that caused the failure. Can be null. */ getCause()96 public @Nullable Throwable getCause() { 97 return mCause; 98 } 99 100 /** Sets whether or not the failure is retriable. */ setRetriable(boolean retriable)101 public FailureDescription setRetriable(boolean retriable) { 102 mRetriable = retriable; 103 return this; 104 } 105 106 /** Returns whether or not the error is retriable or not. */ isRetriable()107 public boolean isRetriable() { 108 return mRetriable; 109 } 110 111 /** Sets the {@link ErrorIdentifier} representing the failure. */ setErrorIdentifier(ErrorIdentifier errorId)112 public FailureDescription setErrorIdentifier(ErrorIdentifier errorId) { 113 mErrorId = errorId; 114 return this; 115 } 116 117 /** Returns the {@link ErrorIdentifier} representing the failure. Can be null. */ getErrorIdentifier()118 public ErrorIdentifier getErrorIdentifier() { 119 return mErrorId; 120 } 121 122 /** Sets the origin of the error. */ setOrigin(String origin)123 public FailureDescription setOrigin(String origin) { 124 mOrigin = origin; 125 return this; 126 } 127 128 /** Returns the origin of the error. Can be null. */ getOrigin()129 public String getOrigin() { 130 return mOrigin; 131 } 132 133 /** Sets the error message. */ setErrorMessage(String errorMessage)134 public void setErrorMessage(String errorMessage) { 135 mErrorMessage = errorMessage; 136 } 137 138 /** Returns the error message associated with the failure. */ getErrorMessage()139 public String getErrorMessage() { 140 return mErrorMessage; 141 } 142 143 @Override toString()144 public String toString() { 145 // For backward compatibility of result interface, toString falls back to the simple message 146 return mErrorMessage; 147 } 148 149 /** 150 * Create a {@link FailureDescription} based on the error message generated from the failure. 151 * 152 * @param errorMessage The error message from the failure. 153 * @return the created {@link FailureDescription} 154 */ create(String errorMessage)155 public static FailureDescription create(String errorMessage) { 156 return create(errorMessage, null); 157 } 158 159 /** 160 * Create a {@link FailureDescription} based on the error message generated from the failure. 161 * 162 * @param errorMessage The error message from the failure. 163 * @param status The status associated with the failure. 164 * @return the created {@link FailureDescription} 165 */ create( String errorMessage, @Nullable TestRecordProto.FailureStatus status)166 public static FailureDescription create( 167 String errorMessage, @Nullable TestRecordProto.FailureStatus status) { 168 FailureDescription info = new FailureDescription(); 169 info.mErrorMessage = errorMessage; 170 info.mFailureStatus = status; 171 return info; 172 } 173 174 @Override hashCode()175 public int hashCode() { 176 final int prime = 31; 177 int result = 1; 178 result = prime * result + ((mActionInProgress == null) ? 0 : mActionInProgress.hashCode()); 179 result = prime * result + ((mDebugHelpMessage == null) ? 0 : mDebugHelpMessage.hashCode()); 180 result = prime * result + ((mErrorMessage == null) ? 0 : mErrorMessage.hashCode()); 181 result = prime * result + ((mFailureStatus == null) ? 0 : mFailureStatus.hashCode()); 182 return result; 183 } 184 185 @Override equals(Object obj)186 public boolean equals(Object obj) { 187 if (this == obj) return true; 188 if (obj == null) return false; 189 if (getClass() != obj.getClass()) return false; 190 FailureDescription other = (FailureDescription) obj; 191 if (mActionInProgress != other.mActionInProgress) return false; 192 if (mDebugHelpMessage == null) { 193 if (other.mDebugHelpMessage != null) return false; 194 } else if (!mDebugHelpMessage.equals(other.mDebugHelpMessage)) return false; 195 if (mErrorMessage == null) { 196 if (other.mErrorMessage != null) return false; 197 } else if (!mErrorMessage.equals(other.mErrorMessage)) return false; 198 if (mFailureStatus != other.mFailureStatus) return false; 199 return true; 200 } 201 } 202