1*b7c941bbSAndroid Build Coastguard Worker /* 2*b7c941bbSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project 3*b7c941bbSAndroid Build Coastguard Worker * 4*b7c941bbSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*b7c941bbSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*b7c941bbSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*b7c941bbSAndroid Build Coastguard Worker * 8*b7c941bbSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*b7c941bbSAndroid Build Coastguard Worker * 10*b7c941bbSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*b7c941bbSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*b7c941bbSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*b7c941bbSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*b7c941bbSAndroid Build Coastguard Worker * limitations under the License. 15*b7c941bbSAndroid Build Coastguard Worker */ 16*b7c941bbSAndroid Build Coastguard Worker 17*b7c941bbSAndroid Build Coastguard Worker package vogar.expect; 18*b7c941bbSAndroid Build Coastguard Worker 19*b7c941bbSAndroid Build Coastguard Worker import com.google.common.collect.Lists; 20*b7c941bbSAndroid Build Coastguard Worker import java.io.PrintWriter; 21*b7c941bbSAndroid Build Coastguard Worker import java.io.StringWriter; 22*b7c941bbSAndroid Build Coastguard Worker import java.util.Arrays; 23*b7c941bbSAndroid Build Coastguard Worker import java.util.Date; 24*b7c941bbSAndroid Build Coastguard Worker import java.util.List; 25*b7c941bbSAndroid Build Coastguard Worker import vogar.expect.util.Strings; 26*b7c941bbSAndroid Build Coastguard Worker 27*b7c941bbSAndroid Build Coastguard Worker /** 28*b7c941bbSAndroid Build Coastguard Worker * An outcome of an action. Some actions may have multiple outcomes. For 29*b7c941bbSAndroid Build Coastguard Worker * example, JUnit tests have one outcome for each test method. 30*b7c941bbSAndroid Build Coastguard Worker */ 31*b7c941bbSAndroid Build Coastguard Worker public final class Outcome { 32*b7c941bbSAndroid Build Coastguard Worker 33*b7c941bbSAndroid Build Coastguard Worker private final String outcomeName; 34*b7c941bbSAndroid Build Coastguard Worker private final Result result; 35*b7c941bbSAndroid Build Coastguard Worker private final String output; 36*b7c941bbSAndroid Build Coastguard Worker private final Date date; 37*b7c941bbSAndroid Build Coastguard Worker Outcome(String outcomeName, Result result, List<String> outputLines)38*b7c941bbSAndroid Build Coastguard Worker public Outcome(String outcomeName, Result result, List<String> outputLines) { 39*b7c941bbSAndroid Build Coastguard Worker this.outcomeName = outcomeName; 40*b7c941bbSAndroid Build Coastguard Worker this.result = result; 41*b7c941bbSAndroid Build Coastguard Worker this.output = sanitizeOutputLines(outputLines); 42*b7c941bbSAndroid Build Coastguard Worker this.date = new Date(); 43*b7c941bbSAndroid Build Coastguard Worker } 44*b7c941bbSAndroid Build Coastguard Worker Outcome(String outcomeName, Result result, String outputLine, Date date)45*b7c941bbSAndroid Build Coastguard Worker public Outcome(String outcomeName, Result result, String outputLine, Date date) { 46*b7c941bbSAndroid Build Coastguard Worker this.outcomeName = outcomeName; 47*b7c941bbSAndroid Build Coastguard Worker this.result = result; 48*b7c941bbSAndroid Build Coastguard Worker this.output = sanitizeOutputLine(outputLine); 49*b7c941bbSAndroid Build Coastguard Worker this.date = date; 50*b7c941bbSAndroid Build Coastguard Worker } 51*b7c941bbSAndroid Build Coastguard Worker Outcome(String outcomeName, Result result, String outputLine)52*b7c941bbSAndroid Build Coastguard Worker public Outcome(String outcomeName, Result result, String outputLine) { 53*b7c941bbSAndroid Build Coastguard Worker this.outcomeName = outcomeName; 54*b7c941bbSAndroid Build Coastguard Worker this.result = result; 55*b7c941bbSAndroid Build Coastguard Worker this.output = sanitizeOutputLine(outputLine); 56*b7c941bbSAndroid Build Coastguard Worker this.date = new Date(); 57*b7c941bbSAndroid Build Coastguard Worker } 58*b7c941bbSAndroid Build Coastguard Worker Outcome(String outcomeName, Result result, Throwable throwable)59*b7c941bbSAndroid Build Coastguard Worker public Outcome(String outcomeName, Result result, Throwable throwable) { 60*b7c941bbSAndroid Build Coastguard Worker this.outcomeName = outcomeName; 61*b7c941bbSAndroid Build Coastguard Worker this.result = result; 62*b7c941bbSAndroid Build Coastguard Worker this.output = sanitizeOutputLines(throwableToLines(throwable)); 63*b7c941bbSAndroid Build Coastguard Worker this.date = new Date(); 64*b7c941bbSAndroid Build Coastguard Worker } 65*b7c941bbSAndroid Build Coastguard Worker sanitizeOutputLines(List<String> outputLines)66*b7c941bbSAndroid Build Coastguard Worker private String sanitizeOutputLines(List<String> outputLines) { 67*b7c941bbSAndroid Build Coastguard Worker List<String> sanitizedStrings = Lists.newArrayList(); 68*b7c941bbSAndroid Build Coastguard Worker for (String line : outputLines) { 69*b7c941bbSAndroid Build Coastguard Worker sanitizedStrings.add(sanitizeOutputLine(line)); 70*b7c941bbSAndroid Build Coastguard Worker } 71*b7c941bbSAndroid Build Coastguard Worker return Strings.join(sanitizedStrings, "\n"); 72*b7c941bbSAndroid Build Coastguard Worker } 73*b7c941bbSAndroid Build Coastguard Worker sanitizeOutputLine(String outputLine)74*b7c941bbSAndroid Build Coastguard Worker private String sanitizeOutputLine(String outputLine) { 75*b7c941bbSAndroid Build Coastguard Worker return Strings.xmlSanitize(outputLine.replaceAll("\r\n?", "\n")); 76*b7c941bbSAndroid Build Coastguard Worker } 77*b7c941bbSAndroid Build Coastguard Worker getDate()78*b7c941bbSAndroid Build Coastguard Worker public Date getDate() { 79*b7c941bbSAndroid Build Coastguard Worker return date; 80*b7c941bbSAndroid Build Coastguard Worker } 81*b7c941bbSAndroid Build Coastguard Worker getName()82*b7c941bbSAndroid Build Coastguard Worker public String getName() { 83*b7c941bbSAndroid Build Coastguard Worker return outcomeName; 84*b7c941bbSAndroid Build Coastguard Worker } 85*b7c941bbSAndroid Build Coastguard Worker getResult()86*b7c941bbSAndroid Build Coastguard Worker public Result getResult() { 87*b7c941bbSAndroid Build Coastguard Worker return result; 88*b7c941bbSAndroid Build Coastguard Worker } 89*b7c941bbSAndroid Build Coastguard Worker getOutput()90*b7c941bbSAndroid Build Coastguard Worker public String getOutput() { 91*b7c941bbSAndroid Build Coastguard Worker return output; 92*b7c941bbSAndroid Build Coastguard Worker } 93*b7c941bbSAndroid Build Coastguard Worker getOutputLines()94*b7c941bbSAndroid Build Coastguard Worker public List<String> getOutputLines() { 95*b7c941bbSAndroid Build Coastguard Worker return Arrays.asList(output.split("\n")); 96*b7c941bbSAndroid Build Coastguard Worker } 97*b7c941bbSAndroid Build Coastguard Worker throwableToLines(Throwable t)98*b7c941bbSAndroid Build Coastguard Worker private static List<String> throwableToLines(Throwable t) { 99*b7c941bbSAndroid Build Coastguard Worker StringWriter writer = new StringWriter(); 100*b7c941bbSAndroid Build Coastguard Worker PrintWriter out = new PrintWriter(writer); 101*b7c941bbSAndroid Build Coastguard Worker t.printStackTrace(out); 102*b7c941bbSAndroid Build Coastguard Worker return Arrays.asList(writer.toString().split("\\n")); 103*b7c941bbSAndroid Build Coastguard Worker } 104*b7c941bbSAndroid Build Coastguard Worker 105*b7c941bbSAndroid Build Coastguard Worker /** 106*b7c941bbSAndroid Build Coastguard Worker * Returns the action's suite name, such as java.lang.Integer or 107*b7c941bbSAndroid Build Coastguard Worker * java.lang.IntegerTest. 108*b7c941bbSAndroid Build Coastguard Worker */ getSuiteName()109*b7c941bbSAndroid Build Coastguard Worker public String getSuiteName() { 110*b7c941bbSAndroid Build Coastguard Worker int split = split(outcomeName); 111*b7c941bbSAndroid Build Coastguard Worker return split == -1 ? "defaultpackage" : outcomeName.substring(0, split); 112*b7c941bbSAndroid Build Coastguard Worker } 113*b7c941bbSAndroid Build Coastguard Worker 114*b7c941bbSAndroid Build Coastguard Worker /** 115*b7c941bbSAndroid Build Coastguard Worker * Returns the specific action name, such as BitTwiddle or testBitTwiddle. 116*b7c941bbSAndroid Build Coastguard Worker */ getTestName()117*b7c941bbSAndroid Build Coastguard Worker public String getTestName() { 118*b7c941bbSAndroid Build Coastguard Worker int split = split(outcomeName); 119*b7c941bbSAndroid Build Coastguard Worker return split == -1 ? outcomeName : outcomeName.substring(split + 1); 120*b7c941bbSAndroid Build Coastguard Worker } 121*b7c941bbSAndroid Build Coastguard Worker split(String name)122*b7c941bbSAndroid Build Coastguard Worker private static int split(String name) { 123*b7c941bbSAndroid Build Coastguard Worker int lastHash = name.indexOf('#'); 124*b7c941bbSAndroid Build Coastguard Worker return lastHash == -1 ? name.lastIndexOf('.') : lastHash; 125*b7c941bbSAndroid Build Coastguard Worker } 126*b7c941bbSAndroid Build Coastguard Worker 127*b7c941bbSAndroid Build Coastguard Worker /** 128*b7c941bbSAndroid Build Coastguard Worker * Returns whether the result indicates that the contents of the Outcome are important. 129*b7c941bbSAndroid Build Coastguard Worker * 130*b7c941bbSAndroid Build Coastguard Worker * For example, for a test skipped because it is unsupported, we don't care about the result. 131*b7c941bbSAndroid Build Coastguard Worker */ matters()132*b7c941bbSAndroid Build Coastguard Worker private boolean matters() { 133*b7c941bbSAndroid Build Coastguard Worker return result != Result.UNSUPPORTED; 134*b7c941bbSAndroid Build Coastguard Worker } 135*b7c941bbSAndroid Build Coastguard Worker getResultValue(Expectation expectation)136*b7c941bbSAndroid Build Coastguard Worker public ResultValue getResultValue(Expectation expectation) { 137*b7c941bbSAndroid Build Coastguard Worker if (matters()) { 138*b7c941bbSAndroid Build Coastguard Worker return expectation.matches(this) ? ResultValue.OK : ResultValue.FAIL; 139*b7c941bbSAndroid Build Coastguard Worker } 140*b7c941bbSAndroid Build Coastguard Worker return ResultValue.IGNORE; 141*b7c941bbSAndroid Build Coastguard Worker } 142*b7c941bbSAndroid Build Coastguard Worker 143*b7c941bbSAndroid Build Coastguard Worker /** 144*b7c941bbSAndroid Build Coastguard Worker * Returns a filesystem db path for this outcome. For example, a path for an outcome with name 145*b7c941bbSAndroid Build Coastguard Worker * "foo.bar.baz#testName" would be "foo/bar/baz/testName". 146*b7c941bbSAndroid Build Coastguard Worker */ getPath()147*b7c941bbSAndroid Build Coastguard Worker public String getPath() { 148*b7c941bbSAndroid Build Coastguard Worker return outcomeName.replaceAll("[\\.#]", "/"); 149*b7c941bbSAndroid Build Coastguard Worker } 150*b7c941bbSAndroid Build Coastguard Worker equals(Object o)151*b7c941bbSAndroid Build Coastguard Worker @Override public boolean equals(Object o) { 152*b7c941bbSAndroid Build Coastguard Worker if (o instanceof Outcome) { 153*b7c941bbSAndroid Build Coastguard Worker Outcome outcome = (Outcome) o; 154*b7c941bbSAndroid Build Coastguard Worker return outcomeName.equals(outcome.outcomeName) 155*b7c941bbSAndroid Build Coastguard Worker && result == outcome.result 156*b7c941bbSAndroid Build Coastguard Worker && output.equals(outcome.output); 157*b7c941bbSAndroid Build Coastguard Worker } 158*b7c941bbSAndroid Build Coastguard Worker return false; 159*b7c941bbSAndroid Build Coastguard Worker } 160*b7c941bbSAndroid Build Coastguard Worker hashCode()161*b7c941bbSAndroid Build Coastguard Worker @Override public int hashCode() { 162*b7c941bbSAndroid Build Coastguard Worker int hashCode = 17; 163*b7c941bbSAndroid Build Coastguard Worker hashCode = 37 * hashCode + outcomeName.hashCode(); 164*b7c941bbSAndroid Build Coastguard Worker hashCode = 37 * hashCode + result.hashCode(); 165*b7c941bbSAndroid Build Coastguard Worker hashCode = 37 * hashCode + output.hashCode(); 166*b7c941bbSAndroid Build Coastguard Worker return hashCode; 167*b7c941bbSAndroid Build Coastguard Worker } 168*b7c941bbSAndroid Build Coastguard Worker toString()169*b7c941bbSAndroid Build Coastguard Worker @Override public String toString() { 170*b7c941bbSAndroid Build Coastguard Worker return "Outcome[name=" + outcomeName + " output=" + output + "]"; 171*b7c941bbSAndroid Build Coastguard Worker } 172*b7c941bbSAndroid Build Coastguard Worker 173*b7c941bbSAndroid Build Coastguard Worker } 174