OLD | NEW |
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 /** The actual command line that will be executed. */ | 100 /** The actual command line that will be executed. */ |
101 String commandLine; | 101 String commandLine; |
102 | 102 |
103 Command(this.executable, this.arguments, [this.environment = null]) { | 103 Command(this.executable, this.arguments, [this.environment = null]) { |
104 if (io.Platform.operatingSystem == 'windows') { | 104 if (io.Platform.operatingSystem == 'windows') { |
105 // Windows can't handle the first command if it is a .bat file or the like | 105 // Windows can't handle the first command if it is a .bat file or the like |
106 // with the slashes going the other direction. | 106 // with the slashes going the other direction. |
107 // TODO(efortuna): Remove this when fixed (Issue 1306). | 107 // TODO(efortuna): Remove this when fixed (Issue 1306). |
108 executable = executable.replaceAll('/', '\\'); | 108 executable = executable.replaceAll('/', '\\'); |
109 } | 109 } |
110 commandLine = "$executable ${Strings.join(arguments, ' ')}"; | 110 commandLine = "$executable ${arguments.join(' ')}"; |
111 } | 111 } |
112 | 112 |
113 String toString() => commandLine; | 113 String toString() => commandLine; |
114 | 114 |
115 Future<bool> get outputIsUpToDate => new Future.immediate(false); | 115 Future<bool> get outputIsUpToDate => new Future.immediate(false); |
116 io.Path get expectedOutputFile => null; | 116 io.Path get expectedOutputFile => null; |
117 bool get isPixelTest => false; | 117 bool get isPixelTest => false; |
118 } | 118 } |
119 | 119 |
120 class CompilationCommand extends Command { | 120 class CompilationCommand extends Command { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 _getArguments(options, htmlFile), | 189 _getArguments(options, htmlFile), |
190 _getEnvironment(dartFlags)); | 190 _getEnvironment(dartFlags)); |
191 | 191 |
192 static Map _getEnvironment(List<String> dartFlags) { | 192 static Map _getEnvironment(List<String> dartFlags) { |
193 var needDartFlags = dartFlags != null && dartFlags.length > 0; | 193 var needDartFlags = dartFlags != null && dartFlags.length > 0; |
194 | 194 |
195 var env = null; | 195 var env = null; |
196 if (needDartFlags) { | 196 if (needDartFlags) { |
197 env = new Map.from(io.Platform.environment); | 197 env = new Map.from(io.Platform.environment); |
198 if (needDartFlags) { | 198 if (needDartFlags) { |
199 env['DART_FLAGS'] = Strings.join(dartFlags, " "); | 199 env['DART_FLAGS'] = dartFlags.join(" "); |
200 } | 200 } |
201 } | 201 } |
202 | 202 |
203 return env; | 203 return env; |
204 } | 204 } |
205 | 205 |
206 static List<String> _getArguments(List<String> options, String htmlFile) { | 206 static List<String> _getArguments(List<String> options, String htmlFile) { |
207 var arguments = new List.from(options); | 207 var arguments = new List.from(options); |
208 arguments.add(htmlFile); | 208 arguments.add(htmlFile); |
209 return arguments; | 209 return arguments; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 var suffixSplit = suffix.split(' '); | 298 var suffixSplit = suffix.split(' '); |
299 suffixSplit.forEach((e) { | 299 suffixSplit.forEach((e) { |
300 if (!e.isEmpty) newArguments.add(e); | 300 if (!e.isEmpty) newArguments.add(e); |
301 }); | 301 }); |
302 | 302 |
303 newArguments.addAll(c.arguments); | 303 newArguments.addAll(c.arguments); |
304 final newCommand = new Command(newExecutablePath, newArguments); | 304 final newCommand = new Command(newExecutablePath, newArguments); |
305 newCommands.add(newCommand); | 305 newCommands.add(newCommand); |
306 // If there are extra spaces inside the prefix or suffix, this fails. | 306 // If there are extra spaces inside the prefix or suffix, this fails. |
307 String expected = | 307 String expected = |
308 '$prefix ${c.executable} $suffix ${Strings.join(c.arguments, ' ')}'; | 308 '$prefix ${c.executable} $suffix ${c.arguments.join(' ')}'; |
309 Expect.stringEquals(expected.trim(), newCommand.commandLine); | 309 Expect.stringEquals(expected.trim(), newCommand.commandLine); |
310 } | 310 } |
311 commands = newCommands; | 311 commands = newCommands; |
312 } | 312 } |
313 } | 313 } |
314 | 314 |
315 CommandOutput get lastCommandOutput { | 315 CommandOutput get lastCommandOutput { |
316 if (commandOutputs.length == 0) { | 316 if (commandOutputs.length == 0) { |
317 throw new Exception("CommandOutputs is empty, maybe no command was run? (" | 317 throw new Exception("CommandOutputs is empty, maybe no command was run? (" |
318 "displayName: '$displayName', " | 318 "displayName: '$displayName', " |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 print('Error on batch runner input stream stdin'); | 1145 print('Error on batch runner input stream stdin'); |
1146 print(' Input line: $line'); | 1146 print(' Input line: $line'); |
1147 print(' Previous test\'s status: $_status'); | 1147 print(' Previous test\'s status: $_status'); |
1148 print(' Error: $err'); | 1148 print(' Error: $err'); |
1149 throw err; | 1149 throw err; |
1150 }; | 1150 }; |
1151 _process.stdin.write(line.charCodes); | 1151 _process.stdin.write(line.charCodes); |
1152 } | 1152 } |
1153 | 1153 |
1154 String _createArgumentsLine(List<String> arguments) { | 1154 String _createArgumentsLine(List<String> arguments) { |
1155 return Strings.join(arguments, ' ').concat('\n'); | 1155 return arguments.join(' ').concat('\n'); |
1156 } | 1156 } |
1157 | 1157 |
1158 void _reportResult() { | 1158 void _reportResult() { |
1159 if (!active) return; | 1159 if (!active) return; |
1160 // _status == '>>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}' | 1160 // _status == '>>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}' |
1161 | 1161 |
1162 var outcome = _status.split(" ")[2]; | 1162 var outcome = _status.split(" ")[2]; |
1163 var exitCode = 0; | 1163 var exitCode = 0; |
1164 if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE; | 1164 if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE; |
1165 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; | 1165 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 _startProcess(callback) { | 1280 _startProcess(callback) { |
1281 Future processFuture = io.Process.start(_executable, _batchArguments); | 1281 Future processFuture = io.Process.start(_executable, _batchArguments); |
1282 processFuture.then((io.Process p) { | 1282 processFuture.then((io.Process p) { |
1283 _process = p; | 1283 _process = p; |
1284 _stdoutStream = new io.StringInputStream(_process.stdout); | 1284 _stdoutStream = new io.StringInputStream(_process.stdout); |
1285 _stderrStream = new io.StringInputStream(_process.stderr); | 1285 _stderrStream = new io.StringInputStream(_process.stderr); |
1286 _process.onExit = makeExitHandler(">>> TEST CRASH"); | 1286 _process.onExit = makeExitHandler(">>> TEST CRASH"); |
1287 callback(); | 1287 callback(); |
1288 }).catchError((e) { | 1288 }).catchError((e) { |
1289 print("Process error:"); | 1289 print("Process error:"); |
1290 print(" Command: $_executable ${Strings.join(_batchArguments, ' ')}"); | 1290 print(" Command: $_executable ${_batchArguments.join(' ')}"); |
1291 print(" Error: $e"); | 1291 print(" Error: $e"); |
1292 // If there is an error starting a batch process, chances are that | 1292 // If there is an error starting a batch process, chances are that |
1293 // it will always fail. So rather than re-trying a 1000+ times, we | 1293 // it will always fail. So rather than re-trying a 1000+ times, we |
1294 // exit. | 1294 // exit. |
1295 exit(1); | 1295 exit(1); |
1296 return true; | 1296 return true; |
1297 }); | 1297 }); |
1298 } | 1298 } |
1299 } | 1299 } |
1300 | 1300 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1457 resumeTesting(); | 1457 resumeTesting(); |
1458 } | 1458 } |
1459 line = stdoutStringStream.readLine(); | 1459 line = stdoutStringStream.readLine(); |
1460 } | 1460 } |
1461 if (!_isSeleniumAvailable) { | 1461 if (!_isSeleniumAvailable) { |
1462 _startSeleniumServer(); | 1462 _startSeleniumServer(); |
1463 } | 1463 } |
1464 }; | 1464 }; |
1465 }).catchError((e) { | 1465 }).catchError((e) { |
1466 print("Error starting process:"); | 1466 print("Error starting process:"); |
1467 print(" Command: $cmd ${Strings.join(arg, ' ')}"); | 1467 print(" Command: $cmd ${arg.join(' ')}"); |
1468 print(" Error: $e"); | 1468 print(" Error: $e"); |
1469 // TODO(ahe): How to report this as a test failure? | 1469 // TODO(ahe): How to report this as a test failure? |
1470 exit(1); | 1470 exit(1); |
1471 return true; | 1471 return true; |
1472 }); | 1472 }); |
1473 } | 1473 } |
1474 } | 1474 } |
1475 | 1475 |
1476 void _runTest(TestCase test) { | 1476 void _runTest(TestCase test) { |
1477 if (test.usesWebDriver) { | 1477 if (test.usesWebDriver) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 } | 1573 } |
1574 throw new Exception('Unable to find inactive batch runner.'); | 1574 throw new Exception('Unable to find inactive batch runner.'); |
1575 } | 1575 } |
1576 | 1576 |
1577 void _tryRunTest() { | 1577 void _tryRunTest() { |
1578 _checkDone(); | 1578 _checkDone(); |
1579 if (_numProcesses < _maxProcesses && !_tests.isEmpty) { | 1579 if (_numProcesses < _maxProcesses && !_tests.isEmpty) { |
1580 TestCase test = _tests.removeFirst(); | 1580 TestCase test = _tests.removeFirst(); |
1581 if (_listTests) { | 1581 if (_listTests) { |
1582 var fields = [test.displayName, | 1582 var fields = [test.displayName, |
1583 Strings.join(new List.from(test.expectedOutcomes), ','), | 1583 test.expectedOutcomes.join(','), |
1584 test.isNegative.toString()]; | 1584 test.isNegative.toString()]; |
1585 fields.addAll(test.commands.last.arguments); | 1585 fields.addAll(test.commands.last.arguments); |
1586 print(Strings.join(fields, '\t')); | 1586 print(fields.join('\t')); |
1587 return; | 1587 return; |
1588 } | 1588 } |
1589 if (test.usesWebDriver && _needsSelenium && !_isSeleniumAvailable || (test | 1589 if (test.usesWebDriver && _needsSelenium && !_isSeleniumAvailable || (test |
1590 is BrowserTestCase && test.waitingForOtherTest)) { | 1590 is BrowserTestCase && test.waitingForOtherTest)) { |
1591 // The test is not yet ready to run. Put the test back in | 1591 // The test is not yet ready to run. Put the test back in |
1592 // the queue. Avoid spin-polling by using a timeout. | 1592 // the queue. Avoid spin-polling by using a timeout. |
1593 _tests.add(test); | 1593 _tests.add(test); |
1594 new Timer(100, (_) => _tryRunTest()); // Don't lose a process. | 1594 new Timer(100, (_) => _tryRunTest()); // Don't lose a process. |
1595 return; | 1595 return; |
1596 } | 1596 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1751 completer.complete(testCase); | 1751 completer.complete(testCase); |
1752 } | 1752 } |
1753 }); | 1753 }); |
1754 } | 1754 } |
1755 runCommand(); | 1755 runCommand(); |
1756 | 1756 |
1757 return completer.future; | 1757 return completer.future; |
1758 } | 1758 } |
1759 } | 1759 } |
1760 | 1760 |
OLD | NEW |