1 /* 2 * Copyright (C) 2010 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 vogar; 18 19 import com.google.common.collect.Lists; 20 import com.google.common.collect.Ordering; 21 import java.util.ArrayList; 22 import java.util.List; 23 import java.util.SortedMap; 24 25 /** 26 * Contains an outcome for a test, along with some metadata pertaining to the history of this test, 27 * including a list of previous outcomes, an outcome corresponding to the tag Vogar is being run 28 * with, if applicable, and the expectation for this test, so that result value information is 29 * available. 30 */ 31 public final class AnnotatedOutcome { 32 public static Ordering<AnnotatedOutcome> ORDER_BY_NAME = new Ordering<AnnotatedOutcome>() { 33 @Override public int compare(AnnotatedOutcome a, AnnotatedOutcome b) { 34 return a.getName().compareTo(b.getName()); 35 } 36 }; 37 38 private final Expectation expectation; 39 private final Outcome outcome; 40 /** a list of previous outcomes for the same action, sorted in chronological order */ 41 private final SortedMap<Long, Outcome> previousOutcomes; 42 /** will be null if not comparing to a tag */ 43 private final String tagName; 44 private final Outcome tagOutcome; 45 private final boolean hasMetadata; 46 AnnotatedOutcome(Outcome outcome, Expectation expectation, SortedMap<Long, Outcome> previousOutcomes, String tagName, Outcome tagOutcome, boolean hasMetadata)47 AnnotatedOutcome(Outcome outcome, Expectation expectation, 48 SortedMap<Long, Outcome> previousOutcomes, String tagName, Outcome tagOutcome, 49 boolean hasMetadata) { 50 if (previousOutcomes == null) { 51 throw new NullPointerException(); 52 } 53 this.expectation = expectation; 54 this.outcome = outcome; 55 this.previousOutcomes = previousOutcomes; 56 this.tagName = tagName; 57 this.tagOutcome = tagOutcome; 58 this.hasMetadata = hasMetadata; 59 } 60 getOutcome()61 public Outcome getOutcome() { 62 return outcome; 63 } 64 getName()65 public String getName() { 66 return outcome.getName(); 67 } 68 getResultValue()69 public ResultValue getResultValue() { 70 return outcome.getResultValue(expectation); 71 } 72 getPreviousResultValues()73 public List<ResultValue> getPreviousResultValues() { 74 List<ResultValue> previousResultValues = new ArrayList<ResultValue>(); 75 for (Outcome previousOutcome : previousOutcomes.values()) { 76 previousResultValues.add(previousOutcome.getResultValue(expectation)); 77 } 78 return previousResultValues; 79 } 80 81 /** 82 * Returns the most recent result value of a run of this test (before the current run). 83 */ getMostRecentResultValue(ResultValue defaultValue)84 public ResultValue getMostRecentResultValue(ResultValue defaultValue) { 85 List<ResultValue> previousResultValues = getPreviousResultValues(); 86 return previousResultValues.isEmpty() ? 87 defaultValue : 88 previousResultValues.get(previousResultValues.size() - 1); 89 } 90 hasTag()91 public boolean hasTag() { 92 return tagOutcome != null; 93 } 94 getTagName()95 public String getTagName() { 96 return tagName; 97 } 98 getTagResultValue()99 public ResultValue getTagResultValue() { 100 return tagOutcome == null ? null : tagOutcome.getResultValue(expectation); 101 } 102 103 /** 104 * Returns true if the outcome is noteworthy given the result value and previous history. 105 */ isNoteworthy()106 public boolean isNoteworthy() { 107 return getResultValue() != ResultValue.OK || recentlyChanged() || changedSinceTag(); 108 } 109 outcomeChanged()110 public boolean outcomeChanged() { 111 List<Outcome> previousOutcomesList = getOutcomeList(); 112 return previousOutcomesList.isEmpty() 113 || !outcome.equals(previousOutcomesList.get(previousOutcomesList.size() - 1)); 114 } 115 getOutcomeList()116 private ArrayList<Outcome> getOutcomeList() { 117 return new ArrayList<Outcome>(previousOutcomes.values()); 118 } 119 120 /** 121 * Returns true if the outcome recently changed in result value. 122 */ recentlyChanged()123 private boolean recentlyChanged() { 124 List<ResultValue> previousResultValues = getPreviousResultValues(); 125 if (previousResultValues.isEmpty()) { 126 return false; 127 } 128 return previousResultValues.get(previousResultValues.size() - 1) != getResultValue(); 129 } 130 changedSinceTag()131 private boolean changedSinceTag() { 132 ResultValue tagResultValue = getTagResultValue(); 133 return tagResultValue != null && tagResultValue != getResultValue(); 134 } 135 136 /** 137 * Returns a Long representing the time the outcome was last run. Returns {@code defaultValue} 138 * if the outcome is not known to have run before. 139 */ lastRun(Long defaultValue)140 public Long lastRun(Long defaultValue) { 141 if (!hasMetadata) { 142 return defaultValue; 143 } 144 List<Long> runTimes = Lists.newArrayList(previousOutcomes.keySet()); 145 return runTimes.isEmpty() ? defaultValue : runTimes.get(runTimes.size() - 1); 146 } 147 } 148