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

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: Make test case enqueuing future based. 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
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. If [function] is `null`, does nothing.
44 */
45 void asynchronously(VoidFunction function) {
46 if (function == null) return;
47 new Timer(0, (_) => function());
48 }
49
50 /** A completer that waits until all added [Future]s complete. */
51 // TODO(rnystrom): Copied from web_components. Remove from here when it gets
52 // added to dart:core. (See #6626.)
53 class FutureGroup {
54 const _FINISHED = -1;
55 int _pending = 0;
56 Completer<List> _completer = new Completer<List>();
57 final List<Future> futures = <Future>[];
58
59 /**
60 * Wait for [task] to complete (assuming this barrier has not already been
61 * marked as completed, otherwise you'll get an exception indicating that a
62 * future has already been completed).
63 */
64 void add(Future task) {
65 if (_pending == _FINISHED) {
66 throw new FutureAlreadyCompleteException();
67 }
68 _pending++;
69 futures.add(task);
70 task.handleException(
71 (e) => _completer.completeException(e, task.stackTrace));
72 task.then((_) {
73 _pending--;
74 if (_pending == 0) {
75 _pending = _FINISHED;
76 _completer.complete(futures);
77 }
78 });
79 }
80
81 Future<List> get future => _completer.future;
82 }
83
84 /**
43 * A TestSuite represents a collection of tests. It creates a [TestCase] 85 * 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. 86 * object for each test to be run, and passes the test cases to a callback.
45 * 87 *
46 * Most TestSuites represent a directory or directory tree containing tests, 88 * Most TestSuites represent a directory or directory tree containing tests,
47 * and a status file containing the expected results when these tests are run. 89 * and a status file containing the expected results when these tests are run.
48 */ 90 */
49 abstract class TestSuite { 91 abstract class TestSuite {
92 final Map configuration;
93 final String suiteName;
94
95 TestSuite(this.configuration, this.suiteName);
96
97 /**
98 * The output directory for this suite's configuration.
99 */
100 String get buildDir {
101 var mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
102 var arch = configuration['arch'].toUpperCase();
103 return "${TestUtils.outputDir(configuration)}$mode$arch";
104 }
105
106 /**
107 * The path to the compiler for this suite's configuration. Returns `null` if
108 * no compiler should be used.
109 */
110 String get compilerPath {
111 if (configuration['compiler'] == 'none') {
112 return null; // No separate compiler for dartium tests.
113 }
114 var name = '$buildDir/${compilerName}';
115 if (!(new File(name)).existsSync() && !configuration['list']) {
116 throw "Executable '$name' does not exist";
117 }
118 return name;
119 }
120
121 /**
122 * The name of the compiler for this suite's configuration. Throws an error
123 * if the configuration does not use a compiler.
124 */
125 String get compilerName {
126 switch (configuration['compiler']) {
127 case 'dartc':
128 case 'dart2js':
129 case 'dart2dart':
130 return executableName;
131 default:
132 throw "Unknown compiler for: ${configuration['compiler']}";
133 }
134 }
135
136 /**
137 * The file name of the executable used to run this suite's tests.
138 */
139 String get executableName {
140 String suffix = getExecutableSuffix(configuration['compiler']);
141 switch (configuration['compiler']) {
142 case 'none':
143 return 'dart$suffix';
144 case 'dartc':
145 return 'analyzer/bin/dart_analyzer$suffix';
146 case 'dart2js':
147 case 'dart2dart':
148 var prefix = '';
149 if (configuration['use_sdk']) {
150 prefix = 'dart-sdk/bin/';
151 }
152 if (configuration['host_checked']) {
153 // The script dart2js_developer is not in the SDK.
154 return 'dart2js_developer$suffix';
155 } else {
156 return '${prefix}dart2js$suffix';
157 }
158 break;
159 default:
160 throw "Unknown executable for: ${configuration['compiler']}";
161 }
162 }
163
164 /**
165 * The file name of the d8 executable.
166 */
167 String get d8FileName {
168 var suffix = getExecutableSuffix('d8');
169 var d8 = '$buildDir/d8$suffix';
170 TestUtils.ensureExists(d8, configuration);
171 return d8;
172 }
173
174 String get dartShellFileName {
175 var name = configuration['dart'];
176 if (name == '') {
177 name = '$buildDir/$executableName';
178 }
179 TestUtils.ensureExists(name, configuration);
180 return name;
181 }
182
183 String get jsShellFileName {
184 var executableSuffix = getExecutableSuffix('jsshell');
185 var executable = 'jsshell$executableSuffix';
186 var jsshellDir = '${TestUtils.dartDir()}/tools/testing/bin';
187 return '$jsshellDir/$executable';
188 }
189
190 /**
191 * The file name of the Dart VM executable.
192 */
193 String get vmFileName {
194 var suffix = getExecutableSuffix('vm');
195 var vm = '$buildDir/dart$suffix';
196 TestUtils.ensureExists(vm, configuration);
197 return vm;
198 }
199
200 /**
201 * The file extension (if any) that should be added to the given executable
202 * name for the current platform.
203 */
204 String getExecutableSuffix(String executable) {
205 if (Platform.operatingSystem == 'windows') {
206 if (executable == 'd8' || executable == 'vm' || executable == 'none') {
207 return '.exe';
208 } else {
209 return '.bat';
210 }
211 }
212 return '';
213 }
214
50 /** 215 /**
51 * Call the callback function onTest with a [TestCase] argument for each 216 * Call the callback function onTest with a [TestCase] argument for each
52 * test in the suite. When all tests have been processed, call [onDone]. 217 * test in the suite. When all tests have been processed, call [onDone].
53 * 218 *
54 * The [testCache] argument provides a persistent store that can be used to 219 * 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 220 * cache information about the test suite, so that directories do not need
56 * to be listed each time. 221 * to be listed each time.
57 */ 222 */
58 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]); 223 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]);
59 } 224 }
60 225
61 226
62 // TODO(1030): remove once in the corelib.
Emily Fortuna 2012/11/09 01:41:44 :-)
63 bool Contains(element, collection) => collection.indexOf(element) >= 0;
64
65
66 void ccTestLister() { 227 void ccTestLister() {
67 port.receive((String runnerPath, SendPort replyTo) { 228 port.receive((String runnerPath, SendPort replyTo) {
68 Future processFuture = Process.start(runnerPath, ["--list"]); 229 Future processFuture = Process.start(runnerPath, ["--list"]);
69 processFuture.then((p) { 230 processFuture.then((p) {
70 // Drain stderr to not leak resources. 231 // Drain stderr to not leak resources.
71 p.stderr.onData = p.stderr.read; 232 p.stderr.onData = p.stderr.read;
72 StringInputStream stdoutStream = new StringInputStream(p.stdout); 233 StringInputStream stdoutStream = new StringInputStream(p.stdout);
73 var streamDone = false; 234 var streamDone = false;
74 var processExited = false; 235 var processExited = false;
75 checkDone() { 236 checkDone() {
(...skipping 30 matching lines...) Expand all
106 267
107 268
108 /** 269 /**
109 * A specialized [TestSuite] that runs tests written in C to unit test 270 * A specialized [TestSuite] that runs tests written in C to unit test
110 * the Dart virtual machine and its API. 271 * the Dart virtual machine and its API.
111 * 272 *
112 * The tests are compiled into a monolithic executable by the build step. 273 * 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. 274 * 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. 275 * Individual tests are run by specifying them on the command line.
115 */ 276 */
116 class CCTestSuite implements TestSuite { 277 class CCTestSuite extends TestSuite {
117 Map configuration;
118 final String suiteName;
119 final String testPrefix; 278 final String testPrefix;
120 String runnerPath; 279 String runnerPath;
121 final String dartDir; 280 final String dartDir;
122 List<String> statusFilePaths; 281 List<String> statusFilePaths;
123 TestCaseEvent doTest; 282 TestCaseEvent doTest;
124 VoidFunction doDone; 283 VoidFunction doDone;
125 ReceivePort receiveTestName; 284 ReceivePort receiveTestName;
126 TestExpectations testExpectations; 285 TestExpectations testExpectations;
127 286
128 CCTestSuite(Map this.configuration, 287 CCTestSuite(Map configuration,
129 String this.suiteName, 288 String suiteName,
130 String runnerName, 289 String runnerName,
131 List<String> this.statusFilePaths, 290 List<String> this.statusFilePaths,
132 {this.testPrefix: ''}) 291 {this.testPrefix: ''})
133 : dartDir = TestUtils.dartDir().toNativePath() { 292 : super(configuration, suiteName),
134 runnerPath = '${TestUtils.buildDir(configuration)}/$runnerName'; 293 dartDir = TestUtils.dartDir().toNativePath() {
294 runnerPath = '$buildDir/$runnerName';
135 } 295 }
136 296
137 void testNameHandler(String testName, ignore) { 297 void testNameHandler(String testName, ignore) {
138 if (testName == "") { 298 if (testName == "") {
139 receiveTestName.close(); 299 receiveTestName.close();
140 doDone(); 300
301 if (doDone != null) doDone();
141 } else { 302 } else {
142 // Only run the tests that match the pattern. Use the name 303 // Only run the tests that match the pattern. Use the name
143 // "suiteName/testName" for cc tests. 304 // "suiteName/testName" for cc tests.
144 RegExp pattern = configuration['selectors'][suiteName]; 305 RegExp pattern = configuration['selectors'][suiteName];
145 String constructedName = '$suiteName/$testPrefix$testName'; 306 String constructedName = '$suiteName/$testPrefix$testName';
146 if (!pattern.hasMatch(constructedName)) return; 307 if (!pattern.hasMatch(constructedName)) return;
147 308
148 var expectations = testExpectations.expectations( 309 var expectations = testExpectations.expectations(
149 '$testPrefix$testName'); 310 '$testPrefix$testName');
150 311
151 if (configuration["report"]) { 312 if (configuration["report"]) {
152 SummaryReport.add(expectations); 313 SummaryReport.add(expectations);
153 } 314 }
154 315
155 if (expectations.contains(SKIP)) return; 316 if (expectations.contains(SKIP)) return;
156 317
157 var args = TestUtils.standardOptions(configuration); 318 var args = TestUtils.standardOptions(configuration);
158 args.add(testName); 319 args.add(testName);
159 320
160 doTest(new TestCase(constructedName, 321 doTest(new TestCase(constructedName,
161 [new Command(runnerPath, args)], 322 [new Command(runnerPath, args)],
162 configuration, 323 configuration,
163 completeHandler, 324 completeHandler,
164 expectations)); 325 expectations));
165 } 326 }
166 } 327 }
167 328
168 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) { 329 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) {
169 doTest = onTest; 330 doTest = onTest;
170 doDone = () => (onDone != null) ? onDone() : null; 331 doDone = onDone;
171 332
172 var filesRead = 0; 333 var filesRead = 0;
173 void statusFileRead() { 334 void statusFileRead() {
174 filesRead++; 335 filesRead++;
175 if (filesRead == statusFilePaths.length) { 336 if (filesRead == statusFilePaths.length) {
176 receiveTestName = new ReceivePort(); 337 receiveTestName = new ReceivePort();
177 var port = spawnFunction(ccTestLister); 338 var port = spawnFunction(ccTestLister);
178 port.send(runnerPath, receiveTestName.toSendPort()); 339 port.send(runnerPath, receiveTestName.toSendPort());
179 receiveTestName.receive(testNameHandler); 340 receiveTestName.receive(testNameHandler);
180 } 341 }
(...skipping 28 matching lines...) Expand all
209 this.multitestOutcome) { 370 this.multitestOutcome) {
210 Expect.isTrue(filePath.isAbsolute); 371 Expect.isTrue(filePath.isAbsolute);
211 } 372 }
212 } 373 }
213 374
214 375
215 /** 376 /**
216 * A standard [TestSuite] implementation that searches for tests in a 377 * A standard [TestSuite] implementation that searches for tests in a
217 * directory, and creates [TestCase]s that compile and/or run them. 378 * directory, and creates [TestCase]s that compile and/or run them.
218 */ 379 */
219 class StandardTestSuite implements TestSuite { 380 class StandardTestSuite extends TestSuite {
220 Map configuration; 381 final Path suiteDir;
221 String suiteName; 382 final List<String> statusFilePaths;
222 Path suiteDir;
223 List<String> statusFilePaths;
224 TestCaseEvent doTest; 383 TestCaseEvent doTest;
225 VoidFunction doDone;
226 int activeTestGenerators = 0;
227 bool listingDone = false;
228 TestExpectations testExpectations; 384 TestExpectations testExpectations;
229 List<TestInformation> cachedTests; 385 List<TestInformation> cachedTests;
230 final Path dartDir; 386 final Path dartDir;
231 Predicate<String> isTestFilePredicate; 387 Predicate<String> isTestFilePredicate;
232 bool _listRecursive; 388 final bool listRecursively;
233 389
234 StandardTestSuite(this.configuration, 390 StandardTestSuite(Map configuration,
235 this.suiteName, 391 String suiteName,
236 Path suiteDirectory, 392 Path suiteDirectory,
237 this.statusFilePaths, 393 this.statusFilePaths,
238 {this.isTestFilePredicate, 394 {this.isTestFilePredicate,
239 bool recursive: false}) 395 bool recursive: false})
240 : dartDir = TestUtils.dartDir(), _listRecursive = recursive, 396 : super(configuration, suiteName),
397 dartDir = TestUtils.dartDir(),
398 listRecursively = recursive,
241 suiteDir = TestUtils.dartDir().join(suiteDirectory); 399 suiteDir = TestUtils.dartDir().join(suiteDirectory);
242 400
243 /** 401 /**
244 * Creates a test suite whose file organization matches an expected structure. 402 * Creates a test suite whose file organization matches an expected structure.
245 * To use this, your suite should look like: 403 * To use this, your suite should look like:
246 * 404 *
247 * dart/ 405 * dart/
248 * path/ 406 * path/
249 * to/ 407 * to/
250 * mytestsuite/ 408 * mytestsuite/
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 * The default implementation assumes a file is a test if 440 * The default implementation assumes a file is a test if
283 * it ends in "Test.dart". 441 * it ends in "Test.dart".
284 */ 442 */
285 bool isTestFile(String filename) { 443 bool isTestFile(String filename) {
286 // Use the specified predicate, if provided. 444 // Use the specified predicate, if provided.
287 if (isTestFilePredicate != null) return isTestFilePredicate(filename); 445 if (isTestFilePredicate != null) return isTestFilePredicate(filename);
288 446
289 return filename.endsWith("Test.dart"); 447 return filename.endsWith("Test.dart");
290 } 448 }
291 449
292 bool listRecursively() => _listRecursive;
293
294 String shellPath() => TestUtils.dartShellFileName(configuration);
295
296 List<String> additionalOptions(Path filePath) => []; 450 List<String> additionalOptions(Path filePath) => [];
297 451
298 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) { 452 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) {
299 // If DumpRenderTree/Dartium is required, and not yet updated, 453 waitForDartium().chain((_) {
300 // wait for update. 454 doTest = onTest;
455
456 return readExpectations();
457 }).chain((expectations) {
458 testExpectations = expectations;
459
460 // Checked if we have already found and generated the tests for
461 // this suite.
462 if (!testCache.containsKey(suiteName)) {
463 cachedTests = testCache[suiteName] = [];
464 return enqueueTests();
465 } else {
466 // We rely on enqueueing completing asynchronously.
467 return asynchronously(() {
468 for (var info in testCache[suiteName]) {
469 enqueueTestCaseFromTestInformation(info);
470 }
471 });
472 }
473 }).then((_) {
474 if (onDone != null) onDone();
475 });
476 }
477
478 /**
479 * If DumpRenderTree/Dartium is required, and not yet updated, waits for
480 * the update then completes. Otherwise completes immediately.
481 */
482 Future waitForDartium() {
Emily Fortuna 2012/11/09 01:41:44 nit: maybe just call this updateDartium since in n
Bob Nystrom 2012/11/09 20:56:26 Done.
483 var completer = new Completer();
301 var updater = runtimeUpdater(configuration); 484 var updater = runtimeUpdater(configuration);
302 if (updater !== null && !updater.updated) { 485 if (updater == null || updater.updated) {
303 Expect.isTrue(updater.isActive); 486 return new Future.immediate(null);
304 updater.onUpdated.add(() {
305 forEachTest(onTest, testCache, onDone);
306 });
307 return;
308 } 487 }
309 488
310 doTest = onTest; 489 Expect.isTrue(updater.isActive);
311 doDone = (onDone != null) ? onDone : (() => null); 490 updater.onUpdated.add(completer.complete);
491
492 return completer.future;
493 }
494
495 /**
496 * Reads the status files and completes with the parsed expectations.
497 */
498 Future<TestExpectations> readExpectations() {
499 var completer = new Completer();
500 var expectations = new TestExpectations();
312 501
313 var filesRead = 0; 502 var filesRead = 0;
314 void statusFileRead() { 503 void statusFileRead() {
315 filesRead++; 504 filesRead++;
316 if (filesRead == statusFilePaths.length) { 505 if (filesRead == statusFilePaths.length) {
317 // Checked if we have already found and generated the tests for 506 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 } 507 }
334 } 508 }
335 509
336 // Read test expectations from status files.
337 testExpectations = new TestExpectations();
338 for (var statusFilePath in statusFilePaths) { 510 for (var statusFilePath in statusFilePaths) {
339 // [forDirectory] adds name_dart2js.status for all tests suites, use it if 511 // [forDirectory] adds name_dart2js.status for all tests suites. Use it
340 // it exists, but otherwise skip it and don't fail. 512 // if it exists, but otherwise skip it and don't fail.
341 if (statusFilePath.endsWith('_dart2js.status')) { 513 if (statusFilePath.endsWith('_dart2js.status')) {
342 File file = new File.fromPath(dartDir.append(statusFilePath)); 514 var file = new File.fromPath(dartDir.append(statusFilePath));
343 if (!file.existsSync()) { 515 if (!file.existsSync()) {
344 filesRead++; 516 filesRead++;
345 continue; 517 continue;
346 } 518 }
347 } 519 }
348 ReadTestExpectationsInto(testExpectations, 520
521 ReadTestExpectationsInto(expectations,
349 dartDir.append(statusFilePath).toNativePath(), 522 dartDir.append(statusFilePath).toNativePath(),
350 configuration, 523 configuration, statusFileRead);
351 statusFileRead);
352 } 524 }
525
526 return completer.future;
353 } 527 }
354 528
355 void processDirectory() { 529 Future enqueueTests() {
356 Directory dir = new Directory.fromPath(suiteDir); 530 Directory dir = new Directory.fromPath(suiteDir);
357 dir.exists().then((exists) { 531 return dir.exists().chain((exists) {
358 if (!exists) { 532 if (!exists) {
359 print('Directory containing tests not found: $suiteDir'); 533 print('Directory containing tests not found: $suiteDir');
360 directoryListingDone(false); 534 return new Future.immediate(null);
361 } else { 535 } else {
362 var lister = dir.list(recursive: listRecursively()); 536 var group = new FutureGroup();
363 lister.onFile = processFile; 537 enqueueDirectory(dir, group);
364 lister.onDone = directoryListingDone; 538 return group.future;
365 } 539 }
366 }); 540 });
367 } 541 }
368 542
543 Future enqueueDirectory(Directory dir, FutureGroup group) {
544 var listCompleter = new Completer();
545 group.add(listCompleter.future);
546
547 var lister = dir.list(recursive: listRecursively);
548 lister.onFile = (file) => enqueueFile(file, group);
549 lister.onDone = listCompleter.complete;
550 }
551
552 void enqueueFile(String filename, FutureGroup group) {
553 if (!isTestFile(filename)) return;
554 Path filePath = new Path.fromNative(filename);
555
556 // Only run the tests that match the pattern.
557 RegExp pattern = configuration['selectors'][suiteName];
558 if (!pattern.hasMatch('$filePath')) return;
559 if (filePath.filename.endsWith('test_config.dart')) return;
560
561 var optionsFromFile = readOptionsFromFile(filePath);
562 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
563
564 if (optionsFromFile['isMultitest']) {
565 group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase));
566 } else {
567 createTestCase(filePath,
568 optionsFromFile['hasCompileError'],
569 optionsFromFile['hasRuntimeError']);
570 }
571 }
572
369 void enqueueTestCaseFromTestInformation(TestInformation info) { 573 void enqueueTestCaseFromTestInformation(TestInformation info) {
370 var filePath = info.filePath; 574 var filePath = info.filePath;
371 var optionsFromFile = info.optionsFromFile; 575 var optionsFromFile = info.optionsFromFile;
372 var isNegative = info.hasCompileError; 576 var isNegative = info.hasCompileError;
373 if (info.hasRuntimeError && hasRuntime) { 577 if (info.hasRuntimeError && hasRuntime) {
374 isNegative = true; 578 isNegative = true;
375 } 579 }
376 580
377 // Look up expectations in status files using a test name generated 581 // Look up expectations in status files using a test name generated
378 // from the test file's path. 582 // from the test file's path.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 info: info)); 670 info: info));
467 } 671 }
468 } 672 }
469 673
470 List<Command> makeCommands(TestInformation info, var vmOptions, var args) { 674 List<Command> makeCommands(TestInformation info, var vmOptions, var args) {
471 switch (configuration['compiler']) { 675 switch (configuration['compiler']) {
472 case 'dart2js': 676 case 'dart2js':
473 args = new List.from(args); 677 args = new List.from(args);
474 String tempDir = createOutputDirectory(info.filePath, ''); 678 String tempDir = createOutputDirectory(info.filePath, '');
475 args.add('--out=$tempDir/out.js'); 679 args.add('--out=$tempDir/out.js');
476 List<Command> commands = <Command>[new Command(shellPath(), args)]; 680 List<Command> commands = <Command>[new Command(dartShellFileName, args)];
477 if (info.hasCompileError) { 681 if (info.hasCompileError) {
478 // Do not attempt to run the compiled result. A compilation 682 // Do not attempt to run the compiled result. A compilation
479 // error should be reported by the compilation command. 683 // error should be reported by the compilation command.
480 } else if (configuration['runtime'] == 'd8') { 684 } else if (configuration['runtime'] == 'd8') {
481 var d8 = TestUtils.d8FileName(configuration); 685 commands.add(new Command(d8FileName, ['$tempDir/out.js']));
482 commands.add(new Command(d8, ['$tempDir/out.js']));
483 } else if (configuration['runtime'] == 'jsshell') { 686 } else if (configuration['runtime'] == 'jsshell') {
484 var jsshell = TestUtils.jsshellFileName(configuration); 687 commands.add(new Command(jsShellFileName, ['$tempDir/out.js']));
485 commands.add(new Command(jsshell, ['$tempDir/out.js']));
486 } 688 }
487 return commands; 689 return commands;
488 690
489 case 'dart2dart': 691 case 'dart2dart':
490 var compilerArguments = new List.from(args); 692 var compilerArguments = new List.from(args);
491 var additionalFlags = 693 var additionalFlags =
492 configuration['additional-compiler-flags'].split(' '); 694 configuration['additional-compiler-flags'].split(' ');
493 for (final flag in additionalFlags) { 695 for (final flag in additionalFlags) {
494 if (flag.isEmpty) continue; 696 if (flag.isEmpty) continue;
495 compilerArguments.add(flag); 697 compilerArguments.add(flag);
496 } 698 }
497 compilerArguments.add('--output-type=dart'); 699 compilerArguments.add('--output-type=dart');
498 String tempDir = createOutputDirectory(info.filePath, ''); 700 String tempDir = createOutputDirectory(info.filePath, '');
499 compilerArguments.add('--out=$tempDir/out.dart'); 701 compilerArguments.add('--out=$tempDir/out.dart');
500 List<Command> commands = 702 List<Command> commands =
501 <Command>[new Command(shellPath(), compilerArguments)]; 703 <Command>[new Command(dartShellFileName, compilerArguments)];
502 if (info.hasCompileError) { 704 if (info.hasCompileError) {
503 // Do not attempt to run the compiled result. A compilation 705 // Do not attempt to run the compiled result. A compilation
504 // error should be reported by the compilation command. 706 // error should be reported by the compilation command.
505 } else if (configuration['runtime'] == 'vm') { 707 } else if (configuration['runtime'] == 'vm') {
506 // TODO(antonm): support checked. 708 // TODO(antonm): support checked.
507 var vmArguments = new List.from(vmOptions); 709 var vmArguments = new List.from(vmOptions);
508 vmArguments.addAll([ 710 vmArguments.addAll([
509 '--ignore-unrecognized-flags', '$tempDir/out.dart']); 711 '--ignore-unrecognized-flags', '$tempDir/out.dart']);
510 commands.add(new Command( 712 commands.add(new Command(vmFileName, vmArguments));
511 TestUtils.vmFileName(configuration),
512 vmArguments));
513 } else { 713 } else {
514 throw 'Unsupported runtime ${configuration["runtime"]} for dart2dart'; 714 throw 'Unsupported runtime ${configuration["runtime"]} for dart2dart';
515 } 715 }
516 return commands; 716 return commands;
517 717
518 case 'none': 718 case 'none':
519 case 'dartc': 719 case 'dartc':
520 var arguments = new List.from(vmOptions); 720 var arguments = new List.from(vmOptions);
521 arguments.addAll(args); 721 arguments.addAll(args);
522 return <Command>[new Command(shellPath(), arguments)]; 722 return <Command>[new Command(dartShellFileName, arguments)];
523 723
524 default: 724 default:
525 throw 'Unknown compiler ${configuration["compiler"]}'; 725 throw 'Unknown compiler ${configuration["compiler"]}';
526 } 726 }
527 } 727 }
528 728
529 CreateTest makeTestCaseCreator(Map optionsFromFile) { 729 CreateTest makeTestCaseCreator(Map optionsFromFile) {
530 return (Path filePath, 730 return (Path filePath,
531 bool hasCompileError, 731 bool hasCompileError,
532 bool hasRuntimeError, 732 bool hasRuntimeError,
533 {bool isNegativeIfChecked: false, 733 {bool isNegativeIfChecked: false,
534 bool hasFatalTypeErrors: false, 734 bool hasFatalTypeErrors: false,
535 Set<String> multitestOutcome: null}) { 735 Set<String> multitestOutcome: null}) {
536 // Cache the test information for each test case. 736 // Cache the test information for each test case.
537 var info = new TestInformation(filePath, 737 var info = new TestInformation(filePath,
538 optionsFromFile, 738 optionsFromFile,
539 hasCompileError, 739 hasCompileError,
540 hasRuntimeError, 740 hasRuntimeError,
541 isNegativeIfChecked, 741 isNegativeIfChecked,
542 hasFatalTypeErrors, 742 hasFatalTypeErrors,
543 multitestOutcome); 743 multitestOutcome);
544 cachedTests.add(info); 744 cachedTests.add(info);
545 enqueueTestCaseFromTestInformation(info); 745 enqueueTestCaseFromTestInformation(info);
546 }; 746 };
547 } 747 }
548 748
549 void processFile(String filename) {
550 if (!isTestFile(filename)) return;
551 Path filePath = new Path.fromNative(filename);
552
553 // Only run the tests that match the pattern.
554 RegExp pattern = configuration['selectors'][suiteName];
555 if (!pattern.hasMatch('$filePath')) return;
556 if (filePath.filename.endsWith('test_config.dart')) return;
557
558 var optionsFromFile = readOptionsFromFile(filePath);
559 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
560
561 if (optionsFromFile['isMultitest']) {
562 testGeneratorStarted();
563 DoMultitest(filePath,
564 TestUtils.buildDir(configuration),
565 suiteDir,
566 createTestCase,
567 testGeneratorDone);
568 } else {
569 createTestCase(filePath,
570 optionsFromFile['hasCompileError'],
571 optionsFromFile['hasRuntimeError']);
572 }
573 }
574
575 /** 749 /**
576 * The [StandardTestSuite] has support for tests that 750 * The [StandardTestSuite] has support for tests that
577 * compile a test from Dart to JavaScript, and then run the resulting 751 * compile a test from Dart to JavaScript, and then run the resulting
578 * JavaScript. This function creates a working directory to hold the 752 * JavaScript. This function creates a working directory to hold the
579 * JavaScript version of the test, and copies the appropriate framework 753 * JavaScript version of the test, and copies the appropriate framework
580 * files to that directory. It creates a [BrowserTestCase], which has 754 * files to that directory. It creates a [BrowserTestCase], which has
581 * two sequential steps to be run by the [ProcessQueue] when the test is 755 * two sequential steps to be run by the [ProcessQueue] when the test is
582 * executed: a compilation 756 * executed: a compilation
583 * step and an execution step, both with the appropriate executable and 757 * step and an execution step, both with the appropriate executable and
584 * arguments. 758 * arguments.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 var testCase = new BrowserTestCase('$suiteName/$testName', 917 var testCase = new BrowserTestCase('$suiteName/$testName',
744 commands, configuration, completeHandler, expectations, 918 commands, configuration, completeHandler, expectations,
745 info, info.hasCompileError || info.hasRuntimeError); 919 info, info.hasCompileError || info.hasRuntimeError);
746 doTest(testCase); 920 doTest(testCase);
747 } 921 }
748 } 922 }
749 923
750 /** Helper to create a compilation command for a single input file. */ 924 /** Helper to create a compilation command for a single input file. */
751 Command _compileCommand(String inputFile, String outputFile, 925 Command _compileCommand(String inputFile, String outputFile,
752 String compiler, String dir, var vmOptions) { 926 String compiler, String dir, var vmOptions) {
753 String executable = TestUtils.compilerPath(configuration); 927 String executable = compilerPath;
754 List<String> args = TestUtils.standardOptions(configuration); 928 List<String> args = TestUtils.standardOptions(configuration);
755 switch (compiler) { 929 switch (compiler) {
756 case 'dart2js': 930 case 'dart2js':
757 case 'dart2dart': 931 case 'dart2dart':
758 if (compiler == 'dart2dart') args.add('--out=$outputFile'); 932 if (compiler == 'dart2dart') args.add('--out=$outputFile');
759 args.add('--out=$outputFile'); 933 args.add('--out=$outputFile');
760 args.add(inputFile); 934 args.add(inputFile);
761 break; 935 break;
762 default: 936 default:
763 Expect.fail('unimplemented compiler $compiler'); 937 Expect.fail('unimplemented compiler $compiler');
764 } 938 }
765 if (executable.endsWith('.dart')) { 939 if (executable.endsWith('.dart')) {
766 // Run the compiler script via the Dart VM. 940 // Run the compiler script via the Dart VM.
767 args.insertRange(0, 1, executable); 941 args.insertRange(0, 1, executable);
768 executable = TestUtils.dartShellFileName(configuration); 942 executable = dartShellFileName;
769 } 943 }
770 return new Command(executable, args); 944 return new Command(executable, args);
771 } 945 }
772 946
773 /** 947 /**
774 * Create a directory for the generated test. If a Dart language test 948 * Create a directory for the generated test. If a Dart language test
775 * needs to be run in a browser, the Dart test needs to be embedded in 949 * needs to be run in a browser, the Dart test needs to be embedded in
776 * an HTML page, with a testing framework based on scripting and DOM events. 950 * an HTML page, with a testing framework based on scripting and DOM events.
777 * These scripts and pages are written to a generated_test directory 951 * These scripts and pages are written to a generated_test directory
778 * inside the build directory of the checkout. 952 * inside the build directory of the checkout.
779 * 953 *
780 * Those tests which are already HTML web applications (web tests), with 954 * Those tests which are already HTML web applications (web tests), with
781 * resources including CSS files and HTML files, need to be compiled into 955 * resources including CSS files and HTML files, need to be compiled into
782 * a work directory where the relative URLS to the resources work. 956 * a work directory where the relative URLS to the resources work.
783 * We use a subdirectory of the build directory that is the same number 957 * We use a subdirectory of the build directory that is the same number
784 * of levels down in the checkout as the original path of the web test. 958 * of levels down in the checkout as the original path of the web test.
785 */ 959 */
786 String createOutputDirectory(Path testPath, String optionsName) { 960 String createOutputDirectory(Path testPath, String optionsName) {
787 Path relative = testPath.relativeTo(TestUtils.dartDir()); 961 Path relative = testPath.relativeTo(TestUtils.dartDir());
788 relative = relative.directoryPath.append(relative.filenameWithoutExtension); 962 relative = relative.directoryPath.append(relative.filenameWithoutExtension);
789 String testUniqueName = relative.toString().replaceAll('/', '_'); 963 String testUniqueName = relative.toString().replaceAll('/', '_');
790 if (!optionsName.isEmpty) { 964 if (!optionsName.isEmpty) {
791 testUniqueName = '$testUniqueName-$optionsName'; 965 testUniqueName = '$testUniqueName-$optionsName';
792 } 966 }
793 967
794 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName', 968 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName',
795 // including any intermediate directories that don't exist. 969 // including any intermediate directories that don't exist.
796 var generatedTestPath = Strings.join( 970 var generatedTestPath = Strings.join([
797 [TestUtils.buildDir(configuration), 971 buildDir,
798 'generated_tests', 972 'generated_tests',
799 "${configuration['compiler']}-${configuration['runtime']}", 973 "${configuration['compiler']}-${configuration['runtime']}",
800 testUniqueName], '/'); 974 testUniqueName
975 ], '/');
801 976
802 TestUtils.mkdirRecursive(new Path('.'), new Path(generatedTestPath)); 977 TestUtils.mkdirRecursive(new Path('.'), new Path(generatedTestPath));
803 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/'); 978 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/');
804 } 979 }
805 980
806 String get scriptType { 981 String get scriptType {
807 switch (configuration['compiler']) { 982 switch (configuration['compiler']) {
808 case 'none': 983 case 'none':
809 case 'dart2dart': 984 case 'dart2dart':
810 return 'application/dart'; 985 return 'application/dart';
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 if (configuration['dartium'] != '') { 1026 if (configuration['dartium'] != '') {
852 return configuration['dartium']; 1027 return configuration['dartium'];
853 } 1028 }
854 if (Platform.operatingSystem == 'macos') { 1029 if (Platform.operatingSystem == 'macos') {
855 return dartDir.append('client/tests/dartium/Chromium.app/Contents/' 1030 return dartDir.append('client/tests/dartium/Chromium.app/Contents/'
856 'MacOS/Chromium').toNativePath(); 1031 'MacOS/Chromium').toNativePath();
857 } 1032 }
858 return dartDir.append('client/tests/dartium/chrome').toNativePath(); 1033 return dartDir.append('client/tests/dartium/chrome').toNativePath();
859 } 1034 }
860 1035
861 void testGeneratorStarted() {
862 ++activeTestGenerators;
863 }
864
865 void testGeneratorDone() {
866 --activeTestGenerators;
867 if (activeTestGenerators == 0 && listingDone) {
868 doDone();
869 }
870 }
871
872 void directoryListingDone(ignore) {
873 listingDone = true;
874 if (activeTestGenerators == 0) {
875 doDone();
876 }
877 }
878
879 void completeHandler(TestCase testCase) { 1036 void completeHandler(TestCase testCase) {
880 } 1037 }
881 1038
882 List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) { 1039 List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) {
883 List args = TestUtils.standardOptions(configuration); 1040 List args = TestUtils.standardOptions(configuration);
884 args.addAll(additionalOptions(filePath)); 1041 args.addAll(additionalOptions(filePath));
885 if (configuration['compiler'] == 'dartc') { 1042 if (configuration['compiler'] == 'dartc') {
886 args.add('--error_format'); 1043 args.add('--error_format');
887 args.add('machine'); 1044 args.add('machine');
888 } 1045 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 "containsLeadingHash": containsLeadingHash, 1217 "containsLeadingHash": containsLeadingHash,
1061 "isolateStubs": isolateStubs, 1218 "isolateStubs": isolateStubs,
1062 "containsDomImport": containsDomImport, 1219 "containsDomImport": containsDomImport,
1063 "isLibraryDefinition": isLibraryDefinition, 1220 "isLibraryDefinition": isLibraryDefinition,
1064 "containsSourceOrImport": containsSourceOrImport, 1221 "containsSourceOrImport": containsSourceOrImport,
1065 "numStaticTypeAnnotations": numStaticTypeAnnotations, 1222 "numStaticTypeAnnotations": numStaticTypeAnnotations,
1066 "numCompileTimeAnnotations": numCompileTimeAnnotations }; 1223 "numCompileTimeAnnotations": numCompileTimeAnnotations };
1067 } 1224 }
1068 1225
1069 List<List<String>> getVmOptions(Map optionsFromFile) { 1226 List<List<String>> getVmOptions(Map optionsFromFile) {
1070 bool needsVmOptions = Contains(configuration['compiler'], 1227 var COMPILERS = const ['none', 'dart2dart', 'dartc'];
1071 const ['none', 'dart2dart', 'dartc']) && 1228 var RUNTIMES = const ['none', 'vm', 'drt', 'dartium'];
1072 Contains(configuration['runtime'], 1229 var needsVmOptions = COMPILERS.contains(configuration['compiler']) &&
1073 const ['none', 'vm', 'drt', 'dartium']); 1230 RUNTIMES.contains(configuration['runtime']);
1074 if (!needsVmOptions) return [[]]; 1231 if (!needsVmOptions) return [[]];
1075 return optionsFromFile['vmOptions']; 1232 return optionsFromFile['vmOptions'];
1076 } 1233 }
1077 } 1234 }
1078 1235
1079 1236
1080 class DartcCompilationTestSuite extends StandardTestSuite { 1237 class DartcCompilationTestSuite extends StandardTestSuite {
1081 List<String> _testDirs; 1238 List<String> _testDirs;
1082 int activityCount = 0;
1083 1239
1084 DartcCompilationTestSuite(Map configuration, 1240 DartcCompilationTestSuite(Map configuration,
1085 String suiteName, 1241 String suiteName,
1086 String directoryPath, 1242 String directoryPath,
1087 List<String> this._testDirs, 1243 List<String> this._testDirs,
1088 List<String> expectations) 1244 List<String> expectations)
1089 : super(configuration, 1245 : super(configuration,
1090 suiteName, 1246 suiteName,
1091 new Path.fromNative(directoryPath), 1247 new Path.fromNative(directoryPath),
1092 expectations); 1248 expectations);
1093 1249
1094 void activityStarted() { ++activityCount; }
1095
1096 void activityCompleted() {
1097 if (--activityCount == 0) {
1098 directoryListingDone(true);
1099 }
1100 }
1101
1102 String shellPath() => TestUtils.compilerPath(configuration);
1103
1104 List<String> additionalOptions(Path filePath) { 1250 List<String> additionalOptions(Path filePath) {
1105 return ['--fatal-warnings', '--fatal-type-errors']; 1251 return ['--fatal-warnings', '--fatal-type-errors'];
1106 } 1252 }
1107 1253
1108 void processDirectory() { 1254 Future enqueueTests() {
1109 // Enqueueing the directory listers is an activity. 1255 var group = new FutureGroup();
1110 activityStarted(); 1256
1257 var listCompleter = new Completer();
1258 group.add(listCompleter.future);
1259
1111 for (String testDir in _testDirs) { 1260 for (String testDir in _testDirs) {
1112 Directory dir = new Directory.fromPath(suiteDir.append(testDir)); 1261 Directory dir = new Directory.fromPath(suiteDir.append(testDir));
1113 if (dir.existsSync()) { 1262 if (dir.existsSync()) {
1114 activityStarted(); 1263 enqueueDirectory(dir, group);
1115 var lister = dir.list(recursive: listRecursively());
1116 lister.onFile = processFile;
1117 lister.onDone = (ignore) => activityCompleted();
1118 } 1264 }
1119 } 1265 }
1120 // Completed the enqueueing of listers. 1266
1121 activityCompleted(); 1267 return group.future;
1122 } 1268 }
1123 } 1269 }
1124 1270
1125 1271
1126 class JUnitTestSuite implements TestSuite { 1272 class JUnitTestSuite extends TestSuite {
1127 Map configuration;
1128 String suiteName;
1129 String directoryPath; 1273 String directoryPath;
1130 String statusFilePath; 1274 String statusFilePath;
1131 final String dartDir; 1275 final String dartDir;
1132 String buildDir;
1133 String classPath; 1276 String classPath;
1134 List<String> testClasses; 1277 List<String> testClasses;
1135 TestCaseEvent doTest; 1278 TestCaseEvent doTest;
1136 VoidFunction doDone; 1279 VoidFunction doDone;
1137 TestExpectations testExpectations; 1280 TestExpectations testExpectations;
1138 1281
1139 JUnitTestSuite(Map this.configuration, 1282 JUnitTestSuite(Map configuration,
1140 String this.suiteName, 1283 String suiteName,
1141 String this.directoryPath, 1284 String this.directoryPath,
1142 String this.statusFilePath) 1285 String this.statusFilePath)
1143 : dartDir = TestUtils.dartDir().toNativePath(); 1286 : super(configuration, suiteName),
1287 dartDir = TestUtils.dartDir().toNativePath();
1144 1288
1145 bool isTestFile(String filename) => filename.endsWith("Tests.java") && 1289 bool isTestFile(String filename) => filename.endsWith("Tests.java") &&
1146 !filename.contains('com/google/dart/compiler/vm') && 1290 !filename.contains('com/google/dart/compiler/vm') &&
1147 !filename.contains('com/google/dart/corelib/SharedTests.java'); 1291 !filename.contains('com/google/dart/corelib/SharedTests.java');
1148 1292
1149 void forEachTest(TestCaseEvent onTest, 1293 void forEachTest(TestCaseEvent onTest,
1150 Map testCacheIgnored, 1294 Map testCacheIgnored,
1151 [VoidFunction onDone]) { 1295 [VoidFunction onDone]) {
1152 doTest = onTest; 1296 doTest = onTest;
1153 doDone = (onDone != null) ? onDone : (() => null); 1297 doDone = onDone;
1154 1298
1155 if (configuration['compiler'] != 'dartc') { 1299 if (configuration['compiler'] != 'dartc') {
1156 // Do nothing. Asynchronously report that the suite is enqueued. 1300 // Do nothing. Asynchronously report that the suite is enqueued.
1157 new Timer(0, (timerUnused){ doDone(); }); 1301 asynchronously(doDone);
1158 return; 1302 return;
1159 } 1303 }
1160 RegExp pattern = configuration['selectors']['dartc']; 1304 RegExp pattern = configuration['selectors']['dartc'];
1161 if (!pattern.hasMatch('junit_tests')) { 1305 if (!pattern.hasMatch('junit_tests')) {
1162 new Timer(0, (timerUnused){ doDone(); }); 1306 asynchronously(doDone);
1163 return; 1307 return;
1164 } 1308 }
1165 1309
1166 buildDir = TestUtils.buildDir(configuration);
1167 computeClassPath(); 1310 computeClassPath();
1168 testClasses = <String>[]; 1311 testClasses = <String>[];
1169 // Do not read the status file. 1312 // Do not read the status file.
1170 // All exclusions are hardcoded in this script, as they are in testcfg.py. 1313 // All exclusions are hardcoded in this script, as they are in testcfg.py.
1171 processDirectory(); 1314 processDirectory();
1172 } 1315 }
1173 1316
1174 void processDirectory() { 1317 void processDirectory() {
1175 directoryPath = '$dartDir/$directoryPath'; 1318 directoryPath = '$dartDir/$directoryPath';
1176 Directory dir = new Directory(directoryPath); 1319 Directory dir = new Directory(directoryPath);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 '$dartDir/third_party/rhino/1_7R3/js.jar', 1374 '$dartDir/third_party/rhino/1_7R3/js.jar',
1232 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar', 1375 '$dartDir/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar',
1233 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar', 1376 '$dartDir/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar',
1234 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar', 1377 '$dartDir/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar',
1235 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar', 1378 '$dartDir/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar',
1236 '$dartDir/third_party/junit/v4_8_2/junit.jar'], 1379 '$dartDir/third_party/junit/v4_8_2/junit.jar'],
1237 Platform.operatingSystem == 'windows'? ';': ':'); // Path separator. 1380 Platform.operatingSystem == 'windows'? ';': ':'); // Path separator.
1238 } 1381 }
1239 } 1382 }
1240 1383
1241
1242 class TestUtils { 1384 class TestUtils {
1243 /** 1385 /**
1244 * The libraries in this directory relies on finding various files 1386 * The libraries in this directory relies on finding various files
1245 * relative to the 'test.dart' script in '.../dart/tools/test.dart'. If 1387 * relative to the 'test.dart' script in '.../dart/tools/test.dart'. If
1246 * the main script using 'test_suite.dart' is not there, the main 1388 * the main script using 'test_suite.dart' is not there, the main
1247 * script must set this to '.../dart/tools/test.dart'. 1389 * script must set this to '.../dart/tools/test.dart'.
1248 */ 1390 */
1249 static String testScriptPath = new Options().script; 1391 static String testScriptPath = new Options().script;
1250 1392
1251 /** 1393 /**
(...skipping 21 matching lines...) Expand all
1273 * Assumes that the directory for [dest] already exists. 1415 * Assumes that the directory for [dest] already exists.
1274 */ 1416 */
1275 static Future copyFile(Path source, Path dest) { 1417 static Future copyFile(Path source, Path dest) {
1276 var output = new File.fromPath(dest).openOutputStream(); 1418 var output = new File.fromPath(dest).openOutputStream();
1277 new File.fromPath(source).openInputStream().pipe(output); 1419 new File.fromPath(source).openInputStream().pipe(output);
1278 var completer = new Completer(); 1420 var completer = new Completer();
1279 output.onClosed = (){ completer.complete(null); }; 1421 output.onClosed = (){ completer.complete(null); };
1280 return completer.future; 1422 return completer.future;
1281 } 1423 }
1282 1424
1283 static String executableSuffix(String executable) {
1284 if (Platform.operatingSystem == 'windows') {
1285 if (executable == 'd8' || executable == 'vm' || executable == 'none') {
1286 return '.exe';
1287 } else {
1288 return '.bat';
1289 }
1290 }
1291 return '';
1292 }
1293
1294 static String executableName(Map configuration) {
1295 String suffix = executableSuffix(configuration['compiler']);
1296 switch (configuration['compiler']) {
1297 case 'none':
1298 return 'dart$suffix';
1299 case 'dartc':
1300 return 'analyzer/bin/dart_analyzer$suffix';
1301 case 'dart2js':
1302 case 'dart2dart':
1303 var prefix = '';
1304 if (configuration['use_sdk']) {
1305 prefix = 'dart-sdk/bin/';
1306 }
1307 if (configuration['host_checked']) {
1308 // The script dart2js_developer is not in the SDK.
1309 return 'dart2js_developer$suffix';
1310 } else {
1311 return '${prefix}dart2js$suffix';
1312 }
1313 break;
1314 default:
1315 throw "Unknown executable for: ${configuration['compiler']}";
1316 }
1317 }
1318
1319 static String compilerName(Map configuration) {
1320 String suffix = executableSuffix(configuration['compiler']);
1321 switch (configuration['compiler']) {
1322 case 'dartc':
1323 case 'dart2js':
1324 case 'dart2dart':
1325 return executableName(configuration);
1326 default:
1327 throw "Unknown compiler for: ${configuration['compiler']}";
1328 }
1329 }
1330
1331 static String dartShellFileName(Map configuration) {
1332 var name = configuration['dart'];
1333 if (name == '') {
1334 name = '${buildDir(configuration)}/${executableName(configuration)}';
1335 }
1336 ensureExists(name, configuration);
1337 return name;
1338 }
1339
1340 static String d8FileName(Map configuration) {
1341 var suffix = executableSuffix('d8');
1342 var d8 = '${buildDir(configuration)}/d8$suffix';
1343 ensureExists(d8, configuration);
1344 return d8;
1345 }
1346
1347 static String vmFileName(Map configuration) {
1348 var suffix = executableSuffix('vm');
1349 var vm = '${buildDir(configuration)}/dart$suffix';
1350 ensureExists(vm, configuration);
1351 return vm;
1352 }
1353
1354 static void ensureExists(String filename, Map configuration) { 1425 static void ensureExists(String filename, Map configuration) {
1355 if (!configuration['list'] && !(new File(filename).existsSync())) { 1426 if (!configuration['list'] && !(new File(filename).existsSync())) {
1356 throw "Executable '$filename' does not exist"; 1427 throw "Executable '$filename' does not exist";
1357 } 1428 }
1358 } 1429 }
1359 1430
1360 static String compilerPath(Map configuration) {
1361 if (configuration['compiler'] == 'none') {
1362 return null; // No separate compiler for dartium tests.
1363 }
1364 var name = '${buildDir(configuration)}/${compilerName(configuration)}';
1365 if (!(new File(name)).existsSync() && !configuration['list']) {
1366 throw "Executable '$name' does not exist";
1367 }
1368 return name;
1369 }
1370
1371 static String outputDir(Map configuration) { 1431 static String outputDir(Map configuration) {
1372 var result = ''; 1432 var result = '';
1373 var system = configuration['system']; 1433 var system = configuration['system'];
1374 if (system == 'linux') { 1434 if (system == 'linux') {
1375 result = 'out/'; 1435 result = 'out/';
1376 } else if (system == 'macos') { 1436 } else if (system == 'macos') {
1377 result = 'xcodebuild/'; 1437 result = 'xcodebuild/';
1378 } else if (system == 'windows') { 1438 } else if (system == 'windows') {
1379 result = 'build/'; 1439 result = 'build/';
1380 } 1440 }
1381 return result; 1441 return result;
1382 } 1442 }
1383 1443
1384 static String buildDir(Map configuration) {
1385 String mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
1386 String arch = configuration['arch'].toUpperCase();
1387 return "${outputDir(configuration)}$mode$arch";
1388 }
1389
1390 static Path dartDir() { 1444 static Path dartDir() {
1391 File scriptFile = new File(testScriptPath); 1445 File scriptFile = new File(testScriptPath);
1392 Path scriptPath = new Path.fromNative(scriptFile.fullPathSync()); 1446 Path scriptPath = new Path.fromNative(scriptFile.fullPathSync());
1393 return scriptPath.directoryPath.directoryPath; 1447 return scriptPath.directoryPath.directoryPath;
1394 } 1448 }
1395 1449
1396 static List<String> standardOptions(Map configuration) { 1450 static List<String> standardOptions(Map configuration) {
1397 List args = ["--ignore-unrecognized-flags"]; 1451 List args = ["--ignore-unrecognized-flags"];
1398 if (configuration["checked"]) { 1452 if (configuration["checked"]) {
1399 args.add('--enable_asserts'); 1453 args.add('--enable_asserts');
(...skipping 11 matching lines...) Expand all
1411 } 1465 }
1412 } 1466 }
1413 // TODO(riocw): Unify our minification calling convention between dart2js 1467 // TODO(riocw): Unify our minification calling convention between dart2js
1414 // and dart2dart. 1468 // and dart2dart.
1415 if (compiler == "dart2js" && configuration["minified"]) { 1469 if (compiler == "dart2js" && configuration["minified"]) {
1416 args.add("--minify"); 1470 args.add("--minify");
1417 } 1471 }
1418 return args; 1472 return args;
1419 } 1473 }
1420 1474
1421 static String jsshellFileName(Map configuration) { 1475 static bool usesWebDriver(String runtime) {
1422 var executableSuffix = executableSuffix('jsshell'); 1476 const BROWSERS = const [
1423 var executable = 'jsshell$executableSuffix'; 1477 'dartium',
1424 var jsshellDir = '${dartDir()}/tools/testing/bin'; 1478 'ie9',
1425 return '$jsshellDir/$executable'; 1479 'ie10',
1480 'safari',
1481 'opera',
1482 'chrome',
1483 'ff'
1484 ];
1485 return BROWSERS.contains(runtime);
1426 } 1486 }
1427 1487
1428 static bool usesWebDriver(String runtime) => Contains(
1429 runtime, const <String>['dartium',
1430 'ie9',
1431 'ie10',
1432 'safari',
1433 'opera',
1434 'chrome',
1435 'ff']);
1436
1437 static bool isBrowserRuntime(String runtime) => 1488 static bool isBrowserRuntime(String runtime) =>
1438 runtime == 'drt' || TestUtils.usesWebDriver(runtime); 1489 runtime == 'drt' || TestUtils.usesWebDriver(runtime);
1439 1490
1440 static bool isJsCommandLineRuntime(String runtime) => 1491 static bool isJsCommandLineRuntime(String runtime) =>
1441 Contains(runtime, const <String>['d8', 'jsshell']); 1492 const ['d8', 'jsshell'].contains(runtime);
1442 1493
1443 } 1494 }
1444 1495
1445 class SummaryReport { 1496 class SummaryReport {
1446 static int total = 0; 1497 static int total = 0;
1447 static int skipped = 0; 1498 static int skipped = 0;
1448 static int noCrash = 0; 1499 static int noCrash = 0;
1449 static int pass = 0; 1500 static int pass = 0;
1450 static int failOk = 0; 1501 static int failOk = 0;
1451 static int fail = 0; 1502 static int fail = 0;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 * $pass tests are expected to pass 1544 * $pass tests are expected to pass
1494 * $failOk tests are expected to fail that we won't fix 1545 * $failOk tests are expected to fail that we won't fix
1495 * $fail tests are expected to fail that we should fix 1546 * $fail tests are expected to fail that we should fix
1496 * $crash tests are expected to crash that we should fix 1547 * $crash tests are expected to crash that we should fix
1497 * $timeout tests are allowed to timeout 1548 * $timeout tests are allowed to timeout
1498 * $compileErrorSkip tests are skipped on browsers due to compile-time error 1549 * $compileErrorSkip tests are skipped on browsers due to compile-time error
1499 """; 1550 """;
1500 print(report); 1551 print(report);
1501 } 1552 }
1502 } 1553 }
OLDNEW
« tools/testing/dart/multitest.dart ('K') | « tools/testing/dart/test_options.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698