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

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

Issue 11275217: Refactor test.dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: "waitForDartium" -> "updateDartium". Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/testing/dart/test_options.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Classes and methods for enumerating and preparing tests. 6 * Classes and methods for enumerating and preparing tests.
7 * 7 *
8 * This library includes: 8 * This library includes:
9 * 9 *
10 * - Creating tests by listing all the Dart files in certain directories, 10 * - Creating tests by listing all the Dart files in certain directories,
(...skipping 22 matching lines...) Expand all
33 typedef void CreateTest(Path filePath, 33 typedef void CreateTest(Path filePath,
34 bool hasCompileError, 34 bool hasCompileError,
35 bool hasRuntimeError, 35 bool hasRuntimeError,
36 {bool isNegativeIfChecked, 36 {bool isNegativeIfChecked,
37 bool hasFatalTypeErrors, 37 bool hasFatalTypeErrors,
38 Set<String> multitestOutcome}); 38 Set<String> multitestOutcome});
39 39
40 typedef void VoidFunction(); 40 typedef void VoidFunction();
41 41
42 /** 42 /**
43 * Calls [function] asynchronously. Returns a future that completes with the
44 * result of the function. If the function is `null`, returns a future that
45 * completes immediately with `null`.
46 */
47 Future asynchronously(function()) {
48 if (function == null) return new Future.immediate(null);
49
50 var completer = new Completer();
51 new Timer(0, (_) {
52 completer.complete(function());
53 });
54
55 return completer.future;
56 }
57
58 /** A completer that waits until all added [Future]s complete. */
59 // TODO(rnystrom): Copied from web_components. Remove from here when it gets
60 // added to dart:core. (See #6626.)
61 class FutureGroup {
62 const _FINISHED = -1;
63 int _pending = 0;
64 Completer<List> _completer = new Completer<List>();
65 final List<Future> futures = <Future>[];
66
67 /**
68 * Wait for [task] to complete (assuming this barrier has not already been
69 * marked as completed, otherwise you'll get an exception indicating that a
70 * future has already been completed).
71 */
72 void add(Future task) {
73 if (_pending == _FINISHED) {
74 throw new FutureAlreadyCompleteException();
75 }
76 _pending++;
77 futures.add(task);
78 task.handleException(
79 (e) => _completer.completeException(e, task.stackTrace));
80 task.then((_) {
81 _pending--;
82 if (_pending == 0) {
83 _pending = _FINISHED;
84 _completer.complete(futures);
85 }
86 });
87 }
88
89 Future<List> get future => _completer.future;
90 }
91
92 /**
43 * A TestSuite represents a collection of tests. It creates a [TestCase] 93 * A TestSuite represents a collection of tests. It creates a [TestCase]
44 * object for each test to be run, and passes the test cases to a callback. 94 * object for each test to be run, and passes the test cases to a callback.
45 * 95 *
46 * Most TestSuites represent a directory or directory tree containing tests, 96 * Most TestSuites represent a directory or directory tree containing tests,
47 * and a status file containing the expected results when these tests are run. 97 * and a status file containing the expected results when these tests are run.
48 */ 98 */
49 abstract class TestSuite { 99 abstract class TestSuite {
100 final Map configuration;
101 final String suiteName;
102
103 TestSuite(this.configuration, this.suiteName);
104
105 /**
106 * The output directory for this suite's configuration.
107 */
108 String get buildDir {
109 var mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
110 var arch = configuration['arch'].toUpperCase();
111 return "${TestUtils.outputDir(configuration)}$mode$arch";
112 }
113
114 /**
115 * The path to the compiler for this suite's configuration. Returns `null` if
116 * no compiler should be used.
117 */
118 String get compilerPath {
119 if (configuration['compiler'] == 'none') {
120 return null; // No separate compiler for dartium tests.
121 }
122 var name = '$buildDir/${compilerName}';
123 if (!(new File(name)).existsSync() && !configuration['list']) {
124 throw "Executable '$name' does not exist";
125 }
126 return name;
127 }
128
129 /**
130 * The name of the compiler for this suite's configuration. Throws an error
131 * if the configuration does not use a compiler.
132 */
133 String get compilerName {
134 switch (configuration['compiler']) {
135 case 'dartc':
136 case 'dart2js':
137 case 'dart2dart':
138 return executableName;
139 default:
140 throw "Unknown compiler for: ${configuration['compiler']}";
141 }
142 }
143
144 /**
145 * The file name of the executable used to run this suite's tests.
146 */
147 String get executableName {
148 String suffix = getExecutableSuffix(configuration['compiler']);
149 switch (configuration['compiler']) {
150 case 'none':
151 return 'dart$suffix';
152 case 'dartc':
153 return 'analyzer/bin/dart_analyzer$suffix';
154 case 'dart2js':
155 case 'dart2dart':
156 var prefix = '';
157 if (configuration['use_sdk']) {
158 prefix = 'dart-sdk/bin/';
159 }
160 if (configuration['host_checked']) {
161 // The script dart2js_developer is not in the SDK.
162 return 'dart2js_developer$suffix';
163 } else {
164 return '${prefix}dart2js$suffix';
165 }
166 break;
167 default:
168 throw "Unknown executable for: ${configuration['compiler']}";
169 }
170 }
171
172 /**
173 * The file name of the d8 executable.
174 */
175 String get d8FileName {
176 var suffix = getExecutableSuffix('d8');
177 var d8 = '$buildDir/d8$suffix';
178 TestUtils.ensureExists(d8, configuration);
179 return d8;
180 }
181
182 String get dartShellFileName {
183 var name = configuration['dart'];
184 if (name == '') {
185 name = '$buildDir/$executableName';
186 }
187 TestUtils.ensureExists(name, configuration);
188 return name;
189 }
190
191 String get jsShellFileName {
192 var executableSuffix = getExecutableSuffix('jsshell');
193 var executable = 'jsshell$executableSuffix';
194 var jsshellDir = '${TestUtils.dartDir()}/tools/testing/bin';
195 return '$jsshellDir/$executable';
196 }
197
198 /**
199 * The file name of the Dart VM executable.
200 */
201 String get vmFileName {
202 var suffix = getExecutableSuffix('vm');
203 var vm = '$buildDir/dart$suffix';
204 TestUtils.ensureExists(vm, configuration);
205 return vm;
206 }
207
208 /**
209 * The file extension (if any) that should be added to the given executable
210 * name for the current platform.
211 */
212 String getExecutableSuffix(String executable) {
213 if (Platform.operatingSystem == 'windows') {
214 if (executable == 'd8' || executable == 'vm' || executable == 'none') {
215 return '.exe';
216 } else {
217 return '.bat';
218 }
219 }
220 return '';
221 }
222
50 /** 223 /**
51 * Call the callback function onTest with a [TestCase] argument for each 224 * Call the callback function onTest with a [TestCase] argument for each
52 * test in the suite. When all tests have been processed, call [onDone]. 225 * test in the suite. When all tests have been processed, call [onDone].
53 * 226 *
54 * The [testCache] argument provides a persistent store that can be used to 227 * The [testCache] argument provides a persistent store that can be used to
55 * cache information about the test suite, so that directories do not need 228 * cache information about the test suite, so that directories do not need
56 * to be listed each time. 229 * to be listed each time.
57 */ 230 */
58 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]); 231 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]);
59 } 232 }
60 233
61 234
62 // TODO(1030): remove once in the corelib.
63 bool Contains(element, collection) => collection.indexOf(element) >= 0;
64
65
66 void ccTestLister() { 235 void ccTestLister() {
67 port.receive((String runnerPath, SendPort replyTo) { 236 port.receive((String runnerPath, SendPort replyTo) {
68 Future processFuture = Process.start(runnerPath, ["--list"]); 237 Future processFuture = Process.start(runnerPath, ["--list"]);
69 processFuture.then((p) { 238 processFuture.then((p) {
70 // Drain stderr to not leak resources. 239 // Drain stderr to not leak resources.
71 p.stderr.onData = p.stderr.read; 240 p.stderr.onData = p.stderr.read;
72 StringInputStream stdoutStream = new StringInputStream(p.stdout); 241 StringInputStream stdoutStream = new StringInputStream(p.stdout);
73 var streamDone = false; 242 var streamDone = false;
74 var processExited = false; 243 var processExited = false;
75 checkDone() { 244 checkDone() {
(...skipping 30 matching lines...) Expand all
106 275
107 276
108 /** 277 /**
109 * A specialized [TestSuite] that runs tests written in C to unit test 278 * A specialized [TestSuite] that runs tests written in C to unit test
110 * the Dart virtual machine and its API. 279 * the Dart virtual machine and its API.
111 * 280 *
112 * The tests are compiled into a monolithic executable by the build step. 281 * The tests are compiled into a monolithic executable by the build step.
113 * The executable lists its tests when run with the --list command line flag. 282 * The executable lists its tests when run with the --list command line flag.
114 * Individual tests are run by specifying them on the command line. 283 * Individual tests are run by specifying them on the command line.
115 */ 284 */
116 class CCTestSuite implements TestSuite { 285 class CCTestSuite extends TestSuite {
117 Map configuration;
118 final String suiteName;
119 final String testPrefix; 286 final String testPrefix;
120 String runnerPath; 287 String runnerPath;
121 final String dartDir; 288 final String dartDir;
122 List<String> statusFilePaths; 289 List<String> statusFilePaths;
123 TestCaseEvent doTest; 290 TestCaseEvent doTest;
124 VoidFunction doDone; 291 VoidFunction doDone;
125 ReceivePort receiveTestName; 292 ReceivePort receiveTestName;
126 TestExpectations testExpectations; 293 TestExpectations testExpectations;
127 294
128 CCTestSuite(Map this.configuration, 295 CCTestSuite(Map configuration,
129 String this.suiteName, 296 String suiteName,
130 String runnerName, 297 String runnerName,
131 List<String> this.statusFilePaths, 298 List<String> this.statusFilePaths,
132 {this.testPrefix: ''}) 299 {this.testPrefix: ''})
133 : dartDir = TestUtils.dartDir().toNativePath() { 300 : super(configuration, suiteName),
134 runnerPath = '${TestUtils.buildDir(configuration)}/$runnerName'; 301 dartDir = TestUtils.dartDir().toNativePath() {
302 runnerPath = '$buildDir/$runnerName';
135 } 303 }
136 304
137 void testNameHandler(String testName, ignore) { 305 void testNameHandler(String testName, ignore) {
138 if (testName == "") { 306 if (testName == "") {
139 receiveTestName.close(); 307 receiveTestName.close();
140 doDone(); 308
309 if (doDone != null) doDone();
141 } else { 310 } else {
142 // Only run the tests that match the pattern. Use the name 311 // Only run the tests that match the pattern. Use the name
143 // "suiteName/testName" for cc tests. 312 // "suiteName/testName" for cc tests.
144 RegExp pattern = configuration['selectors'][suiteName]; 313 RegExp pattern = configuration['selectors'][suiteName];
145 String constructedName = '$suiteName/$testPrefix$testName'; 314 String constructedName = '$suiteName/$testPrefix$testName';
146 if (!pattern.hasMatch(constructedName)) return; 315 if (!pattern.hasMatch(constructedName)) return;
147 316
148 var expectations = testExpectations.expectations( 317 var expectations = testExpectations.expectations(
149 '$testPrefix$testName'); 318 '$testPrefix$testName');
150 319
151 if (configuration["report"]) { 320 if (configuration["report"]) {
152 SummaryReport.add(expectations); 321 SummaryReport.add(expectations);
153 } 322 }
154 323
155 if (expectations.contains(SKIP)) return; 324 if (expectations.contains(SKIP)) return;
156 325
157 var args = TestUtils.standardOptions(configuration); 326 var args = TestUtils.standardOptions(configuration);
158 args.add(testName); 327 args.add(testName);
159 328
160 doTest(new TestCase(constructedName, 329 doTest(new TestCase(constructedName,
161 [new Command(runnerPath, args)], 330 [new Command(runnerPath, args)],
162 configuration, 331 configuration,
163 completeHandler, 332 completeHandler,
164 expectations)); 333 expectations));
165 } 334 }
166 } 335 }
167 336
168 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) { 337 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) {
169 doTest = onTest; 338 doTest = onTest;
170 doDone = () => (onDone != null) ? onDone() : null; 339 doDone = onDone;
171 340
172 var filesRead = 0; 341 var filesRead = 0;
173 void statusFileRead() { 342 void statusFileRead() {
174 filesRead++; 343 filesRead++;
175 if (filesRead == statusFilePaths.length) { 344 if (filesRead == statusFilePaths.length) {
176 receiveTestName = new ReceivePort(); 345 receiveTestName = new ReceivePort();
177 var port = spawnFunction(ccTestLister); 346 var port = spawnFunction(ccTestLister);
178 port.send(runnerPath, receiveTestName.toSendPort()); 347 port.send(runnerPath, receiveTestName.toSendPort());
179 receiveTestName.receive(testNameHandler); 348 receiveTestName.receive(testNameHandler);
180 } 349 }
(...skipping 23 matching lines...) Expand all
204 Set<String> multitestOutcome; 373 Set<String> multitestOutcome;
205 374
206 TestInformation(this.filePath, this.optionsFromFile, 375 TestInformation(this.filePath, this.optionsFromFile,
207 this.hasCompileError, this.hasRuntimeError, 376 this.hasCompileError, this.hasRuntimeError,
208 this.isNegativeIfChecked, this.hasFatalTypeErrors, 377 this.isNegativeIfChecked, this.hasFatalTypeErrors,
209 this.multitestOutcome) { 378 this.multitestOutcome) {
210 Expect.isTrue(filePath.isAbsolute); 379 Expect.isTrue(filePath.isAbsolute);
211 } 380 }
212 } 381 }
213 382
214
215 /** 383 /**
216 * A standard [TestSuite] implementation that searches for tests in a 384 * A standard [TestSuite] implementation that searches for tests in a
217 * directory, and creates [TestCase]s that compile and/or run them. 385 * directory, and creates [TestCase]s that compile and/or run them.
218 */ 386 */
219 class StandardTestSuite implements TestSuite { 387 class StandardTestSuite extends TestSuite {
220 Map configuration; 388 final Path suiteDir;
221 String suiteName; 389 final List<String> statusFilePaths;
222 Path suiteDir;
223 List<String> statusFilePaths;
224 TestCaseEvent doTest; 390 TestCaseEvent doTest;
225 VoidFunction doDone;
226 int activeTestGenerators = 0;
227 bool listingDone = false;
228 TestExpectations testExpectations; 391 TestExpectations testExpectations;
229 List<TestInformation> cachedTests; 392 List<TestInformation> cachedTests;
230 final Path dartDir; 393 final Path dartDir;
231 Predicate<String> isTestFilePredicate; 394 Predicate<String> isTestFilePredicate;
232 bool _listRecursive; 395 final bool listRecursively;
233 396
234 StandardTestSuite(this.configuration, 397 StandardTestSuite(Map configuration,
235 this.suiteName, 398 String suiteName,
236 Path suiteDirectory, 399 Path suiteDirectory,
237 this.statusFilePaths, 400 this.statusFilePaths,
238 {this.isTestFilePredicate, 401 {this.isTestFilePredicate,
239 bool recursive: false}) 402 bool recursive: false})
240 : dartDir = TestUtils.dartDir(), _listRecursive = recursive, 403 : super(configuration, suiteName),
404 dartDir = TestUtils.dartDir(),
405 listRecursively = recursive,
241 suiteDir = TestUtils.dartDir().join(suiteDirectory); 406 suiteDir = TestUtils.dartDir().join(suiteDirectory);
242 407
243 /** 408 /**
244 * Creates a test suite whose file organization matches an expected structure. 409 * Creates a test suite whose file organization matches an expected structure.
245 * To use this, your suite should look like: 410 * To use this, your suite should look like:
246 * 411 *
247 * dart/ 412 * dart/
248 * path/ 413 * path/
249 * to/ 414 * to/
250 * mytestsuite/ 415 * mytestsuite/
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 * The default implementation assumes a file is a test if 447 * The default implementation assumes a file is a test if
283 * it ends in "Test.dart". 448 * it ends in "Test.dart".
284 */ 449 */
285 bool isTestFile(String filename) { 450 bool isTestFile(String filename) {
286 // Use the specified predicate, if provided. 451 // Use the specified predicate, if provided.
287 if (isTestFilePredicate != null) return isTestFilePredicate(filename); 452 if (isTestFilePredicate != null) return isTestFilePredicate(filename);
288 453
289 return filename.endsWith("Test.dart"); 454 return filename.endsWith("Test.dart");
290 } 455 }
291 456
292 bool listRecursively() => _listRecursive;
293
294 String shellPath() => TestUtils.dartShellFileName(configuration);
295
296 List<String> additionalOptions(Path filePath) => []; 457 List<String> additionalOptions(Path filePath) => [];
297 458
298 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) { 459 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) {
299 // If DumpRenderTree/Dartium is required, and not yet updated, 460 updateDartium().chain((_) {
300 // wait for update. 461 doTest = onTest;
462
463 return readExpectations();
464 }).chain((expectations) {
465 testExpectations = expectations;
466
467 // Checked if we have already found and generated the tests for
468 // this suite.
469 if (!testCache.containsKey(suiteName)) {
470 cachedTests = testCache[suiteName] = [];
471 return enqueueTests();
472 } else {
473 // We rely on enqueueing completing asynchronously.
474 return asynchronously(() {
475 for (var info in testCache[suiteName]) {
476 enqueueTestCaseFromTestInformation(info);
477 }
478 });
479 }
480 }).then((_) {
481 if (onDone != null) onDone();
482 });
483 }
484
485 /**
486 * If DumpRenderTree/Dartium is required, and not yet updated, waits for
487 * the update then completes. Otherwise completes immediately.
488 */
489 Future updateDartium() {
490 var completer = new Completer();
301 var updater = runtimeUpdater(configuration); 491 var updater = runtimeUpdater(configuration);
302 if (updater !== null && !updater.updated) { 492 if (updater == null || updater.updated) {
303 Expect.isTrue(updater.isActive); 493 return new Future.immediate(null);
304 updater.onUpdated.add(() {
305 forEachTest(onTest, testCache, onDone);
306 });
307 return;
308 } 494 }
309 495
310 doTest = onTest; 496 Expect.isTrue(updater.isActive);
311 doDone = (onDone != null) ? onDone : (() => null); 497 updater.onUpdated.add(() => completer.complete(null));
498
499 return completer.future;
500 }
501
502 /**
503 * Reads the status files and completes with the parsed expectations.
504 */
505 Future<TestExpectations> readExpectations() {
506 var completer = new Completer();
507 var expectations = new TestExpectations();
312 508
313 var filesRead = 0; 509 var filesRead = 0;
314 void statusFileRead() { 510 void statusFileRead() {
315 filesRead++; 511 filesRead++;
316 if (filesRead == statusFilePaths.length) { 512 if (filesRead == statusFilePaths.length) {
317 // Checked if we have already found and generated the tests for 513 completer.complete(expectations);
318 // this suite.
319 if (!testCache.containsKey(suiteName)) {
320 cachedTests = testCache[suiteName] = [];
321 processDirectory();
322 } else {
323 // We rely on enqueueing completing asynchronously so use a
324 // timer to make it so.
325 void enqueueCachedTests(Timer ignore) {
326 for (var info in testCache[suiteName]) {
327 enqueueTestCaseFromTestInformation(info);
328 }
329 doDone();
330 }
331 new Timer(0, enqueueCachedTests);
332 }
333 } 514 }
334 } 515 }
335 516
336 // Read test expectations from status files.
337 testExpectations = new TestExpectations();
338 for (var statusFilePath in statusFilePaths) { 517 for (var statusFilePath in statusFilePaths) {
339 // [forDirectory] adds name_dart2js.status for all tests suites, use it if 518 // [forDirectory] adds name_dart2js.status for all tests suites. Use it
340 // it exists, but otherwise skip it and don't fail. 519 // if it exists, but otherwise skip it and don't fail.
341 if (statusFilePath.endsWith('_dart2js.status')) { 520 if (statusFilePath.endsWith('_dart2js.status')) {
342 File file = new File.fromPath(dartDir.append(statusFilePath)); 521 var file = new File.fromPath(dartDir.append(statusFilePath));
343 if (!file.existsSync()) { 522 if (!file.existsSync()) {
344 filesRead++; 523 filesRead++;
345 continue; 524 continue;
346 } 525 }
347 } 526 }
348 ReadTestExpectationsInto(testExpectations, 527
528 ReadTestExpectationsInto(expectations,
349 dartDir.append(statusFilePath).toNativePath(), 529 dartDir.append(statusFilePath).toNativePath(),
350 configuration, 530 configuration, statusFileRead);
351 statusFileRead);
352 } 531 }
532
533 return completer.future;
353 } 534 }
354 535
355 void processDirectory() { 536 Future enqueueTests() {
356 Directory dir = new Directory.fromPath(suiteDir); 537 Directory dir = new Directory.fromPath(suiteDir);
357 dir.exists().then((exists) { 538 return dir.exists().chain((exists) {
358 if (!exists) { 539 if (!exists) {
359 print('Directory containing tests not found: $suiteDir'); 540 print('Directory containing tests not found: $suiteDir');
360 directoryListingDone(false); 541 return new Future.immediate(null);
361 } else { 542 } else {
362 var lister = dir.list(recursive: listRecursively()); 543 var group = new FutureGroup();
363 lister.onFile = processFile; 544 enqueueDirectory(dir, group);
364 lister.onDone = directoryListingDone; 545 return group.future;
365 } 546 }
366 }); 547 });
367 } 548 }
368 549
550 void enqueueDirectory(Directory dir, FutureGroup group) {
551 var listCompleter = new Completer();
552 group.add(listCompleter.future);
553
554 var lister = dir.list(recursive: listRecursively);
555 lister.onFile = (file) => enqueueFile(file, group);
556 lister.onDone = listCompleter.complete;
557 }
558
559 void enqueueFile(String filename, FutureGroup group) {
560 if (!isTestFile(filename)) return;
561 Path filePath = new Path.fromNative(filename);
562
563 // Only run the tests that match the pattern.
564 RegExp pattern = configuration['selectors'][suiteName];
565 if (!pattern.hasMatch('$filePath')) return;
566 if (filePath.filename.endsWith('test_config.dart')) return;
567
568 var optionsFromFile = readOptionsFromFile(filePath);
569 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
570
571 if (optionsFromFile['isMultitest']) {
572 group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase));
573 } else {
574 createTestCase(filePath,
575 optionsFromFile['hasCompileError'],
576 optionsFromFile['hasRuntimeError']);
577 }
578 }
579
369 void enqueueTestCaseFromTestInformation(TestInformation info) { 580 void enqueueTestCaseFromTestInformation(TestInformation info) {
370 var filePath = info.filePath; 581 var filePath = info.filePath;
371 var optionsFromFile = info.optionsFromFile; 582 var optionsFromFile = info.optionsFromFile;
372 var isNegative = info.hasCompileError; 583 var isNegative = info.hasCompileError;
373 if (info.hasRuntimeError && hasRuntime) { 584 if (info.hasRuntimeError && hasRuntime) {
374 isNegative = true; 585 isNegative = true;
375 } 586 }
376 587
377 // Look up expectations in status files using a test name generated 588 // Look up expectations in status files using a test name generated
378 // from the test file's path. 589 // from the test file's path.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 info: info)); 691 info: info));
481 } 692 }
482 } 693 }
483 694
484 List<Command> makeCommands(TestInformation info, var vmOptions, var args) { 695 List<Command> makeCommands(TestInformation info, var vmOptions, var args) {
485 switch (configuration['compiler']) { 696 switch (configuration['compiler']) {
486 case 'dart2js': 697 case 'dart2js':
487 args = new List.from(args); 698 args = new List.from(args);
488 String tempDir = createOutputDirectory(info.filePath, ''); 699 String tempDir = createOutputDirectory(info.filePath, '');
489 args.add('--out=$tempDir/out.js'); 700 args.add('--out=$tempDir/out.js');
490 List<Command> commands = <Command>[new Command(shellPath(), args)]; 701 List<Command> commands = <Command>[new Command(dartShellFileName, args)];
491 if (info.hasCompileError) { 702 if (info.hasCompileError) {
492 // Do not attempt to run the compiled result. A compilation 703 // Do not attempt to run the compiled result. A compilation
493 // error should be reported by the compilation command. 704 // error should be reported by the compilation command.
494 } else if (configuration['runtime'] == 'd8') { 705 } else if (configuration['runtime'] == 'd8') {
495 var d8 = TestUtils.d8FileName(configuration); 706 commands.add(new Command(d8FileName, ['$tempDir/out.js']));
496 commands.add(new Command(d8, ['$tempDir/out.js']));
497 } else if (configuration['runtime'] == 'jsshell') { 707 } else if (configuration['runtime'] == 'jsshell') {
498 var jsshell = TestUtils.jsshellFileName(configuration); 708 commands.add(new Command(jsShellFileName, ['$tempDir/out.js']));
499 commands.add(new Command(jsshell, ['$tempDir/out.js']));
500 } 709 }
501 return commands; 710 return commands;
502 711
503 case 'dart2dart': 712 case 'dart2dart':
504 var compilerArguments = new List.from(args); 713 var compilerArguments = new List.from(args);
505 var additionalFlags = 714 var additionalFlags =
506 configuration['additional-compiler-flags'].split(' '); 715 configuration['additional-compiler-flags'].split(' ');
507 for (final flag in additionalFlags) { 716 for (final flag in additionalFlags) {
508 if (flag.isEmpty) continue; 717 if (flag.isEmpty) continue;
509 compilerArguments.add(flag); 718 compilerArguments.add(flag);
510 } 719 }
511 compilerArguments.add('--output-type=dart'); 720 compilerArguments.add('--output-type=dart');
512 String tempDir = createOutputDirectory(info.filePath, ''); 721 String tempDir = createOutputDirectory(info.filePath, '');
513 compilerArguments.add('--out=$tempDir/out.dart'); 722 compilerArguments.add('--out=$tempDir/out.dart');
514 List<Command> commands = 723 List<Command> commands =
515 <Command>[new Command(shellPath(), compilerArguments)]; 724 <Command>[new Command(dartShellFileName, compilerArguments)];
516 if (info.hasCompileError) { 725 if (info.hasCompileError) {
517 // Do not attempt to run the compiled result. A compilation 726 // Do not attempt to run the compiled result. A compilation
518 // error should be reported by the compilation command. 727 // error should be reported by the compilation command.
519 } else if (configuration['runtime'] == 'vm') { 728 } else if (configuration['runtime'] == 'vm') {
520 // TODO(antonm): support checked. 729 // TODO(antonm): support checked.
521 var vmArguments = new List.from(vmOptions); 730 var vmArguments = new List.from(vmOptions);
522 vmArguments.addAll([ 731 vmArguments.addAll([
523 '--ignore-unrecognized-flags', '$tempDir/out.dart']); 732 '--ignore-unrecognized-flags', '$tempDir/out.dart']);
524 commands.add(new Command( 733 commands.add(new Command(vmFileName, vmArguments));
525 TestUtils.vmFileName(configuration),
526 vmArguments));
527 } else { 734 } else {
528 throw 'Unsupported runtime ${configuration["runtime"]} for dart2dart'; 735 throw 'Unsupported runtime ${configuration["runtime"]} for dart2dart';
529 } 736 }
530 return commands; 737 return commands;
531 738
532 case 'none': 739 case 'none':
533 case 'dartc': 740 case 'dartc':
534 var arguments = new List.from(vmOptions); 741 var arguments = new List.from(vmOptions);
535 arguments.addAll(args); 742 arguments.addAll(args);
536 return <Command>[new Command(shellPath(), arguments)]; 743 return <Command>[new Command(dartShellFileName, arguments)];
537 744
538 default: 745 default:
539 throw 'Unknown compiler ${configuration["compiler"]}'; 746 throw 'Unknown compiler ${configuration["compiler"]}';
540 } 747 }
541 } 748 }
542 749
543 CreateTest makeTestCaseCreator(Map optionsFromFile) { 750 CreateTest makeTestCaseCreator(Map optionsFromFile) {
544 return (Path filePath, 751 return (Path filePath,
545 bool hasCompileError, 752 bool hasCompileError,
546 bool hasRuntimeError, 753 bool hasRuntimeError,
547 {bool isNegativeIfChecked: false, 754 {bool isNegativeIfChecked: false,
548 bool hasFatalTypeErrors: false, 755 bool hasFatalTypeErrors: false,
549 Set<String> multitestOutcome: null}) { 756 Set<String> multitestOutcome: null}) {
550 // Cache the test information for each test case. 757 // Cache the test information for each test case.
551 var info = new TestInformation(filePath, 758 var info = new TestInformation(filePath,
552 optionsFromFile, 759 optionsFromFile,
553 hasCompileError, 760 hasCompileError,
554 hasRuntimeError, 761 hasRuntimeError,
555 isNegativeIfChecked, 762 isNegativeIfChecked,
556 hasFatalTypeErrors, 763 hasFatalTypeErrors,
557 multitestOutcome); 764 multitestOutcome);
558 cachedTests.add(info); 765 cachedTests.add(info);
559 enqueueTestCaseFromTestInformation(info); 766 enqueueTestCaseFromTestInformation(info);
560 }; 767 };
561 } 768 }
562 769
563 void processFile(String filename) {
564 if (!isTestFile(filename)) return;
565 Path filePath = new Path.fromNative(filename);
566
567 // Only run the tests that match the pattern.
568 RegExp pattern = configuration['selectors'][suiteName];
569 if (!pattern.hasMatch('$filePath')) return;
570 if (filePath.filename.endsWith('test_config.dart')) return;
571
572 var optionsFromFile = readOptionsFromFile(filePath);
573 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
574
575 if (optionsFromFile['isMultitest']) {
576 testGeneratorStarted();
577 DoMultitest(filePath,
578 TestUtils.buildDir(configuration),
579 suiteDir,
580 createTestCase,
581 testGeneratorDone);
582 } else {
583 createTestCase(filePath,
584 optionsFromFile['hasCompileError'],
585 optionsFromFile['hasRuntimeError']);
586 }
587 }
588
589 /** 770 /**
590 * The [StandardTestSuite] has support for tests that 771 * The [StandardTestSuite] has support for tests that
591 * compile a test from Dart to JavaScript, and then run the resulting 772 * compile a test from Dart to JavaScript, and then run the resulting
592 * JavaScript. This function creates a working directory to hold the 773 * JavaScript. This function creates a working directory to hold the
593 * JavaScript version of the test, and copies the appropriate framework 774 * JavaScript version of the test, and copies the appropriate framework
594 * files to that directory. It creates a [BrowserTestCase], which has 775 * files to that directory. It creates a [BrowserTestCase], which has
595 * two sequential steps to be run by the [ProcessQueue] when the test is 776 * two sequential steps to be run by the [ProcessQueue] when the test is
596 * executed: a compilation step and an execution step, both with the 777 * executed: a compilation step and an execution step, both with the
597 * appropriate executable and arguments. The [expectations] object can be 778 * appropriate executable and arguments. The [expectations] object can be
598 * either a Set<String> if the test is a regular test, or a Map<String 779 * either a Set<String> if the test is a regular test, or a Map<String
599 * subTestName, Set<String>> if we are running a browser multi-test (one 780 * subTestName, Set<String>> if we are running a browser multi-test (one
600 * compilation and many browser runs). 781 * compilation and many browser runs).
601 */ 782 */
602 void enqueueBrowserTest(TestInformation info, 783 void enqueueBrowserTest(TestInformation info,
603 String testName, 784 String testName,
604 Object expectations, 785 Object expectations,
605 bool isWrappingRequired) { 786 bool isWrappingRequired) {
606 Map optionsFromFile = info.optionsFromFile; 787 Map optionsFromFile = info.optionsFromFile;
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 } 975 }
795 doTest(testCase); 976 doTest(testCase);
796 subtestIndex++; 977 subtestIndex++;
797 } while(subtestIndex < subtestNames.length); 978 } while(subtestIndex < subtestNames.length);
798 } 979 }
799 } 980 }
800 981
801 /** Helper to create a compilation command for a single input file. */ 982 /** Helper to create a compilation command for a single input file. */
802 Command _compileCommand(String inputFile, String outputFile, 983 Command _compileCommand(String inputFile, String outputFile,
803 String compiler, String dir, var vmOptions) { 984 String compiler, String dir, var vmOptions) {
804 String executable = TestUtils.compilerPath(configuration); 985 String executable = compilerPath;
805 List<String> args = TestUtils.standardOptions(configuration); 986 List<String> args = TestUtils.standardOptions(configuration);
806 switch (compiler) { 987 switch (compiler) {
807 case 'dart2js': 988 case 'dart2js':
808 case 'dart2dart': 989 case 'dart2dart':
809 if (compiler == 'dart2dart') args.add('--out=$outputFile'); 990 if (compiler == 'dart2dart') args.add('--out=$outputFile');
810 args.add('--out=$outputFile'); 991 args.add('--out=$outputFile');
811 args.add(inputFile); 992 args.add(inputFile);
812 break; 993 break;
813 default: 994 default:
814 Expect.fail('unimplemented compiler $compiler'); 995 Expect.fail('unimplemented compiler $compiler');
815 } 996 }
816 if (executable.endsWith('.dart')) { 997 if (executable.endsWith('.dart')) {
817 // Run the compiler script via the Dart VM. 998 // Run the compiler script via the Dart VM.
818 args.insertRange(0, 1, executable); 999 args.insertRange(0, 1, executable);
819 executable = TestUtils.dartShellFileName(configuration); 1000 executable = dartShellFileName;
820 } 1001 }
821 return new Command(executable, args); 1002 return new Command(executable, args);
822 } 1003 }
823 1004
824 /** 1005 /**
825 * Create a directory for the generated test. If a Dart language test 1006 * Create a directory for the generated test. If a Dart language test
826 * needs to be run in a browser, the Dart test needs to be embedded in 1007 * needs to be run in a browser, the Dart test needs to be embedded in
827 * an HTML page, with a testing framework based on scripting and DOM events. 1008 * an HTML page, with a testing framework based on scripting and DOM events.
828 * These scripts and pages are written to a generated_test directory 1009 * These scripts and pages are written to a generated_test directory
829 * inside the build directory of the checkout. 1010 * inside the build directory of the checkout.
830 * 1011 *
831 * Those tests which are already HTML web applications (web tests), with 1012 * Those tests which are already HTML web applications (web tests), with
832 * resources including CSS files and HTML files, need to be compiled into 1013 * resources including CSS files and HTML files, need to be compiled into
833 * a work directory where the relative URLS to the resources work. 1014 * a work directory where the relative URLS to the resources work.
834 * We use a subdirectory of the build directory that is the same number 1015 * We use a subdirectory of the build directory that is the same number
835 * of levels down in the checkout as the original path of the web test. 1016 * of levels down in the checkout as the original path of the web test.
836 */ 1017 */
837 String createOutputDirectory(Path testPath, String optionsName) { 1018 String createOutputDirectory(Path testPath, String optionsName) {
838 Path relative = testPath.relativeTo(TestUtils.dartDir()); 1019 Path relative = testPath.relativeTo(TestUtils.dartDir());
839 relative = relative.directoryPath.append(relative.filenameWithoutExtension); 1020 relative = relative.directoryPath.append(relative.filenameWithoutExtension);
840 String testUniqueName = relative.toString().replaceAll('/', '_'); 1021 String testUniqueName = relative.toString().replaceAll('/', '_');
841 if (!optionsName.isEmpty) { 1022 if (!optionsName.isEmpty) {
842 testUniqueName = '$testUniqueName-$optionsName'; 1023 testUniqueName = '$testUniqueName-$optionsName';
843 } 1024 }
844 1025
845 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName', 1026 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName',
846 // including any intermediate directories that don't exist. 1027 // including any intermediate directories that don't exist.
847 var generatedTestPath = Strings.join( 1028 var generatedTestPath = Strings.join([
848 [TestUtils.buildDir(configuration), 1029 buildDir,
849 'generated_tests', 1030 'generated_tests',
850 "${configuration['compiler']}-${configuration['runtime']}", 1031 "${configuration['compiler']}-${configuration['runtime']}",
851 testUniqueName], '/'); 1032 testUniqueName
1033 ], '/');
852 1034
853 TestUtils.mkdirRecursive(new Path('.'), new Path(generatedTestPath)); 1035 TestUtils.mkdirRecursive(new Path('.'), new Path(generatedTestPath));
854 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/'); 1036 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/');
855 } 1037 }
856 1038
857 String get scriptType { 1039 String get scriptType {
858 switch (configuration['compiler']) { 1040 switch (configuration['compiler']) {
859 case 'none': 1041 case 'none':
860 case 'dart2dart': 1042 case 'dart2dart':
861 return 'application/dart'; 1043 return 'application/dart';
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 if (configuration['dartium'] != '') { 1084 if (configuration['dartium'] != '') {
903 return configuration['dartium']; 1085 return configuration['dartium'];
904 } 1086 }
905 if (Platform.operatingSystem == 'macos') { 1087 if (Platform.operatingSystem == 'macos') {
906 return dartDir.append('client/tests/dartium/Chromium.app/Contents/' 1088 return dartDir.append('client/tests/dartium/Chromium.app/Contents/'
907 'MacOS/Chromium').toNativePath(); 1089 'MacOS/Chromium').toNativePath();
908 } 1090 }
909 return dartDir.append('client/tests/dartium/chrome').toNativePath(); 1091 return dartDir.append('client/tests/dartium/chrome').toNativePath();
910 } 1092 }
911 1093
912 void testGeneratorStarted() {
913 ++activeTestGenerators;
914 }
915
916 void testGeneratorDone() {
917 --activeTestGenerators;
918 if (activeTestGenerators == 0 && listingDone) {
919 doDone();
920 }
921 }
922
923 void directoryListingDone(ignore) {
924 listingDone = true;
925 if (activeTestGenerators == 0) {
926 doDone();
927 }
928 }
929
930 void completeHandler(TestCase testCase) { 1094 void completeHandler(TestCase testCase) {
931 } 1095 }
932 1096
933 List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) { 1097 List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) {
934 List args = TestUtils.standardOptions(configuration); 1098 List args = TestUtils.standardOptions(configuration);
935 args.addAll(additionalOptions(filePath)); 1099 args.addAll(additionalOptions(filePath));
936 if (configuration['compiler'] == 'dartc') { 1100 if (configuration['compiler'] == 'dartc') {
937 args.add('--error_format'); 1101 args.add('--error_format');
938 args.add('machine'); 1102 args.add('machine');
939 } 1103 }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 "containsLeadingHash": containsLeadingHash, 1294 "containsLeadingHash": containsLeadingHash,
1131 "isolateStubs": isolateStubs, 1295 "isolateStubs": isolateStubs,
1132 "containsDomImport": containsDomImport, 1296 "containsDomImport": containsDomImport,
1133 "isLibraryDefinition": isLibraryDefinition, 1297 "isLibraryDefinition": isLibraryDefinition,
1134 "containsSourceOrImport": containsSourceOrImport, 1298 "containsSourceOrImport": containsSourceOrImport,
1135 "numStaticTypeAnnotations": numStaticTypeAnnotations, 1299 "numStaticTypeAnnotations": numStaticTypeAnnotations,
1136 "numCompileTimeAnnotations": numCompileTimeAnnotations }; 1300 "numCompileTimeAnnotations": numCompileTimeAnnotations };
1137 } 1301 }
1138 1302
1139 List<List<String>> getVmOptions(Map optionsFromFile) { 1303 List<List<String>> getVmOptions(Map optionsFromFile) {
1140 bool needsVmOptions = Contains(configuration['compiler'], 1304 var COMPILERS = const ['none', 'dart2dart', 'dartc'];
1141 const ['none', 'dart2dart', 'dartc']) && 1305 var RUNTIMES = const ['none', 'vm', 'drt', 'dartium'];
1142 Contains(configuration['runtime'], 1306 var needsVmOptions = COMPILERS.contains(configuration['compiler']) &&
1143 const ['none', 'vm', 'drt', 'dartium']); 1307 RUNTIMES.contains(configuration['runtime']);
1144 if (!needsVmOptions) return [[]]; 1308 if (!needsVmOptions) return [[]];
1145 return optionsFromFile['vmOptions']; 1309 return optionsFromFile['vmOptions'];
1146 } 1310 }
1147 } 1311 }
1148 1312
1149 1313
1150 class DartcCompilationTestSuite extends StandardTestSuite { 1314 class DartcCompilationTestSuite extends StandardTestSuite {
1151 List<String> _testDirs; 1315 List<String> _testDirs;
1152 int activityCount = 0;
1153 1316
1154 DartcCompilationTestSuite(Map configuration, 1317 DartcCompilationTestSuite(Map configuration,
1155 String suiteName, 1318 String suiteName,
1156 String directoryPath, 1319 String directoryPath,
1157 List<String> this._testDirs, 1320 List<String> this._testDirs,
1158 List<String> expectations) 1321 List<String> expectations)
1159 : super(configuration, 1322 : super(configuration,
1160 suiteName, 1323 suiteName,
1161 new Path.fromNative(directoryPath), 1324 new Path.fromNative(directoryPath),
1162 expectations); 1325 expectations);
1163 1326
1164 void activityStarted() { ++activityCount; }
1165
1166 void activityCompleted() {
1167 if (--activityCount == 0) {
1168 directoryListingDone(true);
1169 }
1170 }
1171
1172 String shellPath() => TestUtils.compilerPath(configuration);
1173
1174 List<String> additionalOptions(Path filePath) { 1327 List<String> additionalOptions(Path filePath) {
1175 return ['--fatal-warnings', '--fatal-type-errors']; 1328 return ['--fatal-warnings', '--fatal-type-errors'];
1176 } 1329 }
1177 1330
1178 void processDirectory() { 1331 Future enqueueTests() {
1179 // Enqueueing the directory listers is an activity. 1332 var group = new FutureGroup();
1180 activityStarted(); 1333
1181 for (String testDir in _testDirs) { 1334 for (String testDir in _testDirs) {
1182 Directory dir = new Directory.fromPath(suiteDir.append(testDir)); 1335 Directory dir = new Directory.fromPath(suiteDir.append(testDir));
1183 if (dir.existsSync()) { 1336 if (dir.existsSync()) {
1184 activityStarted(); 1337 enqueueDirectory(dir, group);
1185 var lister = dir.list(recursive: listRecursively());
1186 lister.onFile = processFile;
1187 lister.onDone = (ignore) => activityCompleted();
1188 } 1338 }
1189 } 1339 }
1190 // Completed the enqueueing of listers. 1340
1191 activityCompleted(); 1341 return group.future;
1192 } 1342 }
1193 } 1343 }
1194 1344
1195 1345
1196 class JUnitTestSuite implements TestSuite { 1346 class JUnitTestSuite extends TestSuite {
1197 Map configuration;
1198 String suiteName;
1199 String directoryPath; 1347 String directoryPath;
1200 String statusFilePath; 1348 String statusFilePath;
1201 final String dartDir; 1349 final String dartDir;
1202 String buildDir;
1203 String classPath; 1350 String classPath;
1204 List<String> testClasses; 1351 List<String> testClasses;
1205 TestCaseEvent doTest; 1352 TestCaseEvent doTest;
1206 VoidFunction doDone; 1353 VoidFunction doDone;
1207 TestExpectations testExpectations; 1354 TestExpectations testExpectations;
1208 1355
1209 JUnitTestSuite(Map this.configuration, 1356 JUnitTestSuite(Map configuration,
1210 String this.suiteName, 1357 String suiteName,
1211 String this.directoryPath, 1358 String this.directoryPath,
1212 String this.statusFilePath) 1359 String this.statusFilePath)
1213 : dartDir = TestUtils.dartDir().toNativePath(); 1360 : super(configuration, suiteName),
1361 dartDir = TestUtils.dartDir().toNativePath();
1214 1362
1215 bool isTestFile(String filename) => filename.endsWith("Tests.java") && 1363 bool isTestFile(String filename) => filename.endsWith("Tests.java") &&
1216 !filename.contains('com/google/dart/compiler/vm') && 1364 !filename.contains('com/google/dart/compiler/vm') &&
1217 !filename.contains('com/google/dart/corelib/SharedTests.java'); 1365 !filename.contains('com/google/dart/corelib/SharedTests.java');
1218 1366
1219 void forEachTest(TestCaseEvent onTest, 1367 void forEachTest(TestCaseEvent onTest,
1220 Map testCacheIgnored, 1368 Map testCacheIgnored,
1221 [VoidFunction onDone]) { 1369 [VoidFunction onDone]) {
1222 doTest = onTest; 1370 doTest = onTest;
1223 doDone = (onDone != null) ? onDone : (() => null); 1371 doDone = onDone;
1224 1372
1225 if (configuration['compiler'] != 'dartc') { 1373 if (configuration['compiler'] != 'dartc') {
1226 // Do nothing. Asynchronously report that the suite is enqueued. 1374 // Do nothing. Asynchronously report that the suite is enqueued.
1227 new Timer(0, (timerUnused){ doDone(); }); 1375 asynchronously(doDone);
1228 return; 1376 return;
1229 } 1377 }
1230 RegExp pattern = configuration['selectors']['dartc']; 1378 RegExp pattern = configuration['selectors']['dartc'];
1231 if (!pattern.hasMatch('junit_tests')) { 1379 if (!pattern.hasMatch('junit_tests')) {
1232 new Timer(0, (timerUnused){ doDone(); }); 1380 asynchronously(doDone);
1233 return; 1381 return;
1234 } 1382 }
1235 1383
1236 buildDir = TestUtils.buildDir(configuration);
1237 computeClassPath(); 1384 computeClassPath();
1238 testClasses = <String>[]; 1385 testClasses = <String>[];
1239 // Do not read the status file. 1386 // Do not read the status file.
1240 // All exclusions are hardcoded in this script, as they are in testcfg.py. 1387 // All exclusions are hardcoded in this script, as they are in testcfg.py.
1241 processDirectory(); 1388 processDirectory();
1242 } 1389 }
1243 1390
1244 void processDirectory() { 1391 void processDirectory() {
1245 directoryPath = '$dartDir/$directoryPath'; 1392 directoryPath = '$dartDir/$directoryPath';
1246 Directory dir = new Directory(directoryPath); 1393 Directory dir = new Directory(directoryPath);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 '$dartDir/third_party/rhino/1_7R3/js.jar', 1448 '$dartDir/third_party/rhino/1_7R3/js.jar',
1302 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar', 1449 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar',
1303 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar', 1450 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar',
1304 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar', 1451 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar',
1305 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar', 1452 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar',
1306 '$dartDir/third_party/junit/v4_8_2/junit.jar'], 1453 '$dartDir/third_party/junit/v4_8_2/junit.jar'],
1307 Platform.operatingSystem == 'windows'? ';': ':'); // Path separator. 1454 Platform.operatingSystem == 'windows'? ';': ':'); // Path separator.
1308 } 1455 }
1309 } 1456 }
1310 1457
1311
1312 class TestUtils { 1458 class TestUtils {
1313 /** 1459 /**
1314 * The libraries in this directory relies on finding various files 1460 * The libraries in this directory relies on finding various files
1315 * relative to the 'test.dart' script in '.../dart/tools/test.dart'. If 1461 * relative to the 'test.dart' script in '.../dart/tools/test.dart'. If
1316 * the main script using 'test_suite.dart' is not there, the main 1462 * the main script using 'test_suite.dart' is not there, the main
1317 * script must set this to '.../dart/tools/test.dart'. 1463 * script must set this to '.../dart/tools/test.dart'.
1318 */ 1464 */
1319 static String testScriptPath = new Options().script; 1465 static String testScriptPath = new Options().script;
1320 1466
1321 /** 1467 /**
(...skipping 21 matching lines...) Expand all
1343 * Assumes that the directory for [dest] already exists. 1489 * Assumes that the directory for [dest] already exists.
1344 */ 1490 */
1345 static Future copyFile(Path source, Path dest) { 1491 static Future copyFile(Path source, Path dest) {
1346 var output = new File.fromPath(dest).openOutputStream(); 1492 var output = new File.fromPath(dest).openOutputStream();
1347 new File.fromPath(source).openInputStream().pipe(output); 1493 new File.fromPath(source).openInputStream().pipe(output);
1348 var completer = new Completer(); 1494 var completer = new Completer();
1349 output.onClosed = (){ completer.complete(null); }; 1495 output.onClosed = (){ completer.complete(null); };
1350 return completer.future; 1496 return completer.future;
1351 } 1497 }
1352 1498
1353 static String executableSuffix(String executable) {
1354 if (Platform.operatingSystem == 'windows') {
1355 if (executable == 'd8' || executable == 'vm' || executable == 'none') {
1356 return '.exe';
1357 } else {
1358 return '.bat';
1359 }
1360 }
1361 return '';
1362 }
1363
1364 static String executableName(Map configuration) {
1365 String suffix = executableSuffix(configuration['compiler']);
1366 switch (configuration['compiler']) {
1367 case 'none':
1368 return 'dart$suffix';
1369 case 'dartc':
1370 return 'analyzer/bin/dart_analyzer$suffix';
1371 case 'dart2js':
1372 case 'dart2dart':
1373 var prefix = '';
1374 if (configuration['use_sdk']) {
1375 prefix = 'dart-sdk/bin/';
1376 }
1377 if (configuration['host_checked']) {
1378 // The script dart2js_developer is not in the SDK.
1379 return 'dart2js_developer$suffix';
1380 } else {
1381 return '${prefix}dart2js$suffix';
1382 }
1383 break;
1384 default:
1385 throw "Unknown executable for: ${configuration['compiler']}";
1386 }
1387 }
1388
1389 static String compilerName(Map configuration) {
1390 String suffix = executableSuffix(configuration['compiler']);
1391 switch (configuration['compiler']) {
1392 case 'dartc':
1393 case 'dart2js':
1394 case 'dart2dart':
1395 return executableName(configuration);
1396 default:
1397 throw "Unknown compiler for: ${configuration['compiler']}";
1398 }
1399 }
1400
1401 static String dartShellFileName(Map configuration) {
1402 var name = configuration['dart'];
1403 if (name == '') {
1404 name = '${buildDir(configuration)}/${executableName(configuration)}';
1405 }
1406 ensureExists(name, configuration);
1407 return name;
1408 }
1409
1410 static String d8FileName(Map configuration) {
1411 var suffix = executableSuffix('d8');
1412 var d8 = '${buildDir(configuration)}/d8$suffix';
1413 ensureExists(d8, configuration);
1414 return d8;
1415 }
1416
1417 static String vmFileName(Map configuration) {
1418 var suffix = executableSuffix('vm');
1419 var vm = '${buildDir(configuration)}/dart$suffix';
1420 ensureExists(vm, configuration);
1421 return vm;
1422 }
1423
1424 static String flakyFileName() { 1499 static String flakyFileName() {
1425 // If a flaky test did fail, infos about it (i.e. test name, stdin, stdout) 1500 // If a flaky test did fail, infos about it (i.e. test name, stdin, stdout)
1426 // will be written to this file. This is useful for the debugging of 1501 // will be written to this file. This is useful for the debugging of
1427 // flaky tests. 1502 // flaky tests.
1428 // When running on a built bot, the file can be made visible in the waterfal l UI. 1503 // When running on a built bot, the file can be made visible in the waterfal l UI.
1429 return ".flaky.log"; 1504 return ".flaky.log";
1430 } 1505 }
1431 1506
1432 static void ensureExists(String filename, Map configuration) { 1507 static void ensureExists(String filename, Map configuration) {
1433 if (!configuration['list'] && !(new File(filename).existsSync())) { 1508 if (!configuration['list'] && !(new File(filename).existsSync())) {
1434 throw "Executable '$filename' does not exist"; 1509 throw "Executable '$filename' does not exist";
1435 } 1510 }
1436 } 1511 }
1437 1512
1438 static String compilerPath(Map configuration) {
1439 if (configuration['compiler'] == 'none') {
1440 return null; // No separate compiler for dartium tests.
1441 }
1442 var name = '${buildDir(configuration)}/${compilerName(configuration)}';
1443 if (!(new File(name)).existsSync() && !configuration['list']) {
1444 throw "Executable '$name' does not exist";
1445 }
1446 return name;
1447 }
1448
1449 static String outputDir(Map configuration) { 1513 static String outputDir(Map configuration) {
1450 var result = ''; 1514 var result = '';
1451 var system = configuration['system']; 1515 var system = configuration['system'];
1452 if (system == 'linux') { 1516 if (system == 'linux') {
1453 result = 'out/'; 1517 result = 'out/';
1454 } else if (system == 'macos') { 1518 } else if (system == 'macos') {
1455 result = 'xcodebuild/'; 1519 result = 'xcodebuild/';
1456 } else if (system == 'windows') { 1520 } else if (system == 'windows') {
1457 result = 'build/'; 1521 result = 'build/';
1458 } 1522 }
1459 return result; 1523 return result;
1460 } 1524 }
1461 1525
1462 static String buildDir(Map configuration) {
1463 String mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
1464 String arch = configuration['arch'].toUpperCase();
1465 return "${outputDir(configuration)}$mode$arch";
1466 }
1467
1468 static Path dartDir() { 1526 static Path dartDir() {
1469 File scriptFile = new File(testScriptPath); 1527 File scriptFile = new File(testScriptPath);
1470 Path scriptPath = new Path.fromNative(scriptFile.fullPathSync()); 1528 Path scriptPath = new Path.fromNative(scriptFile.fullPathSync());
1471 return scriptPath.directoryPath.directoryPath; 1529 return scriptPath.directoryPath.directoryPath;
1472 } 1530 }
1473 1531
1474 static List<String> standardOptions(Map configuration) { 1532 static List<String> standardOptions(Map configuration) {
1475 List args = ["--ignore-unrecognized-flags"]; 1533 List args = ["--ignore-unrecognized-flags"];
1476 if (configuration["checked"]) { 1534 if (configuration["checked"]) {
1477 args.add('--enable_asserts'); 1535 args.add('--enable_asserts');
(...skipping 11 matching lines...) Expand all
1489 } 1547 }
1490 } 1548 }
1491 // TODO(riocw): Unify our minification calling convention between dart2js 1549 // TODO(riocw): Unify our minification calling convention between dart2js
1492 // and dart2dart. 1550 // and dart2dart.
1493 if (compiler == "dart2js" && configuration["minified"]) { 1551 if (compiler == "dart2js" && configuration["minified"]) {
1494 args.add("--minify"); 1552 args.add("--minify");
1495 } 1553 }
1496 return args; 1554 return args;
1497 } 1555 }
1498 1556
1499 static String jsshellFileName(Map configuration) { 1557 static bool usesWebDriver(String runtime) {
1500 var executableSuffix = executableSuffix('jsshell'); 1558 const BROWSERS = const [
1501 var executable = 'jsshell$executableSuffix'; 1559 'dartium',
1502 var jsshellDir = '${dartDir()}/tools/testing/bin'; 1560 'ie9',
1503 return '$jsshellDir/$executable'; 1561 'ie10',
1562 'safari',
1563 'opera',
1564 'chrome',
1565 'ff'
1566 ];
1567 return BROWSERS.contains(runtime);
1504 } 1568 }
1505 1569
1506 static bool usesWebDriver(String runtime) => Contains(
1507 runtime, const <String>['dartium',
1508 'ie9',
1509 'ie10',
1510 'safari',
1511 'opera',
1512 'chrome',
1513 'ff']);
1514
1515 static bool isBrowserRuntime(String runtime) => 1570 static bool isBrowserRuntime(String runtime) =>
1516 runtime == 'drt' || TestUtils.usesWebDriver(runtime); 1571 runtime == 'drt' || TestUtils.usesWebDriver(runtime);
1517 1572
1518 static bool isJsCommandLineRuntime(String runtime) => 1573 static bool isJsCommandLineRuntime(String runtime) =>
1519 Contains(runtime, const <String>['d8', 'jsshell']); 1574 const ['d8', 'jsshell'].contains(runtime);
1520 1575
1521 } 1576 }
1522 1577
1523 class SummaryReport { 1578 class SummaryReport {
1524 static int total = 0; 1579 static int total = 0;
1525 static int skipped = 0; 1580 static int skipped = 0;
1526 static int noCrash = 0; 1581 static int noCrash = 0;
1527 static int pass = 0; 1582 static int pass = 0;
1528 static int failOk = 0; 1583 static int failOk = 0;
1529 static int fail = 0; 1584 static int fail = 0;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 * $pass tests are expected to pass 1626 * $pass tests are expected to pass
1572 * $failOk tests are expected to fail that we won't fix 1627 * $failOk tests are expected to fail that we won't fix
1573 * $fail tests are expected to fail that we should fix 1628 * $fail tests are expected to fail that we should fix
1574 * $crash tests are expected to crash that we should fix 1629 * $crash tests are expected to crash that we should fix
1575 * $timeout tests are allowed to timeout 1630 * $timeout tests are allowed to timeout
1576 * $compileErrorSkip tests are skipped on browsers due to compile-time error 1631 * $compileErrorSkip tests are skipped on browsers due to compile-time error
1577 """; 1632 """;
1578 print(report); 1633 print(report);
1579 } 1634 }
1580 } 1635 }
OLDNEW
« no previous file with comments | « tools/testing/dart/test_options.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698