Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Side by Side Diff: tools/testing/dart/test_suite.dart

Issue 11293019: Run large html tests individually. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/testing/dart/test_runner.dart ('k') | tools/testing/run_selenium.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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,
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 } 420 }
421 if (expectations.contains(SKIP)) return; 421 if (expectations.contains(SKIP)) return;
422 422
423 if (configuration['compiler'] != 'none' && info.hasCompileError) { 423 if (configuration['compiler'] != 'none' && info.hasCompileError) {
424 // If a compile-time error is expected, and we're testing a 424 // If a compile-time error is expected, and we're testing a
425 // compiler, we never need to attempt to run the program (in a 425 // compiler, we never need to attempt to run the program (in a
426 // browser or otherwise). 426 // browser or otherwise).
427 enqueueStandardTest(info, testName, expectations); 427 enqueueStandardTest(info, testName, expectations);
428 } else if (TestUtils.isBrowserRuntime(configuration['runtime'])) { 428 } else if (TestUtils.isBrowserRuntime(configuration['runtime'])) {
429 bool isWrappingRequired = configuration['compiler'] != 'dart2js'; 429 bool isWrappingRequired = configuration['compiler'] != 'dart2js';
430 enqueueBrowserTest(info, testName, expectations, isWrappingRequired); 430 if (info.optionsFromFile['isMultiHtmlTest']) {
431 // A browser multi-test has multiple expectations for one test file.
432 // Find all the different sub-test expecations for one entire test file.
433 List<String> subtestNames = info.optionsFromFile['subtestNames'];
434 Map<String, Set<String>> multiHtmlTestExpectations = {};
435 for (String name in subtestNames) {
436 String fullTestName = '$testName/$name';
437 multiHtmlTestExpectations[fullTestName] =
438 testExpectations.expectations(fullTestName);
439 }
440 enqueueBrowserTest(info, testName, multiHtmlTestExpectations,
441 isWrappingRequired);
442 } else {
443 enqueueBrowserTest(info, testName, expectations, isWrappingRequired);
444 }
431 } else { 445 } else {
432 enqueueStandardTest(info, testName, expectations); 446 enqueueStandardTest(info, testName, expectations);
433 } 447 }
434 } 448 }
435 449
436 void enqueueStandardTest(TestInformation info, 450 void enqueueStandardTest(TestInformation info,
437 String testName, 451 String testName,
438 Set<String> expectations) { 452 Set<String> expectations) {
439 bool isNegative = info.hasCompileError || 453 bool isNegative = info.hasCompileError ||
440 (configuration['checked'] && info.isNegativeIfChecked); 454 (configuration['checked'] && info.isNegativeIfChecked);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 } 586 }
573 } 587 }
574 588
575 /** 589 /**
576 * The [StandardTestSuite] has support for tests that 590 * The [StandardTestSuite] has support for tests that
577 * compile a test from Dart to JavaScript, and then run the resulting 591 * compile a test from Dart to JavaScript, and then run the resulting
578 * JavaScript. This function creates a working directory to hold the 592 * JavaScript. This function creates a working directory to hold the
579 * JavaScript version of the test, and copies the appropriate framework 593 * JavaScript version of the test, and copies the appropriate framework
580 * files to that directory. It creates a [BrowserTestCase], which has 594 * files to that directory. It creates a [BrowserTestCase], which has
581 * two sequential steps to be run by the [ProcessQueue] when the test is 595 * two sequential steps to be run by the [ProcessQueue] when the test is
582 * executed: a compilation 596 * executed: a compilation step and an execution step, both with the
583 * step and an execution step, both with the appropriate executable and 597 * appropriate executable and arguments. The [expectations] object can be
584 * arguments. 598 * either a Set<String> if the test is a regular test, or a Map<String
599 * subTestName, Set<String>> if we are running a browser multi-test (one
600 * compilation and many browser runs).
585 */ 601 */
586 void enqueueBrowserTest(TestInformation info, 602 void enqueueBrowserTest(TestInformation info,
587 String testName, 603 String testName,
588 Set<String> expectations, 604 Object expectations,
589 bool isWrappingRequired) { 605 bool isWrappingRequired) {
590 Map optionsFromFile = info.optionsFromFile; 606 Map optionsFromFile = info.optionsFromFile;
591 Path filePath = info.filePath; 607 Path filePath = info.filePath;
592 String filename = filePath.toString(); 608 String filename = filePath.toString();
593 bool isWebTest = optionsFromFile['containsDomImport']; 609 bool isWebTest = optionsFromFile['containsDomImport'];
594 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition']; 610 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition'];
595 if (isWrappingRequired 611 if (isWrappingRequired
596 && !isLibraryDefinition && optionsFromFile['containsSourceOrImport']) { 612 && !isLibraryDefinition && optionsFromFile['containsSourceOrImport']) {
597 print('Warning for $filename: Browser tests require #library ' 613 print('Warning for $filename: Browser tests require #library '
598 'in any file that uses #import, #source, or #resource'); 614 'in any file that uses #import, #source, or #resource');
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 Path namePath = new Path(name); 715 Path namePath = new Path(name);
700 Expect.equals(namePath.extension, 'dart'); 716 Expect.equals(namePath.extension, 'dart');
701 String baseName = namePath.filenameWithoutExtension; 717 String baseName = namePath.filenameWithoutExtension;
702 Path fromPath = filePath.directoryPath.join(namePath); 718 Path fromPath = filePath.directoryPath.join(namePath);
703 commands.add(_compileCommand( 719 commands.add(_compileCommand(
704 fromPath.toNativePath(), '$tempDir/$baseName.js', 720 fromPath.toNativePath(), '$tempDir/$baseName.js',
705 compiler, tempDir, vmOptions)); 721 compiler, tempDir, vmOptions));
706 } 722 }
707 } 723 }
708 724
725 // Variables for browser multi-tests.
726 List<String> subtestNames = info.optionsFromFile['subtestNames'];
727 TestCase multitestParentTest;
728 int subtestIndex = 0;
709 // Construct the command that executes the browser test 729 // Construct the command that executes the browser test
710 List<String> args; 730 constructBrowserTestCommands();
711 if (TestUtils.usesWebDriver(runtime)) { 731 do {
712 args = [dartDir.append('tools/testing/run_selenium.py').toNativePath(), 732 List<String> args = <String>[];
713 '--browser=$runtime', 733 String fullHtmlPath = htmlPath;
714 '--timeout=${configuration["timeout"] - 2}', 734 if (info.optionsFromFile['isMultiHtmlTest']
715 '--out=$htmlPath']; 735 && subtestNames.length > 0) {
716 if (runtime == 'dartium') { 736 fullHtmlPath = '${htmlPath}#${subtestNames[subtestIndex]}';
717 args.add('--executable=$dartiumFilename');
718 } 737 }
719 } else { 738 if (TestUtils.usesWebDriver(runtime)) {
720 args = [ 739 args = [
721 dartDir.append('tools/testing/drt-trampoline.py').toNativePath(), 740 dartDir.append('tools/testing/run_selenium.py').toNativePath(),
722 dumpRenderTreeFilename, 741 '--browser=$runtime',
723 '--no-timeout' 742 '--timeout=${configuration["timeout"] - 2}',
724 ]; 743 '--out="$fullHtmlPath"'];
725 if (runtime == 'drt' && 744 if (runtime == 'dartium') {
726 (compiler == 'none' || compiler == 'dart2dart')) { 745 args.add('--executable=$dartiumFilename');
727 var dartFlags = ['--ignore-unrecognized-flags'];
728 if (configuration["checked"]) {
729 dartFlags.add('--enable_asserts');
730 dartFlags.add("--enable_type_checks");
731 } 746 }
732 dartFlags.addAll(vmOptions); 747 } else {
733 args.add('--dart-flags=${Strings.join(dartFlags, " ")}'); 748 args = [
749 dartDir.append('tools/testing/drt-trampoline.py').toNativePath(),
750 dumpRenderTreeFilename,
751 '--no-timeout'
752 ];
753 if (runtime == 'drt' &&
754 (compiler == 'none' || compiler == 'dart2dart')) {
755 var dartFlags = ['--ignore-unrecognized-flags'];
756 if (configuration["checked"]) {
757 dartFlags.add('--enable_asserts');
758 dartFlags.add("--enable_type_checks");
759 }
760 dartFlags.addAll(vmOptions);
761 args.add('--dart-flags=${Strings.join(dartFlags, " ")}');
762 }
763 args.add(fullHtmlPath);
764 if (expectedOutput != null) {
765 args.add('--out-expectation=${expectedOutput.toNativePath()}');
766 }
734 } 767 }
735 args.add(htmlPath); 768 List<String> commandSet = new List<String>.from(commands);
736 if (expectedOutput != null) { 769 if (subtestIndex != 0) {
737 args.add('--out-expectation=${expectedOutput.toNativePath()}'); 770 commandSet = [];
771 args.add('--force-refresh');
738 } 772 }
739 } 773 commandSet.add(new Command('python', args));
740 commands.add(new Command('python', args));
741 774
742 // Create BrowserTestCase and queue it. 775 // Create BrowserTestCase and queue it.
743 var testCase = new BrowserTestCase('$suiteName/$testName', 776 String testDisplayName = '$suiteName/$testName';
744 commands, configuration, completeHandler, expectations, 777 var testCase;
745 info, info.hasCompileError || info.hasRuntimeError); 778 if (info.optionsFromFile['isMultiHtmlTest']) {
746 doTest(testCase); 779 testDisplayName = '$testDisplayName/${subtestNames[subtestIndex]}';
780 testCase = new BrowserTestCase(testDisplayName,
781 commandSet, configuration, completeHandler,
782 expectations['$testName/${subtestNames[subtestIndex]}'],
783 info, info.hasCompileError || info.hasRuntimeError,
784 subtestIndex != 0);
785 } else {
786 testCase = new BrowserTestCase(testDisplayName,
787 commandSet, configuration, completeHandler, expectations,
788 info, info.hasCompileError || info.hasRuntimeError, false);
789 }
790 if (subtestIndex == 0) {
791 multitestParentTest = testCase;
792 } else {
793 multitestParentTest.addObserver(testCase);
794 }
795 doTest(testCase);
796 subtestIndex++;
797 } while(subtestIndex < subtestNames.length);
747 } 798 }
748 } 799 }
749 800
801 void constructBrowserTestCommands() {
802
803 }
804
750 /** Helper to create a compilation command for a single input file. */ 805 /** Helper to create a compilation command for a single input file. */
751 Command _compileCommand(String inputFile, String outputFile, 806 Command _compileCommand(String inputFile, String outputFile,
752 String compiler, String dir, var vmOptions) { 807 String compiler, String dir, var vmOptions) {
753 String executable = TestUtils.compilerPath(configuration); 808 String executable = TestUtils.compilerPath(configuration);
754 List<String> args = TestUtils.standardOptions(configuration); 809 List<String> args = TestUtils.standardOptions(configuration);
755 switch (compiler) { 810 switch (compiler) {
756 case 'dart2js': 811 case 'dart2js':
757 case 'dart2dart': 812 case 'dart2dart':
758 if (compiler == 'dart2dart') args.add('--out=$outputFile'); 813 if (compiler == 'dart2dart') args.add('--out=$outputFile');
759 args.add('--out=$outputFile'); 814 args.add('--out=$outputFile');
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 * executing the copy command printed by the test script. 1017 * executing the copy command printed by the test script.
963 * 1018 *
964 * This method is static as the map is cached and shared amongst 1019 * This method is static as the map is cached and shared amongst
965 * configurations, so it may not use [configuration]. 1020 * configurations, so it may not use [configuration].
966 */ 1021 */
967 static Map readOptionsFromFile(Path filePath) { 1022 static Map readOptionsFromFile(Path filePath) {
968 RegExp testOptionsRegExp = const RegExp(r"// VMOptions=(.*)"); 1023 RegExp testOptionsRegExp = const RegExp(r"// VMOptions=(.*)");
969 RegExp dartOptionsRegExp = const RegExp(r"// DartOptions=(.*)"); 1024 RegExp dartOptionsRegExp = const RegExp(r"// DartOptions=(.*)");
970 RegExp otherScriptsRegExp = const RegExp(r"// OtherScripts=(.*)"); 1025 RegExp otherScriptsRegExp = const RegExp(r"// OtherScripts=(.*)");
971 RegExp multiTestRegExp = const RegExp(r"/// [0-9][0-9]:(.*)"); 1026 RegExp multiTestRegExp = const RegExp(r"/// [0-9][0-9]:(.*)");
1027 RegExp multiHtmlTestRegExp =
1028 const RegExp(r"useHtmlIndividualConfiguration()");
972 RegExp staticTypeRegExp = 1029 RegExp staticTypeRegExp =
973 const RegExp(r"/// ([0-9][0-9]:){0,1}\s*static type warning"); 1030 const RegExp(r"/// ([0-9][0-9]:){0,1}\s*static type warning");
974 RegExp compileTimeRegExp = 1031 RegExp compileTimeRegExp =
975 const RegExp(r"/// ([0-9][0-9]:){0,1}\s*compile-time error"); 1032 const RegExp(r"/// ([0-9][0-9]:){0,1}\s*compile-time error");
976 RegExp staticCleanRegExp = const RegExp(r"// @static-clean"); 1033 RegExp staticCleanRegExp = const RegExp(r"// @static-clean");
977 RegExp leadingHashRegExp = const RegExp(r"^#", multiLine: true); 1034 RegExp leadingHashRegExp = const RegExp(r"^#", multiLine: true);
978 RegExp isolateStubsRegExp = const RegExp(r"// IsolateStubs=(.*)"); 1035 RegExp isolateStubsRegExp = const RegExp(r"// IsolateStubs=(.*)");
979 // TODO(gram) Clean these up once the old directives are not supported. 1036 // TODO(gram) Clean these up once the old directives are not supported.
980 RegExp domImportRegExp = 1037 RegExp domImportRegExp =
981 const RegExp(r"^[#]?import.*dart:html", multiLine: true); 1038 const RegExp(r"^[#]?import.*dart:html", multiLine: true);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 isStaticClean = true; 1085 isStaticClean = true;
1029 } 1086 }
1030 1087
1031 List<String> otherScripts = new List<String>(); 1088 List<String> otherScripts = new List<String>();
1032 matches = otherScriptsRegExp.allMatches(contents); 1089 matches = otherScriptsRegExp.allMatches(contents);
1033 for (var match in matches) { 1090 for (var match in matches) {
1034 otherScripts.addAll(match[1].split(' ').filter((e) => e != '')); 1091 otherScripts.addAll(match[1].split(' ').filter((e) => e != ''));
1035 } 1092 }
1036 1093
1037 bool isMultitest = multiTestRegExp.hasMatch(contents); 1094 bool isMultitest = multiTestRegExp.hasMatch(contents);
1095 bool isMultiHtmlTest = multiHtmlTestRegExp.hasMatch(contents);
1038 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents); 1096 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents);
1039 Match isolateMatch = isolateStubsRegExp.firstMatch(contents); 1097 Match isolateMatch = isolateStubsRegExp.firstMatch(contents);
1040 String isolateStubs = isolateMatch != null ? isolateMatch[1] : ''; 1098 String isolateStubs = isolateMatch != null ? isolateMatch[1] : '';
1041 bool containsDomImport = domImportRegExp.hasMatch(contents); 1099 bool containsDomImport = domImportRegExp.hasMatch(contents);
1042 bool isLibraryDefinition = libraryDefinitionRegExp.hasMatch(contents); 1100 bool isLibraryDefinition = libraryDefinitionRegExp.hasMatch(contents);
1043 bool containsSourceOrImport = sourceOrImportRegExp.hasMatch(contents); 1101 bool containsSourceOrImport = sourceOrImportRegExp.hasMatch(contents);
1044 int numStaticTypeAnnotations = 0; 1102 int numStaticTypeAnnotations = 0;
1045 for (var i in staticTypeRegExp.allMatches(contents)) { 1103 for (var i in staticTypeRegExp.allMatches(contents)) {
1046 numStaticTypeAnnotations++; 1104 numStaticTypeAnnotations++;
1047 } 1105 }
1048 int numCompileTimeAnnotations = 0; 1106 int numCompileTimeAnnotations = 0;
1049 for (var i in compileTimeRegExp.allMatches(contents)) { 1107 for (var i in compileTimeRegExp.allMatches(contents)) {
1050 numCompileTimeAnnotations++; 1108 numCompileTimeAnnotations++;
1051 } 1109 }
1052 1110
1111 // Note: This is brittle. It's the age-old problem of having a context free
1112 // language but the means to easily identify the construct is a regular
1113 // expression, aka impossible. Therefore we just make an approximation of
1114 // the number of top-level "group(...)" occurrences. This assumes you import
1115 // unittest with no prefix and always directly call "group(". It only uses
1116 // top-level "groups" so tests running nested groups will be no-ops.
1117 RegExp numTests = new RegExp(r"\s*[^/]\s*group\('[^,']*");
1118 List<String> subtestNames = [];
1119 Iterator matchesIter = numTests.allMatches(contents).iterator();
1120 while(matchesIter.hasNext && isMultiHtmlTest) {
1121 String fullMatch = matchesIter.next().group(0);
1122 subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
1123 }
1124
1053 return { "vmOptions": result, 1125 return { "vmOptions": result,
1054 "dartOptions": dartOptions, 1126 "dartOptions": dartOptions,
1055 "hasCompileError": hasCompileError, 1127 "hasCompileError": hasCompileError,
1056 "hasRuntimeError": hasRuntimeError, 1128 "hasRuntimeError": hasRuntimeError,
1057 "isStaticClean" : isStaticClean, 1129 "isStaticClean" : isStaticClean,
1058 "otherScripts": otherScripts, 1130 "otherScripts": otherScripts,
1059 "isMultitest": isMultitest, 1131 "isMultitest": isMultitest,
1132 "isMultiHtmlTest": isMultiHtmlTest,
1133 "subtestNames": subtestNames,
1060 "containsLeadingHash": containsLeadingHash, 1134 "containsLeadingHash": containsLeadingHash,
1061 "isolateStubs": isolateStubs, 1135 "isolateStubs": isolateStubs,
1062 "containsDomImport": containsDomImport, 1136 "containsDomImport": containsDomImport,
1063 "isLibraryDefinition": isLibraryDefinition, 1137 "isLibraryDefinition": isLibraryDefinition,
1064 "containsSourceOrImport": containsSourceOrImport, 1138 "containsSourceOrImport": containsSourceOrImport,
1065 "numStaticTypeAnnotations": numStaticTypeAnnotations, 1139 "numStaticTypeAnnotations": numStaticTypeAnnotations,
1066 "numCompileTimeAnnotations": numCompileTimeAnnotations }; 1140 "numCompileTimeAnnotations": numCompileTimeAnnotations };
1067 } 1141 }
1068 1142
1069 List<List<String>> getVmOptions(Map optionsFromFile) { 1143 List<List<String>> getVmOptions(Map optionsFromFile) {
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 * $pass tests are expected to pass 1567 * $pass tests are expected to pass
1494 * $failOk tests are expected to fail that we won't fix 1568 * $failOk tests are expected to fail that we won't fix
1495 * $fail tests are expected to fail that we should fix 1569 * $fail tests are expected to fail that we should fix
1496 * $crash tests are expected to crash that we should fix 1570 * $crash tests are expected to crash that we should fix
1497 * $timeout tests are allowed to timeout 1571 * $timeout tests are allowed to timeout
1498 * $compileErrorSkip tests are skipped on browsers due to compile-time error 1572 * $compileErrorSkip tests are skipped on browsers due to compile-time error
1499 """; 1573 """;
1500 print(report); 1574 print(report);
1501 } 1575 }
1502 } 1576 }
OLDNEW
« no previous file with comments | « tools/testing/dart/test_runner.dart ('k') | tools/testing/run_selenium.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698