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

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

Issue 1264393004: Pass Configuration to Loader and Server. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 5 years, 4 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 | « no previous file | lib/src/runner/browser/server.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 library test.runner; 5 library test.runner;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io'; 8 import 'dart:io';
9 9
10 import 'package:async/async.dart'; 10 import 'package:async/async.dart';
11 11
12 import 'backend/metadata.dart';
13 import 'backend/test_platform.dart'; 12 import 'backend/test_platform.dart';
14 import 'frontend/timeout.dart';
15 import 'runner/application_exception.dart'; 13 import 'runner/application_exception.dart';
16 import 'runner/configuration.dart'; 14 import 'runner/configuration.dart';
17 import 'runner/engine.dart'; 15 import 'runner/engine.dart';
18 import 'runner/load_exception.dart'; 16 import 'runner/load_exception.dart';
19 import 'runner/load_suite.dart'; 17 import 'runner/load_suite.dart';
20 import 'runner/loader.dart'; 18 import 'runner/loader.dart';
21 import 'runner/reporter.dart'; 19 import 'runner/reporter.dart';
22 import 'runner/reporter/compact.dart'; 20 import 'runner/reporter/compact.dart';
23 import 'runner/reporter/expanded.dart'; 21 import 'runner/reporter/expanded.dart';
24 import 'runner/runner_suite.dart'; 22 import 'runner/runner_suite.dart';
25 import 'util/io.dart'; 23 import 'util/io.dart';
26 import 'utils.dart'; 24 import 'utils.dart';
27 25
28 /// The set of platforms for which debug flags are (currently) not supported. 26 /// The set of platforms for which debug flags are (currently) not supported.
29 final _debugUnsupportedPlatforms = new Set.from( 27 final _debugUnsupportedPlatforms = new Set.from(
30 [TestPlatform.vm, TestPlatform.phantomJS]); 28 [TestPlatform.vm, TestPlatform.phantomJS]);
31 29
32 /// A class that loads and runs tests based on a [Configuration]. 30 /// A class that loads and runs tests based on a [Configuration].
33 /// 31 ///
34 /// This maintains a [Loader] and an [Engine] and passes test suites from one to 32 /// This maintains a [Loader] and an [Engine] and passes test suites from one to
35 /// the other, as well as printing out tests with a [CompactReporter] or an 33 /// the other, as well as printing out tests with a [CompactReporter] or an
36 /// [ExpandedReporter]. 34 /// [ExpandedReporter].
37 class Runner { 35 class Runner {
38 /// The configuration for the runner. 36 /// The configuration for the runner.
39 final Configuration _configuration; 37 final Configuration _config;
40 38
41 /// The loader that loads the test suites from the filesystem. 39 /// The loader that loads the test suites from the filesystem.
42 final Loader _loader; 40 final Loader _loader;
43 41
44 /// The engine that runs the test suites. 42 /// The engine that runs the test suites.
45 final Engine _engine; 43 final Engine _engine;
46 44
47 /// The reporter that's emitting the test runner's results. 45 /// The reporter that's emitting the test runner's results.
48 final Reporter _reporter; 46 final Reporter _reporter;
49 47
50 /// The subscription to the stream returned by [_loadSuites]. 48 /// The subscription to the stream returned by [_loadSuites].
51 StreamSubscription _suiteSubscription; 49 StreamSubscription _suiteSubscription;
52 50
53 /// The memoizer for ensuring [close] only runs once. 51 /// The memoizer for ensuring [close] only runs once.
54 final _closeMemo = new AsyncMemoizer(); 52 final _closeMemo = new AsyncMemoizer();
55 bool get _closed => _closeMemo.hasRun; 53 bool get _closed => _closeMemo.hasRun;
56 54
57 /// Creates a new runner based on [configuration]. 55 /// Creates a new runner based on [configuration].
58 factory Runner(Configuration configuration) { 56 factory Runner(Configuration config) {
59 var metadata = new Metadata( 57 var loader = new Loader(config);
60 timeout: configuration.pauseAfterLoad ? Timeout.none : null, 58 var engine = new Engine(concurrency: config.concurrency);
61 verboseTrace: configuration.verboseTrace);
62 var loader = new Loader(configuration.platforms,
63 pubServeUrl: configuration.pubServeUrl,
64 packageRoot: configuration.packageRoot,
65 color: configuration.color,
66 metadata: metadata,
67 jsTrace: configuration.jsTrace);
68 59
69 var engine = new Engine(concurrency: configuration.concurrency); 60 var watch = config.reporter == "compact"
70
71 var watch = configuration.reporter == "compact"
72 ? CompactReporter.watch 61 ? CompactReporter.watch
73 : ExpandedReporter.watch; 62 : ExpandedReporter.watch;
74 63
75 var reporter = watch( 64 var reporter = watch(
76 engine, 65 engine,
77 color: configuration.color, 66 color: config.color,
78 verboseTrace: configuration.verboseTrace, 67 verboseTrace: config.verboseTrace,
79 printPath: configuration.paths.length > 1 || 68 printPath: config.paths.length > 1 ||
80 new Directory(configuration.paths.single).existsSync(), 69 new Directory(config.paths.single).existsSync(),
81 printPlatform: configuration.platforms.length > 1); 70 printPlatform: config.platforms.length > 1);
82 71
83 return new Runner._(configuration, loader, engine, reporter); 72 return new Runner._(config, loader, engine, reporter);
84 } 73 }
85 74
86 Runner._(this._configuration, this._loader, this._engine, this._reporter); 75 Runner._(this._config, this._loader, this._engine, this._reporter);
87 76
88 /// Starts the runner. 77 /// Starts the runner.
89 /// 78 ///
90 /// This starts running tests and printing their progress. It returns whether 79 /// This starts running tests and printing their progress. It returns whether
91 /// or not they ran successfully. 80 /// or not they ran successfully.
92 Future<bool> run() async { 81 Future<bool> run() async {
93 if (_closed) { 82 if (_closed) {
94 throw new StateError("run() may not be called on a closed Runner."); 83 throw new StateError("run() may not be called on a closed Runner.");
95 } 84 }
96 85
97 var suites = _loadSuites(); 86 var suites = _loadSuites();
98 87
99 var success; 88 var success;
100 if (_configuration.pauseAfterLoad) { 89 if (_config.pauseAfterLoad) {
101 success = await _loadThenPause(suites); 90 success = await _loadThenPause(suites);
102 } else { 91 } else {
103 _suiteSubscription = suites.listen(_engine.suiteSink.add); 92 _suiteSubscription = suites.listen(_engine.suiteSink.add);
104 var results = await Future.wait([ 93 var results = await Future.wait([
105 _suiteSubscription.asFuture().then((_) => _engine.suiteSink.close()), 94 _suiteSubscription.asFuture().then((_) => _engine.suiteSink.close()),
106 _engine.run() 95 _engine.run()
107 ], eagerError: true); 96 ], eagerError: true);
108 success = results.last; 97 success = results.last;
109 } 98 }
110 99
111 if (_closed) return false; 100 if (_closed) return false;
112 101
113 if (_engine.passed.length == 0 && _engine.failed.length == 0 && 102 if (_engine.passed.length == 0 && _engine.failed.length == 0 &&
114 _engine.skipped.length == 0 && _configuration.pattern != null) { 103 _engine.skipped.length == 0 && _config.pattern != null) {
115 var message = 'No tests match '; 104 var message = 'No tests match ';
116 105
117 if (_configuration.pattern is RegExp) { 106 if (_config.pattern is RegExp) {
118 var pattern = (_configuration.pattern as RegExp).pattern; 107 var pattern = (_config.pattern as RegExp).pattern;
119 message += 'regular expression "$pattern".'; 108 message += 'regular expression "$pattern".';
120 } else { 109 } else {
121 message += '"${_configuration.pattern}".'; 110 message += '"${_config.pattern}".';
122 } 111 }
123 throw new ApplicationException(message); 112 throw new ApplicationException(message);
124 } 113 }
125 114
126 // Explicitly check "== true" here because [Engine.run] can return `null` 115 // Explicitly check "== true" here because [Engine.run] can return `null`
127 // if the engine was closed prematurely. 116 // if the engine was closed prematurely.
128 return success == true; 117 return success == true;
129 } 118 }
130 119
131 /// Closes the runner. 120 /// Closes the runner.
(...skipping 19 matching lines...) Expand all
151 if (_suiteSubscription != null) _suiteSubscription.cancel(); 140 if (_suiteSubscription != null) _suiteSubscription.cancel();
152 _suiteSubscription = null; 141 _suiteSubscription = null;
153 142
154 // Make sure we close the engine *before* the loader. Otherwise, 143 // Make sure we close the engine *before* the loader. Otherwise,
155 // LoadSuites provided by the loader may get into bad states. 144 // LoadSuites provided by the loader may get into bad states.
156 await _engine.close(); 145 await _engine.close();
157 if (timer != null) timer.cancel(); 146 if (timer != null) timer.cancel();
158 await _loader.close(); 147 await _loader.close();
159 }); 148 });
160 149
161 /// Return a stream of [LoadSuite]s in [_configuration.paths]. 150 /// Return a stream of [LoadSuite]s in [_config.paths].
162 /// 151 ///
163 /// Only tests that match [_configuration.pattern] will be included in the 152 /// Only tests that match [_config.pattern] will be included in the
164 /// suites once they're loaded. 153 /// suites once they're loaded.
165 Stream<LoadSuite> _loadSuites() { 154 Stream<LoadSuite> _loadSuites() {
166 return mergeStreams(_configuration.paths.map((path) { 155 return mergeStreams(_config.paths.map((path) {
167 if (new Directory(path).existsSync()) return _loader.loadDir(path); 156 if (new Directory(path).existsSync()) return _loader.loadDir(path);
168 if (new File(path).existsSync()) return _loader.loadFile(path); 157 if (new File(path).existsSync()) return _loader.loadFile(path);
169 158
170 return new Stream.fromIterable([ 159 return new Stream.fromIterable([
171 new LoadSuite("loading $path", () => 160 new LoadSuite("loading $path", () =>
172 throw new LoadException(path, 'Does not exist.')) 161 throw new LoadException(path, 'Does not exist.'))
173 ]); 162 ]);
174 })).map((loadSuite) { 163 })).map((loadSuite) {
175 return loadSuite.changeSuite((suite) { 164 return loadSuite.changeSuite((suite) {
176 if (_configuration.pattern == null) return suite; 165 if (_config.pattern == null) return suite;
177 return suite.change(tests: suite.tests.where((test) => 166 return suite.change(tests: suite.tests.where((test) =>
178 test.name.contains(_configuration.pattern))); 167 test.name.contains(_config.pattern)));
179 }); 168 });
180 }); 169 });
181 } 170 }
182 171
183 /// Loads each suite in [suites] in order, pausing after load for platforms 172 /// Loads each suite in [suites] in order, pausing after load for platforms
184 /// that support debugging. 173 /// that support debugging.
185 Future<bool> _loadThenPause(Stream<LoadSuite> suites) async { 174 Future<bool> _loadThenPause(Stream<LoadSuite> suites) async {
186 var unsupportedPlatforms = _configuration.platforms 175 var unsupportedPlatforms = _config.platforms
187 .where(_debugUnsupportedPlatforms.contains) 176 .where(_debugUnsupportedPlatforms.contains)
188 .map((platform) => 177 .map((platform) =>
189 platform == TestPlatform.vm ? "the Dart VM" : platform.name) 178 platform == TestPlatform.vm ? "the Dart VM" : platform.name)
190 .toList(); 179 .toList();
191 180
192 if (unsupportedPlatforms.isNotEmpty) { 181 if (unsupportedPlatforms.isNotEmpty) {
193 warn( 182 warn(
194 wordWrap("Debugging is currently unsupported on " 183 wordWrap("Debugging is currently unsupported on "
195 "${toSentence(unsupportedPlatforms)}."), 184 "${toSentence(unsupportedPlatforms)}."),
196 color: _configuration.color); 185 color: _config.color);
197 } 186 }
198 187
199 _suiteSubscription = suites.asyncMap((loadSuite) async { 188 _suiteSubscription = suites.asyncMap((loadSuite) async {
200 // Make the underlying suite null so that the engine doesn't start running 189 // Make the underlying suite null so that the engine doesn't start running
201 // it immediately. 190 // it immediately.
202 _engine.suiteSink.add(loadSuite.changeSuite((_) => null)); 191 _engine.suiteSink.add(loadSuite.changeSuite((_) => null));
203 192
204 var suite = await loadSuite.suite; 193 var suite = await loadSuite.suite;
205 if (suite == null) return; 194 if (suite == null) return;
206 195
(...skipping 16 matching lines...) Expand all
223 /// 212 ///
224 /// This is a no-op for test suites that aren't on platforms where debugging 213 /// This is a no-op for test suites that aren't on platforms where debugging
225 /// is supported. 214 /// is supported.
226 Future _pause(RunnerSuite suite) async { 215 Future _pause(RunnerSuite suite) async {
227 if (suite.platform == null) return; 216 if (suite.platform == null) return;
228 if (_debugUnsupportedPlatforms.contains(suite.platform)) return; 217 if (_debugUnsupportedPlatforms.contains(suite.platform)) return;
229 218
230 try { 219 try {
231 _reporter.pause(); 220 _reporter.pause();
232 221
233 var bold = _configuration.color ? '\u001b[1m' : ''; 222 var bold = _config.color ? '\u001b[1m' : '';
234 var yellow = _configuration.color ? '\u001b[33m' : ''; 223 var yellow = _config.color ? '\u001b[33m' : '';
235 var noColor = _configuration.color ? '\u001b[0m' : ''; 224 var noColor = _config.color ? '\u001b[0m' : '';
236 print(''); 225 print('');
237 226
238 if (suite.platform.isDartVM) { 227 if (suite.platform.isDartVM) {
239 var url = suite.environment.observatoryUrl; 228 var url = suite.environment.observatoryUrl;
240 if (url == null) { 229 if (url == null) {
241 print("${yellow}Observatory URL not found. Make sure you're using " 230 print("${yellow}Observatory URL not found. Make sure you're using "
242 "${suite.platform.name} 1.11 or later.$noColor"); 231 "${suite.platform.name} 1.11 or later.$noColor");
243 } else { 232 } else {
244 print("Observatory URL: $bold$url$noColor"); 233 print("Observatory URL: $bold$url$noColor");
245 } 234 }
(...skipping 16 matching lines...) Expand all
262 251
263 await inCompletionOrder([ 252 await inCompletionOrder([
264 suite.environment.displayPause(), 253 suite.environment.displayPause(),
265 cancelableNext(stdinLines) 254 cancelableNext(stdinLines)
266 ]).first; 255 ]).first;
267 } finally { 256 } finally {
268 _reporter.resume(); 257 _reporter.resume();
269 } 258 }
270 } 259 }
271 } 260 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/runner/browser/server.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698