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

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

Issue 2901923003: Replace the configuration map with a typed object. (Closed)
Patch Set: Created 3 years, 6 months 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
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,
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 import 'dart:async';
16 16 import 'dart:io';
17 import "dart:async"; 17 import 'dart:math';
18 import "dart:io";
19 import "dart:math";
20 import "drt_updater.dart";
21 import "html_test.dart" as htmlTest;
22 import "http_server.dart";
23 import "path.dart";
24 import "multitest.dart";
25 import "expectation.dart";
26 import "expectation_set.dart";
27 import "summary_report.dart";
28 import "test_runner.dart";
29 import "utils.dart";
30 import "http_server.dart" show PREFIX_BUILDDIR, PREFIX_DARTDIR;
31
32 import "compiler_configuration.dart"
33 show CommandArtifact, CompilerConfiguration;
34
35 import "runtime_configuration.dart" show RuntimeConfiguration;
36 18
37 import 'browser_test.dart'; 19 import 'browser_test.dart';
20 import 'compiler_configuration.dart';
21 import 'configuration.dart';
22 import 'drt_updater.dart';
23 import 'expectation.dart';
24 import 'expectation_set.dart';
25 import 'html_test.dart' as html_test;
26 import 'http_server.dart';
27 import 'multitest.dart';
28 import 'path.dart';
29 import 'summary_report.dart';
30 import 'test_configurations.dart';
31 import 'test_runner.dart';
32 import 'utils.dart';
38 33
39 RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*"); 34 RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*");
40 RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration()"); 35 RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration()");
41 // Require at least one non-space character before '//[/#]' 36 // Require at least one non-space character before '//[/#]'
42 RegExp multiTestRegExp = new RegExp(r"\S *" 37 RegExp multiTestRegExp = new RegExp(r"\S *"
43 r"//[#/] \w+:(.*)"); 38 r"//[#/] \w+:(.*)");
44 RegExp dartExtension = new RegExp(r'\.dart$'); 39 RegExp dartExtension = new RegExp(r'\.dart$');
45 40
46 /** 41 /**
47 * A simple function that tests [arg] and returns `true` or `false`. 42 * A simple function that tests [arg] and returns `true` or `false`.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 /** 79 /**
85 * Wait for [task] to complete (assuming this barrier has not already been 80 * Wait for [task] to complete (assuming this barrier has not already been
86 * marked as completed, otherwise you'll get an exception indicating that a 81 * marked as completed, otherwise you'll get an exception indicating that a
87 * future has already been completed). 82 * future has already been completed).
88 */ 83 */
89 void add(Future task) { 84 void add(Future task) {
90 if (_pending == _FINISHED) { 85 if (_pending == _FINISHED) {
91 throw new Exception("FutureFutureAlreadyCompleteException"); 86 throw new Exception("FutureFutureAlreadyCompleteException");
92 } 87 }
93 _pending++; 88 _pending++;
94 var handledTaskFuture = task.catchError((e) { 89 var handledTaskFuture = task.catchError((e, StackTrace s) {
95 if (!wasCompleted) { 90 if (!wasCompleted) {
96 _completer.completeError(e); 91 _completer.completeError(e, s);
97 wasCompleted = true; 92 wasCompleted = true;
98 } 93 }
99 }).then((_) { 94 }).then((_) {
100 _pending--; 95 _pending--;
101 if (_pending == 0) { 96 if (_pending == 0) {
102 _pending = _FINISHED; 97 _pending = _FINISHED;
103 if (!wasCompleted) { 98 if (!wasCompleted) {
104 _completer.complete(futures); 99 _completer.complete(futures);
105 wasCompleted = true; 100 wasCompleted = true;
106 } 101 }
107 } 102 }
108 }); 103 });
109 futures.add(handledTaskFuture); 104 futures.add(handledTaskFuture);
110 } 105 }
111 106
112 Future<List> get future => _completer.future; 107 Future<List> get future => _completer.future;
113 } 108 }
114 109
115 /** 110 /**
116 * A TestSuite represents a collection of tests. It creates a [TestCase] 111 * A TestSuite represents a collection of tests. It creates a [TestCase]
117 * object for each test to be run, and passes the test cases to a callback. 112 * object for each test to be run, and passes the test cases to a callback.
118 * 113 *
119 * Most TestSuites represent a directory or directory tree containing tests, 114 * Most TestSuites represent a directory or directory tree containing tests,
120 * and a status file containing the expected results when these tests are run. 115 * and a status file containing the expected results when these tests are run.
121 */ 116 */
122 abstract class TestSuite { 117 abstract class TestSuite {
123 final Map<String, dynamic> configuration; 118 final Configuration configuration;
124 final String suiteName; 119 final String suiteName;
125 // This function is set by subclasses before enqueueing starts. 120 // This function is set by subclasses before enqueueing starts.
126 Function doTest; 121 Function doTest;
127 Map<String, String> _environmentOverrides; 122 Map<String, String> _environmentOverrides;
128 RuntimeConfiguration runtimeConfiguration;
129 123
130 TestSuite(this.configuration, this.suiteName) { 124 TestSuite(this.configuration, this.suiteName) {
131 TestUtils.buildDir(configuration); // Sets configuration_directory. 125 _environmentOverrides = {
132 if (configuration['configuration_directory'] != null) { 126 'DART_CONFIGURATION': configuration.configurationDirectory
133 _environmentOverrides = { 127 };
134 'DART_CONFIGURATION': configuration['configuration_directory'] as String
135 };
136 }
137 runtimeConfiguration = new RuntimeConfiguration(configuration);
138 } 128 }
139 129
140 Map<String, String> get environmentOverrides => _environmentOverrides; 130 Map<String, String> get environmentOverrides => _environmentOverrides;
141 131
142 /** 132 /**
143 * Whether or not binaries should be found in the root build directory or 133 * Whether or not binaries should be found in the root build directory or
144 * in the built SDK. 134 * in the built SDK.
145 */ 135 */
146 bool get useSdk { 136 bool get useSdk {
147 // The pub suite always uses the SDK. 137 // The pub suite always uses the SDK.
148 // TODO(rnystrom): Eventually, all test suites should run out of the SDK 138 // TODO(rnystrom): Eventually, all test suites should run out of the SDK
149 // and this check should go away. 139 // and this check should go away.
150 // TODO(ahe): This check is broken for several reasons: 140 // TODO(ahe): This check is broken for several reasons:
151 // First, it is not true that all tests should be running out of the 141 // First, it is not true that all tests should be running out of the
152 // SDK. It is absolutely critical to VM development that you can test the 142 // SDK. It is absolutely critical to VM development that you can test the
153 // VM without building the SDK. 143 // VM without building the SDK.
154 // Second, it is convenient for dart2js developers to run tests without 144 // Second, it is convenient for dart2js developers to run tests without
155 // rebuilding the SDK, and similarly, it should be convenient for pub 145 // rebuilding the SDK, and similarly, it should be convenient for pub
156 // developers. 146 // developers.
157 // Third, even if pub can only run from the SDK directory, this is the 147 // Third, even if pub can only run from the SDK directory, this is the
158 // wrong place to work around that problem. Instead, test_options.dart 148 // wrong place to work around that problem. Instead, test_options.dart
159 // should have been modified so that configuration['use_sdk'] is always 149 // should have been modified so that configuration['use_sdk'] is always
160 // true when testing pub. Attempting to override the value here is brittle 150 // true when testing pub. Attempting to override the value here is brittle
161 // because we read configuration['use_sdk'] directly in many places without 151 // because we read configuration['use_sdk'] directly in many places without
162 // using this getter. 152 // using this getter.
163 if (suiteName == 'pub') return true; 153 if (suiteName == 'pub') return true;
164 154
165 return configuration['use_sdk'] as bool; 155 return configuration.useSdk;
166 } 156 }
167 157
168 /** 158 /**
169 * The output directory for this suite's configuration. 159 * The output directory for this suite's configuration.
170 */ 160 */
171 String get buildDir => TestUtils.buildDir(configuration); 161 String get buildDir => configuration.buildDirectory;
172 162
173 /** 163 /**
174 * The path to the compiler for this suite's configuration. Returns `null` if 164 * The path to the compiler for this suite's configuration. Returns `null` if
175 * no compiler should be used. 165 * no compiler should be used.
176 */ 166 */
177 String get compilerPath { 167 String get compilerPath {
178 var compilerConfiguration = new CompilerConfiguration(configuration); 168 var compilerConfiguration = configuration.compilerConfiguration;
179 if (!compilerConfiguration.hasCompiler) return null; 169 if (!compilerConfiguration.hasCompiler) return null;
180 var name = compilerConfiguration.computeCompilerPath(buildDir); 170 var name = compilerConfiguration.computeCompilerPath(buildDir);
181 // TODO(ahe): Only validate this once, in test_options.dart. 171 // TODO(ahe): Only validate this once, in test_options.dart.
182 TestUtils.ensureExists(name, configuration); 172 TestUtils.ensureExists(name, configuration);
183 return name; 173 return name;
184 } 174 }
185 175
186 String get pubPath { 176 String get pubPath {
187 var prefix = 'sdk/bin/'; 177 var prefix = 'sdk/bin/';
188 if (configuration['use_sdk'] as bool) { 178 if (configuration.useSdk) {
189 prefix = '$buildDir/dart-sdk/bin/'; 179 prefix = '$buildDir/dart-sdk/bin/';
190 } 180 }
191 var suffix = getExecutableSuffix('pub'); 181 var suffix = getExecutableSuffix('pub');
192 var name = '${prefix}pub$suffix'; 182 var name = '${prefix}pub$suffix';
193 TestUtils.ensureExists(name, configuration); 183 TestUtils.ensureExists(name, configuration);
194 return name; 184 return name;
195 } 185 }
196 186
197 /// Returns the name of the Dart VM executable. 187 /// Returns the name of the Dart VM executable.
198 String get dartVmBinaryFileName { 188 String get dartVmBinaryFileName {
199 // Controlled by user with the option "--dart". 189 // Controlled by user with the option "--dart".
200 var dartExecutable = configuration['dart'] as String; 190 var dartExecutable = configuration.dartPath;
201 191
202 if (dartExecutable == '') { 192 if (dartExecutable == null) {
203 var suffix = executableBinarySuffix; 193 var suffix = executableBinarySuffix;
204 dartExecutable = useSdk 194 dartExecutable = useSdk
205 ? '$buildDir/dart-sdk/bin/dart$suffix' 195 ? '$buildDir/dart-sdk/bin/dart$suffix'
206 : '$buildDir/dart$suffix'; 196 : '$buildDir/dart$suffix';
207 } 197 }
208 198
209 TestUtils.ensureExists(dartExecutable, configuration); 199 TestUtils.ensureExists(dartExecutable, configuration);
210 return dartExecutable; 200 return dartExecutable;
211 } 201 }
212 202
213 /// Returns the name of the flutter engine executable. 203 /// Returns the name of the flutter engine executable.
214 String get flutterEngineBinaryFileName { 204 String get flutterEngineBinaryFileName {
215 // Controlled by user with the option "--flutter". 205 // Controlled by user with the option "--flutter".
216 var flutterExecutable = configuration['flutter'] as String; 206 var flutterExecutable = configuration.flutterPath;
217 TestUtils.ensureExists(flutterExecutable, configuration); 207 TestUtils.ensureExists(flutterExecutable, configuration);
218 return flutterExecutable; 208 return flutterExecutable;
219 } 209 }
220 210
221 String get dartPrecompiledBinaryFileName { 211 String get dartPrecompiledBinaryFileName {
222 // Controlled by user with the option "--dart_precompiled". 212 // Controlled by user with the option "--dart_precompiled".
223 var dartExecutable = configuration['dart_precompiled'] as String; 213 var dartExecutable = configuration.dartPrecompiledPath;
224 214
225 if (dartExecutable == null || dartExecutable == '') { 215 if (dartExecutable == null || dartExecutable == '') {
226 var suffix = executableBinarySuffix; 216 var suffix = executableBinarySuffix;
227 dartExecutable = '$buildDir/dart_precompiled_runtime$suffix'; 217 dartExecutable = '$buildDir/dart_precompiled_runtime$suffix';
228 } 218 }
229 219
230 TestUtils.ensureExists(dartExecutable, configuration); 220 TestUtils.ensureExists(dartExecutable, configuration);
231 return dartExecutable; 221 return dartExecutable;
232 } 222 }
233 223
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 [VoidFunction onDone]); 275 [VoidFunction onDone]);
286 276
287 // This function will be called for every TestCase of this test suite. 277 // This function will be called for every TestCase of this test suite.
288 // It will 278 // It will
289 // - handle sharding 279 // - handle sharding
290 // - update SummaryReport 280 // - update SummaryReport
291 // - handle SKIP/SKIP_BY_DESIGN markers 281 // - handle SKIP/SKIP_BY_DESIGN markers
292 // - test if the selector matches 282 // - test if the selector matches
293 // and will enqueue the test (if necessary). 283 // and will enqueue the test (if necessary).
294 void enqueueNewTestCase(TestCase testCase) { 284 void enqueueNewTestCase(TestCase testCase) {
295 if (testCase.isNegative && runtimeConfiguration.shouldSkipNegativeTests) { 285 if (testCase.isNegative &&
286 configuration.runtimeConfiguration.shouldSkipNegativeTests) {
296 return; 287 return;
297 } 288 }
298 var expectations = testCase.expectedOutcomes; 289 var expectations = testCase.expectedOutcomes;
299 290
300 // Handle sharding based on the original test path (i.e. all multitests 291 // Handle sharding based on the original test path (i.e. all multitests
301 // of a given original test belong to the same shard) 292 // of a given original test belong to the same shard)
302 var shards = configuration['shards'] as int; 293 if (configuration.shardCount > 1 &&
303 if (shards > 1 && 294 testCase.hash % configuration.shardCount != configuration.shard - 1) {
304 testCase.hash % shards != (configuration['shard'] as int) - 1) {
305 return; 295 return;
306 } 296 }
297
307 // Test if the selector includes this test. 298 // Test if the selector includes this test.
308 var pattern = configuration['selectors'][suiteName] as RegExp; 299 var pattern = configuration.selectors[suiteName];
309 if (!pattern.hasMatch(testCase.displayName)) { 300 if (!pattern.hasMatch(testCase.displayName)) {
310 return; 301 return;
311 } 302 }
312 303
313 if ((configuration['hot_reload'] as bool) || 304 if (configuration.hotReload || configuration.hotReloadRollback) {
314 (configuration['hot_reload_rollback'] as bool)) {
315 // Handle reload special cases. 305 // Handle reload special cases.
316 if (expectations.contains(Expectation.compileTimeError) || 306 if (expectations.contains(Expectation.compileTimeError) ||
317 testCase.hasCompileError || 307 testCase.hasCompileError ||
318 testCase.expectCompileError) { 308 testCase.expectCompileError) {
319 // Running a test that expects a compilation error with hot reloading 309 // Running a test that expects a compilation error with hot reloading
320 // is redundant with a regular run of the test. 310 // is redundant with a regular run of the test.
321 return; 311 return;
322 } 312 }
323 } 313 }
324 314
325 // Update Summary report 315 // Update Summary report
326 if (configuration['report'] as bool) { 316 if (configuration.printReport) {
327 if (testCase.expectCompileError && 317 if (testCase.expectCompileError &&
328 TestUtils.isBrowserRuntime(configuration['runtime'] as String) && 318 configuration.runtime.isBrowser &&
329 new CompilerConfiguration(configuration).hasCompiler) { 319 configuration.compilerConfiguration.hasCompiler) {
330 summaryReport.addCompileErrorSkipTest(); 320 summaryReport.addCompileErrorSkipTest();
331 return; 321 return;
332 } else { 322 } else {
333 summaryReport.add(testCase); 323 summaryReport.add(testCase);
334 } 324 }
335 } 325 }
336 326
337 // Handle skipped tests 327 // Handle skipped tests
338 if (expectations.contains(Expectation.skip) || 328 if (expectations.contains(Expectation.skip) ||
339 expectations.contains(Expectation.skipByDesign) || 329 expectations.contains(Expectation.skipByDesign) ||
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 testName = concat(testName, multitestName); 372 testName = concat(testName, multitestName);
383 return testName; 373 return testName;
384 } 374 }
385 375
386 /** 376 /**
387 * Create a directories for generated assets (tests, html files, 377 * Create a directories for generated assets (tests, html files,
388 * pubspec checkouts ...). 378 * pubspec checkouts ...).
389 */ 379 */
390 380
391 String createOutputDirectory(Path testPath, String optionsName) { 381 String createOutputDirectory(Path testPath, String optionsName) {
392 var checked = configuration['checked'] as bool ? '-checked' : ''; 382 var checked = configuration.isChecked ? '-checked' : '';
393 var strong = configuration['strong'] as bool ? '-strong' : ''; 383 var strong = configuration.isStrong ? '-strong' : '';
394 var minified = configuration['minified'] as bool ? '-minified' : ''; 384 var minified = configuration.isMinified ? '-minified' : '';
395 var sdk = configuration['use_sdk'] as bool ? '-sdk' : ''; 385 var sdk = configuration.useSdk ? '-sdk' : '';
396 var dirName = "${configuration['compiler']}-${configuration['runtime']}" 386 var dirName = "${configuration.compiler.name}-${configuration.runtime.name}"
397 "$checked$strong$minified$sdk"; 387 "$checked$strong$minified$sdk";
398 return createGeneratedTestDirectoryHelper( 388 return createGeneratedTestDirectoryHelper(
399 "tests", dirName, testPath, optionsName); 389 "tests", dirName, testPath, optionsName);
400 } 390 }
401 391
402 String createCompilationOutputDirectory(Path testPath) { 392 String createCompilationOutputDirectory(Path testPath) {
403 var checked = configuration['checked'] as bool ? '-checked' : ''; 393 var checked = configuration.isChecked ? '-checked' : '';
404 var strong = configuration['strong'] as bool ? '-strong' : ''; 394 var strong = configuration.isStrong ? '-strong' : '';
405 var minified = configuration['minified'] as bool ? '-minified' : ''; 395 var minified = configuration.isMinified ? '-minified' : '';
406 var csp = configuration['csp'] as bool ? '-csp' : ''; 396 var csp = configuration.isCsp ? '-csp' : '';
407 var sdk = configuration['use_sdk'] as bool ? '-sdk' : ''; 397 var sdk = configuration.useSdk ? '-sdk' : '';
408 var dirName = "${configuration['compiler']}" 398 var dirName = "${configuration.compiler.name}"
409 "$checked$strong$minified$csp$sdk"; 399 "$checked$strong$minified$csp$sdk";
410 return createGeneratedTestDirectoryHelper( 400 return createGeneratedTestDirectoryHelper(
411 "compilations", dirName, testPath, ""); 401 "compilations", dirName, testPath, "");
412 } 402 }
413 403
414 String createPubspecCheckoutDirectory(Path directoryOfPubspecYaml) { 404 String createPubspecCheckoutDirectory(Path directoryOfPubspecYaml) {
415 var sdk = configuration['use_sdk'] as bool ? 'sdk' : ''; 405 var sdk = configuration.useSdk ? 'sdk' : '';
416 return createGeneratedTestDirectoryHelper( 406 return createGeneratedTestDirectoryHelper(
417 "pubspec_checkouts", sdk, directoryOfPubspecYaml, ""); 407 "pubspec_checkouts", sdk, directoryOfPubspecYaml, "");
418 } 408 }
419 409
420 String createPubPackageBuildsDirectory(Path directoryOfPubspecYaml) { 410 String createPubPackageBuildsDirectory(Path directoryOfPubspecYaml) {
421 return createGeneratedTestDirectoryHelper( 411 return createGeneratedTestDirectoryHelper(
422 "pub_package_builds", 'public_packages', directoryOfPubspecYaml, ""); 412 "pub_package_builds", 'public_packages', directoryOfPubspecYaml, "");
423 } 413 }
424 } 414 }
425 415
(...skipping 18 matching lines...) Expand all
444 * The executable lists its tests when run with the --list command line flag. 434 * The executable lists its tests when run with the --list command line flag.
445 * Individual tests are run by specifying them on the command line. 435 * Individual tests are run by specifying them on the command line.
446 */ 436 */
447 class CCTestSuite extends TestSuite { 437 class CCTestSuite extends TestSuite {
448 final String testPrefix; 438 final String testPrefix;
449 String targetRunnerPath; 439 String targetRunnerPath;
450 String hostRunnerPath; 440 String hostRunnerPath;
451 final String dartDir; 441 final String dartDir;
452 List<String> statusFilePaths; 442 List<String> statusFilePaths;
453 443
454 CCTestSuite(Map<String, dynamic> configuration, String suiteName, 444 CCTestSuite(Configuration configuration, String suiteName, String runnerName,
455 String runnerName, this.statusFilePaths, 445 this.statusFilePaths,
456 {this.testPrefix: ''}) 446 {this.testPrefix: ''})
457 : dartDir = TestUtils.dartDir.toNativePath(), 447 : dartDir = TestUtils.dartDir.toNativePath(),
458 super(configuration, suiteName) { 448 super(configuration, suiteName) {
459 // For running the tests we use the given '$runnerName' binary 449 // For running the tests we use the given '$runnerName' binary
460 targetRunnerPath = '$buildDir/$runnerName'; 450 targetRunnerPath = '$buildDir/$runnerName';
461 451
462 // For listing the tests we use the '$runnerName.host' binary if it exists 452 // For listing the tests we use the '$runnerName.host' binary if it exists
463 // and use '$runnerName' if it doesn't. 453 // and use '$runnerName' if it doesn't.
464 var binarySuffix = Platform.operatingSystem == 'windows' ? '.exe' : ''; 454 var binarySuffix = Platform.operatingSystem == 'windows' ? '.exe' : '';
465 var hostBinary = '$targetRunnerPath.host$binarySuffix'; 455 var hostBinary = '$targetRunnerPath.host$binarySuffix';
466 if (new File(hostBinary).existsSync()) { 456 if (new File(hostBinary).existsSync()) {
467 hostRunnerPath = hostBinary; 457 hostRunnerPath = hostBinary;
468 } else { 458 } else {
469 hostRunnerPath = targetRunnerPath; 459 hostRunnerPath = targetRunnerPath;
470 } 460 }
471 } 461 }
472 462
473 void testNameHandler(ExpectationSet testExpectations, String testName) { 463 void testNameHandler(ExpectationSet testExpectations, String testName) {
474 // Only run the tests that match the pattern. Use the name 464 // Only run the tests that match the pattern. Use the name
475 // "suiteName/testName" for cc tests. 465 // "suiteName/testName" for cc tests.
476 String constructedName = '$suiteName/$testPrefix$testName'; 466 String constructedName = '$suiteName/$testPrefix$testName';
477 467
478 var expectations = testExpectations.expectations('$testPrefix$testName'); 468 var expectations = testExpectations.expectations('$testPrefix$testName');
479 469
480 var args = TestUtils.standardOptions(configuration); 470 var args = configuration.standardOptions.toList();
481 args.add(testName); 471 args.add(testName);
482 472
483 var command = CommandBuilder.instance.getProcessCommand( 473 var command = CommandBuilder.instance.getProcessCommand(
484 'run_vm_unittest', targetRunnerPath, args, environmentOverrides); 474 'run_vm_unittest', targetRunnerPath, args, environmentOverrides);
485 enqueueNewTestCase( 475 enqueueNewTestCase(
486 new TestCase(constructedName, [command], configuration, expectations)); 476 new TestCase(constructedName, [command], configuration, expectations));
487 } 477 }
488 478
489 Future<Null> forEachTest(Function onTest, Map testCache, 479 Future<Null> forEachTest(Function onTest, Map testCache,
490 [VoidFunction onDone]) async { 480 [VoidFunction onDone]) async {
(...skipping 14 matching lines...) Expand all
505 } catch (error) { 495 } catch (error) {
506 print("Fatal error occured: $error"); 496 print("Fatal error occured: $error");
507 exit(1); 497 exit(1);
508 } 498 }
509 } 499 }
510 } 500 }
511 501
512 class TestInformation { 502 class TestInformation {
513 Path filePath; 503 Path filePath;
514 Path originTestPath; 504 Path originTestPath;
515 Map optionsFromFile; 505 Map<String, dynamic> optionsFromFile;
516 bool hasCompileError; 506 bool hasCompileError;
517 bool hasRuntimeError; 507 bool hasRuntimeError;
518 bool isNegativeIfChecked; 508 bool isNegativeIfChecked;
519 bool hasCompileErrorIfChecked; 509 bool hasCompileErrorIfChecked;
520 bool hasStaticWarning; 510 bool hasStaticWarning;
521 String multitestKey; 511 String multitestKey;
522 512
523 TestInformation( 513 TestInformation(
524 this.filePath, 514 this.filePath,
525 this.originTestPath, 515 this.originTestPath,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 final Path suiteDir; 548 final Path suiteDir;
559 final List<String> statusFilePaths; 549 final List<String> statusFilePaths;
560 ExpectationSet testExpectations; 550 ExpectationSet testExpectations;
561 List<TestInformation> cachedTests; 551 List<TestInformation> cachedTests;
562 final Path dartDir; 552 final Path dartDir;
563 Predicate<String> isTestFilePredicate; 553 Predicate<String> isTestFilePredicate;
564 final bool listRecursively; 554 final bool listRecursively;
565 final List<String> extraVmOptions; 555 final List<String> extraVmOptions;
566 List<Uri> _dart2JsBootstrapDependencies; 556 List<Uri> _dart2JsBootstrapDependencies;
567 557
568 StandardTestSuite(Map<String, dynamic> configuration, String suiteName, 558 StandardTestSuite(Configuration configuration, String suiteName,
569 Path suiteDirectory, this.statusFilePaths, 559 Path suiteDirectory, this.statusFilePaths,
570 {this.isTestFilePredicate, bool recursive: false}) 560 {this.isTestFilePredicate, bool recursive: false})
571 : dartDir = TestUtils.dartDir, 561 : dartDir = TestUtils.dartDir,
572 listRecursively = recursive, 562 listRecursively = recursive,
573 suiteDir = TestUtils.dartDir.join(suiteDirectory), 563 suiteDir = TestUtils.dartDir.join(suiteDirectory),
574 extraVmOptions = TestUtils.getExtraVmOptions(configuration), 564 extraVmOptions = configuration.vmOptions,
575 super(configuration, suiteName) { 565 super(configuration, suiteName) {
576 if (!useSdk) { 566 if (!useSdk) {
577 _dart2JsBootstrapDependencies = []; 567 _dart2JsBootstrapDependencies = [];
578 } else { 568 } else {
579 var snapshotPath = TestUtils 569 var snapshotPath = TestUtils
580 .absolutePath( 570 .absolutePath(
581 new Path(buildDir).join(new Path('dart-sdk/bin/snapshots/' 571 new Path(buildDir).join(new Path('dart-sdk/bin/snapshots/'
582 'utils_wrapper.dart.snapshot'))) 572 'utils_wrapper.dart.snapshot')))
583 .toString(); 573 .toString();
584 _dart2JsBootstrapDependencies = [ 574 _dart2JsBootstrapDependencies = [
(...skipping 23 matching lines...) Expand all
608 * 598 *
609 * If you follow that convention, then you can construct one of these like: 599 * If you follow that convention, then you can construct one of these like:
610 * 600 *
611 * new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite'); 601 * new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite');
612 * 602 *
613 * instead of having to create a custom [StandardTestSuite] subclass. In 603 * instead of having to create a custom [StandardTestSuite] subclass. In
614 * particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES] 604 * particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES]
615 * in test.dart, this will all be set up for you. 605 * in test.dart, this will all be set up for you.
616 */ 606 */
617 factory StandardTestSuite.forDirectory( 607 factory StandardTestSuite.forDirectory(
618 Map<String, dynamic> configuration, Path directory) { 608 Configuration configuration, Path directory) {
619 var name = directory.filename; 609 var name = directory.filename;
620 var status_paths = [ 610 var status_paths = [
621 '$directory/$name.status', 611 '$directory/$name.status',
622 '$directory/.status', 612 '$directory/.status',
623 '$directory/${name}_dart2js.status', 613 '$directory/${name}_dart2js.status',
624 '$directory/${name}_analyzer2.status', 614 '$directory/${name}_analyzer2.status',
625 '$directory/${name}_kernel.status' 615 '$directory/${name}_kernel.status'
626 ]; 616 ];
627 617
628 return new StandardTestSuite(configuration, name, directory, status_paths, 618 return new StandardTestSuite(configuration, name, directory, status_paths,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 doTest = null; 657 doTest = null;
668 if (onDone != null) onDone(); 658 if (onDone != null) onDone();
669 } 659 }
670 660
671 /** 661 /**
672 * If Content shell/Dartium is required, and not yet updated, waits for 662 * If Content shell/Dartium is required, and not yet updated, waits for
673 * the update then completes. Otherwise completes immediately. 663 * the update then completes. Otherwise completes immediately.
674 */ 664 */
675 Future updateDartium() { 665 Future updateDartium() {
676 var completer = new Completer(); 666 var completer = new Completer();
677 var updater = runtimeUpdater(configuration); 667 var updater = runtimeUpdater(configuration.runtime, configuration.drtPath,
668 configuration.dartiumPath);
678 if (updater == null || updater.updated) { 669 if (updater == null || updater.updated) {
679 return new Future.value(null); 670 return new Future.value(null);
680 } 671 }
681 672
682 assert(updater.isActive); 673 assert(updater.isActive);
683 updater.onUpdated.add(() => completer.complete(null)); 674 updater.onUpdated.add(() => completer.complete(null));
684 675
685 return completer.future; 676 return completer.future;
686 } 677 }
687 678
(...skipping 30 matching lines...) Expand all
718 .list(recursive: listRecursively) 709 .list(recursive: listRecursively)
719 .where((fse) => fse is File) 710 .where((fse) => fse is File)
720 .forEach((FileSystemEntity entity) { 711 .forEach((FileSystemEntity entity) {
721 enqueueFile((entity as File).path, group); 712 enqueueFile((entity as File).path, group);
722 }); 713 });
723 group.add(lister); 714 group.add(lister);
724 } 715 }
725 716
726 void enqueueFile(String filename, FutureGroup group) { 717 void enqueueFile(String filename, FutureGroup group) {
727 if (isHtmlTestFile(filename)) { 718 if (isHtmlTestFile(filename)) {
728 var info = htmlTest.getInformation(filename); 719 var info = html_test.getInformation(filename);
729 if (info == null) { 720 if (info == null) {
730 DebugLogger 721 DebugLogger
731 .error("HtmlTest $filename does not contain required annotations"); 722 .error("HtmlTest $filename does not contain required annotations");
732 return; 723 return;
733 } 724 }
734 cachedTests.add(info); 725 cachedTests.add(info);
735 enqueueTestCaseFromTestInformation(info); 726 enqueueTestCaseFromTestInformation(info);
736 return; 727 return;
737 } 728 }
738 if (!isTestFile(filename)) return; 729 if (!isTestFile(filename)) return;
739 Path filePath = new Path(filename); 730 Path filePath = new Path(filename);
740 731
741 var optionsFromFile = readOptionsFromFile(filePath); 732 var optionsFromFile = readOptionsFromFile(filePath);
742 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile); 733 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
743 734
744 if (optionsFromFile['isMultitest'] as bool) { 735 if (optionsFromFile['isMultitest'] as bool) {
745 group.add(doMultitest( 736 group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase,
746 filePath, 737 configuration.hotReload || configuration.hotReloadRollback));
747 buildDir,
748 suiteDir,
749 createTestCase,
750 ((configuration['hot_reload'] as bool) ||
751 (configuration['hot_reload_rollback'] as bool))));
752 } else { 738 } else {
753 createTestCase( 739 createTestCase(
754 filePath, 740 filePath,
755 filePath, 741 filePath,
756 optionsFromFile['hasCompileError'] as bool, 742 optionsFromFile['hasCompileError'] as bool,
757 optionsFromFile['hasRuntimeError'] as bool, 743 optionsFromFile['hasRuntimeError'] as bool,
758 hasStaticWarning: optionsFromFile['hasStaticWarning'] as bool); 744 hasStaticWarning: optionsFromFile['hasStaticWarning'] as bool);
759 } 745 }
760 } 746 }
761 747
(...skipping 29 matching lines...) Expand all
791 var optionsFromFile = info.optionsFromFile; 777 var optionsFromFile = info.optionsFromFile;
792 778
793 // If this test is inside a package, we will check if there is a 779 // If this test is inside a package, we will check if there is a
794 // pubspec.yaml file and if so, create a custom package root for it. 780 // pubspec.yaml file and if so, create a custom package root for it.
795 List<Command> baseCommands = <Command>[]; 781 List<Command> baseCommands = <Command>[];
796 Path packageRoot; 782 Path packageRoot;
797 Path packages; 783 Path packages;
798 784
799 if (optionsFromFile['packageRoot'] == null && 785 if (optionsFromFile['packageRoot'] == null &&
800 optionsFromFile['packages'] == null) { 786 optionsFromFile['packages'] == null) {
801 if (configuration['package_root'] != null) { 787 if (configuration.packageRoot != null) {
802 packageRoot = new Path(configuration['package_root'] as String); 788 packageRoot = new Path(configuration.packageRoot);
803 optionsFromFile['packageRoot'] = packageRoot.toNativePath(); 789 optionsFromFile['packageRoot'] = packageRoot.toNativePath();
804 } 790 }
805 if (configuration['packages'] != null) { 791 if (configuration.packages != null) {
806 Path packages = new Path(configuration['packages'] as String); 792 Path packages = new Path(configuration.packages);
807 optionsFromFile['packages'] = packages.toNativePath(); 793 optionsFromFile['packages'] = packages.toNativePath();
808 } 794 }
809 } 795 }
810 if (new CompilerConfiguration(configuration).hasCompiler && 796 if (configuration.compilerConfiguration.hasCompiler &&
811 expectCompileError(info)) { 797 expectCompileError(info)) {
812 // If a compile-time error is expected, and we're testing a 798 // If a compile-time error is expected, and we're testing a
813 // compiler, we never need to attempt to run the program (in a 799 // compiler, we never need to attempt to run the program (in a
814 // browser or otherwise). 800 // browser or otherwise).
815 enqueueStandardTest(baseCommands, info, testName, expectations); 801 enqueueStandardTest(baseCommands, info, testName, expectations);
816 } else if (TestUtils.isBrowserRuntime(configuration['runtime'] as String)) { 802 } else if (configuration.runtime.isBrowser) {
817 if (info.optionsFromFile['isMultiHtmlTest'] as bool) { 803 if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
818 // A browser multi-test has multiple expectations for one test file. 804 // A browser multi-test has multiple expectations for one test file.
819 // Find all the different sub-test expecations for one entire test file. 805 // Find all the different sub-test expecations for one entire test file.
820 var subtestNames = info.optionsFromFile['subtestNames'] as List<String>; 806 var subtestNames = info.optionsFromFile['subtestNames'] as List<String>;
821 var multiHtmlTestExpectations = <String, Set<Expectation>>{}; 807 var multiHtmlTestExpectations = <String, Set<Expectation>>{};
822 for (var name in subtestNames) { 808 for (var name in subtestNames) {
823 var fullTestName = '$testName/$name'; 809 var fullTestName = '$testName/$name';
824 multiHtmlTestExpectations[fullTestName] = 810 multiHtmlTestExpectations[fullTestName] =
825 testExpectations.expectations(fullTestName); 811 testExpectations.expectations(fullTestName);
826 } 812 }
(...skipping 29 matching lines...) Expand all
856 commands.addAll( 842 commands.addAll(
857 makeCommands(info, vmOptionsVariant, allVmOptions, commonArguments)); 843 makeCommands(info, vmOptionsVariant, allVmOptions, commonArguments));
858 enqueueNewTestCase(new TestCase( 844 enqueueNewTestCase(new TestCase(
859 '$suiteName/$testName', commands, configuration, expectations, 845 '$suiteName/$testName', commands, configuration, expectations,
860 isNegative: isNegative(info), info: info)); 846 isNegative: isNegative(info), info: info));
861 } 847 }
862 } 848 }
863 849
864 bool expectCompileError(TestInformation info) { 850 bool expectCompileError(TestInformation info) {
865 return info.hasCompileError || 851 return info.hasCompileError ||
866 ((configuration['checked'] as bool) && info.hasCompileErrorIfChecked); 852 (configuration.isChecked && info.hasCompileErrorIfChecked);
867 } 853 }
868 854
869 bool isNegative(TestInformation info) { 855 bool isNegative(TestInformation info) {
870 bool negative = expectCompileError(info) || 856 bool negative = expectCompileError(info) ||
871 ((configuration['checked'] as bool) && info.isNegativeIfChecked); 857 (configuration.isChecked && info.isNegativeIfChecked);
872 if (info.hasRuntimeError && hasRuntime) { 858 if (info.hasRuntimeError && hasRuntime) {
873 negative = true; 859 negative = true;
874 } 860 }
875 return negative; 861 return negative;
876 } 862 }
877 863
878 List<Command> makeCommands(TestInformation info, int vmOptionsVarient, 864 List<Command> makeCommands(TestInformation info, int vmOptionsVarient,
879 List<String> vmOptions, List<String> args) { 865 List<String> vmOptions, List<String> args) {
880 var commands = <Command>[]; 866 var commands = <Command>[];
881 var compilerConfiguration = new CompilerConfiguration(configuration); 867 var compilerConfiguration = configuration.compilerConfiguration;
882 var sharedOptions = info.optionsFromFile['sharedOptions'] as List<String>; 868 var sharedOptions = info.optionsFromFile['sharedOptions'] as List<String>;
883 869
884 var compileTimeArguments = <String>[]; 870 var compileTimeArguments = <String>[];
885 String tempDir; 871 String tempDir;
886 if (compilerConfiguration.hasCompiler) { 872 if (compilerConfiguration.hasCompiler) {
887 compileTimeArguments = compilerConfiguration.computeCompilerArguments( 873 compileTimeArguments = compilerConfiguration.computeCompilerArguments(
888 vmOptions, sharedOptions, args); 874 vmOptions, sharedOptions, args);
889 // Avoid doing this for analyzer. 875 // Avoid doing this for analyzer.
890 var path = info.filePath; 876 var path = info.filePath;
891 if (vmOptionsVarient != 0) { 877 if (vmOptionsVarient != 0) {
(...skipping 12 matching lines...) Expand all
904 } 890 }
905 } 891 }
906 892
907 CommandArtifact compilationArtifact = 893 CommandArtifact compilationArtifact =
908 compilerConfiguration.computeCompilationArtifact( 894 compilerConfiguration.computeCompilationArtifact(
909 buildDir, 895 buildDir,
910 tempDir, 896 tempDir,
911 CommandBuilder.instance, 897 CommandBuilder.instance,
912 compileTimeArguments, 898 compileTimeArguments,
913 environmentOverrides); 899 environmentOverrides);
914 if (!(configuration['skip-compilation'] as bool)) { 900 if (!configuration.skipCompilation) {
915 commands.addAll(compilationArtifact.commands); 901 commands.addAll(compilationArtifact.commands);
916 } 902 }
917 903
918 if (expectCompileError(info) && compilerConfiguration.hasCompiler) { 904 if (expectCompileError(info) && compilerConfiguration.hasCompiler) {
919 // Do not attempt to run the compiled result. A compilation 905 // Do not attempt to run the compiled result. A compilation
920 // error should be reported by the compilation command. 906 // error should be reported by the compilation command.
921 return commands; 907 return commands;
922 } 908 }
923 909
924 List<String> runtimeArguments = 910 List<String> runtimeArguments =
925 compilerConfiguration.computeRuntimeArguments( 911 compilerConfiguration.computeRuntimeArguments(
926 runtimeConfiguration, 912 configuration.runtimeConfiguration,
927 buildDir, 913 buildDir,
928 info, 914 info,
929 vmOptions, 915 vmOptions,
930 sharedOptions, 916 sharedOptions,
931 args, 917 args,
932 compilationArtifact); 918 compilationArtifact);
933 919
934 return commands 920 return commands
935 ..addAll(runtimeConfiguration.computeRuntimeCommands( 921 ..addAll(configuration.runtimeConfiguration.computeRuntimeCommands(
936 this, 922 this,
937 CommandBuilder.instance, 923 CommandBuilder.instance,
938 compilationArtifact, 924 compilationArtifact,
939 runtimeArguments, 925 runtimeArguments,
940 environmentOverrides)); 926 environmentOverrides));
941 } 927 }
942 928
943 CreateTest makeTestCaseCreator(Map optionsFromFile) { 929 CreateTest makeTestCaseCreator(Map<String, dynamic> optionsFromFile) {
944 return (Path filePath, Path originTestPath, bool hasCompileError, 930 return (Path filePath, Path originTestPath, bool hasCompileError,
945 bool hasRuntimeError, 931 bool hasRuntimeError,
946 {bool isNegativeIfChecked: false, 932 {bool isNegativeIfChecked: false,
947 bool hasCompileErrorIfChecked: false, 933 bool hasCompileErrorIfChecked: false,
948 bool hasStaticWarning: false, 934 bool hasStaticWarning: false,
949 String multitestKey}) { 935 String multitestKey}) {
950 // Cache the test information for each test case. 936 // Cache the test information for each test case.
951 var info = new TestInformation( 937 var info = new TestInformation(
952 filePath, 938 filePath,
953 originTestPath, 939 originTestPath,
(...skipping 13 matching lines...) Expand all
967 * _createUrlPathFromFile takes a [file], which is either located in the dart 953 * _createUrlPathFromFile takes a [file], which is either located in the dart
968 * or in the build directory, and will return a String representing 954 * or in the build directory, and will return a String representing
969 * the relative path to either the dart or the build directory. 955 * the relative path to either the dart or the build directory.
970 * Thus, the returned [String] will be the path component of the URL 956 * Thus, the returned [String] will be the path component of the URL
971 * corresponding to [file] (the http server serves files relative to the 957 * corresponding to [file] (the http server serves files relative to the
972 * dart/build directories). 958 * dart/build directories).
973 */ 959 */
974 String _createUrlPathFromFile(Path file) { 960 String _createUrlPathFromFile(Path file) {
975 file = TestUtils.absolutePath(file); 961 file = TestUtils.absolutePath(file);
976 962
977 var relativeBuildDir = new Path(TestUtils.buildDir(configuration)); 963 var relativeBuildDir = new Path(configuration.buildDirectory);
978 var buildDir = TestUtils.absolutePath(relativeBuildDir); 964 var buildDir = TestUtils.absolutePath(relativeBuildDir);
979 var dartDir = TestUtils.absolutePath(TestUtils.dartDir); 965 var dartDir = TestUtils.absolutePath(TestUtils.dartDir);
980 966
981 var fileString = file.toString(); 967 var fileString = file.toString();
982 if (fileString.startsWith(buildDir.toString())) { 968 if (fileString.startsWith(buildDir.toString())) {
983 var fileRelativeToBuildDir = file.relativeTo(buildDir); 969 var fileRelativeToBuildDir = file.relativeTo(buildDir);
984 return "/$PREFIX_BUILDDIR/$fileRelativeToBuildDir"; 970 return "/$PREFIX_BUILDDIR/$fileRelativeToBuildDir";
985 } else if (fileString.startsWith(dartDir.toString())) { 971 } else if (fileString.startsWith(dartDir.toString())) {
986 var fileRelativeToDartDir = file.relativeTo(dartDir); 972 var fileRelativeToDartDir = file.relativeTo(dartDir);
987 return "/$PREFIX_DARTDIR/$fileRelativeToDartDir"; 973 return "/$PREFIX_DARTDIR/$fileRelativeToDartDir";
988 } 974 }
989 // Unreachable 975 // Unreachable
990 print("Cannot create URL for path $file. Not in build or dart directory."); 976 print("Cannot create URL for path $file. Not in build or dart directory.");
991 exit(1); 977 exit(1);
992 return null; 978 return null;
993 } 979 }
994 980
995 Uri _getUriForBrowserTest(String pathComponent, String subtestName) { 981 Uri _getUriForBrowserTest(String pathComponent, String subtestName) {
996 // Note: If we run test.py with the "--list" option, no http servers 982 // Note: If we run test.py with the "--list" option, no http servers
997 // will be started. So we return a dummy url instead. 983 // will be started. So we return a dummy url instead.
998 if (configuration['list'] as bool) { 984 if (configuration.listTests) {
999 return Uri.parse('http://listing_the_tests_only'); 985 return Uri.parse('http://listing_the_tests_only');
1000 } 986 }
1001 assert(configuration.containsKey('_servers_')); 987
1002 var servers = configuration['_servers_'] as TestingServers; 988 var serverPort = configuration.servers.port;
1003 var serverPort = servers.port; 989 var crossOriginPort = configuration.servers.crossOriginPort;
1004 var crossOriginPort = servers.crossOriginPort;
1005 var parameters = {'crossOriginPort': crossOriginPort.toString()}; 990 var parameters = {'crossOriginPort': crossOriginPort.toString()};
1006 if (subtestName != null) { 991 if (subtestName != null) {
1007 parameters['group'] = subtestName; 992 parameters['group'] = subtestName;
1008 } 993 }
1009 return new Uri( 994 return new Uri(
1010 scheme: 'http', 995 scheme: 'http',
1011 host: configuration['local_ip'] as String, 996 host: configuration.localIP,
1012 port: serverPort, 997 port: serverPort,
1013 path: pathComponent, 998 path: pathComponent,
1014 queryParameters: parameters); 999 queryParameters: parameters);
1015 } 1000 }
1016 1001
1017 void _createWrapperFile( 1002 void _createWrapperFile(
1018 String dartWrapperFilename, Path localDartLibraryFilename) { 1003 String dartWrapperFilename, Path localDartLibraryFilename) {
1019 File file = new File(dartWrapperFilename); 1004 File file = new File(dartWrapperFilename);
1020 RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE); 1005 RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE);
1021 1006
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 Path packageRoot, 1048 Path packageRoot,
1064 Path packages, 1049 Path packages,
1065 TestInformation info, 1050 TestInformation info,
1066 String testName, 1051 String testName,
1067 /* Set<Expectation> | Map<String, Set<Expectation>> */ expectations, 1052 /* Set<Expectation> | Map<String, Set<Expectation>> */ expectations,
1068 List<String> vmOptions, 1053 List<String> vmOptions,
1069 String tempDir) { 1054 String tempDir) {
1070 // TODO(Issue 14651): If we're on dartium, we need to pass [packageRoot] 1055 // TODO(Issue 14651): If we're on dartium, we need to pass [packageRoot]
1071 // on to the browser (it may be test specific). 1056 // on to the browser (it may be test specific).
1072 1057
1073 Path filePath = info.filePath; 1058 var filePath = info.filePath;
1074 String filename = filePath.toString(); 1059 var fileName = filePath.toString();
1075 1060
1076 var compiler = configuration['compiler'] as String; 1061 var optionsFromFile = info.optionsFromFile;
1077 var runtime = configuration['runtime'] as String;
1078 final Map optionsFromFile = info.optionsFromFile;
1079 1062
1080 final String compilationTempDir = 1063 var compilationTempDir = createCompilationOutputDirectory(info.filePath);
1081 createCompilationOutputDirectory(info.filePath);
1082 1064
1083 String dartWrapperFilename = '$tempDir/test.dart'; 1065 var dartWrapperFilename = '$tempDir/test.dart';
1084 String compiledDartWrapperFilename = '$compilationTempDir/test.js'; 1066 var compiledDartWrapperFilename = '$compilationTempDir/test.js';
1085 1067
1086 String content = null; 1068 String content = null;
1087 Path dir = filePath.directoryPath; 1069 var dir = filePath.directoryPath;
1088 String nameNoExt = filePath.filenameWithoutExtension; 1070 var nameNoExt = filePath.filenameWithoutExtension;
1089 1071
1090 String customHtmlPath = dir.append('$nameNoExt.html').toNativePath(); 1072 var customHtmlPath = dir.append('$nameNoExt.html').toNativePath();
1091 File customHtml = new File(customHtmlPath); 1073 var customHtml = new File(customHtmlPath);
1092 1074
1093 // Construct the command(s) that compile all the inputs needed by the 1075 // Construct the command(s) that compile all the inputs needed by the
1094 // browser test. For running Dart in DRT, this will be noop commands. 1076 // browser test. For running Dart in DRT, this will be noop commands.
1095 List<Command> commands = []..addAll(baseCommands); 1077 var commands = baseCommands.toList();
1096 1078
1097 // Use existing HTML document if available. 1079 // Use existing HTML document if available.
1098 String htmlPath; 1080 String htmlPath;
1099 if (customHtml.existsSync()) { 1081 if (customHtml.existsSync()) {
1100 // If necessary, run the Polymer deploy steps. 1082 // If necessary, run the Polymer deploy steps.
1101 // TODO(jmesserly): this should be generalized for any tests that 1083 // TODO(jmesserly): this should be generalized for any tests that
1102 // require Pub deploy, not just polymer. 1084 // require Pub deploy, not just polymer.
1103 if (customHtml.readAsStringSync().contains('<!--polymer-test')) { 1085 if (customHtml.readAsStringSync().contains('<!--polymer-test')) {
1104 if (compiler != 'none') { 1086 if (configuration.compiler != Compiler.none) {
1105 commands.add( 1087 commands.add(
1106 _polymerDeployCommand(customHtmlPath, tempDir, optionsFromFile)); 1088 _polymerDeployCommand(customHtmlPath, tempDir, optionsFromFile));
1107 1089
1108 Path pubspecYamlFile = _findPubspecYamlFile(filePath); 1090 Path pubspecYamlFile = _findPubspecYamlFile(filePath);
1109 Path homeDir = 1091 Path homeDir =
1110 (pubspecYamlFile == null) ? dir : pubspecYamlFile.directoryPath; 1092 (pubspecYamlFile == null) ? dir : pubspecYamlFile.directoryPath;
1111 htmlPath = '$tempDir/${dir.relativeTo(homeDir)}/$nameNoExt.html'; 1093 htmlPath = '$tempDir/${dir.relativeTo(homeDir)}/$nameNoExt.html';
1112 dartWrapperFilename = '${htmlPath}_bootstrap.dart'; 1094 dartWrapperFilename = '${htmlPath}_bootstrap.dart';
1113 compiledDartWrapperFilename = '$dartWrapperFilename.js'; 1095 compiledDartWrapperFilename = '$dartWrapperFilename.js';
1114 } else { 1096 } else {
1115 htmlPath = customHtmlPath; 1097 htmlPath = customHtmlPath;
1116 } 1098 }
1117 } else { 1099 } else {
1118 htmlPath = '$tempDir/test.html'; 1100 htmlPath = '$tempDir/test.html';
1119 dartWrapperFilename = filePath.toNativePath(); 1101 dartWrapperFilename = filePath.toNativePath();
1120 1102
1121 var htmlContents = customHtml.readAsStringSync(); 1103 var htmlContents = customHtml.readAsStringSync();
1122 if (compiler == 'none') { 1104 if (configuration.compiler == Compiler.none) {
1123 var dartUrl = _createUrlPathFromFile(filePath); 1105 var dartUrl = _createUrlPathFromFile(filePath);
1124 var dartScript = 1106 var dartScript =
1125 '<script type="application/dart" src="$dartUrl"></script>'; 1107 '<script type="application/dart" src="$dartUrl"></script>';
1126 var jsUrl = '/packages/browser/dart.js'; 1108 var jsUrl = '/packages/browser/dart.js';
1127 var jsScript = 1109 var jsScript =
1128 '<script type="text/javascript" src="$jsUrl"></script>'; 1110 '<script type="text/javascript" src="$jsUrl"></script>';
1129 htmlContents = htmlContents.replaceAll( 1111 htmlContents = htmlContents.replaceAll(
1130 '%TEST_SCRIPTS%', '$dartScript\n$jsScript'); 1112 '%TEST_SCRIPTS%', '$dartScript\n$jsScript');
1131 } else { 1113 } else {
1132 compiledDartWrapperFilename = '$tempDir/$nameNoExt.js'; 1114 compiledDartWrapperFilename = '$tempDir/$nameNoExt.js';
1133 var jsUrl = '$nameNoExt.js'; 1115 var jsUrl = '$nameNoExt.js';
1134 htmlContents = htmlContents.replaceAll( 1116 htmlContents = htmlContents.replaceAll(
1135 '%TEST_SCRIPTS%', '<script src="$jsUrl"></script>'); 1117 '%TEST_SCRIPTS%', '<script src="$jsUrl"></script>');
1136 } 1118 }
1137 new File(htmlPath).writeAsStringSync(htmlContents); 1119 new File(htmlPath).writeAsStringSync(htmlContents);
1138 } 1120 }
1139 } else { 1121 } else {
1140 htmlPath = '$tempDir/test.html'; 1122 htmlPath = '$tempDir/test.html';
1141 if (configuration['compiler'] != 'dart2js') { 1123 if (configuration.compiler != Compiler.dart2js) {
1142 // test.dart will import the dart test. 1124 // test.dart will import the dart test.
1143 _createWrapperFile(dartWrapperFilename, filePath); 1125 _createWrapperFile(dartWrapperFilename, filePath);
1144 } else { 1126 } else {
1145 dartWrapperFilename = filename; 1127 dartWrapperFilename = fileName;
1146 } 1128 }
1147 1129
1148 // Create the HTML file for the test. 1130 // Create the HTML file for the test.
1149 RandomAccessFile htmlTest = 1131 var htmlTest = new File(htmlPath).openSync(mode: FileMode.WRITE);
1150 new File(htmlPath).openSync(mode: FileMode.WRITE);
1151 1132
1152 String scriptPath = dartWrapperFilename; 1133 var scriptPath = dartWrapperFilename;
1153 if (compiler != 'none') { 1134 if (configuration.compiler != Compiler.none) {
1154 scriptPath = compiledDartWrapperFilename; 1135 scriptPath = compiledDartWrapperFilename;
1155 } 1136 }
1156 scriptPath = _createUrlPathFromFile(new Path(scriptPath)); 1137 scriptPath = _createUrlPathFromFile(new Path(scriptPath));
1157 1138
1158 content = getHtmlContents(filename, scriptType, new Path("$scriptPath")); 1139 content = getHtmlContents(fileName, scriptType, new Path("$scriptPath"));
1159 htmlTest.writeStringSync(content); 1140 htmlTest.writeStringSync(content);
1160 htmlTest.closeSync(); 1141 htmlTest.closeSync();
1161 } 1142 }
1162 1143
1163 if (compiler != 'none') { 1144 if (configuration.compiler != Compiler.none) {
1145 assert(configuration.compiler == Compiler.dart2js);
1146
1164 commands.add(_compileCommand(dartWrapperFilename, 1147 commands.add(_compileCommand(dartWrapperFilename,
1165 compiledDartWrapperFilename, compiler, tempDir, optionsFromFile)); 1148 compiledDartWrapperFilename, tempDir, optionsFromFile));
1166 } 1149 }
1167 1150
1168 // some tests require compiling multiple input scripts. 1151 // some tests require compiling multiple input scripts.
1169 var otherScripts = optionsFromFile['otherScripts'] as List<String>; 1152 var otherScripts = optionsFromFile['otherScripts'] as List<String>;
1170 for (var name in otherScripts) { 1153 for (var name in otherScripts) {
1171 var namePath = new Path(name); 1154 var namePath = new Path(name);
1172 var fileName = namePath.filename;
1173 var fromPath = filePath.directoryPath.join(namePath); 1155 var fromPath = filePath.directoryPath.join(namePath);
1174 if (compiler != 'none') { 1156
1157 if (configuration.compiler != Compiler.none) {
1158 assert(configuration.compiler == Compiler.dart2js);
1175 assert(namePath.extension == 'dart'); 1159 assert(namePath.extension == 'dart');
1160
1176 commands.add(_compileCommand(fromPath.toNativePath(), 1161 commands.add(_compileCommand(fromPath.toNativePath(),
1177 '$tempDir/$fileName.js', compiler, tempDir, optionsFromFile)); 1162 '$tempDir/${namePath.filename}.js', tempDir, optionsFromFile));
1178 } 1163 }
1179 if (compiler == 'none') { 1164
1165 if (configuration.compiler == Compiler.none) {
1180 // For the tests that require multiple input scripts but are not 1166 // For the tests that require multiple input scripts but are not
1181 // compiled, move the input scripts over with the script so they can 1167 // compiled, move the input scripts over with the script so they can
1182 // be accessed. 1168 // be accessed.
1183 var result = new File(fromPath.toNativePath()).readAsStringSync(); 1169 var result = new File(fromPath.toNativePath()).readAsStringSync();
1184 new File('$tempDir/$fileName').writeAsStringSync(result); 1170 new File('$tempDir/${namePath.filename}').writeAsStringSync(result);
1185 } 1171 }
1186 } 1172 }
1187 1173
1188 // Variables for browser multi-tests. 1174 // Variables for browser multi-tests.
1189 var multitest = info.optionsFromFile['isMultiHtmlTest'] as bool; 1175 var multitest = info.optionsFromFile['isMultiHtmlTest'] as bool;
1190 var subtestNames = multitest 1176 var subtestNames = multitest
1191 ? (info.optionsFromFile['subtestNames'] as List<String>) 1177 ? (info.optionsFromFile['subtestNames'] as List<String>)
1192 : <String>[null]; 1178 : <String>[null];
1193 for (var subtestName in subtestNames) { 1179 for (var subtestName in subtestNames) {
1194 // Construct the command that executes the browser test 1180 // Construct the command that executes the browser test
1195 var commandSet = commands.toList(); 1181 var commandSet = commands.toList();
1196 1182
1197 var htmlPath_subtest = _createUrlPathFromFile(new Path(htmlPath)); 1183 var htmlPath_subtest = _createUrlPathFromFile(new Path(htmlPath));
1198 var fullHtmlPath = 1184 var fullHtmlPath =
1199 _getUriForBrowserTest(htmlPath_subtest, subtestName).toString(); 1185 _getUriForBrowserTest(htmlPath_subtest, subtestName).toString();
1200 1186
1201 if (runtime == "drt") { 1187 if (configuration.runtime == Runtime.drt) {
1202 var dartFlags = <String>[]; 1188 var dartFlags = <String>[];
1203 var contentShellOptions = ['--no-timeout', '--run-layout-test']; 1189 var contentShellOptions = ['--no-timeout', '--run-layout-test'];
1204 1190
1205 // Disable the GPU under Linux and Dartium. If the GPU is enabled, 1191 // Disable the GPU under Linux and Dartium. If the GPU is enabled,
1206 // Chrome may send a termination signal to a test. The test will be 1192 // Chrome may send a termination signal to a test. The test will be
1207 // terminated if a machine (bot) doesn't have a GPU or if a test is 1193 // terminated if a machine (bot) doesn't have a GPU or if a test is
1208 // still running after a certain period of time. 1194 // still running after a certain period of time.
1209 if (configuration['system'] == 'linux' && 1195 if (configuration.system == System.linux &&
1210 configuration['runtime'] == 'drt') { 1196 configuration.runtime == Runtime.drt) {
1211 contentShellOptions.add('--disable-gpu'); 1197 contentShellOptions.add('--disable-gpu');
1212 // TODO(terry): Roll 50 need this in conjection with disable-gpu. 1198 // TODO(terry): Roll 50 need this in conjection with disable-gpu.
1213 contentShellOptions.add('--disable-gpu-early-init'); 1199 contentShellOptions.add('--disable-gpu-early-init');
1214 } 1200 }
1215 if (compiler == 'none') { 1201
1202 if (configuration.compiler == Compiler.none) {
1216 dartFlags.add('--ignore-unrecognized-flags'); 1203 dartFlags.add('--ignore-unrecognized-flags');
1217 if (configuration["checked"] as bool) { 1204 if (configuration.isChecked) {
1218 dartFlags.add('--enable_asserts'); 1205 dartFlags.add('--enable_asserts');
1219 dartFlags.add("--enable_type_checks"); 1206 dartFlags.add("--enable_type_checks");
1220 } 1207 }
1221 dartFlags.addAll(vmOptions); 1208 dartFlags.addAll(vmOptions);
1222 } 1209 }
1223 1210
1224 commandSet.add(CommandBuilder.instance.getContentShellCommand( 1211 commandSet.add(CommandBuilder.instance.getContentShellCommand(
1225 contentShellFilename, 1212 contentShellFilename,
1226 fullHtmlPath, 1213 fullHtmlPath,
1227 contentShellOptions, 1214 contentShellOptions,
1228 dartFlags, 1215 dartFlags,
1229 environmentOverrides)); 1216 environmentOverrides));
1230 } else { 1217 } else {
1231 commandSet.add(CommandBuilder.instance.getBrowserTestCommand( 1218 commandSet.add(CommandBuilder.instance.getBrowserTestCommand(
1232 runtime, fullHtmlPath, configuration, !isNegative(info))); 1219 fullHtmlPath, configuration, !isNegative(info)));
1233 } 1220 }
1234 1221
1235 // Create BrowserTestCase and queue it. 1222 // Create BrowserTestCase and queue it.
1236 var fullTestName = multitest ? '$testName/$subtestName' : testName; 1223 var fullTestName = multitest ? '$testName/$subtestName' : testName;
1237 var expectation = (multitest ? expectations[fullTestName] : expectations) 1224 var expectation = (multitest ? expectations[fullTestName] : expectations)
1238 as Set<Expectation>; 1225 as Set<Expectation>;
1239 var testCase = new BrowserTestCase('$suiteName/$fullTestName', commandSet, 1226 var testCase = new BrowserTestCase('$suiteName/$fullTestName', commandSet,
1240 configuration, expectation, info, isNegative(info), fullHtmlPath); 1227 configuration, expectation, info, isNegative(info), fullHtmlPath);
1241 1228
1242 enqueueNewTestCase(testCase); 1229 enqueueNewTestCase(testCase);
1243 } 1230 }
1244 } 1231 }
1245 1232
1246 void enqueueHtmlTest(HtmlTestInformation info, String testName, 1233 void enqueueHtmlTest(HtmlTestInformation info, String testName,
1247 Set<Expectation> expectations) { 1234 Set<Expectation> expectations) {
1248 var compiler = configuration['compiler'] as String; 1235 var compiler = configuration.compiler;
1249 var runtime = configuration['runtime'] as String; 1236 var runtime = configuration.runtime;
1250 // Html tests work only with the browser controller.
1251 if (!TestUtils.isBrowserRuntime(runtime) || runtime == 'drt') {
1252 return;
1253 }
1254 bool compileToJS = (compiler == 'dart2js');
1255 1237
1256 final Path filePath = info.filePath; 1238 // HTML tests work only with the browser controller.
1257 final String tempDir = createOutputDirectory(filePath, ''); 1239 if (!runtime.isBrowser || runtime == Runtime.drt) return;
1258 final Uri tempUri = new Uri.file('$tempDir/');
1259 String contents = htmlTest.getContents(info, compileToJS);
1260 final commands = <Command>[];
1261 1240
1262 void Fail(String message) { 1241 var compileToJS = compiler == Compiler.dart2js;
1242
1243 var filePath = info.filePath;
1244 var tempDir = createOutputDirectory(filePath, '');
1245 var tempUri = new Uri.file('$tempDir/');
1246 var contents = html_test.getContents(info, compileToJS);
1247 var commands = <Command>[];
1248
1249 void fail(String message) {
1263 var msg = "$message: ${info.filePath}"; 1250 var msg = "$message: ${info.filePath}";
1264 DebugLogger.warning(msg); 1251 DebugLogger.warning(msg);
1265 contents = htmlTest.makeFailingHtmlFile(msg); 1252 contents = html_test.makeFailingHtmlFile(msg);
1266 } 1253 }
1267 1254
1268 if (info.scripts.length > 0) { 1255 if (info.scripts.length > 0) {
1269 Uri testUri = new Uri.file(filePath.toNativePath()); 1256 var testUri = new Uri.file(filePath.toNativePath());
1270 for (String scriptPath in info.scripts) { 1257 for (var scriptPath in info.scripts) {
1271 if (!scriptPath.endsWith('.dart') && !scriptPath.endsWith('.js')) { 1258 if (!scriptPath.endsWith('.dart') && !scriptPath.endsWith('.js')) {
1272 Fail('HTML test scripts must be dart or javascript: $scriptPath'); 1259 fail('HTML test scripts must be dart or javascript: $scriptPath');
1273 break; 1260 break;
1274 } 1261 }
1275 Uri uri = Uri.parse(scriptPath); 1262
1263 var uri = Uri.parse(scriptPath);
1276 if (uri.isAbsolute) { 1264 if (uri.isAbsolute) {
1277 Fail('HTML test scripts must have relative paths: $scriptPath'); 1265 fail('HTML test scripts must have relative paths: $scriptPath');
1278 break; 1266 break;
1279 } 1267 }
1268
1280 if (uri.pathSegments.length > 1) { 1269 if (uri.pathSegments.length > 1) {
1281 Fail('HTML test scripts must be in test directory: $scriptPath'); 1270 fail('HTML test scripts must be in test directory: $scriptPath');
1282 break; 1271 break;
1283 } 1272 }
1284 Uri script = testUri.resolveUri(uri); 1273
1285 Uri copiedScript = tempUri.resolveUri(uri); 1274 var script = testUri.resolveUri(uri);
1286 if (compiler == 'none' || scriptPath.endsWith('.js')) { 1275 var copiedScript = tempUri.resolveUri(uri);
1276 if (compiler == Compiler.none || scriptPath.endsWith('.js')) {
1287 new File.fromUri(copiedScript) 1277 new File.fromUri(copiedScript)
1288 .writeAsStringSync(new File.fromUri(script).readAsStringSync()); 1278 .writeAsStringSync(new File.fromUri(script).readAsStringSync());
1289 } else { 1279 } else {
1290 var destination = copiedScript.toFilePath(); 1280 var destination = copiedScript.toFilePath();
1291 if (compileToJS) { 1281 if (compileToJS) {
1292 destination = destination.replaceFirst(dartExtension, '.js'); 1282 destination = destination.replaceFirst(dartExtension, '.js');
1293 } 1283 }
1294 commands.add(_compileCommand(script.toFilePath(), destination, 1284
1295 compiler, tempDir, info.optionsFromFile)); 1285 assert(compiler == Compiler.dart2js);
1286
1287 commands.add(_compileCommand(
1288 script.toFilePath(), destination, tempDir, info.optionsFromFile));
1296 } 1289 }
1297 } 1290 }
1298 } 1291 }
1299 final Uri htmlFile = tempUri.resolve(filePath.filename); 1292
1293 var htmlFile = tempUri.resolve(filePath.filename);
1300 new File.fromUri(htmlFile).writeAsStringSync(contents); 1294 new File.fromUri(htmlFile).writeAsStringSync(contents);
1301 1295
1302 var htmlPath = _createUrlPathFromFile(new Path(htmlFile.toFilePath())); 1296 var htmlPath = _createUrlPathFromFile(new Path(htmlFile.toFilePath()));
1303 var fullHtmlPath = _getUriForBrowserTest(htmlPath, null).toString(); 1297 var fullHtmlPath = _getUriForBrowserTest(htmlPath, null).toString();
1304 commands.add(CommandBuilder.instance.getBrowserHtmlTestCommand(runtime, 1298 commands.add(CommandBuilder.instance.getBrowserHtmlTestCommand(
1305 fullHtmlPath, configuration, info.expectedMessages, !isNegative(info))); 1299 fullHtmlPath, configuration, info.expectedMessages, !isNegative(info)));
1306 String testDisplayName = '$suiteName/$testName'; 1300 var testDisplayName = '$suiteName/$testName';
1307 var testCase = new BrowserTestCase(testDisplayName, commands, configuration, 1301 var testCase = new BrowserTestCase(testDisplayName, commands, configuration,
1308 expectations, info, isNegative(info), fullHtmlPath); 1302 expectations, info, isNegative(info), fullHtmlPath);
1309 enqueueNewTestCase(testCase); 1303 enqueueNewTestCase(testCase);
1310 return;
1311 } 1304 }
1312 1305
1313 /** Helper to create a compilation command for a single input file. */ 1306 /** Helper to create a compilation command for a single input file. */
1314 Command _compileCommand(String inputFile, String outputFile, String compiler, 1307 Command _compileCommand(String inputFile, String outputFile, String dir,
1315 String dir, Map optionsFromFile) { 1308 Map<String, dynamic> optionsFromFile) {
1316 assert(compiler == 'dart2js'); 1309 var args = <String>[];
1317 List<String> args; 1310
1318 if (compilerPath.endsWith('.dart')) { 1311 if (compilerPath.endsWith('.dart')) {
1319 // Run the compiler script via the Dart VM. 1312 // Run the compiler script via the Dart VM.
1320 args = [compilerPath]; 1313 args.add(compilerPath);
1321 } else {
1322 args = [];
1323 } 1314 }
1324 args.addAll(TestUtils.standardOptions(configuration)); 1315
1316 args.addAll(configuration.standardOptions);
1317
1325 var packages = packagesArgument(optionsFromFile['packageRoot'] as String, 1318 var packages = packagesArgument(optionsFromFile['packageRoot'] as String,
1326 optionsFromFile['packages'] as String); 1319 optionsFromFile['packages'] as String);
1327 if (packages != null) args.add(packages); 1320 if (packages != null) args.add(packages);
1321
1328 args.add('--out=$outputFile'); 1322 args.add('--out=$outputFile');
1329 args.add(inputFile); 1323 args.add(inputFile);
1324
1330 var options = optionsFromFile['sharedOptions'] as List<String>; 1325 var options = optionsFromFile['sharedOptions'] as List<String>;
1331 if (options != null) args.addAll(options); 1326 if (options != null) args.addAll(options);
1327
1332 return CommandBuilder.instance.getCompilationCommand( 1328 return CommandBuilder.instance.getCompilationCommand(
1333 compiler, 1329 Compiler.dart2js.name,
1334 outputFile, 1330 outputFile,
1335 !useSdk, 1331 !useSdk,
1336 dart2JsBootstrapDependencies, 1332 dart2JsBootstrapDependencies,
1337 compilerPath, 1333 compilerPath,
1338 args, 1334 args,
1339 environmentOverrides); 1335 environmentOverrides);
1340 } 1336 }
1341 1337
1342 /** Helper to create a Polymer deploy command for a single HTML file. */ 1338 /** Helper to create a Polymer deploy command for a single HTML file. */
1343 Command _polymerDeployCommand( 1339 Command _polymerDeployCommand(String inputFile, String outputDir,
1344 String inputFile, String outputDir, Map optionsFromFile) { 1340 Map<String, dynamic> optionsFromFile) {
1345 List<String> args = []; 1341 var args = <String>[];
1346 String packages = packagesArgument(optionsFromFile['packageRoot'] as String, 1342 var packages = packagesArgument(optionsFromFile['packageRoot'] as String,
1347 optionsFromFile['packages'] as String); 1343 optionsFromFile['packages'] as String);
1348 if (packages != null) args.add(packages); 1344 if (packages != null) args.add(packages);
1349 args 1345 args
1350 ..add('package:polymer/deploy.dart') 1346 ..add('package:polymer/deploy.dart')
1351 ..add('--test') 1347 ..add('--test')
1352 ..add(inputFile) 1348 ..add(inputFile)
1353 ..add('--out') 1349 ..add('--out')
1354 ..add(outputDir) 1350 ..add(outputDir)
1355 ..add('--file-filter') 1351 ..add('--file-filter')
1356 ..add('.svn'); 1352 ..add('.svn');
1357 if (configuration['csp'] as bool) args.add('--csp'); 1353 if (configuration.isCsp) args.add('--csp');
1358 1354
1359 return CommandBuilder.instance.getProcessCommand( 1355 return CommandBuilder.instance.getProcessCommand(
1360 'polymer_deploy', dartVmBinaryFileName, args, environmentOverrides); 1356 'polymer_deploy', dartVmBinaryFileName, args, environmentOverrides);
1361 } 1357 }
1362 1358
1363 String get scriptType { 1359 String get scriptType {
1364 switch (configuration['compiler'] as String) { 1360 switch (configuration.compiler) {
1365 case 'none': 1361 case Compiler.none:
1366 return 'application/dart'; 1362 return 'application/dart';
1367 case 'dart2js': 1363 case Compiler.dart2js:
1368 case 'dart2analyzer': 1364 case Compiler.dart2analyzer:
1369 return 'text/javascript'; 1365 return 'text/javascript';
1370 default: 1366 default:
1371 print('Non-web runtime, so no scriptType for: ' 1367 print('Non-web runtime, so no scriptType for: '
1372 '${configuration["compiler"]}'); 1368 '${configuration.compiler.name}');
1373 exit(1); 1369 exit(1);
1374 return null; 1370 return null;
1375 } 1371 }
1376 } 1372 }
1377 1373
1378 bool get hasRuntime { 1374 bool get hasRuntime => configuration.runtime != Runtime.none;
1379 switch (configuration['runtime'] as String) {
1380 case 'none':
1381 return false;
1382 default:
1383 return true;
1384 }
1385 }
1386 1375
1387 String get contentShellFilename { 1376 String get contentShellFilename {
1388 if (configuration['drt'] != '') { 1377 if (configuration.drtPath != null) return configuration.drtPath;
1389 return configuration['drt'] as String; 1378
1390 }
1391 if (Platform.operatingSystem == 'macos') { 1379 if (Platform.operatingSystem == 'macos') {
1392 final path = dartDir.append( 1380 final path = dartDir.append(
1393 '/client/tests/drt/Content Shell.app/Contents/MacOS/Content Shell'); 1381 '/client/tests/drt/Content Shell.app/Contents/MacOS/Content Shell');
1394 return path.toNativePath(); 1382 return path.toNativePath();
1395 } 1383 }
1396 return dartDir.append('client/tests/drt/content_shell').toNativePath(); 1384 return dartDir.append('client/tests/drt/content_shell').toNativePath();
1397 } 1385 }
1398 1386
1399 List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) { 1387 List<String> commonArgumentsFromFile(
1400 var args = TestUtils.standardOptions(configuration); 1388 Path filePath, Map<String, dynamic> optionsFromFile) {
1389 var args = configuration.standardOptions.toList();
1401 1390
1402 String packages = packagesArgument(optionsFromFile['packageRoot'] as String, 1391 String packages = packagesArgument(optionsFromFile['packageRoot'] as String,
1403 optionsFromFile['packages'] as String); 1392 optionsFromFile['packages'] as String);
1404 if (packages != null) { 1393 if (packages != null) {
1405 args.add(packages); 1394 args.add(packages);
1406 } 1395 }
1407 args.addAll(additionalOptions(filePath)); 1396 args.addAll(additionalOptions(filePath));
1408 if (configuration['analyzer'] as bool) { 1397 if (configuration.compiler == Compiler.dart2analyzer) {
1409 args.add('--format=machine'); 1398 args.add('--format=machine');
1410 args.add('--no-hints'); 1399 args.add('--no-hints');
1411 }
1412 1400
1413 if (configuration["compiler"] == "dart2analyzer" && 1401 if (filePath.filename.contains("dart2js") ||
1414 (filePath.filename.contains("dart2js") || 1402 filePath.directoryPath.segments().last.contains('html_common')) {
1415 filePath.directoryPath.segments().last.contains('html_common'))) { 1403 args.add("--use-dart2js-libraries");
1416 args.add("--use-dart2js-libraries"); 1404 }
1417 } 1405 }
1418 1406
1419 var isMultitest = optionsFromFile["isMultitest"] as bool; 1407 var isMultitest = optionsFromFile["isMultitest"] as bool;
1420 var dartOptions = optionsFromFile["dartOptions"] as List<String>; 1408 var dartOptions = optionsFromFile["dartOptions"] as List<String>;
1421 1409
1422 assert(!isMultitest || dartOptions == null); 1410 assert(!isMultitest || dartOptions == null);
1423 args.add(filePath.toNativePath()); 1411 args.add(filePath.toNativePath());
1424 if (dartOptions != null) { 1412 if (dartOptions != null) {
1425 args.addAll(dartOptions); 1413 args.addAll(dartOptions);
1426 } 1414 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 * an image, if the expectation ends in .png. 'test.dart' will compare the 1486 * an image, if the expectation ends in .png. 'test.dart' will compare the
1499 * snapshot to the expectation file. When tests fail, 'test.dart' saves the 1487 * snapshot to the expectation file. When tests fail, 'test.dart' saves the
1500 * new snapshot into a file so it can be visualized or copied over. 1488 * new snapshot into a file so it can be visualized or copied over.
1501 * Expectations can be recorded for the first time by creating an empty file 1489 * Expectations can be recorded for the first time by creating an empty file
1502 * with the right name (touch test_name_test.png), running the test, and 1490 * with the right name (touch test_name_test.png), running the test, and
1503 * executing the copy command printed by the test script. 1491 * executing the copy command printed by the test script.
1504 * 1492 *
1505 * This method is static as the map is cached and shared amongst 1493 * This method is static as the map is cached and shared amongst
1506 * configurations, so it may not use [configuration]. 1494 * configurations, so it may not use [configuration].
1507 */ 1495 */
1508 Map readOptionsFromFile(Path filePath) { 1496 Map<String, dynamic> readOptionsFromFile(Path filePath) {
1509 if (filePath.filename.endsWith('.dill')) { 1497 if (filePath.filename.endsWith('.dill')) {
1510 return optionsFromKernelFile(); 1498 return optionsFromKernelFile();
1511 } else if (filePath.segments().contains('co19')) { 1499 } else if (filePath.segments().contains('co19')) {
1512 return readOptionsFromCo19File(filePath); 1500 return readOptionsFromCo19File(filePath);
1513 } 1501 }
1514 RegExp testOptionsRegExp = new RegExp(r"// VMOptions=(.*)"); 1502 RegExp testOptionsRegExp = new RegExp(r"// VMOptions=(.*)");
1515 RegExp sharedOptionsRegExp = new RegExp(r"// SharedOptions=(.*)"); 1503 RegExp sharedOptionsRegExp = new RegExp(r"// SharedOptions=(.*)");
1516 RegExp dartOptionsRegExp = new RegExp(r"// DartOptions=(.*)"); 1504 RegExp dartOptionsRegExp = new RegExp(r"// DartOptions=(.*)");
1517 RegExp otherScriptsRegExp = new RegExp(r"// OtherScripts=(.*)"); 1505 RegExp otherScriptsRegExp = new RegExp(r"// OtherScripts=(.*)");
1518 RegExp otherResourcesRegExp = new RegExp(r"// OtherResources=(.*)"); 1506 RegExp otherResourcesRegExp = new RegExp(r"// OtherResources=(.*)");
1519 RegExp packageRootRegExp = new RegExp(r"// PackageRoot=(.*)"); 1507 RegExp packageRootRegExp = new RegExp(r"// PackageRoot=(.*)");
1520 RegExp packagesRegExp = new RegExp(r"// Packages=(.*)"); 1508 RegExp packagesRegExp = new RegExp(r"// Packages=(.*)");
1521 RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)"); 1509 RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)");
1522 // TODO(gram) Clean these up once the old directives are not supported. 1510 // TODO(gram) Clean these up once the old directives are not supported.
1523 RegExp domImportRegExp = new RegExp( 1511 RegExp domImportRegExp = new RegExp(
1524 r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)", 1512 r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
1525 multiLine: true); 1513 multiLine: true);
1526 1514
1527 var bytes = new File(filePath.toNativePath()).readAsBytesSync(); 1515 var bytes = new File(filePath.toNativePath()).readAsBytesSync();
1528 String contents = decodeUtf8(bytes); 1516 String contents = decodeUtf8(bytes);
1529 bytes = null; 1517 bytes = null;
1530 1518
1531 // Find the options in the file. 1519 // Find the options in the file.
1532 var result = <List<String>>[]; 1520 var result = <List<String>>[];
1533 List<String> dartOptions; 1521 List<String> dartOptions;
1534 List<String> sharedOptions; 1522 List<String> sharedOptions;
1535 String packageRoot; 1523 String packageRoot;
1536 String packages; 1524 String packages;
1537 1525
1538 Iterable<Match> matches = testOptionsRegExp.allMatches(contents); 1526 var matches = testOptionsRegExp.allMatches(contents);
1539 for (var match in matches) { 1527 for (var match in matches) {
1540 result.add(match[1].split(' ').where((e) => e != '').toList()); 1528 result.add(match[1].split(' ').where((e) => e != '').toList());
1541 } 1529 }
1542 if (result.isEmpty) result.add([]); 1530 if (result.isEmpty) result.add([]);
1543 1531
1544 matches = dartOptionsRegExp.allMatches(contents); 1532 matches = dartOptionsRegExp.allMatches(contents);
1545 for (var match in matches) { 1533 for (var match in matches) {
1546 if (dartOptions != null) { 1534 if (dartOptions != null) {
1547 throw new Exception( 1535 throw new Exception(
1548 'More than one "// DartOptions=" line in test $filePath'); 1536 'More than one "// DartOptions=" line in test $filePath');
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 "otherScripts": otherScripts, 1614 "otherScripts": otherScripts,
1627 "otherResources": otherResources, 1615 "otherResources": otherResources,
1628 "isMultitest": isMultitest, 1616 "isMultitest": isMultitest,
1629 "isMultiHtmlTest": isMultiHtmlTest, 1617 "isMultiHtmlTest": isMultiHtmlTest,
1630 "subtestNames": subtestNames, 1618 "subtestNames": subtestNames,
1631 "isolateStubs": isolateStubs, 1619 "isolateStubs": isolateStubs,
1632 "containsDomImport": containsDomImport 1620 "containsDomImport": containsDomImport
1633 }; 1621 };
1634 } 1622 }
1635 1623
1636 Map optionsFromKernelFile() { 1624 Map<String, dynamic> optionsFromKernelFile() {
1637 return const { 1625 return const {
1638 "vmOptions": const [const []], 1626 "vmOptions": const [const []],
1639 "sharedOptions": const [], 1627 "sharedOptions": const [],
1640 "dartOptions": null, 1628 "dartOptions": null,
1641 "packageRoot": null, 1629 "packageRoot": null,
1642 "packages": null, 1630 "packages": null,
1643 "hasCompileError": false, 1631 "hasCompileError": false,
1644 "hasRuntimeError": false, 1632 "hasRuntimeError": false,
1645 "hasStaticWarning": false, 1633 "hasStaticWarning": false,
1646 "otherScripts": const [], 1634 "otherScripts": const [],
1647 "isMultitest": false, 1635 "isMultitest": false,
1648 "isMultiHtmlTest": false, 1636 "isMultiHtmlTest": false,
1649 "subtestNames": const [], 1637 "subtestNames": const [],
1650 "isolateStubs": '', 1638 "isolateStubs": '',
1651 "containsDomImport": false, 1639 "containsDomImport": false,
1652 }; 1640 };
1653 } 1641 }
1654 1642
1655 List<List<String>> getVmOptions(Map optionsFromFile) { 1643 List<List<String>> getVmOptions(Map<String, dynamic> optionsFromFile) {
1656 var COMPILERS = const ['none', 'dartk', 'dartkp', 'precompiler', 'app_jit']; 1644 const compilers = const [
1657 var RUNTIMES = const [ 1645 Compiler.none,
1658 'none', 1646 Compiler.dartk,
1659 'dart_precompiled', 1647 Compiler.dartkp,
1660 'vm', 1648 Compiler.precompiler,
1661 'drt', 1649 Compiler.appJit
1662 'dartium',
1663 'ContentShellOnAndroid',
1664 'DartiumOnAndroid'
1665 ]; 1650 ];
1666 var needsVmOptions = COMPILERS.contains(configuration['compiler']) && 1651
1667 RUNTIMES.contains(configuration['runtime']); 1652 const runtimes = const [
1653 Runtime.none,
1654 Runtime.dartPrecompiled,
1655 Runtime.vm,
1656 Runtime.drt,
1657 Runtime.dartium,
1658 Runtime.contentShellOnAndroid,
1659 Runtime.dartiumOnAndroid
1660 ];
1661
1662 var needsVmOptions = compilers.contains(configuration.compiler) &&
1663 runtimes.contains(configuration.runtime);
1668 if (!needsVmOptions) return [[]]; 1664 if (!needsVmOptions) return [[]];
1669 return optionsFromFile['vmOptions'] as List<List<String>>; 1665 return optionsFromFile['vmOptions'] as List<List<String>>;
1670 } 1666 }
1671 1667
1672 /** 1668 /**
1673 * Read options from a co19 test file. 1669 * Read options from a co19 test file.
1674 * 1670 *
1675 * The reason this is different from [readOptionsFromFile] is that 1671 * The reason this is different from [readOptionsFromFile] is that
1676 * co19 is developed based on a contract which defines certain test 1672 * co19 is developed based on a contract which defines certain test
1677 * tags. These tags may appear unused, but should not be removed 1673 * tags. These tags may appear unused, but should not be removed
1678 * without consulting with the co19 team. 1674 * without consulting with the co19 team.
1679 * 1675 *
1680 * Also, [readOptionsFromFile] recognizes a number of additional 1676 * Also, [readOptionsFromFile] recognizes a number of additional
1681 * tags that are not appropriate for use in general tests of 1677 * tags that are not appropriate for use in general tests of
1682 * conformance to the Dart language. Any Dart implementation must 1678 * conformance to the Dart language. Any Dart implementation must
1683 * pass the co19 test suite as is, and not require extra flags, 1679 * pass the co19 test suite as is, and not require extra flags,
1684 * environment variables, configuration files, etc. 1680 * environment variables, configuration files, etc.
1685 */ 1681 */
1686 Map readOptionsFromCo19File(Path filePath) { 1682 Map<String, dynamic> readOptionsFromCo19File(Path filePath) {
1687 String contents = 1683 String contents =
1688 decodeUtf8(new File(filePath.toNativePath()).readAsBytesSync()); 1684 decodeUtf8(new File(filePath.toNativePath()).readAsBytesSync());
1689 1685
1690 bool hasCompileError = contents.contains("@compile-error"); 1686 bool hasCompileError = contents.contains("@compile-error");
1691 bool hasRuntimeError = contents.contains("@runtime-error"); 1687 bool hasRuntimeError = contents.contains("@runtime-error");
1692 bool hasStaticWarning = contents.contains("@static-warning"); 1688 bool hasStaticWarning = contents.contains("@static-warning");
1693 bool isMultitest = multiTestRegExp.hasMatch(contents); 1689 bool isMultitest = multiTestRegExp.hasMatch(contents);
1694 1690
1695 return { 1691 return {
1696 "vmOptions": <List>[[]], 1692 "vmOptions": <List>[[]],
(...skipping 10 matching lines...) Expand all
1707 "subtestNames": <String>[], 1703 "subtestNames": <String>[],
1708 "isolateStubs": '', 1704 "isolateStubs": '',
1709 "containsDomImport": false, 1705 "containsDomImport": false,
1710 }; 1706 };
1711 } 1707 }
1712 } 1708 }
1713 1709
1714 /// Used for testing packages in on off settings, i.e., we pass in the actual 1710 /// Used for testing packages in on off settings, i.e., we pass in the actual
1715 /// directory that we want to test. 1711 /// directory that we want to test.
1716 class PKGTestSuite extends StandardTestSuite { 1712 class PKGTestSuite extends StandardTestSuite {
1717 PKGTestSuite(Map<String, dynamic> configuration, Path directoryPath) 1713 PKGTestSuite(Configuration configuration, Path directoryPath)
1718 : super(configuration, directoryPath.filename, directoryPath, 1714 : super(configuration, directoryPath.filename, directoryPath,
1719 ["$directoryPath/.status"], 1715 ["$directoryPath/.status"],
1720 isTestFilePredicate: (f) => f.endsWith('_test.dart'), 1716 isTestFilePredicate: (f) => f.endsWith('_test.dart'),
1721 recursive: true); 1717 recursive: true);
1722 1718
1723 void enqueueBrowserTest( 1719 void enqueueBrowserTest(
1724 List<Command> baseCommands, 1720 List<Command> baseCommands,
1725 Path packageRoot, 1721 Path packageRoot,
1726 packages, 1722 packages,
1727 TestInformation info, 1723 TestInformation info,
1728 String testName, 1724 String testName,
1729 /* Set<Expectation> | Map<String, Set<Expectation>> */ dynamic 1725 /* Set<Expectation> | Map<String, Set<Expectation>> */ dynamic
1730 expectations) { 1726 expectations) {
1731 var runtime = configuration['runtime'] as String;
1732 var filePath = info.filePath; 1727 var filePath = info.filePath;
1733 var dir = filePath.directoryPath; 1728 var dir = filePath.directoryPath;
1734 var nameNoExt = filePath.filenameWithoutExtension; 1729 var nameNoExt = filePath.filenameWithoutExtension;
1735 var customHtmlPath = dir.append('$nameNoExt.html'); 1730 var customHtmlPath = dir.append('$nameNoExt.html');
1736 var customHtml = new File(customHtmlPath.toNativePath()); 1731 var customHtml = new File(customHtmlPath.toNativePath());
1737 if (!customHtml.existsSync()) { 1732 if (!customHtml.existsSync()) {
1738 super.enqueueBrowserTest( 1733 super.enqueueBrowserTest(
1739 baseCommands, packageRoot, packages, info, testName, expectations); 1734 baseCommands, packageRoot, packages, info, testName, expectations);
1740 } else { 1735 } else {
1741 var relativeHtml = customHtmlPath.relativeTo(TestUtils.dartDir); 1736 var relativeHtml = customHtmlPath.relativeTo(TestUtils.dartDir);
1742 var commands = baseCommands.toList(); 1737 var commands = baseCommands.toList();
1743 var fullPath = _createUrlPathFromFile(customHtmlPath); 1738 var fullPath = _createUrlPathFromFile(customHtmlPath);
1744 1739
1745 commands.add(CommandBuilder.instance.getBrowserTestCommand( 1740 commands.add(CommandBuilder.instance
1746 runtime, fullPath, configuration, !isNegative(info))); 1741 .getBrowserTestCommand(fullPath, configuration, !isNegative(info)));
1747 var testDisplayName = '$suiteName/$testName'; 1742 var testDisplayName = '$suiteName/$testName';
1748 enqueueNewTestCase(new BrowserTestCase( 1743 enqueueNewTestCase(new BrowserTestCase(
1749 testDisplayName, 1744 testDisplayName,
1750 commands, 1745 commands,
1751 configuration, 1746 configuration,
1752 expectations as Set<Expectation>, 1747 expectations as Set<Expectation>,
1753 info, 1748 info,
1754 isNegative(info), 1749 isNegative(info),
1755 relativeHtml.toNativePath())); 1750 relativeHtml.toNativePath()));
1756 } 1751 }
1757 } 1752 }
1758 } 1753 }
1759 1754
1760 /// A DartcCompilationTestSuite will run dartc on all of the tests. 1755 /// A DartcCompilationTestSuite will run dartc on all of the tests.
1761 /// 1756 ///
1762 /// Usually, the result of a dartc run is determined by the output of 1757 /// Usually, the result of a dartc run is determined by the output of
1763 /// dartc in connection with annotations in the test file. 1758 /// dartc in connection with annotations in the test file.
1764 class DartcCompilationTestSuite extends StandardTestSuite { 1759 class DartcCompilationTestSuite extends StandardTestSuite {
1765 List<String> _testDirs; 1760 List<String> _testDirs;
1766 1761
1767 DartcCompilationTestSuite( 1762 DartcCompilationTestSuite(
1768 Map<String, dynamic> configuration, 1763 Configuration configuration,
1769 String suiteName, 1764 String suiteName,
1770 String directoryPath, 1765 String directoryPath,
1771 List<String> this._testDirs, 1766 List<String> this._testDirs,
1772 List<String> expectations) 1767 List<String> expectations)
1773 : super(configuration, suiteName, new Path(directoryPath), expectations); 1768 : super(configuration, suiteName, new Path(directoryPath), expectations);
1774 1769
1775 List<String> additionalOptions(Path filePath) { 1770 List<String> additionalOptions(Path filePath) {
1776 return ['--fatal-warnings', '--fatal-type-errors']; 1771 return ['--fatal-warnings', '--fatal-type-errors'];
1777 } 1772 }
1778 1773
1779 Future enqueueTests() { 1774 Future enqueueTests() {
1780 var group = new FutureGroup(); 1775 var group = new FutureGroup();
1781 1776
1782 for (String testDir in _testDirs) { 1777 for (String testDir in _testDirs) {
1783 Directory dir = new Directory(suiteDir.append(testDir).toNativePath()); 1778 Directory dir = new Directory(suiteDir.append(testDir).toNativePath());
1784 if (dir.existsSync()) { 1779 if (dir.existsSync()) {
1785 enqueueDirectory(dir, group); 1780 enqueueDirectory(dir, group);
1786 } 1781 }
1787 } 1782 }
1788 1783
1789 return group.future; 1784 return group.future;
1790 } 1785 }
1791 } 1786 }
1792 1787
1793 class AnalyzeLibraryTestSuite extends DartcCompilationTestSuite { 1788 class AnalyzeLibraryTestSuite extends DartcCompilationTestSuite {
1794 static String libraryPath(Map<String, dynamic> configuration) => 1789 static String libraryPath(Configuration configuration) =>
1795 configuration['use_sdk'] as bool 1790 configuration.useSdk ? '${configuration.buildDirectory}/dart-sdk' : 'sdk';
1796 ? '${TestUtils.buildDir(configuration)}/dart-sdk'
1797 : 'sdk';
1798 1791
1799 AnalyzeLibraryTestSuite(Map<String, dynamic> configuration) 1792 AnalyzeLibraryTestSuite(Configuration configuration)
1800 : super(configuration, 'analyze_library', libraryPath(configuration), 1793 : super(configuration, 'analyze_library', libraryPath(configuration),
1801 ['lib'], ['tests/lib/analyzer/analyze_library.status']); 1794 ['lib'], ['tests/lib/analyzer/analyze_library.status']);
1802 1795
1803 List<String> additionalOptions(Path filePath, {bool showSdkWarnings}) { 1796 List<String> additionalOptions(Path filePath, {bool showSdkWarnings}) {
1804 var options = super.additionalOptions(filePath); 1797 var options = super.additionalOptions(filePath);
1805 options.add('--sdk-warnings'); 1798 options.add('--sdk-warnings');
1806 return options; 1799 return options;
1807 } 1800 }
1808 1801
1809 bool isTestFile(String filename) { 1802 bool isTestFile(String filename) {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 throw new Exception('Can\'t delete path $native_path. ' 1945 throw new Exception('Can\'t delete path $native_path. '
1953 'This path might be too long'); 1946 'This path might be too long');
1954 } 1947 }
1955 }); 1948 });
1956 } else { 1949 } else {
1957 var dir = new Directory(path); 1950 var dir = new Directory(path);
1958 return dir.delete(recursive: true); 1951 return dir.delete(recursive: true);
1959 } 1952 }
1960 } 1953 }
1961 1954
1962 static void deleteTempSnapshotDirectory(Map configuration) { 1955 static void deleteTempSnapshotDirectory(Configuration configuration) {
1963 if (configuration['compiler'] == 'dart2app' || 1956 if (configuration.compiler == Compiler.appJit ||
1964 configuration['compiler'] == 'dart2appjit' || 1957 configuration.compiler == Compiler.precompiler) {
1965 configuration['compiler'] == 'precompiler') { 1958 var checked = configuration.isChecked ? '-checked' : '';
1966 var checked = (configuration['checked'] as bool) ? '-checked' : ''; 1959 var strong = configuration.isStrong ? '-strong' : '';
1967 var strong = (configuration['strong'] as bool) ? '-strong' : ''; 1960 var minified = configuration.isMinified ? '-minified' : '';
1968 var minified = (configuration['minified'] as bool) ? '-minified' : ''; 1961 var csp = configuration.isCsp ? '-csp' : '';
1969 var csp = (configuration['csp'] as bool) ? '-csp' : ''; 1962 var sdk = configuration.useSdk ? '-sdk' : '';
1970 var sdk = (configuration['use_sdk'] as bool) ? '-sdk' : ''; 1963 var dirName = "${configuration.compiler.name}"
1971 var dirName = "${configuration['compiler']}"
1972 "$checked$strong$minified$csp$sdk"; 1964 "$checked$strong$minified$csp$sdk";
1973 String generatedPath = "${TestUtils.buildDir(configuration)}" 1965 var generatedPath =
1974 "/generated_compilations/$dirName"; 1966 configuration.buildDirectory + "/generated_compilations/$dirName";
1975 TestUtils.deleteDirectory(generatedPath); 1967 TestUtils.deleteDirectory(generatedPath);
1976 } 1968 }
1977 } 1969 }
1978 1970
1979 static final debugLogFilePath = new Path(".debug.log"); 1971 static final debugLogFilePath = new Path(".debug.log");
1980 1972
1981 /// If a flaky test did fail, infos about it (i.e. test name, stdin, stdout) 1973 /// If a flaky test did fail, infos about it (i.e. test name, stdin, stdout)
1982 /// will be written to this file. 1974 /// will be written to this file.
1983 /// 1975 ///
1984 /// This is useful for debugging flaky tests. When running on a buildbot, the 1976 /// This is useful for debugging flaky tests. When running on a buildbot, the
1985 /// file can be made visible in the waterfall UI. 1977 /// file can be made visible in the waterfall UI.
1986 static const flakyFileName = ".flaky.log"; 1978 static const flakyFileName = ".flaky.log";
1987 1979
1988 /// If test.py was invoked with '--write-test-outcome-log it will write 1980 /// If test.py was invoked with '--write-test-outcome-log it will write
1989 /// test outcomes to this file. 1981 /// test outcomes to this file.
1990 static const testOutcomeFileName = ".test-outcome.log"; 1982 static const testOutcomeFileName = ".test-outcome.log";
1991 1983
1992 static void ensureExists(String filename, Map configuration) { 1984 static void ensureExists(String filename, Configuration configuration) {
1993 if (!(configuration['list'] as bool) && 1985 if (!configuration.listTests && !existsCache.doesFileExist(filename)) {
1994 !existsCache.doesFileExist(filename)) {
1995 throw "'$filename' does not exist"; 1986 throw "'$filename' does not exist";
1996 } 1987 }
1997 } 1988 }
1998 1989
1999 static Path absolutePath(Path path) { 1990 static Path absolutePath(Path path) {
2000 if (!path.isAbsolute) { 1991 if (!path.isAbsolute) {
2001 return currentWorkingDirectory.join(path); 1992 return currentWorkingDirectory.join(path);
2002 } 1993 }
2003 return path; 1994 return path;
2004 } 1995 }
2005 1996
2006 static String outputDir(Map configuration) {
2007 var result = '';
2008 var system = configuration['system'] as String;
2009 if (system == 'fuchsia' ||
2010 system == 'linux' ||
2011 system == 'android' ||
2012 system == 'windows') {
2013 result = 'out/';
2014 } else if (system == 'macos') {
2015 result = 'xcodebuild/';
2016 } else {
2017 throw new Exception('Unknown operating system: "$system"');
2018 }
2019 return result;
2020 }
2021
2022 static List<String> standardOptions(Map configuration) {
2023 var args = ["--ignore-unrecognized-flags"];
2024 var compiler = configuration["compiler"] as String;
2025 if (compiler == "dart2js") {
2026 args = ['--generate-code-with-compile-time-errors', '--test-mode'];
2027 if (configuration["checked"] as bool) {
2028 args.add('--enable-checked-mode');
2029 }
2030 // args.add("--verbose");
2031 if (!isBrowserRuntime(configuration['runtime'] as String)) {
2032 args.add("--allow-mock-compilation");
2033 args.add("--categories=all");
2034 }
2035 }
2036 if ((compiler == "dart2js") && (configuration["minified"] as bool)) {
2037 args.add("--minify");
2038 }
2039 if (compiler == "dart2js" && (configuration["csp"] as bool)) {
2040 args.add("--csp");
2041 }
2042 if (compiler == "dart2js" && (configuration["cps_ir"] as bool)) {
2043 args.add("--use-cps-ir");
2044 }
2045 if (compiler == "dart2js" && (configuration["fast_startup"] as bool)) {
2046 args.add("--fast-startup");
2047 }
2048 if (compiler == "dart2js" &&
2049 (configuration["dart2js_with_kernel"] as bool)) {
2050 args.add("--use-kernel");
2051 }
2052 return args;
2053 }
2054
2055 static bool isBrowserRuntime(String runtime) {
2056 const BROWSERS = const [
2057 'drt',
2058 'dartium',
2059 'ie9',
2060 'ie10',
2061 'ie11',
2062 'safari',
2063 'opera',
2064 'chrome',
2065 'ff',
2066 'chromeOnAndroid',
2067 'safarimobilesim',
2068 'ContentShellOnAndroid',
2069 'DartiumOnAndroid'
2070 ];
2071 return BROWSERS.contains(runtime);
2072 }
2073
2074 static bool isJsCommandLineRuntime(String runtime) =>
2075 const ['d8', 'jsshell'].contains(runtime);
2076
2077 static bool isCommandLineAnalyzer(String compiler) =>
2078 compiler == 'dart2analyzer';
2079
2080 static String buildDir(Map configuration) {
2081 // FIXME(kustermann,ricow): Our code assumes that the returned 'buildDir'
2082 // is relative to the current working directory.
2083 // Thus, if we pass in an absolute path (e.g. '--build-directory=/tmp/out')
2084 // we get into trouble.
2085 if (configuration['build_directory'] == '') {
2086 configuration['configuration_directory'] =
2087 configurationDir(configuration);
2088 configuration['build_directory'] = outputDir(configuration) +
2089 (configuration['configuration_directory'] as String);
2090 }
2091 return configuration['build_directory'] as String;
2092 }
2093
2094 static String configurationDir(Map configuration) {
2095 // This returns the correct configuration directory (the last component
2096 // of the output directory path) for regular dart checkouts.
2097 // Dartium checkouts use the --build-directory option to pass in the
2098 // correct build directory explicitly.
2099 // We allow our code to have been cross compiled, i.e., that there
2100 // is an X in front of the arch. We don't allow both a cross compiled
2101 // and a normal version to be present (except if you specifically pass
2102 // in the build_directory).
2103 String mode;
2104 switch (configuration['mode'] as String) {
2105 case 'debug':
2106 mode = 'Debug';
2107 break;
2108 case 'release':
2109 mode = 'Release';
2110 break;
2111 case 'product':
2112 mode = 'Product';
2113 break;
2114 default:
2115 throw 'Unrecognized mode configuration: ${configuration['mode']}';
2116 }
2117 String os;
2118 switch (configuration['system'] as String) {
2119 case 'android':
2120 os = 'Android';
2121 break;
2122 case 'fuchsia':
2123 case 'linux':
2124 case 'macos':
2125 case 'windows':
2126 os = '';
2127 break;
2128 default:
2129 throw 'Unrecognized operating system: ${configuration['system']}';
2130 }
2131 var arch = (configuration['arch'] as String).toUpperCase();
2132 var normal = '$mode$os$arch';
2133 var cross = '$mode${os}X$arch';
2134 var outDir = outputDir(configuration);
2135 var normalDir = new Directory(new Path('$outDir$normal').toNativePath());
2136 var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
2137 if (normalDir.existsSync() && crossDir.existsSync()) {
2138 throw "You can't have both $normalDir and $crossDir, we don't know which"
2139 " binary to use";
2140 }
2141 if (crossDir.existsSync()) {
2142 return cross;
2143 }
2144 return normal;
2145 }
2146
2147 /**
2148 * Gets extra options under [key] passed to the testing script.
2149 */
2150 static List<String> getExtraOptions(Map configuration, String key) {
2151 if (configuration[key] == null) return <String>[];
2152 return (configuration[key] as String)
2153 .split(" ")
2154 .map((s) => s.trim())
2155 .where((s) => s.isNotEmpty)
2156 .toList();
2157 }
2158
2159 /**
2160 * Gets extra vm options passed to the testing script.
2161 */
2162 static List<String> getExtraVmOptions(Map configuration) =>
2163 getExtraOptions(configuration, 'vm_options');
2164
2165 static int shortNameCounter = 0; // Make unique short file names on Windows. 1997 static int shortNameCounter = 0; // Make unique short file names on Windows.
2166 1998
2167 static String getShortName(String path) { 1999 static String getShortName(String path) {
2168 final PATH_REPLACEMENTS = const { 2000 final PATH_REPLACEMENTS = const {
2169 "pkg_polymer_e2e_test_bad_import_test": "polymer_bi", 2001 "pkg_polymer_e2e_test_bad_import_test": "polymer_bi",
2170 "pkg_polymer_e2e_test_canonicalization_test": "polymer_c16n", 2002 "pkg_polymer_e2e_test_canonicalization_test": "polymer_c16n",
2171 "pkg_polymer_e2e_test_experimental_boot_test": "polymer_boot", 2003 "pkg_polymer_e2e_test_experimental_boot_test": "polymer_boot",
2172 "pkg_polymer_e2e_test_good_import_test": "polymer_gi", 2004 "pkg_polymer_e2e_test_good_import_test": "polymer_gi",
2173 "tests_co19_src_Language_12_Expressions_14_Function_Invocation_": 2005 "tests_co19_src_Language_12_Expressions_14_Function_Invocation_":
2174 "co19_fn_invoke_", 2006 "co19_fn_invoke_",
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2238 } 2070 }
2239 if (path.length > WINDOWS_SHORTEN_PATH_LIMIT) { 2071 if (path.length > WINDOWS_SHORTEN_PATH_LIMIT) {
2240 ++shortNameCounter; 2072 ++shortNameCounter;
2241 var pathEnd = path.substring(path.length - WINDOWS_PATH_END_LENGTH); 2073 var pathEnd = path.substring(path.length - WINDOWS_PATH_END_LENGTH);
2242 path = "short${shortNameCounter}_$pathEnd"; 2074 path = "short${shortNameCounter}_$pathEnd";
2243 } 2075 }
2244 } 2076 }
2245 return path; 2077 return path;
2246 } 2078 }
2247 } 2079 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698