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 import "dart:uri"; |
24 import '../../../pkg/path/lib/path.dart' as pathLib; | |
Mads Ager (google)
2013/01/07 07:15:52
I would prefer that we only use one path library i
| |
24 | 25 |
25 part "browser_test.dart"; | 26 part "browser_test.dart"; |
26 | 27 |
27 | 28 |
28 // TODO(rnystrom): Add to dart:core? | 29 // TODO(rnystrom): Add to dart:core? |
29 /** | 30 /** |
30 * A simple function that tests [arg] and returns `true` or `false`. | 31 * A simple function that tests [arg] and returns `true` or `false`. |
31 */ | 32 */ |
32 typedef bool Predicate<T>(T arg); | 33 typedef bool Predicate<T>(T arg); |
33 | 34 |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
394 */ | 395 */ |
395 class StandardTestSuite extends TestSuite { | 396 class StandardTestSuite extends TestSuite { |
396 final Path suiteDir; | 397 final Path suiteDir; |
397 final List<String> statusFilePaths; | 398 final List<String> statusFilePaths; |
398 TestCaseEvent doTest; | 399 TestCaseEvent doTest; |
399 TestExpectations testExpectations; | 400 TestExpectations testExpectations; |
400 List<TestInformation> cachedTests; | 401 List<TestInformation> cachedTests; |
401 final Path dartDir; | 402 final Path dartDir; |
402 Predicate<String> isTestFilePredicate; | 403 Predicate<String> isTestFilePredicate; |
403 final bool listRecursively; | 404 final bool listRecursively; |
405 /** | |
406 * The set of servers that have been started to run these tests (Could be | |
407 * none). | |
408 */ | |
409 List serverList; | |
404 | 410 |
405 StandardTestSuite(Map configuration, | 411 StandardTestSuite(Map configuration, |
406 String suiteName, | 412 String suiteName, |
407 Path suiteDirectory, | 413 Path suiteDirectory, |
408 this.statusFilePaths, | 414 this.statusFilePaths, |
415 this.serverList, | |
409 {this.isTestFilePredicate, | 416 {this.isTestFilePredicate, |
410 bool recursive: false}) | 417 bool recursive: false}) |
411 : super(configuration, suiteName), | 418 : super(configuration, suiteName), |
412 dartDir = TestUtils.dartDir(), | 419 dartDir = TestUtils.dartDir(), |
413 listRecursively = recursive, | 420 listRecursively = recursive, |
414 suiteDir = TestUtils.dartDir().join(suiteDirectory); | 421 suiteDir = TestUtils.dartDir().join(suiteDirectory); |
415 | 422 |
416 /** | 423 /** |
417 * Creates a test suite whose file organization matches an expected structure. | 424 * Creates a test suite whose file organization matches an expected structure. |
418 * To use this, your suite should look like: | 425 * To use this, your suite should look like: |
(...skipping 13 matching lines...) Expand all Loading... | |
432 * * The status file uses the same name. | 439 * * The status file uses the same name. |
433 * * Test files are directly in that directory and end in "_test.dart". | 440 * * Test files are directly in that directory and end in "_test.dart". |
434 * | 441 * |
435 * If you follow that convention, then you can construct one of these like: | 442 * If you follow that convention, then you can construct one of these like: |
436 * | 443 * |
437 * new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite'); | 444 * new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite'); |
438 * | 445 * |
439 * instead of having to create a custom [StandardTestSuite] subclass. In | 446 * instead of having to create a custom [StandardTestSuite] subclass. In |
440 * particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES] | 447 * particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES] |
441 * in test.dart, this will all be set up for you. | 448 * in test.dart, this will all be set up for you. |
449 * | |
450 * The [StandardTestSuite] also optionally takes a list of servers that have | |
451 * been started up by the test harness, to be used by browser tests. | |
442 */ | 452 */ |
443 factory StandardTestSuite.forDirectory( | 453 factory StandardTestSuite.forDirectory( |
444 Map configuration, Path directory) { | 454 Map configuration, Path directory, [List serverList = const []]) { |
445 final name = directory.filename; | 455 final name = directory.filename; |
446 | 456 |
447 return new StandardTestSuite(configuration, | 457 return new StandardTestSuite(configuration, |
448 name, directory, | 458 name, directory, |
449 ['$directory/$name.status', '$directory/${name}_dart2js.status'], | 459 ['$directory/$name.status', '$directory/${name}_dart2js.status'], |
460 serverList, | |
450 isTestFilePredicate: (filename) => filename.endsWith('_test.dart'), | 461 isTestFilePredicate: (filename) => filename.endsWith('_test.dart'), |
451 recursive: true); | 462 recursive: true); |
452 } | 463 } |
453 | 464 |
454 Collection<Uri> get dart2JsBootstrapDependencies { | 465 Collection<Uri> get dart2JsBootstrapDependencies { |
455 if (!useSdk) return []; | 466 if (!useSdk) return []; |
456 | 467 |
457 var snapshotPath = TestUtils.absolutePath(new Path(buildDir).join( | 468 var snapshotPath = TestUtils.absolutePath(new Path(buildDir).join( |
458 new Path('dart-sdk/lib/_internal/compiler/' | 469 new Path('dart-sdk/lib/_internal/compiler/' |
459 'implementation/dart2js.dart.snapshot'))).toString(); | 470 'implementation/dart2js.dart.snapshot'))).toString(); |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
846 dartLibraryFilename = new Path('test_as_library.dart'); | 857 dartLibraryFilename = new Path('test_as_library.dart'); |
847 File file = new File('$tempDir/$dartLibraryFilename'); | 858 File file = new File('$tempDir/$dartLibraryFilename'); |
848 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE); | 859 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE); |
849 dartLibrary.writeStringSync(wrapDartTestInLibrary(filePath)); | 860 dartLibrary.writeStringSync(wrapDartTestInLibrary(filePath)); |
850 dartLibrary.closeSync(); | 861 dartLibrary.closeSync(); |
851 } | 862 } |
852 | 863 |
853 File file = new File(dartWrapperFilename); | 864 File file = new File(dartWrapperFilename); |
854 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE); | 865 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE); |
855 dartWrapper.writeStringSync( | 866 dartWrapper.writeStringSync( |
856 dartTestWrapper(dartDir, dartLibraryFilename)); | 867 dartTestWrapper(dartDir, file.name, dartLibraryFilename)); |
857 dartWrapper.closeSync(); | 868 dartWrapper.closeSync(); |
858 } else { | 869 } else { |
859 dartWrapperFilename = filename; | 870 dartWrapperFilename = filename; |
860 // TODO(whesse): Once test.py is retired, adjust the relative path in | 871 // TODO(whesse): Once test.py is retired, adjust the relative path in |
861 // the client/samples/dartcombat test to its css file, remove the | 872 // the client/samples/dartcombat test to its css file, remove the |
862 // "../../" from this path, and move this out of the isWebTest guard. | 873 // "../../" from this path, and move this out of the isWebTest guard. |
863 // Also remove getHtmlName, and just use test.html. | 874 // Also remove getHtmlName, and just use test.html. |
864 // TODO(efortuna): this shortening of htmlFilename is a band-aid until | 875 // TODO(efortuna): this shortening of htmlFilename is a band-aid until |
865 // the above TODO gets fixed. Windows cannot have paths that are longer | 876 // the above TODO gets fixed. Windows cannot have paths that are longer |
866 // than 260 characters, and without this hack, we were running past the | 877 // than 260 characters, and without this hack, we were running past the |
867 // the limit. | 878 // the limit. |
868 String htmlFilename = getHtmlName(filename); | 879 String htmlFilename = getHtmlName(filename); |
869 while ('$tempDir/../$htmlFilename'.length >= 260) { | 880 while ('$tempDir/../$htmlFilename'.length >= 260) { |
870 htmlFilename = htmlFilename.substring(htmlFilename.length~/2); | 881 htmlFilename = htmlFilename.substring(htmlFilename.length~/2); |
871 } | 882 } |
872 htmlPath = '$tempDir/../$htmlFilename'; | 883 htmlPath = '$tempDir/../$htmlFilename'; |
873 } | 884 } |
874 final String scriptPath = (compiler == 'none') ? | 885 final String scriptPath = (compiler == 'none') ? |
875 dartWrapperFilename : compiledDartWrapperFilename; | 886 dartWrapperFilename : compiledDartWrapperFilename; |
876 // Create the HTML file for the test. | 887 // Create the HTML file for the test. |
877 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE); | 888 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE); |
878 String filePrefix = ''; | |
879 if (Platform.operatingSystem == 'windows') { | |
880 // Firefox on Windows does not like absolute file path names that start | |
881 // with 'C:' adding 'file:///' solves the problem. | |
882 filePrefix = 'file:///'; | |
883 } | |
884 String content = null; | 889 String content = null; |
885 Path dir = filePath.directoryPath; | 890 Path dir = filePath.directoryPath; |
886 String nameNoExt = filePath.filenameWithoutExtension; | 891 String nameNoExt = filePath.filenameWithoutExtension; |
887 Path pngPath = dir.append('$nameNoExt.png'); | 892 Path pngPath = dir.append('$nameNoExt.png'); |
888 Path txtPath = dir.append('$nameNoExt.txt'); | 893 Path txtPath = dir.append('$nameNoExt.txt'); |
889 Path expectedOutput = null; | 894 Path expectedOutput = null; |
890 if (new File.fromPath(pngPath).existsSync()) { | 895 if (new File.fromPath(pngPath).existsSync()) { |
891 expectedOutput = pngPath; | 896 expectedOutput = pngPath; |
892 content = getHtmlLayoutContents(scriptType, '$filePrefix$scriptPath'); | 897 content = getHtmlLayoutContents(scriptType, pathLib.relative(scriptPath, |
898 from: pathLib.dirname(htmlPath))); | |
893 } else if (new File.fromPath(txtPath).existsSync()) { | 899 } else if (new File.fromPath(txtPath).existsSync()) { |
894 expectedOutput = txtPath; | 900 expectedOutput = txtPath; |
895 content = getHtmlLayoutContents(scriptType, '$filePrefix$scriptPath'); | 901 content = getHtmlLayoutContents(scriptType, pathLib.relative(scriptPath, |
902 from: pathLib.dirname(htmlPath))); | |
896 } else { | 903 } else { |
897 final htmlLocation = new Path.fromNative(htmlPath); | 904 final htmlLocation = new Path.fromNative(htmlPath); |
898 content = getHtmlContents( | 905 content = getHtmlContents( |
899 filename, | 906 filename, |
900 dartDir.append('pkg/unittest/test_controller.js') | 907 dartDir.append('pkg/unittest/test_controller.js') |
901 .relativeTo(htmlLocation), | 908 .relativeTo(htmlLocation), |
902 dartDir.append('client/dart.js').relativeTo(htmlLocation), | 909 dartDir.append('client/dart.js').relativeTo(htmlLocation), |
903 scriptType, | 910 scriptType, |
904 new Path.fromNative(scriptPath).relativeTo(htmlLocation)); | 911 new Path.fromNative(scriptPath).relativeTo(htmlLocation)); |
905 } | 912 } |
(...skipping 29 matching lines...) Expand all Loading... | |
935 do { | 942 do { |
936 List<Command> commandSet = new List<Command>.from(commands); | 943 List<Command> commandSet = new List<Command>.from(commands); |
937 if (subtestIndex != 0) { | 944 if (subtestIndex != 0) { |
938 // NOTE: The first time we enter this loop, all the compilation | 945 // NOTE: The first time we enter this loop, all the compilation |
939 // commands will be executed. On subsequent loop iterations, we | 946 // commands will be executed. On subsequent loop iterations, we |
940 // don't need to do any compilations. Thus we set "commandSet = []". | 947 // don't need to do any compilations. Thus we set "commandSet = []". |
941 commandSet = []; | 948 commandSet = []; |
942 } | 949 } |
943 | 950 |
944 List<String> args = <String>[]; | 951 List<String> args = <String>[]; |
945 String fullHtmlPath = htmlPath.startsWith('http:') ? htmlPath : | 952 var basePath = TestUtils.dartDir().toString(); |
946 (htmlPath.startsWith('/') ? | 953 htmlPath = htmlPath.startsWith(basePath) ? |
947 'file://$htmlPath' : | 954 htmlPath.substring(basePath.length) : htmlPath; |
948 'file:///$htmlPath'); | 955 String fullHtmlPath = htmlPath; |
956 if (!htmlPath.startsWith('http')) { | |
957 if (!htmlPath.startsWith('/')) htmlPath = '/$htmlPath'; | |
958 fullHtmlPath = 'http://127.0.0.1:${serverList[0].port}$htmlPath?' | |
959 'crossOriginPort=${serverList[1].port}'; | |
960 } | |
949 if (info.optionsFromFile['isMultiHtmlTest'] | 961 if (info.optionsFromFile['isMultiHtmlTest'] |
950 && subtestNames.length > 0) { | 962 && subtestNames.length > 0) { |
951 fullHtmlPath = '${fullHtmlPath}#${subtestNames[subtestIndex]}'; | 963 fullHtmlPath = '${fullHtmlPath}#${subtestNames[subtestIndex]}'; |
952 } | 964 } |
953 | 965 |
954 if (TestUtils.usesWebDriver(runtime)) { | 966 if (TestUtils.usesWebDriver(runtime)) { |
955 args = [ | 967 args = [ |
956 dartDir.append('tools/testing/run_selenium.py').toNativePath(), | 968 dartDir.append('tools/testing/run_selenium.py').toNativePath(), |
957 '--browser=$runtime', | 969 '--browser=$runtime', |
958 '--timeout=${configuration["timeout"] - 2}', | 970 '--timeout=${configuration["timeout"] - 2}', |
(...skipping 21 matching lines...) Expand all Loading... | |
980 dartFlags.add("--enable_type_checks"); | 992 dartFlags.add("--enable_type_checks"); |
981 } | 993 } |
982 dartFlags.addAll(vmOptions); | 994 dartFlags.addAll(vmOptions); |
983 } | 995 } |
984 if (compiler == 'none') { | 996 if (compiler == 'none') { |
985 var packageRootPath = packageRoot(optionsFromFile['packageRoot']); | 997 var packageRootPath = packageRoot(optionsFromFile['packageRoot']); |
986 if (packageRootPath != null) { | 998 if (packageRootPath != null) { |
987 var absolutePath = | 999 var absolutePath = |
988 TestUtils.absolutePath(new Path(packageRootPath)); | 1000 TestUtils.absolutePath(new Path(packageRootPath)); |
989 packageRootUri = new Uri.fromComponents( | 1001 packageRootUri = new Uri.fromComponents( |
990 scheme: 'file', | 1002 scheme: 'http', |
991 path: absolutePath.toString()); | 1003 path: '127.0.0.1:${serverList[0].port}/' |
1004 '${pathLib.relative(absolutePath.toString(), from: | |
1005 TestUtils.dartDir().toString())}'); | |
992 } | 1006 } |
993 } | 1007 } |
994 | 1008 |
995 if (expectedOutput != null) { | 1009 if (expectedOutput != null) { |
996 if (expectedOutput.toNativePath().endsWith('.png')) { | 1010 if (expectedOutput.toNativePath().endsWith('.png')) { |
997 // pixel tests are specified by running DRT "foo.html'-p" | 1011 // pixel tests are specified by running DRT "foo.html'-p" |
998 dumpRenderTreeOptions.add('--notree'); | 1012 dumpRenderTreeOptions.add('--notree'); |
999 fullHtmlPath = "${fullHtmlPath}'-p"; | 1013 fullHtmlPath = "${fullHtmlPath}'-p"; |
1000 } | 1014 } |
1001 } | 1015 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1090 } | 1104 } |
1091 | 1105 |
1092 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName', | 1106 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName', |
1093 // including any intermediate directories that don't exist. | 1107 // including any intermediate directories that don't exist. |
1094 // If the tests are run in checked or minified mode we add that to the | 1108 // If the tests are run in checked or minified mode we add that to the |
1095 // '$compile-$runtime' directory name. | 1109 // '$compile-$runtime' directory name. |
1096 var checked = configuration['checked'] ? '-checked' : ''; | 1110 var checked = configuration['checked'] ? '-checked' : ''; |
1097 var minified = configuration['minified'] ? '-minified' : ''; | 1111 var minified = configuration['minified'] ? '-minified' : ''; |
1098 var dirName = "${configuration['compiler']}-${configuration['runtime']}" | 1112 var dirName = "${configuration['compiler']}-${configuration['runtime']}" |
1099 "$checked$minified"; | 1113 "$checked$minified"; |
1100 Path generatedTestPath = new Path.fromNative(buildDir) | 1114 Path generatedTestPath = new Path.fromNative(dartDir.toString()) |
1115 .append(buildDir.toString()) | |
1101 .append('generated_tests') | 1116 .append('generated_tests') |
1102 .append(dirName) | 1117 .append(dirName) |
1103 .append(testUniqueName); | 1118 .append(testUniqueName); |
1104 | 1119 |
1105 TestUtils.mkdirRecursive(new Path('.'), generatedTestPath); | 1120 TestUtils.mkdirRecursive(new Path('.'), generatedTestPath); |
1106 return new File.fromPath(generatedTestPath).fullPathSync() | 1121 return new File.fromPath(generatedTestPath).fullPathSync() |
1107 .replaceAll('\\', '/'); | 1122 .replaceAll('\\', '/'); |
1108 } | 1123 } |
1109 | 1124 |
1110 String get scriptType { | 1125 String get scriptType { |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1806 * $pass tests are expected to pass | 1821 * $pass tests are expected to pass |
1807 * $failOk tests are expected to fail that we won't fix | 1822 * $failOk tests are expected to fail that we won't fix |
1808 * $fail tests are expected to fail that we should fix | 1823 * $fail tests are expected to fail that we should fix |
1809 * $crash tests are expected to crash that we should fix | 1824 * $crash tests are expected to crash that we should fix |
1810 * $timeout tests are allowed to timeout | 1825 * $timeout tests are allowed to timeout |
1811 * $compileErrorSkip tests are skipped on browsers due to compile-time error | 1826 * $compileErrorSkip tests are skipped on browsers due to compile-time error |
1812 """; | 1827 """; |
1813 print(report); | 1828 print(report); |
1814 } | 1829 } |
1815 } | 1830 } |
OLD | NEW |