Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: tools/testing/dart/test_runner.dart

Issue 227113010: Truncate excessively long output from tests in test.dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Classes and methods for executing tests. 6 * Classes and methods for executing tests.
7 * 7 *
8 * This module includes: 8 * This module includes:
9 * - Managing parallel execution of tests, including timeout checks. 9 * - Managing parallel execution of tests, including timeout checks.
10 * - Evaluating the output of each test as pass/fail/crash/timeout. 10 * - Evaluating the output of each test as pass/fail/crash/timeout.
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 } 663 }
664 664
665 Command getModifyPubspecCommand(String pubspecYamlFile, Map depsOverrides, 665 Command getModifyPubspecCommand(String pubspecYamlFile, Map depsOverrides,
666 {String destinationFile: null}) { 666 {String destinationFile: null}) {
667 if (destinationFile == null) destinationFile = pubspecYamlFile; 667 if (destinationFile == null) destinationFile = pubspecYamlFile;
668 return _getUniqueCommand(new ModifyPubspecYamlCommand._( 668 return _getUniqueCommand(new ModifyPubspecYamlCommand._(
669 pubspecYamlFile, destinationFile, depsOverrides)); 669 pubspecYamlFile, destinationFile, depsOverrides));
670 } 670 }
671 671
672 Command _getUniqueCommand(Command command) { 672 Command _getUniqueCommand(Command command) {
673 // All Command classes have hashCode/operator==, so we check if this command 673 // All Command classes implement hashCode and operator==.
674 // has already been build, if so we return the cached one, otherwise we 674 // We check if this command has already been built.
675 // If so, we return the cached one. Otherwise we
675 // store the one given as [command] argument. 676 // store the one given as [command] argument.
676 var cachedCommand = _cachedCommands[command]; 677 var cachedCommand = _cachedCommands[command];
677 if (cachedCommand != null) { 678 if (cachedCommand != null) {
678 return cachedCommand; 679 return cachedCommand;
679 } 680 }
680 _cachedCommands[command] = command; 681 _cachedCommands[command] = command;
681 return command; 682 return command;
682 } 683 }
683 } 684 }
684 685
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 command, exitCode, timedOut, stdout, stderr, time); 1668 command, exitCode, timedOut, stdout, stderr, time);
1668 } 1669 }
1669 1670
1670 return new CommandOutputImpl( 1671 return new CommandOutputImpl(
1671 command, exitCode, timedOut, stdout, stderr, 1672 command, exitCode, timedOut, stdout, stderr,
1672 time, compilationSkipped, pid); 1673 time, compilationSkipped, pid);
1673 } 1674 }
1674 1675
1675 1676
1676 /** 1677 /**
1678 * An OutputLog records the output from a test, but truncates it if
1679 * it is longer than MAX_HEAD characters, and just keeps the head and
1680 * the last TAIL_LENGTH characters of the output.
1681 */
1682 class OutputLog {
1683 static const int MAX_HEAD = 100 * 1024;
1684 static const int TAIL_LENGTH = 10 * 1024;
1685 List<int> head = <int>[];
1686 List<int> tail;
1687 List<int> complete;
1688 bool dataDropped = false;
1689
1690 OutputLog();
1691
1692 void add(List<int> data) {
1693 if (complete != null) {
1694 throw new StateError("Cannot add to OutputLog after calling toList");
1695 }
1696 if (tail == null) {
1697 head.addAll(data);
1698 if (head.length > MAX_HEAD) {
1699 tail = head.sublist(MAX_HEAD);
1700 head.length = MAX_HEAD;
Ivan Posva 2014/04/10 00:10:44 This is making matters actually worse, ending up u
Bill Hesse 2014/04/11 07:39:48 These variables are only live while the test is ru
1701 }
1702 } else {
1703 tail.addAll(data);
1704 }
1705 if (tail != null && tail.length > 2 * TAIL_LENGTH) {
1706 tail = _truncatedTail();
1707 dataDropped = true;
1708 }
1709 }
1710
1711 List<int> _truncatedTail() =>
1712 tail.length > TAIL_LENGTH ?
1713 tail.sublist(tail.length - TAIL_LENGTH) :
1714 tail;
1715
1716 List<int> toList() {
1717 if (complete == null) {
1718 complete = head;
1719 if (dataDropped) {
1720 complete.addAll("""
1721
1722 *****************************************************************************
1723
1724 Data removed due to excessive length
1725
1726 *****************************************************************************
1727
1728 """.codeUnits);
1729 complete.addAll(_truncatedTail());
1730 } else if (tail != null) {
1731 complete.addAll(tail);
1732 }
1733 head = null;
1734 tail = null;
1735 }
1736 return complete;
1737 }
1738 }
1739
1740 /**
1677 * A RunningProcess actually runs a test, getting the command lines from 1741 * A RunningProcess actually runs a test, getting the command lines from
1678 * its [TestCase], starting the test process (and first, a compilation 1742 * its [TestCase], starting the test process (and first, a compilation
1679 * process if the TestCase is a [BrowserTestCase]), creating a timeout 1743 * process if the TestCase is a [BrowserTestCase]), creating a timeout
1680 * timer, and recording the results in a new [CommandOutput] object, which it 1744 * timer, and recording the results in a new [CommandOutput] object, which it
1681 * attaches to the TestCase. The lifetime of the RunningProcess is limited 1745 * attaches to the TestCase. The lifetime of the RunningProcess is limited
1682 * to the time it takes to start the process, run the process, and record 1746 * to the time it takes to start the process, run the process, and record
1683 * the result; there are no pointers to it, so it should be available to 1747 * the result; there are no pointers to it, so it should be available to
1684 * be garbage collected as soon as it is done. 1748 * be garbage collected as soon as it is done.
1685 */ 1749 */
1686 class RunningProcess { 1750 class RunningProcess {
1687 ProcessCommand command; 1751 ProcessCommand command;
1688 int timeout; 1752 int timeout;
1689 bool timedOut = false; 1753 bool timedOut = false;
1690 DateTime startTime; 1754 DateTime startTime;
1691 Timer timeoutTimer; 1755 Timer timeoutTimer;
1692 int pid; 1756 int pid;
1693 List<int> stdout = <int>[]; 1757 OutputLog stdout = new OutputLog();
1694 List<int> stderr = <int>[]; 1758 OutputLog stderr = new OutputLog();
1695 bool compilationSkipped = false; 1759 bool compilationSkipped = false;
1696 Completer<CommandOutput> completer; 1760 Completer<CommandOutput> completer;
1697 1761
1698 RunningProcess(this.command, this.timeout); 1762 RunningProcess(this.command, this.timeout);
1699 1763
1700 Future<CommandOutput> run() { 1764 Future<CommandOutput> run() {
1701 completer = new Completer<CommandOutput>(); 1765 completer = new Completer<CommandOutput>();
1702 startTime = new DateTime.now(); 1766 startTime = new DateTime.now();
1703 _runCommand(); 1767 _runCommand();
1704 return completer.future; 1768 return completer.future;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 } 1871 }
1808 var commandOutput = _createCommandOutput(command, exitCode); 1872 var commandOutput = _createCommandOutput(command, exitCode);
1809 completer.complete(commandOutput); 1873 completer.complete(commandOutput);
1810 } 1874 }
1811 1875
1812 CommandOutput _createCommandOutput(ProcessCommand command, int exitCode) { 1876 CommandOutput _createCommandOutput(ProcessCommand command, int exitCode) {
1813 var commandOutput = createCommandOutput( 1877 var commandOutput = createCommandOutput(
1814 command, 1878 command,
1815 exitCode, 1879 exitCode,
1816 timedOut, 1880 timedOut,
1817 stdout, 1881 stdout.toList(),
1818 stderr, 1882 stderr.toList(),
1819 new DateTime.now().difference(startTime), 1883 new DateTime.now().difference(startTime),
1820 compilationSkipped, 1884 compilationSkipped,
1821 pid); 1885 pid);
1822 return commandOutput; 1886 return commandOutput;
1823 } 1887 }
1824 1888
1825 StreamSubscription _drainStream(Stream<List<int>> source, 1889 StreamSubscription _drainStream(Stream<List<int>> source,
1826 List<int> destination) { 1890 OutputLog destination) {
1827 return source.listen(destination.addAll); 1891 return source.listen(destination.add);
1828 } 1892 }
1829 1893
1830 Map<String, String> _createProcessEnvironment() { 1894 Map<String, String> _createProcessEnvironment() {
1831 var environment = new Map.from(io.Platform.environment); 1895 var environment = new Map.from(io.Platform.environment);
1832 1896
1833 if (command.environmentOverrides != null) { 1897 if (command.environmentOverrides != null) {
1834 for (var key in command.environmentOverrides.keys) { 1898 for (var key in command.environmentOverrides.keys) {
1835 environment[key] = command.environmentOverrides[key]; 1899 environment[key] = command.environmentOverrides[key];
1836 } 1900 }
1837 } 1901 }
(...skipping 30 matching lines...) Expand all
1868 1932
1869 io.Process _process; 1933 io.Process _process;
1870 Map _processEnvironmentOverrides; 1934 Map _processEnvironmentOverrides;
1871 Completer _stdoutCompleter; 1935 Completer _stdoutCompleter;
1872 Completer _stderrCompleter; 1936 Completer _stderrCompleter;
1873 StreamSubscription<String> _stdoutSubscription; 1937 StreamSubscription<String> _stdoutSubscription;
1874 StreamSubscription<String> _stderrSubscription; 1938 StreamSubscription<String> _stderrSubscription;
1875 Function _processExitHandler; 1939 Function _processExitHandler;
1876 1940
1877 bool _currentlyRunning = false; 1941 bool _currentlyRunning = false;
1878 List<int> _testStdout; 1942 OutputLog _testStdout;
1879 List<int> _testStderr; 1943 OutputLog _testStderr;
1880 String _status; 1944 String _status;
1881 DateTime _startTime; 1945 DateTime _startTime;
1882 Timer _timer; 1946 Timer _timer;
1883 1947
1884 BatchRunnerProcess(); 1948 BatchRunnerProcess();
1885 1949
1886 Future<CommandOutput> runCommand(String runnerType, ProcessCommand command, 1950 Future<CommandOutput> runCommand(String runnerType, ProcessCommand command,
1887 int timeout, List<String> arguments) { 1951 int timeout, List<String> arguments) {
1888 assert(_completer == null); 1952 assert(_completer == null);
1889 assert(!_currentlyRunning); 1953 assert(!_currentlyRunning);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 if (killTimer != null) killTimer.cancel(); 1989 if (killTimer != null) killTimer.cancel();
1926 terminateCompleter.complete(true); 1990 terminateCompleter.complete(true);
1927 }; 1991 };
1928 _process.kill(); 1992 _process.kill();
1929 1993
1930 return terminateCompleter.future; 1994 return terminateCompleter.future;
1931 } 1995 }
1932 1996
1933 void doStartTest(Command command, int timeout) { 1997 void doStartTest(Command command, int timeout) {
1934 _startTime = new DateTime.now(); 1998 _startTime = new DateTime.now();
1935 _testStdout = []; 1999 _testStdout = new OutputLog();
1936 _testStderr = []; 2000 _testStderr = new OutputLog();
1937 _status = null; 2001 _status = null;
1938 _stdoutCompleter = new Completer(); 2002 _stdoutCompleter = new Completer();
1939 _stderrCompleter = new Completer(); 2003 _stderrCompleter = new Completer();
1940 _timer = new Timer(new Duration(seconds: timeout), 2004 _timer = new Timer(new Duration(seconds: timeout),
1941 _timeoutHandler); 2005 _timeoutHandler);
1942 2006
1943 var line = _createArgumentsLine(_arguments, timeout); 2007 var line = _createArgumentsLine(_arguments, timeout);
1944 _process.stdin.write(line); 2008 _process.stdin.write(line);
1945 _stdoutSubscription.resume(); 2009 _stdoutSubscription.resume();
1946 _stderrSubscription.resume(); 2010 _stderrSubscription.resume();
1947 Future.wait([_stdoutCompleter.future, 2011 Future.wait([_stdoutCompleter.future,
1948 _stderrCompleter.future]).then((_) => _reportResult()); 2012 _stderrCompleter.future]).then((_) => _reportResult());
1949 } 2013 }
1950 2014
1951 String _createArgumentsLine(List<String> arguments, int timeout) { 2015 String _createArgumentsLine(List<String> arguments, int timeout) {
1952 return arguments.join(' ') + '\n'; 2016 return arguments.join(' ') + '\n';
1953 } 2017 }
1954 2018
1955 void _reportResult() { 2019 void _reportResult() {
1956 if (!_currentlyRunning) return; 2020 if (!_currentlyRunning) return;
1957 // _status == '>>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}' 2021 // _status == '>>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}'
1958 2022
1959 var outcome = _status.split(" ")[2]; 2023 var outcome = _status.split(" ")[2];
1960 var exitCode = 0; 2024 var exitCode = 0;
1961 if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE; 2025 if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE;
1962 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; 2026 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1;
1963 var output = createCommandOutput(_command, 2027 var output = createCommandOutput(_command,
1964 exitCode, 2028 exitCode,
1965 (outcome == "TIMEOUT"), 2029 (outcome == "TIMEOUT"),
1966 _testStdout, 2030 _testStdout.toList(),
1967 _testStderr, 2031 _testStderr.toList(),
1968 new DateTime.now().difference(_startTime), 2032 new DateTime.now().difference(_startTime),
1969 false); 2033 false);
1970 assert(_completer != null); 2034 assert(_completer != null);
1971 _completer.complete(output); 2035 _completer.complete(output);
1972 _completer = null; 2036 _completer = null;
1973 _currentlyRunning = false; 2037 _currentlyRunning = false;
1974 } 2038 }
1975 2039
1976 ExitCodeEvent makeExitHandler(String status) { 2040 ExitCodeEvent makeExitHandler(String status) {
1977 void handler(int exitCode) { 2041 void handler(int exitCode) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 .transform(UTF8.decoder) 2077 .transform(UTF8.decoder)
2014 .transform(new LineSplitter()); 2078 .transform(new LineSplitter());
2015 _stdoutSubscription = _stdoutStream.listen((String line) { 2079 _stdoutSubscription = _stdoutStream.listen((String line) {
2016 if (line.startsWith('>>> TEST')) { 2080 if (line.startsWith('>>> TEST')) {
2017 _status = line; 2081 _status = line;
2018 } else if (line.startsWith('>>> BATCH')) { 2082 } else if (line.startsWith('>>> BATCH')) {
2019 // ignore 2083 // ignore
2020 } else if (line.startsWith('>>> ')) { 2084 } else if (line.startsWith('>>> ')) {
2021 throw new Exception("Unexpected command from batch runner: '$line'."); 2085 throw new Exception("Unexpected command from batch runner: '$line'.");
2022 } else { 2086 } else {
2023 _testStdout.addAll(encodeUtf8(line)); 2087 _testStdout.add(encodeUtf8(line));
2024 _testStdout.addAll("\n".codeUnits); 2088 _testStdout.add("\n".codeUnits);
2025 } 2089 }
2026 if (_status != null) { 2090 if (_status != null) {
2027 _stdoutSubscription.pause(); 2091 _stdoutSubscription.pause();
2028 _timer.cancel(); 2092 _timer.cancel();
2029 _stdoutCompleter.complete(null); 2093 _stdoutCompleter.complete(null);
2030 } 2094 }
2031 }); 2095 });
2032 _stdoutSubscription.pause(); 2096 _stdoutSubscription.pause();
2033 2097
2034 var _stderrStream = 2098 var _stderrStream =
2035 _process.stderr 2099 _process.stderr
2036 .transform(UTF8.decoder) 2100 .transform(UTF8.decoder)
2037 .transform(new LineSplitter()); 2101 .transform(new LineSplitter());
2038 _stderrSubscription = _stderrStream.listen((String line) { 2102 _stderrSubscription = _stderrStream.listen((String line) {
2039 if (line.startsWith('>>> EOF STDERR')) { 2103 if (line.startsWith('>>> EOF STDERR')) {
2040 _stderrSubscription.pause(); 2104 _stderrSubscription.pause();
2041 _stderrCompleter.complete(null); 2105 _stderrCompleter.complete(null);
2042 } else { 2106 } else {
2043 _testStderr.addAll(encodeUtf8(line)); 2107 _testStderr.add(encodeUtf8(line));
2044 _testStderr.addAll("\n".codeUnits); 2108 _testStderr.add("\n".codeUnits);
2045 } 2109 }
2046 }); 2110 });
2047 _stderrSubscription.pause(); 2111 _stderrSubscription.pause();
2048 2112
2049 _processExitHandler = makeExitHandler(">>> TEST CRASH"); 2113 _processExitHandler = makeExitHandler(">>> TEST CRASH");
2050 _process.exitCode.then((exitCode) { 2114 _process.exitCode.then((exitCode) {
2051 _processExitHandler(exitCode); 2115 _processExitHandler(exitCode);
2052 }); 2116 });
2053 2117
2054 _process.stdin.done.catchError((err) { 2118 _process.stdin.done.catchError((err) {
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
2870 } 2934 }
2871 } 2935 }
2872 2936
2873 void eventAllTestsDone() { 2937 void eventAllTestsDone() {
2874 for (var listener in _eventListener) { 2938 for (var listener in _eventListener) {
2875 listener.allDone(); 2939 listener.allDone();
2876 } 2940 }
2877 _allDone(); 2941 _allDone();
2878 } 2942 }
2879 } 2943 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698