Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Test infrastructure for testing pub. Unlike typical unit tests, most pub | 6 * Test infrastructure for testing pub. Unlike typical unit tests, most pub |
| 7 * tests are integration tests that stage some stuff on the file system, run | 7 * tests are integration tests that stage some stuff on the file system, run |
| 8 * pub, and then validate the results. This library provides an API to build | 8 * pub, and then validate the results. This library provides an API to build |
| 9 * tests like that. | 9 * tests like that. |
| 10 */ | 10 */ |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 */ | 438 */ |
| 439 final String appPath = "myapp"; | 439 final String appPath = "myapp"; |
| 440 | 440 |
| 441 /** | 441 /** |
| 442 * The path of the packages directory in the mock app used for tests. Relative | 442 * The path of the packages directory in the mock app used for tests. Relative |
| 443 * to the sandbox directory. | 443 * to the sandbox directory. |
| 444 */ | 444 */ |
| 445 final String packagesPath = "$appPath/packages"; | 445 final String packagesPath = "$appPath/packages"; |
| 446 | 446 |
| 447 /** | 447 /** |
| 448 * The path to the build directory of the Dart repository. This is only set if | |
| 449 * [ensureBuild] has been run for this test. | |
| 450 */ | |
| 451 String _buildPath; | |
| 452 | |
| 453 /** | |
| 448 * The type for callbacks that will be fired during [runPub]. Takes the sandbox | 454 * The type for callbacks that will be fired during [runPub]. Takes the sandbox |
| 449 * directory as a parameter. | 455 * directory as a parameter. |
| 450 */ | 456 */ |
| 451 typedef Future _ScheduledEvent(Directory parentDir); | 457 typedef Future _ScheduledEvent(Directory parentDir); |
| 452 | 458 |
| 453 /** | 459 /** |
| 454 * The list of events that are scheduled to run as part of the test case. | 460 * The list of events that are scheduled to run as part of the test case. |
| 455 */ | 461 */ |
| 456 List<_ScheduledEvent> _scheduled; | 462 List<_ScheduledEvent> _scheduled; |
| 457 | 463 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 } | 508 } |
| 503 | 509 |
| 504 /// Get the path to the root "util/test/pub" directory containing the pub tests. | 510 /// Get the path to the root "util/test/pub" directory containing the pub tests. |
| 505 String get testDirectory { | 511 String get testDirectory { |
| 506 var dir = new Path.fromNative(new Options().script); | 512 var dir = new Path.fromNative(new Options().script); |
| 507 while (dir.filename != 'pub') dir = dir.directoryPath; | 513 while (dir.filename != 'pub') dir = dir.directoryPath; |
| 508 | 514 |
| 509 return new File(dir.toNativePath()).fullPathSync(); | 515 return new File(dir.toNativePath()).fullPathSync(); |
| 510 } | 516 } |
| 511 | 517 |
| 518 /// Whether the tests are running on a build bot. | |
| 519 bool get onBuildBot => Platform.environment.containsKey('BUILDBOT_BUILDERNAME'); | |
| 520 | |
| 512 /** | 521 /** |
| 513 * Schedules a call to the Pub command-line utility. Runs Pub with [args] and | 522 * Schedules a call to the Pub command-line utility. Runs Pub with [args] and |
| 514 * validates that its results match [output], [error], and [exitCode]. | 523 * validates that its results match [output], [error], and [exitCode]. |
| 524 * | |
| 525 * If [realSdk] is true, runs Pub against the real Dart SDK. [ensureBuild] must | |
| 526 * be called before this method if [realSdk] is true. | |
| 515 */ | 527 */ |
| 516 void schedulePub({List<String> args, Pattern output, Pattern error, | 528 void schedulePub({List<String> args, Pattern output, Pattern error, |
| 517 int exitCode: 0}) { | 529 int exitCode: 0, bool realSdk: false}) { |
| 518 _schedule((sandboxDir) { | 530 _schedule((sandboxDir) { |
| 519 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); | 531 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); |
| 520 | 532 |
| 521 return ensureDir(pathInSandbox(appPath)).chain((_) { | 533 return ensureDir(pathInSandbox(appPath)).chain((_) { |
| 522 // Find a Dart executable we can use to spawn. Use the same one that was | 534 // Find a Dart executable we can use to spawn. Use the same one that was |
| 523 // used to run this script itself. | 535 // used to run this script itself. |
| 524 var dartBin = new Options().executable; | 536 var dartBin = new Options().executable; |
| 525 | 537 |
| 526 // If the executable looks like a path, get its full path. That way we | 538 // If the executable looks like a path, get its full path. That way we |
| 527 // can still find it when we spawn it with a different working directory. | 539 // can still find it when we spawn it with a different working directory. |
| 528 if (dartBin.contains(Platform.pathSeparator)) { | 540 if (dartBin.contains(Platform.pathSeparator)) { |
| 529 dartBin = new File(dartBin).fullPathSync(); | 541 dartBin = new File(dartBin).fullPathSync(); |
| 530 } | 542 } |
| 531 | 543 |
| 532 // Find the main pub entrypoint. | 544 // Find the main pub entrypoint. |
| 533 var pubPath = fs.joinPaths(testDirectory, '../../pub/pub.dart'); | 545 var pubPath = fs.joinPaths(testDirectory, '../../pub/pub.dart'); |
| 534 | 546 |
| 535 var dartArgs = | 547 var dartArgs = |
| 536 ['--enable-type-checks', '--enable-asserts', pubPath, '--trace']; | 548 ['--enable-type-checks', '--enable-asserts', pubPath, '--trace']; |
| 537 dartArgs.addAll(args); | 549 dartArgs.addAll(args); |
| 538 | 550 |
| 539 var environment = new Map.from(Platform.environment); | 551 var environment = new Map.from(Platform.environment); |
| 540 environment['PUB_CACHE'] = pathInSandbox(cachePath); | 552 environment['PUB_CACHE'] = pathInSandbox(cachePath); |
| 541 environment['DART_SDK'] = pathInSandbox(sdkPath); | 553 if (realSdk) { |
| 554 if (_buildPath == null) { | |
| 555 throw "Test error: expected a Dart build directory to exist."; | |
| 556 } | |
| 557 environment['DART_SDK'] = join(_buildPath, "dart-sdk"); | |
| 558 } else { | |
| 559 environment['DART_SDK'] = pathInSandbox(sdkPath); | |
| 560 } | |
| 542 | 561 |
| 543 return runProcess(dartBin, dartArgs, workingDir: pathInSandbox(appPath), | 562 return runProcess(dartBin, dartArgs, workingDir: pathInSandbox(appPath), |
| 544 environment: environment); | 563 environment: environment); |
| 545 }).transform((result) { | 564 }).transform((result) { |
| 546 var failures = []; | 565 var failures = []; |
| 547 | 566 |
| 548 _validateOutput(failures, 'stdout', output, result.stdout); | 567 _validateOutput(failures, 'stdout', output, result.stdout); |
| 549 _validateOutput(failures, 'stderr', error, result.stderr); | 568 _validateOutput(failures, 'stderr', error, result.stderr); |
| 550 | 569 |
| 551 if (result.exitCode != exitCode) { | 570 if (result.exitCode != exitCode) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 582 * Skips the current test if Git is not installed. This validates that the | 601 * Skips the current test if Git is not installed. This validates that the |
| 583 * current test is running on a buildbot in which case we expect git to be | 602 * current test is running on a buildbot in which case we expect git to be |
| 584 * installed. If we are not running on the buildbot, we will instead see if git | 603 * installed. If we are not running on the buildbot, we will instead see if git |
| 585 * is installed and skip the test if not. This way, users don't need to have git | 604 * is installed and skip the test if not. This way, users don't need to have git |
| 586 * installed to run the tests locally (unless they actually care about the pub | 605 * installed to run the tests locally (unless they actually care about the pub |
| 587 * git tests). | 606 * git tests). |
| 588 */ | 607 */ |
| 589 void ensureGit() { | 608 void ensureGit() { |
| 590 _schedule((_) { | 609 _schedule((_) { |
| 591 return isGitInstalled.transform((installed) { | 610 return isGitInstalled.transform((installed) { |
| 592 if (!installed && | 611 if (!installed && !onBuildBot) { |
| 593 !Platform.environment.containsKey('BUILDBOT_BUILDERNAME')) { | |
| 594 _abortScheduled = true; | 612 _abortScheduled = true; |
| 595 } | 613 } |
| 596 return null; | 614 return null; |
| 597 }); | 615 }); |
| 598 }); | 616 }); |
| 599 } | 617 } |
| 600 | 618 |
| 619 /// Skips the current test if the Dart repository's build step has not been run. | |
| 620 /// If we're running on a build bot, this will not skip the test. | |
| 621 /// | |
| 622 /// This ensures that users don't need to have built Dart themselves to run the | |
| 623 /// test, and that the test will always run on the build bot. | |
|
Bob Nystrom
2012/10/16 21:00:02
"and" -> "but"
nweiz
2012/10/16 21:09:24
Done.
| |
| 624 void ensureBuild() { | |
| 625 _schedule((_) { | |
| 626 return _findBuildDirectory().transform((dir) { | |
| 627 if (dir == null && !onBuildBot) { | |
| 628 _abortScheduled = true; | |
| 629 } | |
| 630 }); | |
| 631 }); | |
| 632 } | |
| 633 | |
| 634 /// All possible names for the output directory of the Dart build. | |
| 635 final List<String> _buildNames = [ | |
| 636 'ReleaseIA32', 'DebugIA32', 'ReleaseX64', 'DebugX64', 'ReleaseSIMARM', | |
| 637 'DebugSIMARM', 'ReleaseARM', 'DebugARM' | |
| 638 ]; | |
| 639 | |
| 640 /// Returns the path to the output directory of the Dart build, or null if none | |
| 641 /// is found. This also sets [_buildPath] if a build directory is found. | |
| 642 Future<String> _findBuildDirectory() { | |
| 643 if (_buildPath != null) return new Future.immediate(_buildPath); | |
| 644 | |
| 645 var buildDirectories = _buildNames.map((name) => | |
| 646 join(testDirectory, '../../../out', name)); | |
|
Bob Nystrom
2012/10/16 21:00:02
This directory is only "out" on Linux. On Mac, it'
nweiz
2012/10/16 21:09:24
It's like they want this to be difficult :p. Fixed
| |
| 647 return Futures.wait(buildDirectories.map(dirExists)).transform((found) { | |
| 648 for (var i = 0; i < found.length; i++) { | |
| 649 if (found[i]) { | |
| 650 _buildPath = buildDirectories[i]; | |
| 651 return _buildPath; | |
| 652 } | |
| 653 } | |
| 654 return null; | |
| 655 }); | |
| 656 } | |
| 657 | |
| 601 Future<Directory> _setUpSandbox() { | 658 Future<Directory> _setUpSandbox() { |
| 602 return createTempDir(); | 659 return createTempDir(); |
| 603 } | 660 } |
| 604 | 661 |
| 605 Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) { | 662 Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) { |
| 606 if (scheduled == null) return new Future.immediate(null); | 663 if (scheduled == null) return new Future.immediate(null); |
| 607 var iterator = scheduled.iterator(); | 664 var iterator = scheduled.iterator(); |
| 608 | 665 |
| 609 Future runNextEvent(_) { | 666 Future runNextEvent(_) { |
| 610 if (_abortScheduled || !iterator.hasNext()) { | 667 if (_abortScheduled || !iterator.hasNext()) { |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1202 } | 1259 } |
| 1203 | 1260 |
| 1204 /** | 1261 /** |
| 1205 * Schedules a callback to be called after Pub is run with [runPub], even if it | 1262 * Schedules a callback to be called after Pub is run with [runPub], even if it |
| 1206 * fails. | 1263 * fails. |
| 1207 */ | 1264 */ |
| 1208 void _scheduleCleanup(_ScheduledEvent event) { | 1265 void _scheduleCleanup(_ScheduledEvent event) { |
| 1209 if (_scheduledCleanup == null) _scheduledCleanup = []; | 1266 if (_scheduledCleanup == null) _scheduledCleanup = []; |
| 1210 _scheduledCleanup.add(event); | 1267 _scheduledCleanup.add(event); |
| 1211 } | 1268 } |
| OLD | NEW |