Chromium Code Reviews| 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:io"); | 17 #import("dart:io"); |
| 18 #import("dart:isolate"); | 18 #import("dart:isolate"); |
| 19 #import("status_file_parser.dart"); | 19 #import("status_file_parser.dart"); |
| 20 #import("test_runner.dart"); | 20 #import("test_runner.dart"); |
| 21 #import("multitest.dart"); | 21 #import("multitest.dart"); |
| 22 #import("drt_updater.dart"); | 22 #import("drt_updater.dart"); |
| 23 #import("dart:uri"); | |
| 23 | 24 |
| 24 #source("browser_test.dart"); | 25 #source("browser_test.dart"); |
| 25 | 26 |
| 26 | 27 |
| 27 // TODO(rnystrom): Add to dart:core? | 28 // TODO(rnystrom): Add to dart:core? |
| 28 /** | 29 /** |
| 29 * A simple function that tests [arg] and returns `true` or `false`. | 30 * A simple function that tests [arg] and returns `true` or `false`. |
| 30 */ | 31 */ |
| 31 typedef bool Predicate<T>(T arg); | 32 typedef bool Predicate<T>(T arg); |
| 32 | 33 |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 Map configuration, Path directory) { | 427 Map configuration, Path directory) { |
| 427 final name = directory.filename; | 428 final name = directory.filename; |
| 428 | 429 |
| 429 return new StandardTestSuite(configuration, | 430 return new StandardTestSuite(configuration, |
| 430 name, directory, | 431 name, directory, |
| 431 ['$directory/$name.status', '$directory/${name}_dart2js.status'], | 432 ['$directory/$name.status', '$directory/${name}_dart2js.status'], |
| 432 isTestFilePredicate: (filename) => filename.endsWith('_test.dart'), | 433 isTestFilePredicate: (filename) => filename.endsWith('_test.dart'), |
| 433 recursive: true); | 434 recursive: true); |
| 434 } | 435 } |
| 435 | 436 |
| 437 Collection<Uri> get dart2JsBootstrapDependencies { | |
| 438 if (!useDart2JsFromSdk) return []; | |
| 439 | |
| 440 var snapshotPath = TestUtils.absolutePath(new Path(buildDir).join( | |
| 441 new Path('dart-sdk/lib/_internal/compiler/' | |
| 442 'implementation/dart2js.dart.snapshot'))).toString(); | |
| 443 return [new Uri.fromComponents(scheme: 'file', path: snapshotPath)]; | |
| 444 } | |
| 445 | |
| 446 bool get useDart2JsFromSdk { | |
| 447 return configuration['use_sdk']; | |
| 448 } | |
| 449 | |
| 436 /** | 450 /** |
| 437 * The default implementation assumes a file is a test if | 451 * The default implementation assumes a file is a test if |
| 438 * it ends in "Test.dart". | 452 * it ends in "Test.dart". |
| 439 */ | 453 */ |
| 440 bool isTestFile(String filename) { | 454 bool isTestFile(String filename) { |
| 441 // Use the specified predicate, if provided. | 455 // Use the specified predicate, if provided. |
| 442 if (isTestFilePredicate != null) return isTestFilePredicate(filename); | 456 if (isTestFilePredicate != null) return isTestFilePredicate(filename); |
| 443 | 457 |
| 444 return filename.endsWith("Test.dart"); | 458 return filename.endsWith("Test.dart"); |
| 445 } | 459 } |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 info: info)); | 696 info: info)); |
| 683 } | 697 } |
| 684 } | 698 } |
| 685 | 699 |
| 686 List<Command> makeCommands(TestInformation info, var vmOptions, var args) { | 700 List<Command> makeCommands(TestInformation info, var vmOptions, var args) { |
| 687 switch (configuration['compiler']) { | 701 switch (configuration['compiler']) { |
| 688 case 'dart2js': | 702 case 'dart2js': |
| 689 args = new List.from(args); | 703 args = new List.from(args); |
| 690 String tempDir = createOutputDirectory(info.filePath, ''); | 704 String tempDir = createOutputDirectory(info.filePath, ''); |
| 691 args.add('--out=$tempDir/out.js'); | 705 args.add('--out=$tempDir/out.js'); |
| 692 List<Command> commands = <Command>[new Command(compilerPath, args)]; | 706 |
| 707 List<Command> commands = | |
| 708 <Command>[new Dart2JsCommand("$tempDir/out.js", | |
| 709 !useDart2JsFromSdk, | |
| 710 dart2JsBootstrapDependencies, | |
| 711 compilerPath, | |
| 712 args)]; | |
| 693 if (info.hasCompileError) { | 713 if (info.hasCompileError) { |
| 694 // Do not attempt to run the compiled result. A compilation | 714 // Do not attempt to run the compiled result. A compilation |
| 695 // error should be reported by the compilation command. | 715 // error should be reported by the compilation command. |
| 696 } else if (configuration['runtime'] == 'd8') { | 716 } else if (configuration['runtime'] == 'd8') { |
| 697 commands.add(new Command(d8FileName, ['$tempDir/out.js'])); | 717 commands.add(new Command(d8FileName, ['$tempDir/out.js'])); |
| 698 } else if (configuration['runtime'] == 'jsshell') { | 718 } else if (configuration['runtime'] == 'jsshell') { |
| 699 commands.add(new Command(jsShellFileName, ['$tempDir/out.js'])); | 719 commands.add(new Command(jsShellFileName, ['$tempDir/out.js'])); |
| 700 } | 720 } |
| 701 return commands; | 721 return commands; |
| 702 | 722 |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 991 args.add(inputFile); | 1011 args.add(inputFile); |
| 992 break; | 1012 break; |
| 993 default: | 1013 default: |
| 994 Expect.fail('unimplemented compiler $compiler'); | 1014 Expect.fail('unimplemented compiler $compiler'); |
| 995 } | 1015 } |
| 996 if (executable.endsWith('.dart')) { | 1016 if (executable.endsWith('.dart')) { |
| 997 // Run the compiler script via the Dart VM. | 1017 // Run the compiler script via the Dart VM. |
| 998 args.insertRange(0, 1, executable); | 1018 args.insertRange(0, 1, executable); |
| 999 executable = dartShellFileName; | 1019 executable = dartShellFileName; |
| 1000 } | 1020 } |
| 1021 if (configuration['compiler'] == 'dart2js') { | |
| 1022 return new Dart2JsCommand(outputFile, | |
| 1023 !useDart2JsFromSdk, | |
| 1024 dart2JsBootstrapDependencies, | |
| 1025 compilerPath, | |
| 1026 args); | |
| 1027 } | |
| 1001 return new Command(executable, args); | 1028 return new Command(executable, args); |
| 1002 } | 1029 } |
| 1003 | 1030 |
| 1004 /** | 1031 /** |
| 1005 * Create a directory for the generated test. If a Dart language test | 1032 * Create a directory for the generated test. If a Dart language test |
| 1006 * needs to be run in a browser, the Dart test needs to be embedded in | 1033 * needs to be run in a browser, the Dart test needs to be embedded in |
| 1007 * an HTML page, with a testing framework based on scripting and DOM events. | 1034 * an HTML page, with a testing framework based on scripting and DOM events. |
| 1008 * These scripts and pages are written to a generated_test directory | 1035 * These scripts and pages are written to a generated_test directory |
| 1009 * inside the build directory of the checkout. | 1036 * inside the build directory of the checkout. |
| 1010 * | 1037 * |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1487 '$dartDir/third_party/rhino/1_7R3/js.jar', | 1514 '$dartDir/third_party/rhino/1_7R3/js.jar', |
| 1488 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar', | 1515 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar', |
| 1489 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar', | 1516 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar', |
| 1490 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar', | 1517 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar', |
| 1491 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar', | 1518 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar', |
| 1492 '$dartDir/third_party/junit/v4_8_2/junit.jar'], | 1519 '$dartDir/third_party/junit/v4_8_2/junit.jar'], |
| 1493 Platform.operatingSystem == 'windows'? ';': ':'); // Path separator. | 1520 Platform.operatingSystem == 'windows'? ';': ':'); // Path separator. |
| 1494 } | 1521 } |
| 1495 } | 1522 } |
| 1496 | 1523 |
| 1524 class LastModifiedCache { | |
| 1525 Map<String, Date> _cache = <String, Date>{}; | |
| 1526 | |
| 1527 /** | |
| 1528 * Returns the last modified date of the given [uri]. | |
| 1529 * | |
| 1530 * The return value will be cached for future queries. If [uri] is a local | |
| 1531 * file, it's last modified [Date] will be returned. If the file does not | |
| 1532 * exist, null will be returned instead. | |
| 1533 * In case [uri] is not a local file, this method will always return | |
| 1534 * the current date. | |
| 1535 */ | |
| 1536 Date getLastModified(Uri uri) { | |
| 1537 if (uri.scheme == "file") { | |
| 1538 if (_cache.containsKey(uri.path)) { | |
| 1539 return _cache[uri.path]; | |
| 1540 } | |
| 1541 var file = new File(new Path(uri.path).toNativePath()); | |
| 1542 _cache[uri.path] = file.existsSync() ? file.lastModifiedSync() : null; | |
| 1543 return _cache[uri.path]; | |
| 1544 } | |
| 1545 return new Date.now(); | |
| 1546 } | |
| 1547 } | |
| 1548 | |
| 1497 class TestUtils { | 1549 class TestUtils { |
| 1498 /** | 1550 /** |
| 1499 * The libraries in this directory relies on finding various files | 1551 * The libraries in this directory relies on finding various files |
| 1500 * relative to the 'test.dart' script in '.../dart/tools/test.dart'. If | 1552 * relative to the 'test.dart' script in '.../dart/tools/test.dart'. If |
| 1501 * the main script using 'test_suite.dart' is not there, the main | 1553 * the main script using 'test_suite.dart' is not there, the main |
| 1502 * script must set this to '.../dart/tools/test.dart'. | 1554 * script must set this to '.../dart/tools/test.dart'. |
| 1503 */ | 1555 */ |
| 1504 static String testScriptPath = new Options().script; | 1556 static String testScriptPath = new Options().script; |
| 1505 | 1557 static LastModifiedCache lastModifiedCache = new LastModifiedCache(); |
| 1558 static Path currentWorkingDirectory = new Path.fromNative(new Directory.curren t().path); | |
| 1506 /** | 1559 /** |
| 1507 * Creates a directory using a [relativePath] to an existing | 1560 * Creates a directory using a [relativePath] to an existing |
| 1508 * [base] directory if that [relativePath] does not already exist. | 1561 * [base] directory if that [relativePath] does not already exist. |
| 1509 */ | 1562 */ |
| 1510 static Directory mkdirRecursive(Path base, Path relativePath) { | 1563 static Directory mkdirRecursive(Path base, Path relativePath) { |
| 1511 if (relativePath.isAbsolute) { | 1564 if (relativePath.isAbsolute) { |
| 1512 base = new Path('/'); | 1565 base = new Path('/'); |
| 1513 } | 1566 } |
| 1514 Directory dir = new Directory.fromPath(base); | 1567 Directory dir = new Directory.fromPath(base); |
| 1515 Expect.isTrue(dir.existsSync(), | 1568 Expect.isTrue(dir.existsSync(), |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1541 new File.fromPath(source).openInputStream().pipe(output); | 1594 new File.fromPath(source).openInputStream().pipe(output); |
| 1542 var completer = new Completer(); | 1595 var completer = new Completer(); |
| 1543 output.onClosed = (){ completer.complete(null); }; | 1596 output.onClosed = (){ completer.complete(null); }; |
| 1544 return completer.future; | 1597 return completer.future; |
| 1545 } | 1598 } |
| 1546 | 1599 |
| 1547 static String flakyFileName() { | 1600 static String flakyFileName() { |
| 1548 // If a flaky test did fail, infos about it (i.e. test name, stdin, stdout) | 1601 // If a flaky test did fail, infos about it (i.e. test name, stdin, stdout) |
| 1549 // will be written to this file. This is useful for the debugging of | 1602 // will be written to this file. This is useful for the debugging of |
| 1550 // flaky tests. | 1603 // flaky tests. |
| 1551 // When running on a built bot, the file can be made visible in the | 1604 // When running on a built bot, the file can be made visible in the |
| 1552 // waterfall UI. | 1605 // waterfall UI. |
| 1553 return ".flaky.log"; | 1606 return ".flaky.log"; |
| 1554 } | 1607 } |
| 1555 | 1608 |
| 1556 static void ensureExists(String filename, Map configuration) { | 1609 static void ensureExists(String filename, Map configuration) { |
| 1557 if (!configuration['list'] && !(new File(filename).existsSync())) { | 1610 if (!configuration['list'] && !(new File(filename).existsSync())) { |
| 1558 throw "Executable '$filename' does not exist"; | 1611 throw "Executable '$filename' does not exist"; |
| 1559 } | 1612 } |
| 1560 } | 1613 } |
| 1561 | 1614 |
| 1615 static Path absolutePath(Path path) { | |
|
Bill Hesse
2012/12/11 10:51:04
We have many places in the code where we instead u
kustermann
2012/12/11 13:11:22
Writing "new Path.fromNative(new File.fromPath(pat
| |
| 1616 if (!path.isAbsolute) { | |
| 1617 return currentWorkingDirectory.join(path); | |
| 1618 } | |
| 1619 return path; | |
| 1620 } | |
| 1621 | |
| 1622 static String outputDir(Map configuration) { | |
| 1623 var result = ''; | |
| 1624 var system = configuration['system']; | |
| 1625 if (system == 'linux') { | |
| 1626 result = 'out/'; | |
| 1627 } else if (system == 'macos') { | |
| 1628 result = 'xcodebuild/'; | |
| 1629 } else if (system == 'windows') { | |
| 1630 result = 'build/'; | |
| 1631 } | |
| 1632 return result; | |
| 1633 } | |
| 1634 | |
| 1562 static Path dartDir() { | 1635 static Path dartDir() { |
| 1563 File scriptFile = new File(testScriptPath); | 1636 File scriptFile = new File(testScriptPath); |
| 1564 Path scriptPath = new Path.fromNative(scriptFile.fullPathSync()); | 1637 Path scriptPath = new Path.fromNative(scriptFile.fullPathSync()); |
| 1565 return scriptPath.directoryPath.directoryPath; | 1638 return scriptPath.directoryPath.directoryPath; |
| 1566 } | 1639 } |
| 1567 | 1640 |
| 1568 static List<String> standardOptions(Map configuration) { | 1641 static List<String> standardOptions(Map configuration) { |
| 1569 List args = ["--ignore-unrecognized-flags"]; | 1642 List args = ["--ignore-unrecognized-flags"]; |
| 1570 if (configuration["checked"]) { | 1643 if (configuration["checked"]) { |
| 1571 args.add('--enable_asserts'); | 1644 args.add('--enable_asserts'); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1682 * $pass tests are expected to pass | 1755 * $pass tests are expected to pass |
| 1683 * $failOk tests are expected to fail that we won't fix | 1756 * $failOk tests are expected to fail that we won't fix |
| 1684 * $fail tests are expected to fail that we should fix | 1757 * $fail tests are expected to fail that we should fix |
| 1685 * $crash tests are expected to crash that we should fix | 1758 * $crash tests are expected to crash that we should fix |
| 1686 * $timeout tests are allowed to timeout | 1759 * $timeout tests are allowed to timeout |
| 1687 * $compileErrorSkip tests are skipped on browsers due to compile-time error | 1760 * $compileErrorSkip tests are skipped on browsers due to compile-time error |
| 1688 """; | 1761 """; |
| 1689 print(report); | 1762 print(report); |
| 1690 } | 1763 } |
| 1691 } | 1764 } |
| OLD | NEW |