diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/test/TestLogHelper.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/test/TestLogHelper.java | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestLogHelper.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestLogHelper.java new file mode 100644 index 0000000000..462c24ce6c --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestLogHelper.java @@ -0,0 +1,141 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// 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.google.devtools.build.lib.rules.test; + +import com.google.common.io.ByteStreams; +import com.google.devtools.build.lib.rules.test.TestStrategy.TestOutputFormat; +import com.google.devtools.build.lib.vfs.Path; + +import java.io.BufferedOutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; + +/** + * A helper class for test log handling. It determines whether the test log should + * be output and formats the test log for console display. + */ +public class TestLogHelper { + + public static final String HEADER_DELIMITER = + "-----------------------------------------------------------------------------"; + + /** + * Determines whether the test log should be output from the current outputMode + * and whether the test has passed or not. + */ + public static boolean shouldOutputTestLog(TestOutputFormat outputMode, boolean hasPassed) { + return (outputMode == TestOutputFormat.ALL) || + (!hasPassed && (outputMode == TestOutputFormat.ERRORS)); + } + + /** + * Reads the contents of the test log from the provided testOutput file, adds + * header and footer and returns the result. + * This method also looks for a header delimiter and cuts off the text before it, + * except if the header is 50 lines or longer. + */ + public static void writeTestLog(Path testOutput, String testName, OutputStream out) + throws IOException { + InputStream input = null; + PrintStream printOut = new PrintStream(new BufferedOutputStream(out)); + try { + final String outputHeader = + "==================== Test output for " + testName + ":"; + final String outputFooter = + "================================================================================"; + + printOut.println(outputHeader); + printOut.flush(); + + input = testOutput.getInputStream(); + FilterTestHeaderOutputStream filteringOutputStream = getHeaderFilteringOutputStream(printOut); + ByteStreams.copy(input, filteringOutputStream); + + if (!filteringOutputStream.foundHeader()) { + InputStream inputAgain = testOutput.getInputStream(); + try { + ByteStreams.copy(inputAgain, out); + } finally { + inputAgain.close(); + } + } + + printOut.println(outputFooter); + } finally { + printOut.flush(); + if (input != null) { + input.close(); + } + } + } + + /** + * Returns an output stream that doesn't write to original until it + * sees HEADER_DELIMITER by itself on a line. + */ + public static FilterTestHeaderOutputStream getHeaderFilteringOutputStream(OutputStream original) { + return new FilterTestHeaderOutputStream(original); + } + + private TestLogHelper() { + // Prevent Java from creating a public constructor. + } + + /** + * Use this class to filter the streaming output of a test until we see the + * header delimiter. + */ + public static class FilterTestHeaderOutputStream extends FilterOutputStream { + + private boolean seenDelimiter = false; + private StringBuilder lineBuilder = new StringBuilder(); + + private static final int NEWLINE = '\n'; + + public FilterTestHeaderOutputStream(OutputStream out) { + super(out); + } + + @Override + public void write(int b) throws IOException { + if (seenDelimiter) { + out.write(b); + } else if (b == NEWLINE) { + String line = lineBuilder.toString(); + lineBuilder = new StringBuilder(); + if (line.equals(TestLogHelper.HEADER_DELIMITER)) { + seenDelimiter = true; + } + } else if (lineBuilder.length() <= TestLogHelper.HEADER_DELIMITER.length()) { + lineBuilder.append((char) b); + } + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + if (seenDelimiter) { + out.write(b, off, len); + } else { + super.write(b, off, len); + } + } + + public boolean foundHeader() { + return seenDelimiter; + } + } +} |