blob: 04b5fc2cac445f58bd2ee24dca7b6eca1fdff86c [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* 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 com.facebook.buck.test;
import com.facebook.buck.util.Ansi;
import com.facebook.buck.util.TimeFormat;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import java.util.List;
import javax.annotation.concurrent.Immutable;
@Immutable
public class TestCaseSummary {
/**
* Transformation to annotate TestCaseSummary marking them as being read from cached results
*/
public static final Function<TestCaseSummary, TestCaseSummary> TO_CACHED_TRANSFORMATION =
new Function<TestCaseSummary, TestCaseSummary>() {
@Override
public TestCaseSummary apply(TestCaseSummary summary) {
return new TestCaseSummary(summary, /* isCached */ true);
}
};
public static final int MAX_STATUS_WIDTH = 7;
private final String testCaseName;
private final ImmutableList<TestResultSummary> testResults;
private final boolean isSuccess;
private final boolean isDryRun;
private final boolean hasAssumptionViolations;
private final int skippedCount;
private final int failureCount;
private final long totalTime;
private final boolean isCached;
/**
* Creates a TestCaseSummary which is assumed to be not read from cached results
*/
public TestCaseSummary(String testCaseName, List<TestResultSummary> testResults) {
this.testCaseName = testCaseName;
this.testResults = ImmutableList.copyOf(testResults);
boolean isSuccess = true;
boolean isDryRun = false;
boolean hasAssumptionViolations = false;
int skippedCount = 0;
int failureCount = 0;
long totalTime = 0L;
for (TestResultSummary result : testResults) {
totalTime += result.getTime();
switch (result.getType()) {
case SUCCESS:
break;
case DRY_RUN:
isDryRun = true;
break;
case ASSUMPTION_VIOLATION:
hasAssumptionViolations = true;
++skippedCount;
break;
case FAILURE:
isSuccess = false;
++failureCount;
break;
}
}
this.isSuccess = isSuccess;
this.isDryRun = isDryRun;
this.hasAssumptionViolations = hasAssumptionViolations;
this.skippedCount = skippedCount;
this.failureCount = failureCount;
this.totalTime = totalTime;
this.isCached = false;
}
/** Creates a copy of {@code summary} with the specified value of {@code isCached}. */
private TestCaseSummary(TestCaseSummary summary, boolean isCached) {
this.testCaseName = summary.testCaseName;
this.testResults = summary.testResults;
this.isSuccess = summary.isSuccess;
this.isDryRun = summary.isDryRun;
this.hasAssumptionViolations = summary.hasAssumptionViolations;
this.skippedCount = summary.skippedCount;
this.failureCount = summary.failureCount;
this.totalTime = summary.totalTime;
this.isCached = isCached;
}
public boolean isSuccess() {
return isSuccess;
}
public boolean hasAssumptionViolations() {
return hasAssumptionViolations;
}
public String getTestCaseName() {
return testCaseName;
}
/** @return the total time to run all of the tests in this test case, in milliseconds */
public long getTotalTime() {
return totalTime;
}
/** @return a one-line, printable summary */
public String getOneLineSummary(boolean hasPassingDependencies, Ansi ansi) {
String statusText;
Ansi.SeverityLevel severityLevel;
if (isDryRun) {
severityLevel = Ansi.SeverityLevel.WARNING;
statusText = "DRYRUN";
} else if (!isSuccess()) {
if (hasPassingDependencies) {
severityLevel = Ansi.SeverityLevel.ERROR;
statusText = "FAIL";
} else {
severityLevel = Ansi.SeverityLevel.WARNING;
statusText = "DROP";
}
} else {
if (hasAssumptionViolations) {
severityLevel = Ansi.SeverityLevel.WARNING;
statusText = "ASSUME";
} else {
if (testResults.isEmpty()) {
severityLevel = Ansi.SeverityLevel.WARNING;
statusText = "NOTESTS";
} else {
severityLevel = Ansi.SeverityLevel.OK;
statusText = "PASS";
}
}
}
String status = ansi.asHighlightedStatusText(severityLevel, statusText);
int paddingWidth = MAX_STATUS_WIDTH - statusText.length();
String padding = "";
for (int position = 0; position < paddingWidth; position++) {
padding += ' ';
}
int passedCount = testResults.size() - failureCount - skippedCount;
return String.format("%s%s %s %2d Passed %2d Skipped %2d Failed %s",
status,
padding,
!isCached ? TimeFormat.formatForConsole(totalTime, ansi)
: ansi.asHighlightedStatusText(severityLevel, "CACHED"),
passedCount,
skippedCount,
failureCount,
testCaseName);
}
public ImmutableList<TestResultSummary> getTestResults() {
return testResults;
}
public int getFailureCount() {
return failureCount;
}
@Override
public String toString() {
return String.format("%s %s",
getShortStatusSummaryString(),
testCaseName);
}
private String getShortStatusSummaryString() {
if (isSuccess) {
if (hasAssumptionViolations) {
return "ASSUME";
} else {
return "PASS";
}
} else {
return "FAIL";
}
}
}