| 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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 class KernelCompilationCommand extends CompilationCommand { | 229 class KernelCompilationCommand extends CompilationCommand { |
| 230 KernelCompilationCommand._( | 230 KernelCompilationCommand._( |
| 231 String displayName, | 231 String displayName, |
| 232 String outputFile, | 232 String outputFile, |
| 233 bool neverSkipCompilation, | 233 bool neverSkipCompilation, |
| 234 List<Uri> bootstrapDependencies, | 234 List<Uri> bootstrapDependencies, |
| 235 String executable, | 235 String executable, |
| 236 List<String> arguments, | 236 List<String> arguments, |
| 237 Map<String, String> environmentOverrides) | 237 Map<String, String> environmentOverrides) |
| 238 : super._(displayName, outputFile, neverSkipCompilation, | 238 : super._(displayName, outputFile, neverSkipCompilation, |
| 239 bootstrapDependencies, executable, arguments, | 239 bootstrapDependencies, executable, arguments, environmentOverrides); |
| 240 environmentOverrides); | |
| 241 | 240 |
| 242 int get maxNumRetries => 1; | 241 int get maxNumRetries => 1; |
| 243 } | 242 } |
| 244 | 243 |
| 245 /// This is just a Pair(String, Map) class with hashCode and operator == | 244 /// This is just a Pair(String, Map) class with hashCode and operator == |
| 246 class AddFlagsKey { | 245 class AddFlagsKey { |
| 247 final String flags; | 246 final String flags; |
| 248 final Map env; | 247 final Map env; |
| 249 AddFlagsKey(this.flags, this.env); | 248 AddFlagsKey(this.flags, this.env); |
| 250 // Just use object identity for environment map | 249 // Just use object identity for environment map |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 VmCommand._(String executable, List<String> arguments, | 366 VmCommand._(String executable, List<String> arguments, |
| 368 Map<String, String> environmentOverrides) | 367 Map<String, String> environmentOverrides) |
| 369 : super._("vm", executable, arguments, environmentOverrides); | 368 : super._("vm", executable, arguments, environmentOverrides); |
| 370 } | 369 } |
| 371 | 370 |
| 372 class VmBatchCommand extends ProcessCommand implements VmCommand { | 371 class VmBatchCommand extends ProcessCommand implements VmCommand { |
| 373 final String dartFile; | 372 final String dartFile; |
| 374 final bool checked; | 373 final bool checked; |
| 375 | 374 |
| 376 VmBatchCommand._(String executable, String dartFile, List<String> arguments, | 375 VmBatchCommand._(String executable, String dartFile, List<String> arguments, |
| 377 Map<String, String> environmentOverrides, {this.checked: true}) | 376 Map<String, String> environmentOverrides, |
| 377 {this.checked: true}) |
| 378 : this.dartFile = dartFile, | 378 : this.dartFile = dartFile, |
| 379 super._('vm-batch', executable, arguments, environmentOverrides); | 379 super._('vm-batch', executable, arguments, environmentOverrides); |
| 380 | 380 |
| 381 @override | 381 @override |
| 382 List<String> get batchArguments => checked | 382 List<String> get batchArguments => |
| 383 ? ['--checked', dartFile] | 383 checked ? ['--checked', dartFile] : [dartFile]; |
| 384 : [dartFile]; | |
| 385 | 384 |
| 386 @override | 385 @override |
| 387 bool _equal(VmBatchCommand other) { | 386 bool _equal(VmBatchCommand other) { |
| 388 return super._equal(other) && | 387 return super._equal(other) && |
| 389 dartFile == other.dartFile && | 388 dartFile == other.dartFile && |
| 390 checked == other.checked; | 389 checked == other.checked; |
| 391 } | 390 } |
| 392 | 391 |
| 393 @override | 392 @override |
| 394 void _buildHashCode(HashCodeBuilder builder) { | 393 void _buildHashCode(HashCodeBuilder builder) { |
| 395 super._buildHashCode(builder); | 394 super._buildHashCode(builder); |
| 396 builder.addJson(dartFile); | 395 builder.addJson(dartFile); |
| 397 builder.addJson(checked); | 396 builder.addJson(checked); |
| 398 } | 397 } |
| 399 } | 398 } |
| 400 | 399 |
| 401 class AdbPrecompilationCommand extends Command { | 400 class AdbPrecompilationCommand extends Command { |
| 402 final String precompiledRunnerFilename; | 401 final String precompiledRunnerFilename; |
| 403 final String processTestFilename; | 402 final String processTestFilename; |
| 404 final String precompiledTestDirectory; | 403 final String precompiledTestDirectory; |
| 405 final List<String> arguments; | 404 final List<String> arguments; |
| 406 final bool useBlobs; | 405 final bool useBlobs; |
| 407 | 406 |
| 408 AdbPrecompilationCommand._(this.precompiledRunnerFilename, | 407 AdbPrecompilationCommand._( |
| 409 this.processTestFilename, | 408 this.precompiledRunnerFilename, |
| 410 this.precompiledTestDirectory, | 409 this.processTestFilename, |
| 411 this.arguments, | 410 this.precompiledTestDirectory, |
| 412 this.useBlobs) | 411 this.arguments, |
| 412 this.useBlobs) |
| 413 : super._("adb_precompilation"); | 413 : super._("adb_precompilation"); |
| 414 | 414 |
| 415 void _buildHashCode(HashCodeBuilder builder) { | 415 void _buildHashCode(HashCodeBuilder builder) { |
| 416 super._buildHashCode(builder); | 416 super._buildHashCode(builder); |
| 417 builder.add(precompiledRunnerFilename); | 417 builder.add(precompiledRunnerFilename); |
| 418 builder.add(precompiledTestDirectory); | 418 builder.add(precompiledTestDirectory); |
| 419 builder.add(arguments); | 419 builder.add(arguments); |
| 420 builder.add(useBlobs); | 420 builder.add(useBlobs); |
| 421 } | 421 } |
| 422 | 422 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 | 641 |
| 642 VmCommand getVmCommand(String executable, List<String> arguments, | 642 VmCommand getVmCommand(String executable, List<String> arguments, |
| 643 Map<String, String> environmentOverrides) { | 643 Map<String, String> environmentOverrides) { |
| 644 var command = new VmCommand._(executable, arguments, environmentOverrides); | 644 var command = new VmCommand._(executable, arguments, environmentOverrides); |
| 645 return _getUniqueCommand(command); | 645 return _getUniqueCommand(command); |
| 646 } | 646 } |
| 647 | 647 |
| 648 VmBatchCommand getVmBatchCommand(String executable, String tester, | 648 VmBatchCommand getVmBatchCommand(String executable, String tester, |
| 649 List<String> arguments, Map<String, String> environmentOverrides, | 649 List<String> arguments, Map<String, String> environmentOverrides, |
| 650 {bool checked: true}) { | 650 {bool checked: true}) { |
| 651 var command = | 651 var command = new VmBatchCommand._( |
| 652 new VmBatchCommand._(executable, tester, arguments, environmentOverrides
, | 652 executable, tester, arguments, environmentOverrides, |
| 653 checked: checked); | 653 checked: checked); |
| 654 return _getUniqueCommand(command); | 654 return _getUniqueCommand(command); |
| 655 } | 655 } |
| 656 | 656 |
| 657 AdbPrecompilationCommand getAdbPrecompiledCommand(String precompiledRunner, | 657 AdbPrecompilationCommand getAdbPrecompiledCommand( |
| 658 String processTest, | 658 String precompiledRunner, |
| 659 String testDirectory, | 659 String processTest, |
| 660 List<String> arguments, | 660 String testDirectory, |
| 661 bool useBlobs) { | 661 List<String> arguments, |
| 662 bool useBlobs) { |
| 662 var command = new AdbPrecompilationCommand._( | 663 var command = new AdbPrecompilationCommand._( |
| 663 precompiledRunner, processTest, testDirectory, arguments, useBlobs); | 664 precompiledRunner, processTest, testDirectory, arguments, useBlobs); |
| 664 return _getUniqueCommand(command); | 665 return _getUniqueCommand(command); |
| 665 } | 666 } |
| 666 | 667 |
| 667 Command getJSCommandlineCommand(String displayName, executable, arguments, | 668 Command getJSCommandlineCommand(String displayName, executable, arguments, |
| 668 [environment = null]) { | 669 [environment = null]) { |
| 669 var command = new JSCommandlineCommand._( | 670 var command = new JSCommandlineCommand._( |
| 670 displayName, executable, arguments, environment); | 671 displayName, executable, arguments, environment); |
| 671 return _getUniqueCommand(command); | 672 return _getUniqueCommand(command); |
| 672 } | 673 } |
| 673 | 674 |
| 674 Command getProcessCommand(String displayName, executable, arguments, | 675 Command getProcessCommand(String displayName, executable, arguments, |
| 675 [environment = null, workingDirectory = null]) { | 676 [environment = null, workingDirectory = null]) { |
| 676 var command = new ProcessCommand._( | 677 var command = new ProcessCommand._( |
| 677 displayName, executable, arguments, environment, workingDirectory); | 678 displayName, executable, arguments, environment, workingDirectory); |
| 678 return _getUniqueCommand(command); | 679 return _getUniqueCommand(command); |
| 679 } | 680 } |
| 680 | 681 |
| 681 Command getCopyCommand(String sourceDirectory, String destinationDirectory) { | 682 Command getCopyCommand(String sourceDirectory, String destinationDirectory) { |
| 682 var command = | 683 var command = |
| 683 new CleanDirectoryCopyCommand._(sourceDirectory, destinationDirectory); | 684 new CleanDirectoryCopyCommand._(sourceDirectory, destinationDirectory); |
| 684 return _getUniqueCommand(command); | 685 return _getUniqueCommand(command); |
| 685 } | 686 } |
| 686 | 687 |
| 687 Command getPubCommand(String pubCommand, String pubExecutable, | 688 Command getPubCommand(String pubCommand, String pubExecutable, |
| 688 String pubspecYamlDirectory, String pubCacheDirectory, | 689 String pubspecYamlDirectory, String pubCacheDirectory, |
| 689 {List<String> arguments: const <String>[]}) { | 690 {List<String> arguments: const <String>[]}) { |
| 690 var command = new PubCommand._( | 691 var command = new PubCommand._(pubCommand, pubExecutable, |
| 691 pubCommand, pubExecutable, pubspecYamlDirectory, pubCacheDirectory, | 692 pubspecYamlDirectory, pubCacheDirectory, arguments); |
| 692 arguments); | |
| 693 return _getUniqueCommand(command); | 693 return _getUniqueCommand(command); |
| 694 } | 694 } |
| 695 | 695 |
| 696 Command getMakeSymlinkCommand(String link, String target) { | 696 Command getMakeSymlinkCommand(String link, String target) { |
| 697 return _getUniqueCommand(new MakeSymlinkCommand._(link, target)); | 697 return _getUniqueCommand(new MakeSymlinkCommand._(link, target)); |
| 698 } | 698 } |
| 699 | 699 |
| 700 Command _getUniqueCommand(Command command) { | 700 Command _getUniqueCommand(Command command) { |
| 701 // All Command classes implement hashCode and operator==. | 701 // All Command classes implement hashCode and operator==. |
| 702 // We check if this command has already been built. | 702 // We check if this command has already been built. |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1603 } | 1603 } |
| 1604 | 1604 |
| 1605 Expectation outcome = | 1605 Expectation outcome = |
| 1606 exitCode == 0 ? Expectation.PASS : Expectation.COMPILETIME_ERROR; | 1606 exitCode == 0 ? Expectation.PASS : Expectation.COMPILETIME_ERROR; |
| 1607 return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative); | 1607 return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative); |
| 1608 } | 1608 } |
| 1609 } | 1609 } |
| 1610 | 1610 |
| 1611 class KernelCompilationCommandOutputImpl extends CompilationCommandOutputImpl { | 1611 class KernelCompilationCommandOutputImpl extends CompilationCommandOutputImpl { |
| 1612 KernelCompilationCommandOutputImpl( | 1612 KernelCompilationCommandOutputImpl( |
| 1613 Command command, int exitCode, bool timedOut, | 1613 Command command, |
| 1614 List<int> stdout, List<int> stderr, | 1614 int exitCode, |
| 1615 Duration time, bool compilationSkipped) | 1615 bool timedOut, |
| 1616 List<int> stdout, |
| 1617 List<int> stderr, |
| 1618 Duration time, |
| 1619 bool compilationSkipped) |
| 1616 : super(command, exitCode, timedOut, stdout, stderr, time, | 1620 : super(command, exitCode, timedOut, stdout, stderr, time, |
| 1617 compilationSkipped); | 1621 compilationSkipped); |
| 1618 | 1622 |
| 1619 bool get canRunDependendCommands { | 1623 bool get canRunDependendCommands { |
| 1620 // See [BatchRunnerProcess]: 0 means success, 1 means compile-time error. | 1624 // See [BatchRunnerProcess]: 0 means success, 1 means compile-time error. |
| 1621 // TODO(asgerf): When the frontend supports it, continue running even if | 1625 // TODO(asgerf): When the frontend supports it, continue running even if |
| 1622 // there were compile-time errors. See kernel_sdk issue #18. | 1626 // there were compile-time errors. See kernel_sdk issue #18. |
| 1623 return !hasCrashed && !timedOut && exitCode == 0; | 1627 return !hasCrashed && !timedOut && exitCode == 0; |
| 1624 } | 1628 } |
| 1625 | 1629 |
| 1626 Expectation result(TestCase testCase) { | 1630 Expectation result(TestCase testCase) { |
| 1627 Expectation result = super.result(testCase); | 1631 Expectation result = super.result(testCase); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1777 if (tail != null && tail.length > 2 * TAIL_LENGTH) { | 1781 if (tail != null && tail.length > 2 * TAIL_LENGTH) { |
| 1778 tail = _truncatedTail(); | 1782 tail = _truncatedTail(); |
| 1779 dataDropped = true; | 1783 dataDropped = true; |
| 1780 } | 1784 } |
| 1781 } | 1785 } |
| 1782 | 1786 |
| 1783 List<int> _truncatedTail() => tail.length > TAIL_LENGTH | 1787 List<int> _truncatedTail() => tail.length > TAIL_LENGTH |
| 1784 ? tail.sublist(tail.length - TAIL_LENGTH) | 1788 ? tail.sublist(tail.length - TAIL_LENGTH) |
| 1785 : tail; | 1789 : tail; |
| 1786 | 1790 |
| 1787 | |
| 1788 void _checkUtf8(List<int> data) { | 1791 void _checkUtf8(List<int> data) { |
| 1789 try { | 1792 try { |
| 1790 UTF8.decode(data, allowMalformed: false); | 1793 UTF8.decode(data, allowMalformed: false); |
| 1791 } on FormatException catch (e) { | 1794 } on FormatException catch (e) { |
| 1792 hasNonUtf8 = true; | 1795 hasNonUtf8 = true; |
| 1793 String malformed = UTF8.decode(data, allowMalformed: true); | 1796 String malformed = UTF8.decode(data, allowMalformed: true); |
| 1794 data..clear() | 1797 data |
| 1795 ..addAll(UTF8.encode(malformed)) | 1798 ..clear() |
| 1796 ..addAll(""" | 1799 ..addAll(UTF8.encode(malformed)) |
| 1800 ..addAll(""" |
| 1797 | 1801 |
| 1798 ***************************************************************************** | 1802 ***************************************************************************** |
| 1799 | 1803 |
| 1800 test.dart: The output of this test contained non-UTF8 formatted data. | 1804 test.dart: The output of this test contained non-UTF8 formatted data. |
| 1801 | 1805 |
| 1802 ***************************************************************************** | 1806 ***************************************************************************** |
| 1803 | 1807 |
| 1804 """ | 1808 """ |
| 1805 .codeUnits); | 1809 .codeUnits); |
| 1806 } | 1810 } |
| 1807 } | 1811 } |
| 1808 | 1812 |
| 1809 | |
| 1810 List<int> toList() { | 1813 List<int> toList() { |
| 1811 if (complete == null) { | 1814 if (complete == null) { |
| 1812 complete = head; | 1815 complete = head; |
| 1813 if (dataDropped) { | 1816 if (dataDropped) { |
| 1814 complete.addAll(""" | 1817 complete.addAll(""" |
| 1815 | 1818 |
| 1816 ***************************************************************************** | 1819 ***************************************************************************** |
| 1817 | 1820 |
| 1818 test.dart: Data was removed due to excessive length | 1821 test.dart: Data was removed due to excessive length |
| 1819 | 1822 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1833 } | 1836 } |
| 1834 } | 1837 } |
| 1835 | 1838 |
| 1836 // Helper to get a list of all child pids for a parent process. | 1839 // Helper to get a list of all child pids for a parent process. |
| 1837 // The first element of the list is the parent pid. | 1840 // The first element of the list is the parent pid. |
| 1838 Future<List<int>> _getPidList(pid, diagnostics) async { | 1841 Future<List<int>> _getPidList(pid, diagnostics) async { |
| 1839 var pid_list = [pid]; | 1842 var pid_list = [pid]; |
| 1840 var lines; | 1843 var lines; |
| 1841 var start_line = 0; | 1844 var start_line = 0; |
| 1842 if (io.Platform.isLinux || io.Platform.isMacOS) { | 1845 if (io.Platform.isLinux || io.Platform.isMacOS) { |
| 1843 var result = await io.Process.run("pgrep", | 1846 var result = await io.Process |
| 1844 ["-P", "${pid_list[0]}"], | 1847 .run("pgrep", ["-P", "${pid_list[0]}"], runInShell: true); |
| 1845 runInShell: true); | |
| 1846 lines = result.stdout.split('\n'); | 1848 lines = result.stdout.split('\n'); |
| 1847 } else if (io.Platform.isWindows) { | 1849 } else if (io.Platform.isWindows) { |
| 1848 var result = await io.Process.run("wmic", | 1850 var result = await io.Process.run( |
| 1849 ["process", "where" , "(ParentProcessId=${pid_list[0]})", | 1851 "wmic", |
| 1850 "get", "ProcessId"], | 1852 [ |
| 1853 "process", |
| 1854 "where", |
| 1855 "(ParentProcessId=${pid_list[0]})", |
| 1856 "get", |
| 1857 "ProcessId" |
| 1858 ], |
| 1851 runInShell: true); | 1859 runInShell: true); |
| 1852 lines = result.stdout.split('\n'); | 1860 lines = result.stdout.split('\n'); |
| 1853 // Skip first line containing header "ProcessId". | 1861 // Skip first line containing header "ProcessId". |
| 1854 start_line = 1; | 1862 start_line = 1; |
| 1855 } else { | 1863 } else { |
| 1856 assert(false); | 1864 assert(false); |
| 1857 } | 1865 } |
| 1858 if (lines.length > start_line) { | 1866 if (lines.length > start_line) { |
| 1859 for (int i = start_line; i < lines.length; ++i) { | 1867 for (int i = start_line; i < lines.length; ++i) { |
| 1860 var pid = int.parse(lines[i], onError: (source) => null); | 1868 var pid = int.parse(lines[i], onError: (source) => null); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1884 DateTime startTime; | 1892 DateTime startTime; |
| 1885 Timer timeoutTimer; | 1893 Timer timeoutTimer; |
| 1886 int pid; | 1894 int pid; |
| 1887 OutputLog stdout = new OutputLog(); | 1895 OutputLog stdout = new OutputLog(); |
| 1888 OutputLog stderr = new OutputLog(); | 1896 OutputLog stderr = new OutputLog(); |
| 1889 List<String> diagnostics = <String>[]; | 1897 List<String> diagnostics = <String>[]; |
| 1890 bool compilationSkipped = false; | 1898 bool compilationSkipped = false; |
| 1891 Completer<CommandOutput> completer; | 1899 Completer<CommandOutput> completer; |
| 1892 Map configuration; | 1900 Map configuration; |
| 1893 | 1901 |
| 1894 RunningProcess(this.command, | 1902 RunningProcess(this.command, this.timeout, {this.configuration}); |
| 1895 this.timeout, | |
| 1896 {this.configuration}); | |
| 1897 | 1903 |
| 1898 Future<CommandOutput> run() { | 1904 Future<CommandOutput> run() { |
| 1899 completer = new Completer<CommandOutput>(); | 1905 completer = new Completer<CommandOutput>(); |
| 1900 startTime = new DateTime.now(); | 1906 startTime = new DateTime.now(); |
| 1901 _runCommand(); | 1907 _runCommand(); |
| 1902 return completer.future; | 1908 return completer.future; |
| 1903 } | 1909 } |
| 1904 | 1910 |
| 1905 void _runCommand() { | 1911 void _runCommand() { |
| 1906 command.outputIsUpToDate.then((bool isUpToDate) { | 1912 command.outputIsUpToDate.then((bool isUpToDate) { |
| 1907 if (isUpToDate) { | 1913 if (isUpToDate) { |
| 1908 compilationSkipped = true; | 1914 compilationSkipped = true; |
| 1909 _commandComplete(0); | 1915 _commandComplete(0); |
| 1910 } else { | 1916 } else { |
| 1911 var processEnvironment = _createProcessEnvironment(); | 1917 var processEnvironment = _createProcessEnvironment(); |
| 1912 var args = command.arguments; | 1918 var args = command.arguments; |
| 1913 Future processFuture = io.Process.start( | 1919 Future processFuture = io.Process.start(command.executable, args, |
| 1914 command.executable, args, | |
| 1915 environment: processEnvironment, | 1920 environment: processEnvironment, |
| 1916 workingDirectory: command.workingDirectory); | 1921 workingDirectory: command.workingDirectory); |
| 1917 processFuture.then((io.Process process) { | 1922 processFuture.then((io.Process process) { |
| 1918 StreamSubscription stdoutSubscription = | 1923 StreamSubscription stdoutSubscription = |
| 1919 _drainStream(process.stdout, stdout); | 1924 _drainStream(process.stdout, stdout); |
| 1920 StreamSubscription stderrSubscription = | 1925 StreamSubscription stderrSubscription = |
| 1921 _drainStream(process.stderr, stderr); | 1926 _drainStream(process.stderr, stderr); |
| 1922 | 1927 |
| 1923 var stdoutCompleter = new Completer(); | 1928 var stdoutCompleter = new Completer(); |
| 1924 var stderrCompleter = new Completer(); | 1929 var stderrCompleter = new Completer(); |
| 1925 | 1930 |
| 1926 bool stdoutDone = false; | 1931 bool stdoutDone = false; |
| 1927 bool stderrDone = false; | 1932 bool stderrDone = false; |
| 1928 pid = process.pid; | 1933 pid = process.pid; |
| 1929 | 1934 |
| 1930 // This timer is used to close stdio to the subprocess once we got | 1935 // This timer is used to close stdio to the subprocess once we got |
| 1931 // the exitCode. Sometimes descendants of the subprocess keep stdio | 1936 // the exitCode. Sometimes descendants of the subprocess keep stdio |
| 1932 // handles alive even though the direct subprocess is dead. | 1937 // handles alive even though the direct subprocess is dead. |
| 1933 Timer watchdogTimer; | 1938 Timer watchdogTimer; |
| 1934 | 1939 |
| 1935 closeStdout([_]) { | 1940 closeStdout([_]) { |
| 1936 if (!stdoutDone) { | 1941 if (!stdoutDone) { |
| 1937 stdoutCompleter.complete(); | 1942 stdoutCompleter.complete(); |
| 1938 stdoutDone = true; | 1943 stdoutDone = true; |
| 1939 if (stderrDone && watchdogTimer != null) { | 1944 if (stderrDone && watchdogTimer != null) { |
| 1940 watchdogTimer.cancel(); | 1945 watchdogTimer.cancel(); |
| 1941 } | 1946 } |
| 1942 } | 1947 } |
| 1943 } | 1948 } |
| 1949 |
| 1944 closeStderr([_]) { | 1950 closeStderr([_]) { |
| 1945 if (!stderrDone) { | 1951 if (!stderrDone) { |
| 1946 stderrCompleter.complete(); | 1952 stderrCompleter.complete(); |
| 1947 stderrDone = true; | 1953 stderrDone = true; |
| 1948 | 1954 |
| 1949 if (stdoutDone && watchdogTimer != null) { | 1955 if (stdoutDone && watchdogTimer != null) { |
| 1950 watchdogTimer.cancel(); | 1956 watchdogTimer.cancel(); |
| 1951 } | 1957 } |
| 1952 } | 1958 } |
| 1953 } | 1959 } |
| 1954 | 1960 |
| 1955 // Close stdin so that tests that try to block on input will fail. | 1961 // Close stdin so that tests that try to block on input will fail. |
| 1956 process.stdin.close(); | 1962 process.stdin.close(); |
| 1957 timeoutHandler() async { | 1963 timeoutHandler() async { |
| 1958 timedOut = true; | 1964 timedOut = true; |
| 1959 if (process != null) { | 1965 if (process != null) { |
| 1960 var executable; | 1966 var executable; |
| 1961 if (io.Platform.isLinux) { | 1967 if (io.Platform.isLinux) { |
| 1962 executable = 'eu-stack'; | 1968 executable = 'eu-stack'; |
| 1963 } else if (io.Platform.isMacOS) { | 1969 } else if (io.Platform.isMacOS) { |
| 1964 // Try to print stack traces of the timed out process. | 1970 // Try to print stack traces of the timed out process. |
| 1965 // `sample` is a sampling profiler but we ask it sample for 1 | 1971 // `sample` is a sampling profiler but we ask it sample for 1 |
| 1966 // second with a 4 second delay between samples so that we only | 1972 // second with a 4 second delay between samples so that we only |
| 1967 // sample the threads once. | 1973 // sample the threads once. |
| 1968 executable = '/usr/bin/sample'; | 1974 executable = '/usr/bin/sample'; |
| 1969 } else if (io.Platform.isWindows) { | 1975 } else if (io.Platform.isWindows) { |
| 1970 bool is_x64 = command.executable.contains("X64") || | 1976 bool is_x64 = command.executable.contains("X64") || |
| 1971 command.executable.contains("SIMARM64"); | 1977 command.executable.contains("SIMARM64"); |
| 1972 var win_sdk_path = configuration['win_sdk_path']; | 1978 var win_sdk_path = configuration['win_sdk_path']; |
| 1973 if (win_sdk_path != null) { | 1979 if (win_sdk_path != null) { |
| 1974 executable = win_sdk_path + | 1980 executable = win_sdk_path + |
| 1975 "\\Debuggers\\" + (is_x64 ? "x64" : "x86") + "\\cdb.exe"; | 1981 "\\Debuggers\\" + |
| 1982 (is_x64 ? "x64" : "x86") + |
| 1983 "\\cdb.exe"; |
| 1976 diagnostics.add("Using $executable to print stack traces"); | 1984 diagnostics.add("Using $executable to print stack traces"); |
| 1977 } else { | 1985 } else { |
| 1978 diagnostics.add("win_sdk path not found"); | 1986 diagnostics.add("win_sdk path not found"); |
| 1979 } | 1987 } |
| 1980 } else { | 1988 } else { |
| 1981 diagnostics.add("Capturing stack traces on" | 1989 diagnostics.add("Capturing stack traces on" |
| 1982 "${io.Platform.operatingSystem} not supported"); | 1990 "${io.Platform.operatingSystem} not supported"); |
| 1983 } | 1991 } |
| 1984 if (executable != null) { | 1992 if (executable != null) { |
| 1985 var pid_list = await _getPidList(process.pid, diagnostics); | 1993 var pid_list = await _getPidList(process.pid, diagnostics); |
| 1986 diagnostics.add("Process list including children: $pid_list"); | 1994 diagnostics.add("Process list including children: $pid_list"); |
| 1987 for (pid in pid_list) { | 1995 for (pid in pid_list) { |
| 1988 var arguments; | 1996 var arguments; |
| 1989 if (io.Platform.isLinux) { | 1997 if (io.Platform.isLinux) { |
| 1990 arguments = ['-p $pid']; | 1998 arguments = ['-p $pid']; |
| 1991 } else if (io.Platform.isMacOS) { | 1999 } else if (io.Platform.isMacOS) { |
| 1992 arguments = ['$pid', '1', '4000', '-mayDie']; | 2000 arguments = ['$pid', '1', '4000', '-mayDie']; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2093 } | 2101 } |
| 2094 } | 2102 } |
| 2095 for (var excludedEnvironmentVariable in EXCLUDED_ENVIRONMENT_VARIABLES) { | 2103 for (var excludedEnvironmentVariable in EXCLUDED_ENVIRONMENT_VARIABLES) { |
| 2096 environment.remove(excludedEnvironmentVariable); | 2104 environment.remove(excludedEnvironmentVariable); |
| 2097 } | 2105 } |
| 2098 | 2106 |
| 2099 return environment; | 2107 return environment; |
| 2100 } | 2108 } |
| 2101 } | 2109 } |
| 2102 | 2110 |
| 2103 class BatchRunnerProcess { | 2111 class BatchRunnerProcess { |
| 2104 Completer<CommandOutput> _completer; | 2112 Completer<CommandOutput> _completer; |
| 2105 ProcessCommand _command; | 2113 ProcessCommand _command; |
| 2106 List<String> _arguments; | 2114 List<String> _arguments; |
| 2107 String _runnerType; | 2115 String _runnerType; |
| 2108 | 2116 |
| 2109 io.Process _process; | 2117 io.Process _process; |
| 2110 Map _processEnvironmentOverrides; | 2118 Map _processEnvironmentOverrides; |
| 2111 Completer _stdoutCompleter; | 2119 Completer _stdoutCompleter; |
| 2112 Completer _stderrCompleter; | 2120 Completer _stderrCompleter; |
| 2113 StreamSubscription<String> _stdoutSubscription; | 2121 StreamSubscription<String> _stdoutSubscription; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2218 if (_timer != null) _timer.cancel(); | 2226 if (_timer != null) _timer.cancel(); |
| 2219 _status = status; | 2227 _status = status; |
| 2220 _stdoutSubscription.cancel(); | 2228 _stdoutSubscription.cancel(); |
| 2221 _stderrSubscription.cancel(); | 2229 _stderrSubscription.cancel(); |
| 2222 _startProcess(_reportResult); | 2230 _startProcess(_reportResult); |
| 2223 } else { | 2231 } else { |
| 2224 // No active test case running. | 2232 // No active test case running. |
| 2225 _process = null; | 2233 _process = null; |
| 2226 } | 2234 } |
| 2227 } | 2235 } |
| 2236 |
| 2228 return handler; | 2237 return handler; |
| 2229 } | 2238 } |
| 2230 | 2239 |
| 2231 void _timeoutHandler() { | 2240 void _timeoutHandler() { |
| 2232 _processExitHandler = makeExitHandler(">>> TEST TIMEOUT"); | 2241 _processExitHandler = makeExitHandler(">>> TEST TIMEOUT"); |
| 2233 _process.kill(); | 2242 _process.kill(); |
| 2234 } | 2243 } |
| 2235 | 2244 |
| 2236 _startProcess(callback) { | 2245 _startProcess(callback) { |
| 2237 assert(_command is ProcessCommand); | 2246 assert(_command is ProcessCommand); |
| 2238 var executable = _command.executable; | 2247 var executable = _command.executable; |
| 2239 var arguments = []..addAll(_command.batchArguments)..add('--batch'); | 2248 var arguments = [] |
| 2249 ..addAll(_command.batchArguments) |
| 2250 ..add('--batch'); |
| 2240 var environment = new Map.from(io.Platform.environment); | 2251 var environment = new Map.from(io.Platform.environment); |
| 2241 if (_processEnvironmentOverrides != null) { | 2252 if (_processEnvironmentOverrides != null) { |
| 2242 for (var key in _processEnvironmentOverrides.keys) { | 2253 for (var key in _processEnvironmentOverrides.keys) { |
| 2243 environment[key] = _processEnvironmentOverrides[key]; | 2254 environment[key] = _processEnvironmentOverrides[key]; |
| 2244 } | 2255 } |
| 2245 } | 2256 } |
| 2246 Future processFuture = | 2257 Future processFuture = |
| 2247 io.Process.start(executable, arguments, environment: environment); | 2258 io.Process.start(executable, arguments, environment: environment); |
| 2248 processFuture.then((io.Process p) { | 2259 processFuture.then((io.Process p) { |
| 2249 _process = p; | 2260 _process = p; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 | 2383 |
| 2373 Iterator<TestSuite> iterator = testSuites.iterator; | 2384 Iterator<TestSuite> iterator = testSuites.iterator; |
| 2374 void enqueueNextSuite() { | 2385 void enqueueNextSuite() { |
| 2375 if (!iterator.moveNext()) { | 2386 if (!iterator.moveNext()) { |
| 2376 // We're finished with building the dependency graph. | 2387 // We're finished with building the dependency graph. |
| 2377 graph.sealGraph(); | 2388 graph.sealGraph(); |
| 2378 } else { | 2389 } else { |
| 2379 iterator.current.forEachTest(newTest, testCache, enqueueNextSuite); | 2390 iterator.current.forEachTest(newTest, testCache, enqueueNextSuite); |
| 2380 } | 2391 } |
| 2381 } | 2392 } |
| 2393 |
| 2382 enqueueNextSuite(); | 2394 enqueueNextSuite(); |
| 2383 } | 2395 } |
| 2384 } | 2396 } |
| 2385 | 2397 |
| 2386 /* | 2398 /* |
| 2387 * [CommandEnqueuer] will | 2399 * [CommandEnqueuer] will |
| 2388 * - change node.state to NodeState.Enqueuing as soon as all dependencies have | 2400 * - change node.state to NodeState.Enqueuing as soon as all dependencies have |
| 2389 * a state of NodeState.Successful | 2401 * a state of NodeState.Successful |
| 2390 * - change node.state to NodeState.UnableToRun if one or more dependencies | 2402 * - change node.state to NodeState.UnableToRun if one or more dependencies |
| 2391 * have a state of NodeState.Failed/NodeState.UnableToRun. | 2403 * have a state of NodeState.Failed/NodeState.UnableToRun. |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2662 return _runCommand(command, timeout).then((CommandOutput output) { | 2674 return _runCommand(command, timeout).then((CommandOutput output) { |
| 2663 if (retriesLeft > 0 && shouldRetryCommand(output)) { | 2675 if (retriesLeft > 0 && shouldRetryCommand(output)) { |
| 2664 DebugLogger.warning("Rerunning Command: ($retriesLeft " | 2676 DebugLogger.warning("Rerunning Command: ($retriesLeft " |
| 2665 "attempt(s) remains) [cmd: $command]"); | 2677 "attempt(s) remains) [cmd: $command]"); |
| 2666 return runCommand(retriesLeft - 1); | 2678 return runCommand(retriesLeft - 1); |
| 2667 } else { | 2679 } else { |
| 2668 return new Future.value(output); | 2680 return new Future.value(output); |
| 2669 } | 2681 } |
| 2670 }); | 2682 }); |
| 2671 } | 2683 } |
| 2684 |
| 2672 return runCommand(command.maxNumRetries); | 2685 return runCommand(command.maxNumRetries); |
| 2673 } | 2686 } |
| 2674 | 2687 |
| 2675 Future<CommandOutput> _runCommand(Command command, int timeout) { | 2688 Future<CommandOutput> _runCommand(Command command, int timeout) { |
| 2676 var batchMode = !globalConfiguration['noBatch']; | 2689 var batchMode = !globalConfiguration['noBatch']; |
| 2677 var dart2jsBatchMode = globalConfiguration['dart2js_batch']; | 2690 var dart2jsBatchMode = globalConfiguration['dart2js_batch']; |
| 2678 | 2691 |
| 2679 if (command is BrowserTestCommand) { | 2692 if (command is BrowserTestCommand) { |
| 2680 return _startBrowserControllerTest(command, timeout); | 2693 return _startBrowserControllerTest(command, timeout); |
| 2681 } else if (command is KernelCompilationCommand) { | 2694 } else if (command is KernelCompilationCommand) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2698 return _runAdbPrecompilationCommand(device, command, timeout) | 2711 return _runAdbPrecompilationCommand(device, command, timeout) |
| 2699 .whenComplete(() { | 2712 .whenComplete(() { |
| 2700 adbDevicePool.releaseDevice(device); | 2713 adbDevicePool.releaseDevice(device); |
| 2701 }); | 2714 }); |
| 2702 }); | 2715 }); |
| 2703 } else if (command is VmBatchCommand) { | 2716 } else if (command is VmBatchCommand) { |
| 2704 var name = command.displayName; | 2717 var name = command.displayName; |
| 2705 return _getBatchRunner(command.displayName + command.dartFile) | 2718 return _getBatchRunner(command.displayName + command.dartFile) |
| 2706 .runCommand(name, command, timeout, command.arguments); | 2719 .runCommand(name, command, timeout, command.arguments); |
| 2707 } else { | 2720 } else { |
| 2708 return new RunningProcess( | 2721 return new RunningProcess(command, timeout, |
| 2709 command, timeout, configuration: globalConfiguration).run(); | 2722 configuration: globalConfiguration) |
| 2723 .run(); |
| 2710 } | 2724 } |
| 2711 } | 2725 } |
| 2712 | 2726 |
| 2713 Future<CommandOutput> _runAdbPrecompilationCommand( | 2727 Future<CommandOutput> _runAdbPrecompilationCommand( |
| 2714 AdbDevice device, AdbPrecompilationCommand command, int timeout) async { | 2728 AdbDevice device, AdbPrecompilationCommand command, int timeout) async { |
| 2715 var runner = command.precompiledRunnerFilename; | 2729 var runner = command.precompiledRunnerFilename; |
| 2716 var processTest = command.processTestFilename; | 2730 var processTest = command.processTestFilename; |
| 2717 var testdir = command.precompiledTestDirectory; | 2731 var testdir = command.precompiledTestDirectory; |
| 2718 var arguments = command.arguments; | 2732 var arguments = command.arguments; |
| 2719 var devicedir = DartPrecompiledAdbRuntimeConfiguration.DeviceDir; | 2733 var devicedir = DartPrecompiledAdbRuntimeConfiguration.DeviceDir; |
| 2720 var deviceTestDir = DartPrecompiledAdbRuntimeConfiguration.DeviceTestDir; | 2734 var deviceTestDir = DartPrecompiledAdbRuntimeConfiguration.DeviceTestDir; |
| 2721 | 2735 |
| 2722 // We copy all the files which the vm precompiler puts into the test | 2736 // We copy all the files which the vm precompiler puts into the test |
| 2723 // directory. | 2737 // directory. |
| 2724 List<String> files = new io.Directory(testdir) | 2738 List<String> files = new io.Directory(testdir) |
| 2725 .listSync() | 2739 .listSync() |
| 2726 .map((file) => file.path) | 2740 .map((file) => file.path) |
| 2727 .map((path) => path.substring(path.lastIndexOf('/') + 1)) | 2741 .map((path) => path.substring(path.lastIndexOf('/') + 1)) |
| 2728 .toList(); | 2742 .toList(); |
| 2729 | 2743 |
| 2730 var timeoutDuration = new Duration(seconds: timeout); | 2744 var timeoutDuration = new Duration(seconds: timeout); |
| 2731 | 2745 |
| 2732 // All closures are of type "Future<AdbCommandResult> run()" | 2746 // All closures are of type "Future<AdbCommandResult> run()" |
| 2733 List<Function> steps = []; | 2747 List<Function> steps = []; |
| 2734 | 2748 |
| 2735 steps.add(() => device.runAdbShellCommand(['rm', '-Rf', deviceTestDir])); | 2749 steps.add(() => device.runAdbShellCommand(['rm', '-Rf', deviceTestDir])); |
| 2736 steps.add(() => device.runAdbShellCommand(['mkdir', '-p', deviceTestDir])); | 2750 steps.add(() => device.runAdbShellCommand(['mkdir', '-p', deviceTestDir])); |
| 2737 steps.add(() => device.pushCachedData(runner, | 2751 steps.add(() => |
| 2738 '$devicedir/dart_precompiled_runtime')
); | 2752 device.pushCachedData(runner, '$devicedir/dart_precompiled_runtime')); |
| 2739 steps.add(() => device.pushCachedData(processTest, | 2753 steps.add( |
| 2740 '$devicedir/process_test')); | 2754 () => device.pushCachedData(processTest, '$devicedir/process_test')); |
| 2741 steps.add(() => device.runAdbShellCommand( | 2755 steps.add(() => device.runAdbShellCommand([ |
| 2742 ['chmod', '777', '$devicedir/dart_precompiled_runtime $devicedir/process
_test'])); | 2756 'chmod', |
| 2757 '777', |
| 2758 '$devicedir/dart_precompiled_runtime $devicedir/process_test' |
| 2759 ])); |
| 2743 | 2760 |
| 2744 for (var file in files) { | 2761 for (var file in files) { |
| 2745 steps.add(() => device | 2762 steps.add(() => device |
| 2746 .runAdbCommand(['push', '$testdir/$file', '$deviceTestDir/$file'])); | 2763 .runAdbCommand(['push', '$testdir/$file', '$deviceTestDir/$file'])); |
| 2747 } | 2764 } |
| 2748 | 2765 |
| 2749 steps.add(() => device.runAdbShellCommand( | 2766 steps.add(() => device.runAdbShellCommand( |
| 2750 [ | 2767 [ |
| 2751 '$devicedir/dart_precompiled_runtime', | 2768 '$devicedir/dart_precompiled_runtime', |
| 2752 ]..addAll(arguments), | 2769 ]..addAll(arguments), |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2921 } | 2938 } |
| 2922 | 2939 |
| 2923 if (io.Platform.operatingSystem == 'linux') { | 2940 if (io.Platform.operatingSystem == 'linux') { |
| 2924 decodeOutput(); | 2941 decodeOutput(); |
| 2925 // No matter which command we ran: If we get failures due to the | 2942 // No matter which command we ran: If we get failures due to the |
| 2926 // "xvfb-run" issue 7564, try re-running the test. | 2943 // "xvfb-run" issue 7564, try re-running the test. |
| 2927 bool containsFailureMsg(String line) { | 2944 bool containsFailureMsg(String line) { |
| 2928 return line.contains(MESSAGE_CANNOT_OPEN_DISPLAY) || | 2945 return line.contains(MESSAGE_CANNOT_OPEN_DISPLAY) || |
| 2929 line.contains(MESSAGE_FAILED_TO_RUN_COMMAND); | 2946 line.contains(MESSAGE_FAILED_TO_RUN_COMMAND); |
| 2930 } | 2947 } |
| 2948 |
| 2931 if (stdout.any(containsFailureMsg) || stderr.any(containsFailureMsg)) { | 2949 if (stdout.any(containsFailureMsg) || stderr.any(containsFailureMsg)) { |
| 2932 return true; | 2950 return true; |
| 2933 } | 2951 } |
| 2934 } | 2952 } |
| 2935 | |
| 2936 } | 2953 } |
| 2937 return false; | 2954 return false; |
| 2938 } | 2955 } |
| 2939 | 2956 |
| 2940 /* | 2957 /* |
| 2941 * [TestCaseCompleter] will listen for | 2958 * [TestCaseCompleter] will listen for |
| 2942 * NodeState.Processing -> NodeState.{Successful,Failed} state changes and | 2959 * NodeState.Processing -> NodeState.{Successful,Failed} state changes and |
| 2943 * will complete a TestCase if it is finished. | 2960 * will complete a TestCase if it is finished. |
| 2944 * | 2961 * |
| 2945 * It provides a stream [finishedTestCases], which will stream all TestCases | 2962 * It provides a stream [finishedTestCases], which will stream all TestCases |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3224 } | 3241 } |
| 3225 } | 3242 } |
| 3226 | 3243 |
| 3227 void eventAllTestsDone() { | 3244 void eventAllTestsDone() { |
| 3228 for (var listener in _eventListener) { | 3245 for (var listener in _eventListener) { |
| 3229 listener.allDone(); | 3246 listener.allDone(); |
| 3230 } | 3247 } |
| 3231 _allDone(); | 3248 _allDone(); |
| 3232 } | 3249 } |
| 3233 } | 3250 } |
| OLD | NEW |