| 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 enumerating and preparing tests. | 6 * Classes and methods for enumerating and preparing tests. |
| 7 * | 7 * |
| 8 * This library includes: | 8 * This library includes: |
| 9 * | 9 * |
| 10 * - Creating tests by listing all the Dart files in certain directories, | 10 * - Creating tests by listing all the Dart files in certain directories, |
| 11 * and creating [TestCase]s for those files that meet the relevant criteria. | 11 * and creating [TestCase]s for those files that meet the relevant criteria. |
| 12 * - Preparing tests, including copying files and frameworks to temporary | 12 * - Preparing tests, including copying files and frameworks to temporary |
| 13 * directories, and computing the command line and arguments to be run. | 13 * directories, and computing the command line and arguments to be run. |
| 14 */ | 14 */ |
| 15 library test_suite; | 15 library test_suite; |
| 16 | 16 |
| 17 import "dart:async"; | 17 import "dart:async"; |
| 18 import "dart:io"; | 18 import "dart:io"; |
| 19 import "dart:isolate"; | 19 import "dart:isolate"; |
| 20 import "drt_updater.dart"; | 20 import "drt_updater.dart"; |
| 21 import "multitest.dart"; | 21 import "multitest.dart"; |
| 22 import "status_file_parser.dart"; | 22 import "status_file_parser.dart"; |
| 23 import "test_runner.dart"; | 23 import "test_runner.dart"; |
| 24 import "utils.dart"; | 24 import "utils.dart"; |
| 25 import "http_server.dart" show PREFIX_BUILDDIR, PREFIX_DARTDIR; | 25 import "http_server.dart" show PREFIX_BUILDDIR, PREFIX_DARTDIR; |
| 26 | 26 |
| 27 part "browser_test.dart"; | 27 part "browser_test.dart"; |
| 28 | 28 |
| 29 | 29 |
| 30 // TODO(rnystrom): Add to dart:core? | |
| 31 /** | 30 /** |
| 32 * A simple function that tests [arg] and returns `true` or `false`. | 31 * A simple function that tests [arg] and returns `true` or `false`. |
| 33 */ | 32 */ |
| 34 typedef bool Predicate<T>(T arg); | 33 typedef bool Predicate<T>(T arg); |
| 35 | 34 |
| 36 typedef void CreateTest(Path filePath, | 35 typedef void CreateTest(Path filePath, |
| 37 bool hasCompileError, | 36 bool hasCompileError, |
| 38 bool hasRuntimeError, | 37 bool hasRuntimeError, |
| 39 {bool isNegativeIfChecked, | 38 {bool isNegativeIfChecked, |
| 40 bool hasFatalTypeErrors, | 39 bool hasFatalTypeErrors, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 * | 102 * |
| 104 * Most TestSuites represent a directory or directory tree containing tests, | 103 * Most TestSuites represent a directory or directory tree containing tests, |
| 105 * and a status file containing the expected results when these tests are run. | 104 * and a status file containing the expected results when these tests are run. |
| 106 */ | 105 */ |
| 107 abstract class TestSuite { | 106 abstract class TestSuite { |
| 108 final Map configuration; | 107 final Map configuration; |
| 109 final String suiteName; | 108 final String suiteName; |
| 110 | 109 |
| 111 TestSuite(this.configuration, this.suiteName); | 110 TestSuite(this.configuration, this.suiteName); |
| 112 | 111 |
| 112 String get configurationDir { |
| 113 return TestUtils.configurationDir(configuration); |
| 114 } |
| 115 |
| 113 /** | 116 /** |
| 114 * Whether or not binaries should be found in the root build directory or | 117 * Whether or not binaries should be found in the root build directory or |
| 115 * in the built SDK. | 118 * in the built SDK. |
| 116 */ | 119 */ |
| 117 bool get useSdk { | 120 bool get useSdk { |
| 118 // The pub suite always uses the SDK. | 121 // The pub suite always uses the SDK. |
| 119 // TODO(rnystrom): Eventually, all test suites should run out of the SDK | 122 // TODO(rnystrom): Eventually, all test suites should run out of the SDK |
| 120 // and this check should go away. | 123 // and this check should go away. |
| 121 if (suiteName == 'pub') return true; | 124 if (suiteName == 'pub') return true; |
| 122 | 125 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 * The tests are compiled into a monolithic executable by the build step. | 306 * The tests are compiled into a monolithic executable by the build step. |
| 304 * The executable lists its tests when run with the --list command line flag. | 307 * The executable lists its tests when run with the --list command line flag. |
| 305 * Individual tests are run by specifying them on the command line. | 308 * Individual tests are run by specifying them on the command line. |
| 306 */ | 309 */ |
| 307 class CCTestSuite extends TestSuite { | 310 class CCTestSuite extends TestSuite { |
| 308 final String testPrefix; | 311 final String testPrefix; |
| 309 String targetRunnerPath; | 312 String targetRunnerPath; |
| 310 String hostRunnerPath; | 313 String hostRunnerPath; |
| 311 final String dartDir; | 314 final String dartDir; |
| 312 List<String> statusFilePaths; | 315 List<String> statusFilePaths; |
| 313 TestCaseEvent doTest; | 316 Function doTest; |
| 314 VoidFunction doDone; | 317 VoidFunction doDone; |
| 315 ReceivePort receiveTestName; | 318 ReceivePort receiveTestName; |
| 316 TestExpectations testExpectations; | 319 TestExpectations testExpectations; |
| 317 | 320 |
| 318 CCTestSuite(Map configuration, | 321 CCTestSuite(Map configuration, |
| 319 String suiteName, | 322 String suiteName, |
| 320 String runnerName, | 323 String runnerName, |
| 321 List<String> this.statusFilePaths, | 324 List<String> this.statusFilePaths, |
| 322 {this.testPrefix: ''}) | 325 {this.testPrefix: ''}) |
| 323 : super(configuration, suiteName), | 326 : super(configuration, suiteName), |
| (...skipping 29 matching lines...) Expand all Loading... |
| 353 | 356 |
| 354 if (configuration["report"]) { | 357 if (configuration["report"]) { |
| 355 SummaryReport.add(expectations); | 358 SummaryReport.add(expectations); |
| 356 } | 359 } |
| 357 | 360 |
| 358 if (expectations.contains(SKIP)) return; | 361 if (expectations.contains(SKIP)) return; |
| 359 | 362 |
| 360 var args = TestUtils.standardOptions(configuration); | 363 var args = TestUtils.standardOptions(configuration); |
| 361 args.add(testName); | 364 args.add(testName); |
| 362 | 365 |
| 366 var command = CommandBuilder.instance.getCommand( |
| 367 'run_vm_unittest', targetRunnerPath, args, configurationDir); |
| 363 doTest( | 368 doTest( |
| 364 new TestCase(constructedName, | 369 new TestCase(constructedName, |
| 365 [new Command('run_vm_unittest', targetRunnerPath, args)], | 370 [command], |
| 366 configuration, | 371 configuration, |
| 367 completeHandler, | |
| 368 expectations)); | 372 expectations)); |
| 369 } | 373 } |
| 370 } | 374 } |
| 371 | 375 |
| 372 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) { | 376 void forEachTest(Function onTest, Map testCache, [VoidFunction onDone]) { |
| 373 doTest = onTest; | 377 doTest = onTest; |
| 374 doDone = onDone; | 378 doDone = onDone; |
| 375 | 379 |
| 376 var filesRead = 0; | 380 var filesRead = 0; |
| 377 void statusFileRead() { | 381 void statusFileRead() { |
| 378 filesRead++; | 382 filesRead++; |
| 379 if (filesRead == statusFilePaths.length) { | 383 if (filesRead == statusFilePaths.length) { |
| 380 receiveTestName = new ReceivePort(); | 384 receiveTestName = new ReceivePort(); |
| 381 var port = spawnFunction(ccTestLister); | 385 var port = spawnFunction(ccTestLister); |
| 382 port.send(hostRunnerPath, receiveTestName.toSendPort()); | 386 port.send(hostRunnerPath, receiveTestName.toSendPort()); |
| 383 receiveTestName.receive(testNameHandler); | 387 receiveTestName.receive(testNameHandler); |
| 384 } | 388 } |
| 385 } | 389 } |
| 386 | 390 |
| 387 testExpectations = new TestExpectations(); | 391 testExpectations = new TestExpectations(); |
| 388 for (var statusFilePath in statusFilePaths) { | 392 for (var statusFilePath in statusFilePaths) { |
| 389 ReadTestExpectationsInto(testExpectations, | 393 ReadTestExpectationsInto(testExpectations, |
| 390 '$dartDir/$statusFilePath', | 394 '$dartDir/$statusFilePath', |
| 391 configuration, | 395 configuration, |
| 392 statusFileRead); | 396 statusFileRead); |
| 393 } | 397 } |
| 394 } | 398 } |
| 395 | |
| 396 void completeHandler(TestCase testCase) { | |
| 397 } | |
| 398 } | 399 } |
| 399 | 400 |
| 400 | 401 |
| 401 class TestInformation { | 402 class TestInformation { |
| 402 Path filePath; | 403 Path filePath; |
| 403 Map optionsFromFile; | 404 Map optionsFromFile; |
| 404 bool hasCompileError; | 405 bool hasCompileError; |
| 405 bool hasRuntimeError; | 406 bool hasRuntimeError; |
| 406 bool isNegativeIfChecked; | 407 bool isNegativeIfChecked; |
| 407 bool hasFatalTypeErrors; | 408 bool hasFatalTypeErrors; |
| 408 Set<String> multitestOutcome; | 409 Set<String> multitestOutcome; |
| 409 | 410 |
| 410 TestInformation(this.filePath, this.optionsFromFile, | 411 TestInformation(this.filePath, this.optionsFromFile, |
| 411 this.hasCompileError, this.hasRuntimeError, | 412 this.hasCompileError, this.hasRuntimeError, |
| 412 this.isNegativeIfChecked, this.hasFatalTypeErrors, | 413 this.isNegativeIfChecked, this.hasFatalTypeErrors, |
| 413 this.multitestOutcome) { | 414 this.multitestOutcome) { |
| 414 assert(filePath.isAbsolute); | 415 assert(filePath.isAbsolute); |
| 415 } | 416 } |
| 416 } | 417 } |
| 417 | 418 |
| 418 /** | 419 /** |
| 419 * A standard [TestSuite] implementation that searches for tests in a | 420 * A standard [TestSuite] implementation that searches for tests in a |
| 420 * directory, and creates [TestCase]s that compile and/or run them. | 421 * directory, and creates [TestCase]s that compile and/or run them. |
| 421 */ | 422 */ |
| 422 class StandardTestSuite extends TestSuite { | 423 class StandardTestSuite extends TestSuite { |
| 423 final Path suiteDir; | 424 final Path suiteDir; |
| 424 final List<String> statusFilePaths; | 425 final List<String> statusFilePaths; |
| 425 TestCaseEvent doTest; | 426 Function doTest; |
| 426 TestExpectations testExpectations; | 427 TestExpectations testExpectations; |
| 427 List<TestInformation> cachedTests; | 428 List<TestInformation> cachedTests; |
| 428 final Path dartDir; | 429 final Path dartDir; |
| 429 Predicate<String> isTestFilePredicate; | 430 Predicate<String> isTestFilePredicate; |
| 430 final bool listRecursively; | 431 final bool listRecursively; |
| 431 | 432 |
| 432 static final RegExp multiTestRegExp = new RegExp(r"/// [0-9][0-9]:(.*)"); | 433 static final RegExp multiTestRegExp = new RegExp(r"/// [0-9][0-9]:(.*)"); |
| 433 | 434 |
| 434 StandardTestSuite(Map configuration, | 435 StandardTestSuite(Map configuration, |
| 435 String suiteName, | 436 String suiteName, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 */ | 500 */ |
| 500 bool isTestFile(String filename) { | 501 bool isTestFile(String filename) { |
| 501 // Use the specified predicate, if provided. | 502 // Use the specified predicate, if provided. |
| 502 if (isTestFilePredicate != null) return isTestFilePredicate(filename); | 503 if (isTestFilePredicate != null) return isTestFilePredicate(filename); |
| 503 | 504 |
| 504 return filename.endsWith("Test.dart"); | 505 return filename.endsWith("Test.dart"); |
| 505 } | 506 } |
| 506 | 507 |
| 507 List<String> additionalOptions(Path filePath) => []; | 508 List<String> additionalOptions(Path filePath) => []; |
| 508 | 509 |
| 509 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) { | 510 void forEachTest(Function onTest, Map testCache, [VoidFunction onDone]) { |
| 510 updateDartium().then((_) { | 511 updateDartium().then((_) { |
| 511 doTest = onTest; | 512 doTest = onTest; |
| 512 | 513 |
| 513 return readExpectations(); | 514 return readExpectations(); |
| 514 }).then((expectations) { | 515 }).then((expectations) { |
| 515 testExpectations = expectations; | 516 testExpectations = expectations; |
| 516 | 517 |
| 517 // Checked if we have already found and generated the tests for | 518 // Checked if we have already found and generated the tests for |
| 518 // this suite. | 519 // this suite. |
| 519 if (!testCache.containsKey(suiteName)) { | 520 if (!testCache.containsKey(suiteName)) { |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 var commonArguments = commonArgumentsFromFile(info.filePath, | 733 var commonArguments = commonArgumentsFromFile(info.filePath, |
| 733 info.optionsFromFile); | 734 info.optionsFromFile); |
| 734 | 735 |
| 735 List<List<String>> vmOptionsList = getVmOptions(info.optionsFromFile); | 736 List<List<String>> vmOptionsList = getVmOptions(info.optionsFromFile); |
| 736 assert(!vmOptionsList.isEmpty); | 737 assert(!vmOptionsList.isEmpty); |
| 737 | 738 |
| 738 for (var vmOptions in vmOptionsList) { | 739 for (var vmOptions in vmOptionsList) { |
| 739 doTest(new TestCase('$suiteName/$testName', | 740 doTest(new TestCase('$suiteName/$testName', |
| 740 makeCommands(info, vmOptions, commonArguments), | 741 makeCommands(info, vmOptions, commonArguments), |
| 741 configuration, | 742 configuration, |
| 742 completeHandler, | |
| 743 expectations, | 743 expectations, |
| 744 isNegative: isNegative, | 744 isNegative: isNegative, |
| 745 info: info)); | 745 info: info)); |
| 746 } | 746 } |
| 747 } | 747 } |
| 748 | 748 |
| 749 List<Command> makeCommands(TestInformation info, var vmOptions, var args) { | 749 List<Command> makeCommands(TestInformation info, var vmOptions, var args) { |
| 750 var compiler = configuration['compiler']; | 750 var compiler = configuration['compiler']; |
| 751 switch (compiler) { | 751 switch (compiler) { |
| 752 case 'dart2js': | 752 case 'dart2js': |
| 753 args = new List.from(args); | 753 args = new List.from(args); |
| 754 String tempDir = createOutputDirectory(info.filePath, ''); | 754 String tempDir = createOutputDirectory(info.filePath, ''); |
| 755 args.add('--out=$tempDir/out.js'); | 755 args.add('--out=$tempDir/out.js'); |
| 756 | 756 |
| 757 List<Command> commands = | 757 var command = CommandBuilder.instance.getCompilationCommand( |
| 758 <Command>[new CompilationCommand(compiler, | 758 compiler, "$tempDir/out.js", !useSdk, |
| 759 "$tempDir/out.js", | 759 dart2JsBootstrapDependencies, compilerPath, args, configurationDir); |
| 760 !useSdk, | 760 |
| 761 dart2JsBootstrapDependencies, | 761 List<Command> commands = <Command>[command]; |
| 762 compilerPath, | |
| 763 args)]; | |
| 764 if (info.hasCompileError) { | 762 if (info.hasCompileError) { |
| 765 // Do not attempt to run the compiled result. A compilation | 763 // Do not attempt to run the compiled result. A compilation |
| 766 // error should be reported by the compilation command. | 764 // error should be reported by the compilation command. |
| 767 } else if (configuration['runtime'] == 'd8') { | 765 } else if (configuration['runtime'] == 'd8') { |
| 768 commands.add(new Command("d8", d8FileName, ['$tempDir/out.js'])); | 766 commands.add(CommandBuilder.instance.getCommand( |
| 767 "d8", d8FileName, ['$tempDir/out.js'], configurationDir)); |
| 769 } else if (configuration['runtime'] == 'jsshell') { | 768 } else if (configuration['runtime'] == 'jsshell') { |
| 770 commands.add( | 769 commands.add(CommandBuilder.instance.getCommand( |
| 771 new Command("jsshell", jsShellFileName, ['$tempDir/out.js'])); | 770 "jsshell", jsShellFileName, ['$tempDir/out.js'], configurationDir)); |
| 772 } | 771 } |
| 773 return commands; | 772 return commands; |
| 774 | 773 |
| 775 case 'dart2dart': | 774 case 'dart2dart': |
| 776 args = new List.from(args); | 775 args = new List.from(args); |
| 777 args.add('--output-type=dart'); | 776 args.add('--output-type=dart'); |
| 778 String tempDir = createOutputDirectory(info.filePath, ''); | 777 String tempDir = createOutputDirectory(info.filePath, ''); |
| 779 args.add('--out=$tempDir/out.dart'); | 778 args.add('--out=$tempDir/out.dart'); |
| 780 | 779 |
| 781 List<Command> commands = | 780 List<Command> commands = |
| 782 <Command>[new CompilationCommand(compiler, | 781 <Command>[CommandBuilder.instance.getCompilationCommand( |
| 783 "$tempDir/out.dart", | 782 compiler, "$tempDir/out.dart", !useSdk, |
| 784 !useSdk, | 783 dart2JsBootstrapDependencies, compilerPath, args, |
| 785 dart2JsBootstrapDependencies, | 784 configurationDir)]; |
| 786 compilerPath, | |
| 787 args)]; | |
| 788 if (info.hasCompileError) { | 785 if (info.hasCompileError) { |
| 789 // Do not attempt to run the compiled result. A compilation | 786 // Do not attempt to run the compiled result. A compilation |
| 790 // error should be reported by the compilation command. | 787 // error should be reported by the compilation command. |
| 791 } else if (configuration['runtime'] == 'vm') { | 788 } else if (configuration['runtime'] == 'vm') { |
| 792 // TODO(antonm): support checked. | 789 // TODO(antonm): support checked. |
| 793 var vmArguments = new List.from(vmOptions); | 790 var vmArguments = new List.from(vmOptions); |
| 794 vmArguments.addAll([ | 791 vmArguments.addAll([ |
| 795 '--ignore-unrecognized-flags', '$tempDir/out.dart']); | 792 '--ignore-unrecognized-flags', '$tempDir/out.dart']); |
| 796 commands.add(new Command("vm", vmFileName, vmArguments)); | 793 commands.add(CommandBuilder.instance.getCommand( |
| 794 "vm", vmFileName, vmArguments, configurationDir)); |
| 797 } else { | 795 } else { |
| 798 throw 'Unsupported runtime ${configuration["runtime"]} for dart2dart'; | 796 throw 'Unsupported runtime ${configuration["runtime"]} for dart2dart'; |
| 799 } | 797 } |
| 800 return commands; | 798 return commands; |
| 801 | 799 |
| 802 case 'none': | 800 case 'none': |
| 803 case 'dartc': | 801 var arguments = new List.from(vmOptions); |
| 802 arguments.addAll(args); |
| 803 return <Command>[CommandBuilder.instance.getCommand( |
| 804 'vm', dartShellFileName, arguments, configurationDir)]; |
| 805 |
| 804 case 'dartanalyzer': | 806 case 'dartanalyzer': |
| 805 case 'dart2analyzer': | 807 case 'dart2analyzer': |
| 806 var displayName = (configuration['compiler'] == 'none' | 808 return <Command>[CommandBuilder.instance.getAnalysisCommand( |
| 807 ? 'vm' : configuration['compiler']); | 809 compiler, dartShellFileName, args, configurationDir, |
| 808 var arguments = new List.from(vmOptions); | 810 flavour: compiler)]; |
| 809 arguments.addAll(args); | |
| 810 return <Command>[ | |
| 811 new Command(displayName, dartShellFileName, arguments)]; | |
| 812 | 811 |
| 813 default: | 812 default: |
| 814 throw 'Unknown compiler ${configuration["compiler"]}'; | 813 throw 'Unknown compiler ${configuration["compiler"]}'; |
| 815 } | 814 } |
| 816 } | 815 } |
| 817 | 816 |
| 818 CreateTest makeTestCaseCreator(RegExp pattern, Map optionsFromFile) { | 817 CreateTest makeTestCaseCreator(RegExp pattern, Map optionsFromFile) { |
| 819 return (Path filePath, | 818 return (Path filePath, |
| 820 bool hasCompileError, | 819 bool hasCompileError, |
| 821 bool hasRuntimeError, | 820 bool hasRuntimeError, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 File file = new File(dartWrapperFilename); | 892 File file = new File(dartWrapperFilename); |
| 894 RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE); | 893 RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE); |
| 895 | 894 |
| 896 var usePackageImport = dartLibraryFilename.segments().contains("pkg"); | 895 var usePackageImport = dartLibraryFilename.segments().contains("pkg"); |
| 897 var libraryPathComponent = _createUrlPathFromFile(dartLibraryFilename); | 896 var libraryPathComponent = _createUrlPathFromFile(dartLibraryFilename); |
| 898 dartWrapper.writeStringSync(dartTestWrapper(usePackageImport, | 897 dartWrapper.writeStringSync(dartTestWrapper(usePackageImport, |
| 899 libraryPathComponent)); | 898 libraryPathComponent)); |
| 900 dartWrapper.closeSync(); | 899 dartWrapper.closeSync(); |
| 901 } | 900 } |
| 902 | 901 |
| 903 | |
| 904 /** | 902 /** |
| 905 * The [StandardTestSuite] has support for tests that | 903 * The [StandardTestSuite] has support for tests that |
| 906 * compile a test from Dart to JavaScript, and then run the resulting | 904 * compile a test from Dart to JavaScript, and then run the resulting |
| 907 * JavaScript. This function creates a working directory to hold the | 905 * JavaScript. This function creates a working directory to hold the |
| 908 * JavaScript version of the test, and copies the appropriate framework | 906 * JavaScript version of the test, and copies the appropriate framework |
| 909 * files to that directory. It creates a [BrowserTestCase], which has | 907 * files to that directory. It creates a [BrowserTestCase], which has |
| 910 * two sequential steps to be run by the [ProcessQueue] when the test is | 908 * two sequential steps to be run by the [ProcessQueue] when the test is |
| 911 * executed: a compilation step and an execution step, both with the | 909 * executed: a compilation step and an execution step, both with the |
| 912 * appropriate executable and arguments. The [expectations] object can be | 910 * appropriate executable and arguments. The [expectations] object can be |
| 913 * either a Set<String> if the test is a regular test, or a Map<String | 911 * either a Set<String> if the test is a regular test, or a Map<String |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 // compiled, move the input scripts over with the script so they can | 999 // compiled, move the input scripts over with the script so they can |
| 1002 // be accessed. | 1000 // be accessed. |
| 1003 String result = new File.fromPath(fromPath).readAsStringSync(); | 1001 String result = new File.fromPath(fromPath).readAsStringSync(); |
| 1004 new File('$tempDir/$baseName.dart').writeAsStringSync(result); | 1002 new File('$tempDir/$baseName.dart').writeAsStringSync(result); |
| 1005 } | 1003 } |
| 1006 } | 1004 } |
| 1007 | 1005 |
| 1008 | 1006 |
| 1009 // Variables for browser multi-tests. | 1007 // Variables for browser multi-tests. |
| 1010 List<String> subtestNames = info.optionsFromFile['subtestNames']; | 1008 List<String> subtestNames = info.optionsFromFile['subtestNames']; |
| 1011 BrowserTestCase multitestParentTest; | |
| 1012 int subtestIndex = 0; | 1009 int subtestIndex = 0; |
| 1013 // Construct the command that executes the browser test | 1010 // Construct the command that executes the browser test |
| 1014 do { | 1011 do { |
| 1015 List<Command> commandSet = new List<Command>.from(commands); | 1012 List<Command> commandSet = new List<Command>.from(commands); |
| 1016 if (subtestIndex != 0) { | |
| 1017 // NOTE: The first time we enter this loop, all the compilation | |
| 1018 // commands will be executed. On subsequent loop iterations, we | |
| 1019 // don't need to do any compilations. Thus we set "commandSet = []". | |
| 1020 commandSet = []; | |
| 1021 } | |
| 1022 | 1013 |
| 1023 var htmlPath_subtest = _createUrlPathFromFile(new Path(htmlPath)); | 1014 var htmlPath_subtest = _createUrlPathFromFile(new Path(htmlPath)); |
| 1024 var fullHtmlPath = _getUriForBrowserTest(info, htmlPath_subtest, | 1015 var fullHtmlPath = _getUriForBrowserTest(info, htmlPath_subtest, |
| 1025 subtestNames, subtestIndex); | 1016 subtestNames, subtestIndex); |
| 1026 | 1017 |
| 1027 List<String> args = <String>[]; | 1018 List<String> args = <String>[]; |
| 1028 | 1019 |
| 1029 if (configuration['use_browser_controller']) { | 1020 if (configuration['use_browser_controller']) { |
| 1030 // This command is not actually run, it is used for reproducing | 1021 // This command is not actually run, it is used for reproducing |
| 1031 // the failure. | 1022 // the failure. |
| 1032 args = ['tools/testing/dart/launch_browser.dart', | 1023 args = ['tools/testing/dart/launch_browser.dart', |
| 1033 runtime, | 1024 runtime, |
| 1034 fullHtmlPath]; | 1025 fullHtmlPath]; |
| 1035 commandSet.add(new Command(runtime, | 1026 commandSet.add(CommandBuilder.instance.getBrowserTestCommand( |
| 1036 TestUtils.dartTestExecutable.toString(), | 1027 runtime, fullHtmlPath, |
| 1037 args)); | 1028 TestUtils.dartTestExecutable.toString(), args, configurationDir)); |
| 1038 } else if (TestUtils.usesWebDriver(runtime)) { | 1029 } else if (TestUtils.usesWebDriver(runtime)) { |
| 1039 args = [ | 1030 args = [ |
| 1040 dartDir.append('tools/testing/run_selenium.py').toNativePath(), | 1031 dartDir.append('tools/testing/run_selenium.py').toNativePath(), |
| 1041 '--browser=$runtime', | 1032 '--browser=$runtime', |
| 1042 // NOTE: This value will be overridden by the test runner | 1033 // NOTE: This value will be overridden by the test runner |
| 1043 '--timeout=${configuration['timeout']}', | 1034 '--timeout=${configuration['timeout']}', |
| 1044 '--out=$fullHtmlPath']; | 1035 '--out=$fullHtmlPath']; |
| 1045 if (runtime == 'dartium') { | 1036 if (runtime == 'dartium') { |
| 1046 args.add('--executable=$dartiumFilename'); | 1037 args.add('--executable=$dartiumFilename'); |
| 1047 } | 1038 } |
| 1048 if (subtestIndex != 0) { | 1039 if (subtestIndex != 0) { |
| 1049 args.add('--force-refresh'); | 1040 args.add('--force-refresh'); |
| 1050 } | 1041 } |
| 1051 commandSet.add(new Command(runtime, 'python', args)); | 1042 commandSet.add(CommandBuilder.instance.getSeleniumTestCommand( |
| 1043 runtime, fullHtmlPath, 'python', args, configurationDir)); |
| 1052 } else { | 1044 } else { |
| 1053 if (runtime != "drt") { | 1045 assert(runtime == "drt"); |
| 1054 print("Unknown runtime $runtime"); | |
| 1055 exit(1); | |
| 1056 } | |
| 1057 | 1046 |
| 1058 var dartFlags = []; | 1047 var dartFlags = []; |
| 1059 var contentShellOptions = []; | 1048 var contentShellOptions = []; |
| 1060 | 1049 |
| 1061 contentShellOptions.add('--no-timeout'); | 1050 contentShellOptions.add('--no-timeout'); |
| 1062 contentShellOptions.add('--dump-render-tree'); | 1051 contentShellOptions.add('--dump-render-tree'); |
| 1063 | 1052 |
| 1064 if (compiler == 'none' || compiler == 'dart2dart') { | 1053 if (compiler == 'none' || compiler == 'dart2dart') { |
| 1065 dartFlags.add('--ignore-unrecognized-flags'); | 1054 dartFlags.add('--ignore-unrecognized-flags'); |
| 1066 if (configuration["checked"]) { | 1055 if (configuration["checked"]) { |
| 1067 dartFlags.add('--enable_asserts'); | 1056 dartFlags.add('--enable_asserts'); |
| 1068 dartFlags.add("--enable_type_checks"); | 1057 dartFlags.add("--enable_type_checks"); |
| 1069 } | 1058 } |
| 1070 dartFlags.addAll(vmOptions); | 1059 dartFlags.addAll(vmOptions); |
| 1071 } | 1060 } |
| 1072 | 1061 |
| 1073 if (expectedOutput != null) { | 1062 if (expectedOutput != null) { |
| 1074 if (expectedOutput.toNativePath().endsWith('.png')) { | 1063 if (expectedOutput.toNativePath().endsWith('.png')) { |
| 1075 // pixel tests are specified by running DRT "foo.html'-p" | 1064 // pixel tests are specified by running DRT "foo.html'-p" |
| 1076 contentShellOptions.add('--notree'); | 1065 contentShellOptions.add('--notree'); |
| 1077 fullHtmlPath = "${fullHtmlPath}'-p"; | 1066 fullHtmlPath = "${fullHtmlPath}'-p"; |
| 1078 } | 1067 } |
| 1079 } | 1068 } |
| 1080 commandSet.add(new ContentShellCommand(contentShellFilename, | 1069 commandSet.add(CommandBuilder.instance.getContentShellCommand( |
| 1081 fullHtmlPath, | 1070 contentShellFilename, fullHtmlPath, contentShellOptions, |
| 1082 contentShellOptions, | 1071 dartFlags, expectedOutput, configurationDir)); |
| 1083 dartFlags, | |
| 1084 expectedOutput)); | |
| 1085 } | 1072 } |
| 1086 | 1073 |
| 1087 // Create BrowserTestCase and queue it. | 1074 // Create BrowserTestCase and queue it. |
| 1088 String testDisplayName = '$suiteName/$testName'; | 1075 String testDisplayName = '$suiteName/$testName'; |
| 1089 var testCase; | 1076 var testCase; |
| 1090 if (info.optionsFromFile['isMultiHtmlTest']) { | 1077 if (info.optionsFromFile['isMultiHtmlTest']) { |
| 1091 testDisplayName = '$testDisplayName/${subtestNames[subtestIndex]}'; | 1078 testDisplayName = '$testDisplayName/${subtestNames[subtestIndex]}'; |
| 1092 testCase = new BrowserTestCase(testDisplayName, | 1079 testCase = new BrowserTestCase(testDisplayName, |
| 1093 commandSet, configuration, completeHandler, | 1080 commandSet, configuration, |
| 1094 expectations['$testName/${subtestNames[subtestIndex]}'], | 1081 expectations['$testName/${subtestNames[subtestIndex]}'], |
| 1095 info, info.hasCompileError || info.hasRuntimeError, fullHtmlPath, | 1082 info, info.hasCompileError || info.hasRuntimeError, fullHtmlPath); |
| 1096 subtestIndex != 0); | |
| 1097 } else { | 1083 } else { |
| 1098 testCase = new BrowserTestCase(testDisplayName, | 1084 testCase = new BrowserTestCase(testDisplayName, |
| 1099 commandSet, configuration, completeHandler, expectations, | 1085 commandSet, configuration, expectations, |
| 1100 info, info.hasCompileError || info.hasRuntimeError, fullHtmlPath, | 1086 info, info.hasCompileError || info.hasRuntimeError, fullHtmlPath); |
| 1101 false); | |
| 1102 } | |
| 1103 if (subtestIndex == 0) { | |
| 1104 multitestParentTest = testCase; | |
| 1105 } else { | |
| 1106 multitestParentTest.addObserver(testCase); | |
| 1107 } | 1087 } |
| 1108 | 1088 |
| 1109 doTest(testCase); | 1089 doTest(testCase); |
| 1110 subtestIndex++; | 1090 subtestIndex++; |
| 1111 } while(subtestIndex < subtestNames.length); | 1091 } while(subtestIndex < subtestNames.length); |
| 1112 } | 1092 } |
| 1113 } | 1093 } |
| 1114 | 1094 |
| 1115 /** Helper to create a compilation command for a single input file. */ | 1095 /** Helper to create a compilation command for a single input file. */ |
| 1116 Command _compileCommand(String inputFile, String outputFile, | 1096 Command _compileCommand(String inputFile, String outputFile, |
| 1117 String compiler, String dir, vmOptions, optionsFromFile) { | 1097 String compiler, String dir, vmOptions, optionsFromFile) { |
| 1118 assert (['dart2js', 'dart2dart'].contains(compiler)); | 1098 assert (['dart2js', 'dart2dart'].contains(compiler)); |
| 1119 String executable = compilerPath; | 1099 String executable = compilerPath; |
| 1120 List<String> args = TestUtils.standardOptions(configuration); | 1100 List<String> args = TestUtils.standardOptions(configuration); |
| 1121 String packageRoot = | 1101 String packageRoot = |
| 1122 packageRootArgument(optionsFromFile['packageRoot']); | 1102 packageRootArgument(optionsFromFile['packageRoot']); |
| 1123 if (packageRoot != null) { | 1103 if (packageRoot != null) { |
| 1124 args.add(packageRoot); | 1104 args.add(packageRoot); |
| 1125 } | 1105 } |
| 1126 args.add('--out=$outputFile'); | 1106 args.add('--out=$outputFile'); |
| 1127 args.add(inputFile); | 1107 args.add(inputFile); |
| 1128 if (executable.endsWith('.dart')) { | 1108 if (executable.endsWith('.dart')) { |
| 1129 // Run the compiler script via the Dart VM. | 1109 // Run the compiler script via the Dart VM. |
| 1130 args.insert(0, executable); | 1110 args.insert(0, executable); |
| 1131 executable = dartShellFileName; | 1111 executable = dartShellFileName; |
| 1132 } | 1112 } |
| 1133 return new CompilationCommand(compiler, | 1113 return CommandBuilder.instance.getCompilationCommand( |
| 1134 outputFile, | 1114 compiler, outputFile, !useSdk, |
| 1135 !useSdk, | 1115 dart2JsBootstrapDependencies, compilerPath, args, configurationDir); |
| 1136 dart2JsBootstrapDependencies, | |
| 1137 compilerPath, | |
| 1138 args); | |
| 1139 } | 1116 } |
| 1140 | 1117 |
| 1141 /** | 1118 /** |
| 1142 * Create a directory for the generated test. If a Dart language test | 1119 * Create a directory for the generated test. If a Dart language test |
| 1143 * needs to be run in a browser, the Dart test needs to be embedded in | 1120 * needs to be run in a browser, the Dart test needs to be embedded in |
| 1144 * an HTML page, with a testing framework based on scripting and DOM events. | 1121 * an HTML page, with a testing framework based on scripting and DOM events. |
| 1145 * These scripts and pages are written to a generated_test directory | 1122 * These scripts and pages are written to a generated_test directory |
| 1146 * inside the build directory of the checkout. | 1123 * inside the build directory of the checkout. |
| 1147 * | 1124 * |
| 1148 * Those tests which are already HTML web applications (web tests), with | 1125 * Those tests which are already HTML web applications (web tests), with |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1221 if (configuration['dartium'] != '') { | 1198 if (configuration['dartium'] != '') { |
| 1222 return configuration['dartium']; | 1199 return configuration['dartium']; |
| 1223 } | 1200 } |
| 1224 if (Platform.operatingSystem == 'macos') { | 1201 if (Platform.operatingSystem == 'macos') { |
| 1225 return dartDir.append('client/tests/dartium/Chromium.app/Contents/' | 1202 return dartDir.append('client/tests/dartium/Chromium.app/Contents/' |
| 1226 'MacOS/Chromium').toNativePath(); | 1203 'MacOS/Chromium').toNativePath(); |
| 1227 } | 1204 } |
| 1228 return dartDir.append('client/tests/dartium/chrome').toNativePath(); | 1205 return dartDir.append('client/tests/dartium/chrome').toNativePath(); |
| 1229 } | 1206 } |
| 1230 | 1207 |
| 1231 void completeHandler(TestCase testCase) { | |
| 1232 } | |
| 1233 | |
| 1234 List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) { | 1208 List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) { |
| 1235 List args = TestUtils.standardOptions(configuration); | 1209 List args = TestUtils.standardOptions(configuration); |
| 1236 | 1210 |
| 1237 String packageRoot = packageRootArgument(optionsFromFile['packageRoot']); | 1211 String packageRoot = packageRootArgument(optionsFromFile['packageRoot']); |
| 1238 if (packageRoot != null) { | 1212 if (packageRoot != null) { |
| 1239 args.add(packageRoot); | 1213 args.add(packageRoot); |
| 1240 } | 1214 } |
| 1241 args.addAll(additionalOptions(filePath)); | 1215 args.addAll(additionalOptions(filePath)); |
| 1242 if (configuration['analyzer']) { | 1216 if (configuration['analyzer']) { |
| 1243 args.add('--machine'); | 1217 args.add('--machine'); |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1660 'org.junit.runner.JUnitCore']; | 1634 'org.junit.runner.JUnitCore']; |
| 1661 args.addAll(testClasses); | 1635 args.addAll(testClasses); |
| 1662 | 1636 |
| 1663 // Lengthen the timeout for JUnit tests. It is normal for them | 1637 // Lengthen the timeout for JUnit tests. It is normal for them |
| 1664 // to run for a few minutes. | 1638 // to run for a few minutes. |
| 1665 Map updatedConfiguration = new Map(); | 1639 Map updatedConfiguration = new Map(); |
| 1666 configuration.forEach((key, value) { | 1640 configuration.forEach((key, value) { |
| 1667 updatedConfiguration[key] = value; | 1641 updatedConfiguration[key] = value; |
| 1668 }); | 1642 }); |
| 1669 updatedConfiguration['timeout'] *= 3; | 1643 updatedConfiguration['timeout'] *= 3; |
| 1644 var command = CommandBuilder.instance.getCommand( |
| 1645 'junit_test', 'java', args, configurationDir); |
| 1670 doTest(new TestCase(suiteName, | 1646 doTest(new TestCase(suiteName, |
| 1671 [new Command('junit_test', 'java', args)], | 1647 [command], |
| 1672 updatedConfiguration, | 1648 updatedConfiguration, |
| 1673 completeHandler, | |
| 1674 new Set<String>.from([PASS]))); | 1649 new Set<String>.from([PASS]))); |
| 1675 doDone(); | 1650 doDone(); |
| 1676 } | 1651 } |
| 1677 | 1652 |
| 1678 void completeHandler(TestCase testCase) { | |
| 1679 } | |
| 1680 | |
| 1681 void computeClassPath() { | 1653 void computeClassPath() { |
| 1682 classPath = | 1654 classPath = |
| 1683 ['$buildDir/analyzer/util/analyzer/dart_analyzer.jar', | 1655 ['$buildDir/analyzer/util/analyzer/dart_analyzer.jar', |
| 1684 '$buildDir/analyzer/dart_analyzer_tests.jar', | 1656 '$buildDir/analyzer/dart_analyzer_tests.jar', |
| 1685 // Third party libraries. | 1657 // Third party libraries. |
| 1686 '$dartDir/third_party/args4j/2.0.12/args4j-2.0.12.jar', | 1658 '$dartDir/third_party/args4j/2.0.12/args4j-2.0.12.jar', |
| 1687 '$dartDir/third_party/guava/r13/guava-13.0.1.jar', | 1659 '$dartDir/third_party/guava/r13/guava-13.0.1.jar', |
| 1688 '$dartDir/third_party/rhino/1_7R3/js.jar', | 1660 '$dartDir/third_party/rhino/1_7R3/js.jar', |
| 1689 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar', | 1661 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar', |
| 1690 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar', | 1662 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar', |
| 1691 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar', | 1663 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar', |
| 1692 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar', | 1664 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar', |
| 1693 '$dartDir/third_party/junit/v4_8_2/junit.jar'] | 1665 '$dartDir/third_party/junit/v4_8_2/junit.jar'] |
| 1694 .join(Platform.operatingSystem == 'windows'? ';': ':'); // Path separat
or. | 1666 .join(Platform.operatingSystem == 'windows'? ';': ':'); |
| 1695 } | 1667 } |
| 1696 } | 1668 } |
| 1697 | 1669 |
| 1698 class LastModifiedCache { | 1670 class LastModifiedCache { |
| 1699 Map<String, DateTime> _cache = <String, DateTime>{}; | 1671 Map<String, DateTime> _cache = <String, DateTime>{}; |
| 1700 | 1672 |
| 1701 /** | 1673 /** |
| 1702 * Returns the last modified date of the given [uri]. | 1674 * Returns the last modified date of the given [uri]. |
| 1703 * | 1675 * |
| 1704 * The return value will be cached for future queries. If [uri] is a local | 1676 * The return value will be cached for future queries. If [uri] is a local |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1966 * $pass tests are expected to pass | 1938 * $pass tests are expected to pass |
| 1967 * $failOk tests are expected to fail that we won't fix | 1939 * $failOk tests are expected to fail that we won't fix |
| 1968 * $fail tests are expected to fail that we should fix | 1940 * $fail tests are expected to fail that we should fix |
| 1969 * $crash tests are expected to crash that we should fix | 1941 * $crash tests are expected to crash that we should fix |
| 1970 * $timeout tests are allowed to timeout | 1942 * $timeout tests are allowed to timeout |
| 1971 * $compileErrorSkip tests are skipped on browsers due to compile-time error | 1943 * $compileErrorSkip tests are skipped on browsers due to compile-time error |
| 1972 """; | 1944 """; |
| 1973 print(report); | 1945 print(report); |
| 1974 } | 1946 } |
| 1975 } | 1947 } |
| OLD | NEW |