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

Side by Side Diff: lib/src/executable.dart

Issue 1062813006: Add the ability to run test suites in parallel. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 5 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
« no previous file with comments | « lib/src/backend/live_test_controller.dart ('k') | lib/src/runner/browser/compiler_pool.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 // TODO(nweiz): This is under lib so that it can be used by the unittest dummy 5 // TODO(nweiz): This is under lib so that it can be used by the unittest dummy
6 // package. Once that package is no longer being updated, move this back into 6 // package. Once that package is no longer being updated, move this back into
7 // bin. 7 // bin.
8 library test.executable; 8 library test.executable;
9 9
10 import 'dart:async'; 10 import 'dart:async';
11 import 'dart:io'; 11 import 'dart:io';
12 import 'dart:isolate'; 12 import 'dart:isolate';
13 import 'dart:math' as math;
13 14
14 import 'package:args/args.dart'; 15 import 'package:args/args.dart';
15 import 'package:stack_trace/stack_trace.dart'; 16 import 'package:stack_trace/stack_trace.dart';
16 import 'package:yaml/yaml.dart'; 17 import 'package:yaml/yaml.dart';
17 18
18 import 'backend/test_platform.dart'; 19 import 'backend/test_platform.dart';
19 import 'runner/reporter/compact.dart'; 20 import 'runner/reporter/compact.dart';
20 import 'runner/load_exception.dart'; 21 import 'runner/load_exception.dart';
21 import 'runner/loader.dart'; 22 import 'runner/loader.dart';
22 import 'util/exit_codes.dart' as exit_codes; 23 import 'util/exit_codes.dart' as exit_codes;
23 import 'util/io.dart'; 24 import 'util/io.dart';
24 import 'utils.dart'; 25 import 'utils.dart';
25 26
26 /// The argument parser used to parse the executable arguments. 27 /// The argument parser used to parse the executable arguments.
27 final _parser = new ArgParser(allowTrailingOptions: true); 28 final _parser = new ArgParser(allowTrailingOptions: true);
28 29
30 /// The default number of test suites to run at once.
31 ///
32 /// This defaults to half the available processors, since presumably some of
33 /// them will be used for the OS and other processes.
34 final _defaultConcurrency = math.max(1, Platform.numberOfProcessors ~/ 2);
35
29 /// A merged stream of all signals that tell the test runner to shut down 36 /// A merged stream of all signals that tell the test runner to shut down
30 /// gracefully. 37 /// gracefully.
31 /// 38 ///
32 /// Signals will only be captured as long as this has an active subscription. 39 /// Signals will only be captured as long as this has an active subscription.
33 /// Otherwise, they'll be handled by Dart's default signal handler, which 40 /// Otherwise, they'll be handled by Dart's default signal handler, which
34 /// terminates the program immediately. 41 /// terminates the program immediately.
35 final _signals = mergeStreams([ 42 final _signals = mergeStreams([
36 ProcessSignal.SIGTERM.watch(), ProcessSignal.SIGINT.watch() 43 ProcessSignal.SIGTERM.watch(), ProcessSignal.SIGINT.watch()
37 ]); 44 ]);
38 45
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 'Regular expression syntax is supported.'); 80 'Regular expression syntax is supported.');
74 _parser.addOption("plain-name", 81 _parser.addOption("plain-name",
75 abbr: 'N', 82 abbr: 'N',
76 help: 'A plain-text substring of the name of the test to run.'); 83 help: 'A plain-text substring of the name of the test to run.');
77 _parser.addOption("platform", 84 _parser.addOption("platform",
78 abbr: 'p', 85 abbr: 'p',
79 help: 'The platform(s) on which to run the tests.', 86 help: 'The platform(s) on which to run the tests.',
80 allowed: TestPlatform.all.map((platform) => platform.identifier).toList(), 87 allowed: TestPlatform.all.map((platform) => platform.identifier).toList(),
81 defaultsTo: 'vm', 88 defaultsTo: 'vm',
82 allowMultiple: true); 89 allowMultiple: true);
90 _parser.addOption("concurrency",
91 abbr: 'j',
92 help: 'The number of concurrent test suites run.\n'
93 '(defaults to $_defaultConcurrency)',
94 valueHelp: 'threads');
83 _parser.addOption("pub-serve", 95 _parser.addOption("pub-serve",
84 help: 'The port of a pub serve instance serving "test/".', 96 help: 'The port of a pub serve instance serving "test/".',
85 hide: !supportsPubServe, 97 hide: !supportsPubServe,
86 valueHelp: 'port'); 98 valueHelp: 'port');
87 _parser.addFlag("color", defaultsTo: null, 99 _parser.addFlag("color", defaultsTo: null,
88 help: 'Whether to use terminal colors.\n(auto-detected by default)'); 100 help: 'Whether to use terminal colors.\n(auto-detected by default)');
89 101
90 var options; 102 var options;
91 try { 103 try {
92 options = _parser.parse(args); 104 options = _parser.parse(args);
(...skipping 27 matching lines...) Expand all
120 return; 132 return;
121 } 133 }
122 } 134 }
123 135
124 var platforms = options["platform"].map(TestPlatform.find); 136 var platforms = options["platform"].map(TestPlatform.find);
125 var loader = new Loader(platforms, 137 var loader = new Loader(platforms,
126 pubServeUrl: pubServeUrl, 138 pubServeUrl: pubServeUrl,
127 packageRoot: options["package-root"], 139 packageRoot: options["package-root"],
128 color: color); 140 color: color);
129 141
142 var concurrency = _defaultConcurrency;
143 if (options["concurrency"] != null) {
144 try {
145 concurrency = int.parse(options["concurrency"]);
146 } catch (error) {
147 _printUsage('Couldn\'t parse --concurrency "${options["concurrency"]}":'
148 ' ${error.message}');
149 exitCode = exit_codes.usage;
150 return;
151 }
152 }
153
130 var signalSubscription; 154 var signalSubscription;
131 var closed = false; 155 var closed = false;
132 signalSubscription = _signals.listen((_) { 156 signalSubscription = _signals.listen((_) {
133 signalSubscription.cancel(); 157 signalSubscription.cancel();
134 closed = true; 158 closed = true;
135 loader.close(); 159 loader.close();
136 }); 160 });
137 161
138 new Future.sync(() { 162 new Future.sync(() {
139 var paths = options.rest; 163 var paths = options.rest;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 if (pattern is RegExp) { 203 if (pattern is RegExp) {
180 stderr.write('regular expression "${pattern.pattern}".'); 204 stderr.write('regular expression "${pattern.pattern}".');
181 } else { 205 } else {
182 stderr.writeln('"$pattern".'); 206 stderr.writeln('"$pattern".');
183 } 207 }
184 exitCode = exit_codes.data; 208 exitCode = exit_codes.data;
185 return null; 209 return null;
186 } 210 }
187 } 211 }
188 212
189 var reporter = new CompactReporter(flatten(suites), color: color); 213 var reporter = new CompactReporter(flatten(suites),
214 concurrency: concurrency, color: color);
190 215
191 // Override the signal handler to close [reporter]. [loader] will still be 216 // Override the signal handler to close [reporter]. [loader] will still be
192 // closed in the [whenComplete] below. 217 // closed in the [whenComplete] below.
193 signalSubscription.onData((_) { 218 signalSubscription.onData((_) {
194 signalSubscription.cancel(); 219 signalSubscription.cancel();
195 closed = true; 220 closed = true;
196 221
197 // Wait a bit to print this message, since printing it eagerly looks weird 222 // Wait a bit to print this message, since printing it eagerly looks weird
198 // if the tests then finish immediately. 223 // if the tests then finish immediately.
199 var timer = new Timer(new Duration(seconds: 1), () { 224 var timer = new Timer(new Duration(seconds: 1), () {
200 print("Waiting for current test to finish."); 225 // Print a blank line first to ensure that this doesn't interfere with
226 // the compact reporter's unfinished line.
227 print("");
228 print("Waiting for current test(s) to finish.");
201 print("Press Control-C again to terminate immediately."); 229 print("Press Control-C again to terminate immediately.");
202 }); 230 });
203 231
204 reporter.close().then((_) => timer.cancel()); 232 reporter.close().then((_) => timer.cancel());
205 }); 233 });
206 234
207 return reporter.run().then((success) { 235 return reporter.run().then((success) {
208 exitCode = success ? 0 : 1; 236 exitCode = success ? 0 : 1;
209 }).whenComplete(() { 237 }).whenComplete(() {
210 signalSubscription.cancel(); 238 signalSubscription.cancel();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 output = stderr; 284 output = stderr;
257 } 285 }
258 286
259 output.write("""$message 287 output.write("""$message
260 288
261 Usage: pub run test:test [files or directories...] 289 Usage: pub run test:test [files or directories...]
262 290
263 ${_parser.usage} 291 ${_parser.usage}
264 """); 292 """);
265 } 293 }
OLDNEW
« no previous file with comments | « lib/src/backend/live_test_controller.dart ('k') | lib/src/runner/browser/compiler_pool.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698