1 /* 2 * Copyright (C) 2023 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.skipped; 17 18 import java.util.regex.Matcher; 19 import java.util.regex.Pattern; 20 21 /** Provide a reason and its metadata for skipping a test. */ 22 public class SkipReason { 23 24 private final String reason; 25 private final String trigger; 26 private final String bugId; 27 28 // Limit the possibilities for reported trigger type, but store as a string. 29 public static enum DemotionTrigger { 30 UNKNOWN_TRIGGER, // Unspecified trigger 31 MANUAL, // Inserted directly via API 32 LATENCY, // Test is out of SLO on latency 33 ERROR_RATE, // Test is out of SLO on error rate 34 FLAKINESS; // Test is out of SLO on flakiness score 35 } 36 SkipReason(String message, String trigger)37 public SkipReason(String message, String trigger) { 38 this(message, trigger, ""); 39 } 40 SkipReason(String message, DemotionTrigger trigger)41 public SkipReason(String message, DemotionTrigger trigger) { 42 this(message, trigger, ""); 43 } 44 SkipReason(String message, DemotionTrigger trigger, String bugId)45 public SkipReason(String message, DemotionTrigger trigger, String bugId) { 46 this( 47 message, 48 trigger == null ? DemotionTrigger.UNKNOWN_TRIGGER.name() : trigger.name(), 49 bugId); 50 } 51 SkipReason(String message, String trigger, String bugId)52 public SkipReason(String message, String trigger, String bugId) { 53 this.reason = message; 54 this.trigger = trigger; 55 this.bugId = bugId; 56 } 57 58 /** Returns the reason associated with the skip status. */ getReason()59 public String getReason() { 60 return reason; 61 } 62 63 /** Returns the trigger associated with the skip status. */ getTrigger()64 public String getTrigger() { 65 return trigger; 66 } 67 68 /** Returns the bug id associated with skip status. Optional. */ getBugId()69 public String getBugId() { 70 return bugId; 71 } 72 73 @Override toString()74 public String toString() { 75 return "SkipReason[reason=" + reason + ", trigger=" + trigger + ", bugId=" + bugId + "]"; 76 } 77 78 /** Parses {@link #toString()} into a {@link SkipReason}. */ fromString(String skipReasonMessage)79 public static SkipReason fromString(String skipReasonMessage) { 80 Pattern p = Pattern.compile("SkipReason\\[reason=(.*), trigger=(.*), bugId=(.*)\\]"); 81 Matcher m = p.matcher(skipReasonMessage); 82 if (m.find()) { 83 String reason = m.group(1); 84 String trigger = m.group(2); 85 String bugId = m.group(3); 86 return new SkipReason(reason, DemotionTrigger.valueOf(trigger), bugId); 87 } 88 throw new RuntimeException( 89 String.format("Cannot parse '%s' as SkipReason.", skipReasonMessage)); 90 } 91 } 92