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