From 052d61b1da0ffbcaa613ee777fadab215b42a648 Mon Sep 17 00:00:00 2001 From: "whesse@google.com" Date: Wed, 9 Apr 2014 10:38:28 +0000 Subject: [PATCH] Truncate excessively long output from tests in test.dart. BUG=dartbug.com/18084 R=kustermann@google.com Review URL: https://codereview.chromium.org//227113010 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@34867 260f80e4-7a28-3924-810f-c04153c831b5 --- tools/testing/dart/test_runner.dart | 100 +++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 18 deletions(-) diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart index ed530cce4ba..a3d59b9b560 100644 --- a/tools/testing/dart/test_runner.dart +++ b/tools/testing/dart/test_runner.dart @@ -670,8 +670,9 @@ class CommandBuilder { } Command _getUniqueCommand(Command command) { - // All Command classes have hashCode/operator==, so we check if this command - // has already been build, if so we return the cached one, otherwise we + // All Command classes implement hashCode and operator==. + // We check if this command has already been built. + // If so, we return the cached one. Otherwise we // store the one given as [command] argument. var cachedCommand = _cachedCommands[command]; if (cachedCommand != null) { @@ -1673,6 +1674,69 @@ CommandOutput createCommandOutput(Command command, } +/** + * An OutputLog records the output from a test, but truncates it if + * it is longer than MAX_HEAD characters, and just keeps the head and + * the last TAIL_LENGTH characters of the output. + */ +class OutputLog { + static const int MAX_HEAD = 100 * 1024; + static const int TAIL_LENGTH = 10 * 1024; + List head = []; + List tail; + List complete; + bool dataDropped = false; + + OutputLog(); + + void add(List data) { + if (complete != null) { + throw new StateError("Cannot add to OutputLog after calling toList"); + } + if (tail == null) { + head.addAll(data); + if (head.length > MAX_HEAD) { + tail = head.sublist(MAX_HEAD); + head.length = MAX_HEAD; + } + } else { + tail.addAll(data); + } + if (tail != null && tail.length > 2 * TAIL_LENGTH) { + tail = _truncatedTail(); + dataDropped = true; + } + } + + List _truncatedTail() => + tail.length > TAIL_LENGTH ? + tail.sublist(tail.length - TAIL_LENGTH) : + tail; + + List toList() { + if (complete == null) { + complete = head; + if (dataDropped) { + complete.addAll(""" + +***************************************************************************** + +Data removed due to excessive length + +***************************************************************************** + +""".codeUnits); + complete.addAll(_truncatedTail()); + } else if (tail != null) { + complete.addAll(tail); + } + head = null; + tail = null; + } + return complete; + } +} + /** * A RunningProcess actually runs a test, getting the command lines from * its [TestCase], starting the test process (and first, a compilation @@ -1690,8 +1754,8 @@ class RunningProcess { DateTime startTime; Timer timeoutTimer; int pid; - List stdout = []; - List stderr = []; + OutputLog stdout = new OutputLog(); + OutputLog stderr = new OutputLog(); bool compilationSkipped = false; Completer completer; @@ -1814,8 +1878,8 @@ class RunningProcess { command, exitCode, timedOut, - stdout, - stderr, + stdout.toList(), + stderr.toList(), new DateTime.now().difference(startTime), compilationSkipped, pid); @@ -1823,8 +1887,8 @@ class RunningProcess { } StreamSubscription _drainStream(Stream> source, - List destination) { - return source.listen(destination.addAll); + OutputLog destination) { + return source.listen(destination.add); } Map _createProcessEnvironment() { @@ -1875,8 +1939,8 @@ class BatchRunnerProcess { Function _processExitHandler; bool _currentlyRunning = false; - List _testStdout; - List _testStderr; + OutputLog _testStdout; + OutputLog _testStderr; String _status; DateTime _startTime; Timer _timer; @@ -1932,8 +1996,8 @@ class BatchRunnerProcess { void doStartTest(Command command, int timeout) { _startTime = new DateTime.now(); - _testStdout = []; - _testStderr = []; + _testStdout = new OutputLog(); + _testStderr = new OutputLog(); _status = null; _stdoutCompleter = new Completer(); _stderrCompleter = new Completer(); @@ -1963,8 +2027,8 @@ class BatchRunnerProcess { var output = createCommandOutput(_command, exitCode, (outcome == "TIMEOUT"), - _testStdout, - _testStderr, + _testStdout.toList(), + _testStderr.toList(), new DateTime.now().difference(_startTime), false); assert(_completer != null); @@ -2020,8 +2084,8 @@ class BatchRunnerProcess { } else if (line.startsWith('>>> ')) { throw new Exception("Unexpected command from batch runner: '$line'."); } else { - _testStdout.addAll(encodeUtf8(line)); - _testStdout.addAll("\n".codeUnits); + _testStdout.add(encodeUtf8(line)); + _testStdout.add("\n".codeUnits); } if (_status != null) { _stdoutSubscription.pause(); @@ -2040,8 +2104,8 @@ class BatchRunnerProcess { _stderrSubscription.pause(); _stderrCompleter.complete(null); } else { - _testStderr.addAll(encodeUtf8(line)); - _testStderr.addAll("\n".codeUnits); + _testStderr.add(encodeUtf8(line)); + _testStderr.add("\n".codeUnits); } }); _stderrSubscription.pause();