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

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: Cleanup of CL and of existing code. Created 4 years, 7 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) {
Florian Schneider 2016/04/27 13:53:05 s/aquire/acquire/
kustermann 2016/05/02 10:40:23 Done.
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']));
Florian Schneider 2016/04/28 13:18:30 Maybe add a TODO that we should push the runner (d
kustermann 2016/05/02 10:40:23 Done.
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 }
2547
2548 if (command.useBlobs) {
2549 steps.add(() => device.runAdbShellCommand(
2550 ['$devicedir/runner', '--run-precompiled-snapshot=$devicedir',
2551 '--use_blobs', 'ignored.dart']));
2552 } else {
2553 steps.add(() => device.runAdbShellCommand(
2554 ['$devicedir/runner', '--run-precompiled-snapshot=$devicedir',
2555 'ignored.dart']));
2556 }
2557
2558 var stopwatch = new Stopwatch()..start();
2559 var writer = new StringBuffer();
2560
2561 await device.waitForBootCompleted();
2562 await device.waitForDevice();
2563
2564 AdbCommandResult result;
2565 for (var i = 0; i < steps.length; i++) {
2566 var fun = steps[i];
2567 var commandStopwatch = new Stopwatch()..start();
2568 result = await fun();
2569
2570 writer.writeln("Executing ${result.command}");
2571 if (result.stdout.length > 0) {
2572 writer.writeln("Stdout:\n${result.stdout.trim()}");
2573 }
2574 if (result.stderr.length > 0) {
2575 writer.writeln("Stderr:\n${result.stderr.trim()}");
2576 }
2577 writer.writeln("ExitCode: ${result.exitCode}");
2578 writer.writeln("Time: ${commandStopwatch.elapsed}");
2579 writer.writeln("");
2580
2581 // If one command fails, we stop processing the others and return
2582 // immediately.
2583 if (result.exitCode != 0) break;
2584 }
2585 return createCommandOutput(
2586 command, result.exitCode, false, UTF8.encode('$writer'),
2587 [], stopwatch.elapsed, false);
2588 }
2589
2468 BatchRunnerProcess _getBatchRunner(String identifier) { 2590 BatchRunnerProcess _getBatchRunner(String identifier) {
2469 // Start batch processes if needed 2591 // Start batch processes if needed
2470 var runners = _batchProcesses[identifier]; 2592 var runners = _batchProcesses[identifier];
2471 if (runners == null) { 2593 if (runners == null) {
2472 runners = new List<BatchRunnerProcess>(maxProcesses); 2594 runners = new List<BatchRunnerProcess>(maxProcesses);
2473 for (int i = 0; i < maxProcesses; i++) { 2595 for (int i = 0; i < maxProcesses; i++) {
2474 runners[i] = new BatchRunnerProcess(); 2596 runners[i] = new BatchRunnerProcess();
2475 } 2597 }
2476 _batchProcesses[identifier] = runners; 2598 _batchProcesses[identifier] = runners;
2477 } 2599 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
2709 Map _globalConfiguration; 2831 Map _globalConfiguration;
2710 2832
2711 Function _allDone; 2833 Function _allDone;
2712 final dgraph.Graph _graph = new dgraph.Graph(); 2834 final dgraph.Graph _graph = new dgraph.Graph();
2713 List<EventListener> _eventListener; 2835 List<EventListener> _eventListener;
2714 2836
2715 ProcessQueue(this._globalConfiguration, maxProcesses, maxBrowserProcesses, 2837 ProcessQueue(this._globalConfiguration, maxProcesses, maxBrowserProcesses,
2716 DateTime startTime, testSuites, this._eventListener, this._allDone, 2838 DateTime startTime, testSuites, this._eventListener, this._allDone,
2717 [bool verbose = false, 2839 [bool verbose = false,
2718 String recordingOutputFile, 2840 String recordingOutputFile,
2719 String recordedInputFile]) { 2841 String recordedInputFile,
2842 AdbDevicePool adbDevicePool]) {
2720 void setupForListing(TestCaseEnqueuer testCaseEnqueuer) { 2843 void setupForListing(TestCaseEnqueuer testCaseEnqueuer) {
2721 _graph.events 2844 _graph.events
2722 .where((event) => event is dgraph.GraphSealedEvent) 2845 .where((event) => event is dgraph.GraphSealedEvent)
2723 .listen((dgraph.GraphSealedEvent event) { 2846 .listen((dgraph.GraphSealedEvent event) {
2724 var testCases = new List.from(testCaseEnqueuer.remainingTestCases); 2847 var testCases = new List.from(testCaseEnqueuer.remainingTestCases);
2725 testCases.sort((a, b) => a.displayName.compareTo(b.displayName)); 2848 testCases.sort((a, b) => a.displayName.compareTo(b.displayName));
2726 2849
2727 print("\nGenerating all matching test cases ....\n"); 2850 print("\nGenerating all matching test cases ....\n");
2728 2851
2729 for (TestCase testCase in testCases) { 2852 for (TestCase testCase in testCases) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2810 var commandEnqueuer = new CommandEnqueuer(_graph); 2933 var commandEnqueuer = new CommandEnqueuer(_graph);
2811 2934
2812 // CommandExecutor will execute commands 2935 // CommandExecutor will execute commands
2813 var executor; 2936 var executor;
2814 if (recording) { 2937 if (recording) {
2815 executor = new RecordingCommandExecutor(new Path(recordingOutputFile)); 2938 executor = new RecordingCommandExecutor(new Path(recordingOutputFile));
2816 } else if (replaying) { 2939 } else if (replaying) {
2817 executor = new ReplayingCommandExecutor(new Path(recordedInputFile)); 2940 executor = new ReplayingCommandExecutor(new Path(recordedInputFile));
2818 } else { 2941 } else {
2819 executor = new CommandExecutorImpl( 2942 executor = new CommandExecutorImpl(
2820 _globalConfiguration, maxProcesses, maxBrowserProcesses); 2943 _globalConfiguration, maxProcesses,
2944 maxBrowserProcesses, adbDevicePool: adbDevicePool);
2821 } 2945 }
2822 2946
2823 // Run "runnable commands" using [executor] subject to 2947 // Run "runnable commands" using [executor] subject to
2824 // maxProcesses/maxBrowserProcesses constraint 2948 // maxProcesses/maxBrowserProcesses constraint
2825 commandQueue = new CommandQueue(_graph, testCaseEnqueuer, executor, 2949 commandQueue = new CommandQueue(_graph, testCaseEnqueuer, executor,
2826 maxProcesses, maxBrowserProcesses, verbose); 2950 maxProcesses, maxBrowserProcesses, verbose);
2827 2951
2828 // Finish test cases when all commands were run (or some failed) 2952 // Finish test cases when all commands were run (or some failed)
2829 var testCaseCompleter = 2953 var testCaseCompleter =
2830 new TestCaseCompleter(_graph, testCaseEnqueuer, commandQueue); 2954 new TestCaseCompleter(_graph, testCaseEnqueuer, commandQueue);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2886 } 3010 }
2887 } 3011 }
2888 3012
2889 void eventAllTestsDone() { 3013 void eventAllTestsDone() {
2890 for (var listener in _eventListener) { 3014 for (var listener in _eventListener) {
2891 listener.allDone(); 3015 listener.allDone();
2892 } 3016 }
2893 _allDone(); 3017 _allDone();
2894 } 3018 }
2895 } 3019 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698