/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package vogar; import com.google.common.collect.Lists; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; import java.util.Date; import java.util.List; import vogar.util.Strings; /** * An outcome of an action. Some actions may have multiple outcomes. For * example, JUnit tests have one outcome for each test method. */ public final class Outcome { private final String outcomeName; private final Result result; private final String output; private final Date date; public Outcome(String outcomeName, Result result, List<String> outputLines) { this.outcomeName = outcomeName; this.result = result; this.output = sanitizeOutputLines(outputLines); this.date = new Date(); } public Outcome(String outcomeName, Result result, String outputLine, Date date) { this.outcomeName = outcomeName; this.result = result; this.output = sanitizeOutputLine(outputLine); this.date = date; } public Outcome(String outcomeName, Result result, String outputLine) { this.outcomeName = outcomeName; this.result = result; this.output = sanitizeOutputLine(outputLine); this.date = new Date(); } public Outcome(String outcomeName, Result result, Throwable throwable) { this.outcomeName = outcomeName; this.result = result; this.output = sanitizeOutputLines(throwableToLines(throwable)); this.date = new Date(); } private String sanitizeOutputLines(List<String> outputLines) { List<String> sanitizedStrings = Lists.newArrayList(); for (String line : outputLines) { sanitizedStrings.add(sanitizeOutputLine(line)); } return Strings.join(sanitizedStrings, "\n"); } private String sanitizeOutputLine(String outputLine) { return Strings.xmlSanitize(outputLine.replaceAll("\r\n?", "\n")); } public Date getDate() { return date; } public String getName() { return outcomeName; } public Result getResult() { return result; } public String getOutput() { return output; } public List<String> getOutputLines() { return Arrays.asList(output.split("\n")); } private static List<String> throwableToLines(Throwable t) { StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); t.printStackTrace(out); return Arrays.asList(writer.toString().split("\\n")); } /** * Returns the action's suite name, such as java.lang.Integer or * java.lang.IntegerTest. */ public String getSuiteName() { int split = split(outcomeName); return split == -1 ? "defaultpackage" : outcomeName.substring(0, split); } /** * Returns the specific action name, such as BitTwiddle or testBitTwiddle. */ public String getTestName() { int split = split(outcomeName); return split == -1 ? outcomeName : outcomeName.substring(split + 1); } private static int split(String name) { int lastHash = name.indexOf('#'); return lastHash == -1 ? name.lastIndexOf('.') : lastHash; } /** * Returns whether the result indicates that the contents of the Outcome are important. * * For example, for a test skipped because it is unsupported, we don't care about the result. */ private boolean matters() { return result != Result.UNSUPPORTED; } public ResultValue getResultValue(Expectation expectation) { if (matters()) { return expectation.matches(this) ? ResultValue.OK : ResultValue.FAIL; } return ResultValue.IGNORE; } /** * Returns a filesystem db path for this outcome. For example, a path for an outcome with name * "foo.bar.baz#testName" would be "foo/bar/baz/testName". */ public String getPath() { return outcomeName.replaceAll("[\\.#]", "/"); } @Override public boolean equals(Object o) { if (o instanceof Outcome) { Outcome outcome = (Outcome) o; return outcomeName.equals(outcome.outcomeName) && result == outcome.result && output.equals(outcome.output); } return false; } @Override public int hashCode() { int hashCode = 17; hashCode = 37 * hashCode + outcomeName.hashCode(); hashCode = 37 * hashCode + result.hashCode(); hashCode = 37 * hashCode + output.hashCode(); return hashCode; } @Override public String toString() { return "Outcome[name=" + outcomeName + " output=" + output + "]"; } }