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

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

Issue 1922163002: Initial support to test.dart for running precompiler tests on android devices (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Classes and methods for executing tests. 6 * Classes and methods for executing tests.
7 * 7 *
8 * This module includes: 8 * This module includes:
9 * - Managing parallel execution of tests, including timeout checks. 9 * - Managing parallel execution of tests, including timeout checks.
10 * - Evaluating the output of each test as pass/fail/crash/timeout. 10 * - Evaluating the output of each test as pass/fail/crash/timeout.
11 */ 11 */
12 library test_runner; 12 library test_runner;
13 13
14 import "dart:async"; 14 import "dart:async";
15 import "dart:collection" show Queue; 15 import "dart:collection" show Queue;
16 import "dart:convert" show LineSplitter, UTF8, JSON; 16 import "dart:convert" show LineSplitter, UTF8, JSON;
17 // We need to use the 'io' prefix here, otherwise io.exitCode will shadow 17 // We need to use the 'io' prefix here, otherwise io.exitCode will shadow
18 // CommandOutput.exitCode in subclasses of CommandOutput. 18 // CommandOutput.exitCode in subclasses of CommandOutput.
19 import "dart:io" as io; 19 import "dart:io" as io;
20 import "dart:math" as math; 20 import "dart:math" as math;
21 import 'android.dart';
21 import 'dependency_graph.dart' as dgraph; 22 import 'dependency_graph.dart' as dgraph;
22 import "browser_controller.dart"; 23 import "browser_controller.dart";
23 import "path.dart"; 24 import "path.dart";
24 import "status_file_parser.dart"; 25 import "status_file_parser.dart";
25 import "test_progress.dart"; 26 import "test_progress.dart";
26 import "test_suite.dart"; 27 import "test_suite.dart";
27 import "utils.dart"; 28 import "utils.dart";
28 import 'record_and_replay.dart'; 29 import 'record_and_replay.dart';
29 30
30 const int CRASHING_BROWSER_EXITCODE = -10; 31 const int CRASHING_BROWSER_EXITCODE = -10;
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 bool _equal(AnalysisCommand other) => 338 bool _equal(AnalysisCommand other) =>
338 super._equal(other) && flavor == other.flavor; 339 super._equal(other) && flavor == other.flavor;
339 } 340 }
340 341
341 class VmCommand extends ProcessCommand { 342 class VmCommand extends ProcessCommand {
342 VmCommand._(String executable, List<String> arguments, 343 VmCommand._(String executable, List<String> arguments,
343 Map<String, String> environmentOverrides) 344 Map<String, String> environmentOverrides)
344 : super._("vm", executable, arguments, environmentOverrides); 345 : super._("vm", executable, arguments, environmentOverrides);
345 } 346 }
346 347
348 class AdbPrecompilationCommand extends Command {
349 final String precompiledRunnerFilename;
350 final String precompiledTestDirectory;
351 final bool useBlobs;
352
353 AdbPrecompilationCommand._(this.precompiledRunnerFilename,
354 this.precompiledTestDirectory,
355 this.useBlobs)
356 : super._("adb_precompilation");
357
358 void _buildHashCode(HashCodeBuilder builder) {
359 super._buildHashCode(builder);
360 builder.add(precompiledRunnerFilename);
361 builder.add(precompiledTestDirectory);
362 builder.add(useBlobs);
363 }
364
365 bool _equal(AdbPrecompilationCommand other) =>
366 super._equal(other) &&
367 precompiledRunnerFilename == other.precompiledRunnerFilename &&
368 useBlobs == other.useBlobs &&
369 precompiledTestDirectory == other.precompiledTestDirectory;
370
371 String toString() => 'Steps to push precompiled runner and precompiled code '
372 'to an attached device. Uses (and requires) adb.';
373 }
374
347 class JSCommandlineCommand extends ProcessCommand { 375 class JSCommandlineCommand extends ProcessCommand {
348 JSCommandlineCommand._( 376 JSCommandlineCommand._(
349 String displayName, String executable, List<String> arguments, 377 String displayName, String executable, List<String> arguments,
350 [Map<String, String> environmentOverrides = null]) 378 [Map<String, String> environmentOverrides = null])
351 : super._(displayName, executable, arguments, environmentOverrides); 379 : super._(displayName, executable, arguments, environmentOverrides);
352 } 380 }
353 381
354 class PubCommand extends ProcessCommand { 382 class PubCommand extends ProcessCommand {
355 final String command; 383 final String command;
356 384
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 flavor, displayName, executable, arguments, environmentOverrides); 631 flavor, displayName, executable, arguments, environmentOverrides);
604 return _getUniqueCommand(command); 632 return _getUniqueCommand(command);
605 } 633 }
606 634
607 VmCommand getVmCommand(String executable, List<String> arguments, 635 VmCommand getVmCommand(String executable, List<String> arguments,
608 Map<String, String> environmentOverrides) { 636 Map<String, String> environmentOverrides) {
609 var command = new VmCommand._(executable, arguments, environmentOverrides); 637 var command = new VmCommand._(executable, arguments, environmentOverrides);
610 return _getUniqueCommand(command); 638 return _getUniqueCommand(command);
611 } 639 }
612 640
641 AdbPrecompilationCommand getAdbPrecompiledCommand(String precompiledRunner,
642 String testDirectory,
643 bool useBlobs) {
644 var command = new AdbPrecompilationCommand._(
645 precompiledRunner, testDirectory, useBlobs);
646 return _getUniqueCommand(command);
647 }
648
613 Command getJSCommandlineCommand(String displayName, executable, arguments, 649 Command getJSCommandlineCommand(String displayName, executable, arguments,
614 [environment = null]) { 650 [environment = null]) {
615 var command = new JSCommandlineCommand._( 651 var command = new JSCommandlineCommand._(
616 displayName, executable, arguments, environment); 652 displayName, executable, arguments, environment);
617 return _getUniqueCommand(command); 653 return _getUniqueCommand(command);
618 } 654 }
619 655
620 Command getProcessCommand(String displayName, executable, arguments, 656 Command getProcessCommand(String displayName, executable, arguments,
621 [environment = null, workingDirectory = null]) { 657 [environment = null, workingDirectory = null]) {
622 var command = new ProcessCommand._( 658 var command = new ProcessCommand._(
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped); 1654 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
1619 } else if (command is BrowserTestCommand) { 1655 } else if (command is BrowserTestCommand) {
1620 return new HTMLBrowserCommandOutputImpl( 1656 return new HTMLBrowserCommandOutputImpl(
1621 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped); 1657 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
1622 } else if (command is AnalysisCommand) { 1658 } else if (command is AnalysisCommand) {
1623 return new AnalysisCommandOutputImpl( 1659 return new AnalysisCommandOutputImpl(
1624 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped); 1660 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
1625 } else if (command is VmCommand) { 1661 } else if (command is VmCommand) {
1626 return new VmCommandOutputImpl( 1662 return new VmCommandOutputImpl(
1627 command, exitCode, timedOut, stdout, stderr, time, pid); 1663 command, exitCode, timedOut, stdout, stderr, time, pid);
1664 } else if (command is AdbPrecompilationCommand) {
1665 return new VmCommandOutputImpl(
1666 command, exitCode, timedOut, stdout, stderr, time, pid);
1628 } else if (command is CompilationCommand) { 1667 } else if (command is CompilationCommand) {
1629 if (command.displayName == 'precompiler' || 1668 if (command.displayName == 'precompiler' ||
1630 command.displayName == 'dart2snapshot') { 1669 command.displayName == 'dart2snapshot') {
1631 return new VmCommandOutputImpl( 1670 return new VmCommandOutputImpl(
1632 command, exitCode, timedOut, stdout, stderr, time, pid); 1671 command, exitCode, timedOut, stdout, stderr, time, pid);
1633 } 1672 }
1634 return new CompilationCommandOutputImpl( 1673 return new CompilationCommandOutputImpl(
1635 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped); 1674 command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
1636 } else if (command is JSCommandlineCommand) { 1675 } else if (command is JSCommandlineCommand) {
1637 return new JsCommandlineOutputImpl( 1676 return new JsCommandlineOutputImpl(
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
2389 Future cleanup(); 2428 Future cleanup();
2390 // TODO(kustermann): The [timeout] parameter should be a property of Command 2429 // TODO(kustermann): The [timeout] parameter should be a property of Command
2391 Future<CommandOutput> runCommand( 2430 Future<CommandOutput> runCommand(
2392 dgraph.Node node, Command command, int timeout); 2431 dgraph.Node node, Command command, int timeout);
2393 } 2432 }
2394 2433
2395 class CommandExecutorImpl implements CommandExecutor { 2434 class CommandExecutorImpl implements CommandExecutor {
2396 final Map globalConfiguration; 2435 final Map globalConfiguration;
2397 final int maxProcesses; 2436 final int maxProcesses;
2398 final int maxBrowserProcesses; 2437 final int maxBrowserProcesses;
2438 AdbDevicePool adbDevicePool;
2399 2439
2400 // For dart2js and analyzer batch processing, 2440 // For dart2js and analyzer batch processing,
2401 // we keep a list of batch processes. 2441 // we keep a list of batch processes.
2402 final _batchProcesses = new Map<String, List<BatchRunnerProcess>>(); 2442 final _batchProcesses = new Map<String, List<BatchRunnerProcess>>();
2403 // We keep a BrowserTestRunner for every configuration. 2443 // We keep a BrowserTestRunner for every configuration.
2404 final _browserTestRunners = new Map<Map, BrowserTestRunner>(); 2444 final _browserTestRunners = new Map<Map, BrowserTestRunner>();
2405 2445
2406 bool _finishing = false; 2446 bool _finishing = false;
2407 2447
2408 CommandExecutorImpl( 2448 CommandExecutorImpl(
2409 this.globalConfiguration, this.maxProcesses, this.maxBrowserProcesses); 2449 this.globalConfiguration, this.maxProcesses, this.maxBrowserProcesses,
2450 {this.adbDevicePool});
2410 2451
2411 Future cleanup() { 2452 Future cleanup() {
2412 assert(!_finishing); 2453 assert(!_finishing);
2413 _finishing = true; 2454 _finishing = true;
2414 2455
2415 Future _terminateBatchRunners() { 2456 Future _terminateBatchRunners() {
2416 var futures = []; 2457 var futures = [];
2417 for (var runners in _batchProcesses.values) { 2458 for (var runners in _batchProcesses.values) {
2418 futures.addAll(runners.map((runner) => runner.terminate())); 2459 futures.addAll(runners.map((runner) => runner.terminate()));
2419 } 2460 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2453 if (command is BrowserTestCommand) { 2494 if (command is BrowserTestCommand) {
2454 return _startBrowserControllerTest(command, timeout); 2495 return _startBrowserControllerTest(command, timeout);
2455 } else if (command is CompilationCommand && dart2jsBatchMode) { 2496 } else if (command is CompilationCommand && dart2jsBatchMode) {
2456 return _getBatchRunner("dart2js") 2497 return _getBatchRunner("dart2js")
2457 .runCommand("dart2js", command, timeout, command.arguments); 2498 .runCommand("dart2js", command, timeout, command.arguments);
2458 } else if (command is AnalysisCommand && batchMode) { 2499 } else if (command is AnalysisCommand && batchMode) {
2459 return _getBatchRunner(command.flavor) 2500 return _getBatchRunner(command.flavor)
2460 .runCommand(command.flavor, command, timeout, command.arguments); 2501 .runCommand(command.flavor, command, timeout, command.arguments);
2461 } else if (command is ScriptCommand) { 2502 } else if (command is ScriptCommand) {
2462 return command.run(); 2503 return command.run();
2504 } else if (command is AdbPrecompilationCommand) {
2505 assert(adbDevicePool != null);
2506 return adbDevicePool.aquireDevice().then((AdbDevice device) {
2507 return _runAdbPrecompilationCommand(device, command).whenComplete(() {
2508 adbDevicePool.releaseDevice(device);
2509 });
2510 });
2463 } else { 2511 } else {
2464 return new RunningProcess(command, timeout).run(); 2512 return new RunningProcess(command, timeout).run();
2465 } 2513 }
2466 } 2514 }
2467 2515
2516 Future<CommandOutput> _runAdbPrecompilationCommand(
2517 AdbDevice device, AdbPrecompilationCommand command) async {
2518 var runner = command.precompiledRunnerFilename;
2519 var testdir = command.precompiledTestDirectory;
2520 var devicedir = '/data/local/tmp/precompilation-testing';
2521
2522 // We copy all the files which the vm precompiler puts into the test
2523 // directory.
2524 List<String> files = new io.Directory(testdir)
2525 .listSync()
2526 .where((fse) => fse is io.File)
2527 .map((file) => file.path)
2528 .map((path) => path.substring(path.lastIndexOf('/') + 1))
2529 .toList();
2530
2531 // All closures are of type "Future<AdbCommandResult> run()"
2532 List<Function> steps = [];
2533
2534 steps.add(() => device.runAdbShellCommand(
2535 ['rm', '-Rf', devicedir]));
2536 steps.add(() => device.runAdbShellCommand(
2537 ['mkdir', devicedir]));
2538 steps.add(() => device.runAdbCommand(
2539 ['push', runner, '$devicedir/runner']));
2540 steps.add(() => device.runAdbShellCommand(
2541 ['chmod', '777', '$devicedir/runner']));
2542
2543 for (var file in files) {
2544 steps.add(() => device.runAdbCommand(
2545 ['push', '$testdir/$file', '$devicedir/$file']));
2546 steps.add(() => device.runAdbShellCommand(
2547 ['chmod', '777', '$devicedir/$file']));
2548 }
2549
2550 if (command.useBlobs) {
2551 steps.add(() => device.runAdbShellCommand(
2552 ['$devicedir/runner', '--run-precompiled-snapshot=$devicedir',
2553 '--use_blobs', 'ignored.dart']));
2554 } else {
2555 steps.add(() => device.runAdbShellCommand(
2556 ['$devicedir/runner', '--run-precompiled-snapshot=$devicedir',
2557 'ignored.dart']));
2558 }
2559
2560 var stopwatch = new Stopwatch()..start();
2561 var writer = new StringBuffer();
2562
2563 await device.waitForBootCompleted();
2564 await device.waitForDevice();
2565
2566 AdbCommandResult result;
2567 for (var i = 0; i < steps.length; i++) {
2568 var fun = steps[i];
2569 var commandStopwatch = new Stopwatch()..start();
2570 result = await fun();
2571
2572 writer.writeln("Executing ${result.command}");
2573 if (result.stdout.length > 0) {
2574 writer.writeln("Stdout:\n${result.stdout.trim()}");
2575 }
2576 if (result.stderr.length > 0) {
2577 writer.writeln("Stderr:\n${result.stderr.trim()}");
2578 }
2579 writer.writeln("ExitCode: ${result.exitCode}");
2580 writer.writeln("Time: ${commandStopwatch.elapsed}");
2581 writer.writeln("");
2582
2583 // If one command fails, we stop processing the others and return
2584 // immediately.
2585 if (result.exitCode != 0) break;
2586 }
2587 return createCommandOutput(
2588 command, 0, false, UTF8.encode('$writer'),
2589 [], stopwatch.elapsed, false);
2590 }
2591
2468 BatchRunnerProcess _getBatchRunner(String identifier) { 2592 BatchRunnerProcess _getBatchRunner(String identifier) {
2469 // Start batch processes if needed 2593 // Start batch processes if needed
2470 var runners = _batchProcesses[identifier]; 2594 var runners = _batchProcesses[identifier];
2471 if (runners == null) { 2595 if (runners == null) {
2472 runners = new List<BatchRunnerProcess>(maxProcesses); 2596 runners = new List<BatchRunnerProcess>(maxProcesses);
2473 for (int i = 0; i < maxProcesses; i++) { 2597 for (int i = 0; i < maxProcesses; i++) {
2474 runners[i] = new BatchRunnerProcess(); 2598 runners[i] = new BatchRunnerProcess();
2475 } 2599 }
2476 _batchProcesses[identifier] = runners; 2600 _batchProcesses[identifier] = runners;
2477 } 2601 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
2709 Map _globalConfiguration; 2833 Map _globalConfiguration;
2710 2834
2711 Function _allDone; 2835 Function _allDone;
2712 final dgraph.Graph _graph = new dgraph.Graph(); 2836 final dgraph.Graph _graph = new dgraph.Graph();
2713 List<EventListener> _eventListener; 2837 List<EventListener> _eventListener;
2714 2838
2715 ProcessQueue(this._globalConfiguration, maxProcesses, maxBrowserProcesses, 2839 ProcessQueue(this._globalConfiguration, maxProcesses, maxBrowserProcesses,
2716 DateTime startTime, testSuites, this._eventListener, this._allDone, 2840 DateTime startTime, testSuites, this._eventListener, this._allDone,
2717 [bool verbose = false, 2841 [bool verbose = false,
2718 String recordingOutputFile, 2842 String recordingOutputFile,
2719 String recordedInputFile]) { 2843 String recordedInputFile,
2844 AdbDevicePool adbDevicePool]) {
2720 void setupForListing(TestCaseEnqueuer testCaseEnqueuer) { 2845 void setupForListing(TestCaseEnqueuer testCaseEnqueuer) {
2721 _graph.events 2846 _graph.events
2722 .where((event) => event is dgraph.GraphSealedEvent) 2847 .where((event) => event is dgraph.GraphSealedEvent)
2723 .listen((dgraph.GraphSealedEvent event) { 2848 .listen((dgraph.GraphSealedEvent event) {
2724 var testCases = new List.from(testCaseEnqueuer.remainingTestCases); 2849 var testCases = new List.from(testCaseEnqueuer.remainingTestCases);
2725 testCases.sort((a, b) => a.displayName.compareTo(b.displayName)); 2850 testCases.sort((a, b) => a.displayName.compareTo(b.displayName));
2726 2851
2727 print("\nGenerating all matching test cases ....\n"); 2852 print("\nGenerating all matching test cases ....\n");
2728 2853
2729 for (TestCase testCase in testCases) { 2854 for (TestCase testCase in testCases) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2810 var commandEnqueuer = new CommandEnqueuer(_graph); 2935 var commandEnqueuer = new CommandEnqueuer(_graph);
2811 2936
2812 // CommandExecutor will execute commands 2937 // CommandExecutor will execute commands
2813 var executor; 2938 var executor;
2814 if (recording) { 2939 if (recording) {
2815 executor = new RecordingCommandExecutor(new Path(recordingOutputFile)); 2940 executor = new RecordingCommandExecutor(new Path(recordingOutputFile));
2816 } else if (replaying) { 2941 } else if (replaying) {
2817 executor = new ReplayingCommandExecutor(new Path(recordedInputFile)); 2942 executor = new ReplayingCommandExecutor(new Path(recordedInputFile));
2818 } else { 2943 } else {
2819 executor = new CommandExecutorImpl( 2944 executor = new CommandExecutorImpl(
2820 _globalConfiguration, maxProcesses, maxBrowserProcesses); 2945 _globalConfiguration, maxProcesses,
2946 maxBrowserProcesses, adbDevicePool: adbDevicePool);
2821 } 2947 }
2822 2948
2823 // Run "runnable commands" using [executor] subject to 2949 // Run "runnable commands" using [executor] subject to
2824 // maxProcesses/maxBrowserProcesses constraint 2950 // maxProcesses/maxBrowserProcesses constraint
2825 commandQueue = new CommandQueue(_graph, testCaseEnqueuer, executor, 2951 commandQueue = new CommandQueue(_graph, testCaseEnqueuer, executor,
2826 maxProcesses, maxBrowserProcesses, verbose); 2952 maxProcesses, maxBrowserProcesses, verbose);
2827 2953
2828 // Finish test cases when all commands were run (or some failed) 2954 // Finish test cases when all commands were run (or some failed)
2829 var testCaseCompleter = 2955 var testCaseCompleter =
2830 new TestCaseCompleter(_graph, testCaseEnqueuer, commandQueue); 2956 new TestCaseCompleter(_graph, testCaseEnqueuer, commandQueue);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2886 } 3012 }
2887 } 3013 }
2888 3014
2889 void eventAllTestsDone() { 3015 void eventAllTestsDone() {
2890 for (var listener in _eventListener) { 3016 for (var listener in _eventListener) {
2891 listener.allDone(); 3017 listener.allDone();
2892 } 3018 }
2893 _allDone(); 3019 _allDone();
2894 } 3020 }
2895 } 3021 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698