aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/test/TestLogHelper.java
diff options
context:
space:
mode:
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.java141
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;
+ }
+ }
+}