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 java.io.PrintWriter; 21 import java.io.StringWriter; 22 import java.util.Arrays; 23 import java.util.Date; 24 import java.util.List; 25 import vogar.util.Strings; 26 27 /** 28 * An outcome of an action. Some actions may have multiple outcomes. For 29 * example, JUnit tests have one outcome for each test method. 30 */ 31 public final class Outcome { 32 33 private final String outcomeName; 34 private final Result result; 35 private final String output; 36 private final Date date; 37 Outcome(String outcomeName, Result result, List<String> outputLines)38 public Outcome(String outcomeName, Result result, List<String> outputLines) { 39 this.outcomeName = outcomeName; 40 this.result = result; 41 this.output = sanitizeOutputLines(outputLines); 42 this.date = new Date(); 43 } 44 Outcome(String outcomeName, Result result, String outputLine, Date date)45 public Outcome(String outcomeName, Result result, String outputLine, Date date) { 46 this.outcomeName = outcomeName; 47 this.result = result; 48 this.output = sanitizeOutputLine(outputLine); 49 this.date = date; 50 } 51 Outcome(String outcomeName, Result result, String outputLine)52 public Outcome(String outcomeName, Result result, String outputLine) { 53 this.outcomeName = outcomeName; 54 this.result = result; 55 this.output = sanitizeOutputLine(outputLine); 56 this.date = new Date(); 57 } 58 Outcome(String outcomeName, Result result, Throwable throwable)59 public Outcome(String outcomeName, Result result, Throwable throwable) { 60 this.outcomeName = outcomeName; 61 this.result = result; 62 this.output = sanitizeOutputLines(throwableToLines(throwable)); 63 this.date = new Date(); 64 } 65 sanitizeOutputLines(List<String> outputLines)66 private String sanitizeOutputLines(List<String> outputLines) { 67 List<String> sanitizedStrings = Lists.newArrayList(); 68 for (String line : outputLines) { 69 sanitizedStrings.add(sanitizeOutputLine(line)); 70 } 71 return Strings.join(sanitizedStrings, "\n"); 72 } 73 sanitizeOutputLine(String outputLine)74 private String sanitizeOutputLine(String outputLine) { 75 return Strings.xmlSanitize(outputLine.replaceAll("\r\n?", "\n")); 76 } 77 getDate()78 public Date getDate() { 79 return date; 80 } 81 getName()82 public String getName() { 83 return outcomeName; 84 } 85 getResult()86 public Result getResult() { 87 return result; 88 } 89 getOutput()90 public String getOutput() { 91 return output; 92 } 93 getOutputLines()94 public List<String> getOutputLines() { 95 return Arrays.asList(output.split("\n")); 96 } 97 throwableToLines(Throwable t)98 private static List<String> throwableToLines(Throwable t) { 99 StringWriter writer = new StringWriter(); 100 PrintWriter out = new PrintWriter(writer); 101 t.printStackTrace(out); 102 return Arrays.asList(writer.toString().split("\\n")); 103 } 104 105 /** 106 * Returns the action's suite name, such as java.lang.Integer or 107 * java.lang.IntegerTest. 108 */ getSuiteName()109 public String getSuiteName() { 110 int split = split(outcomeName); 111 return split == -1 ? "defaultpackage" : outcomeName.substring(0, split); 112 } 113 114 /** 115 * Returns the specific action name, such as BitTwiddle or testBitTwiddle. 116 */ getTestName()117 public String getTestName() { 118 int split = split(outcomeName); 119 return split == -1 ? outcomeName : outcomeName.substring(split + 1); 120 } 121 split(String name)122 private static int split(String name) { 123 int lastHash = name.indexOf('#'); 124 return lastHash == -1 ? name.lastIndexOf('.') : lastHash; 125 } 126 127 /** 128 * Returns whether the result indicates that the contents of the Outcome are important. 129 * 130 * For example, for a test skipped because it is unsupported, we don't care about the result. 131 */ matters()132 private boolean matters() { 133 return result != Result.UNSUPPORTED; 134 } 135 getResultValue(Expectation expectation)136 public ResultValue getResultValue(Expectation expectation) { 137 if (matters()) { 138 if (expectation.matches(this)) { 139 return ResultValue.OK; 140 } else if (expectation.getIsFromExpectationFile()) { 141 // If the expectation is created from a file, make this a warning, to 142 // mimic CTS's behavior. 143 return ResultValue.WARNING; 144 } 145 return ResultValue.FAIL; 146 } 147 return ResultValue.IGNORE; 148 } 149 150 /** 151 * Returns a filesystem db path for this outcome. For example, a path for an outcome with name 152 * "foo.bar.baz#testName" would be "foo/bar/baz/testName". 153 */ getPath()154 public String getPath() { 155 return outcomeName.replaceAll("[\\.#]", "/"); 156 } 157 equals(Object o)158 @Override public boolean equals(Object o) { 159 if (o instanceof Outcome) { 160 Outcome outcome = (Outcome) o; 161 return outcomeName.equals(outcome.outcomeName) 162 && result == outcome.result 163 && output.equals(outcome.output); 164 } 165 return false; 166 } 167 hashCode()168 @Override public int hashCode() { 169 int hashCode = 17; 170 hashCode = 37 * hashCode + outcomeName.hashCode(); 171 hashCode = 37 * hashCode + result.hashCode(); 172 hashCode = 37 * hashCode + output.hashCode(); 173 return hashCode; 174 } 175 toString()176 @Override public String toString() { 177 return "Outcome[name=" + outcomeName + " output=" + output + "]"; 178 } 179 180 } 181