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

Side by Side Diff: utils/tests/pub/test_pub.dart

Issue 11785028: Commit Martin's patch for pub + lib_v2. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revise. Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « utils/tests/pub/pub_uploader_test.dart ('k') | no next file » | 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) 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 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub 5 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub
6 /// tests are integration tests that stage some stuff on the file system, run 6 /// tests are integration tests that stage some stuff on the file system, run
7 /// pub, and then validate the results. This library provides an API to build 7 /// pub, and then validate the results. This library provides an API to build
8 /// tests like that. 8 /// tests like that.
9 library test_pub; 9 library test_pub;
10 10
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 for (var spec in resolvedPubspecs) { 163 for (var spec in resolvedPubspecs) {
164 var name = spec['name']; 164 var name = spec['name'];
165 var version = spec['version']; 165 var version = spec['version'];
166 var versions = _servedPackages.putIfAbsent( 166 var versions = _servedPackages.putIfAbsent(
167 name, () => <String, String>{}); 167 name, () => <String, String>{});
168 versions[version] = yaml(spec); 168 versions[version] = yaml(spec);
169 } 169 }
170 170
171 _servedPackageDir.contents.clear(); 171 _servedPackageDir.contents.clear();
172 for (var name in _servedPackages.keys) { 172 for (var name in _servedPackages.keys) {
173 var versions = _servedPackages[name].keys.toList()); 173 var versions = _servedPackages[name].keys.toList();
174 _servedPackageDir.contents.addAll([ 174 _servedPackageDir.contents.addAll([
175 file('$name.json', 175 file('$name.json',
176 json.stringify({'versions': versions})), 176 json.stringify({'versions': versions})),
177 dir(name, [ 177 dir(name, [
178 dir('versions', flatten(versions.mappedBy((version) { 178 dir('versions', flatten(versions.mappedBy((version) {
179 return [ 179 return [
180 file('$version.yaml', _servedPackages[name][version]), 180 file('$version.yaml', _servedPackages[name][version]),
181 tar('$version.tar.gz', [ 181 tar('$version.tar.gz', [
182 file('pubspec.yaml', _servedPackages[name][version]), 182 file('pubspec.yaml', _servedPackages[name][version]),
183 libDir(name, '$name $version') 183 libDir(name, '$name $version')
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 if (createdSandboxDir != null) return deleteDir(createdSandboxDir); 458 if (createdSandboxDir != null) return deleteDir(createdSandboxDir);
459 return new Future.immediate(null); 459 return new Future.immediate(null);
460 }); 460 });
461 } 461 }
462 462
463 final future = _setUpSandbox().then((sandboxDir) { 463 final future = _setUpSandbox().then((sandboxDir) {
464 createdSandboxDir = sandboxDir; 464 createdSandboxDir = sandboxDir;
465 return _runScheduled(sandboxDir, _scheduled); 465 return _runScheduled(sandboxDir, _scheduled);
466 }); 466 });
467 467
468 future.catchError((error) { 468 future.catchError((e) {
469 // If an error occurs during testing, delete the sandbox, throw the error so 469 // If an error occurs during testing, delete the sandbox, throw the error so
470 // that the test framework sees it, then finally call asyncDone so that the 470 // that the test framework sees it, then finally call asyncDone so that the
471 // test framework knows we're done doing asynchronous stuff. 471 // test framework knows we're done doing asynchronous stuff.
472 var subFuture = _runScheduled(createdSandboxDir, _scheduledOnException) 472 var subFuture = _runScheduled(createdSandboxDir, _scheduledOnException)
473 .then((_) => cleanup()); 473 .then((_) => cleanup());
474 subFuture.catchError((e) { 474 subFuture.catchError((e) {
475 print("Exception while cleaning up: ${e.error}"); 475 print("Exception while cleaning up: ${e.error}");
476 print(e.stackTrace); 476 print(e.stackTrace);
477 registerException(e.error, e.stackTrace); 477 registerException(e.error, e.stackTrace);
478 return true; 478 return true;
479 }); 479 });
480 subFuture.then((_) => registerException(e.error, e.stackTrace));
481 return true;
482 });
483
480 timeout(future, _TIMEOUT, 'waiting for a test to complete') 484 timeout(future, _TIMEOUT, 'waiting for a test to complete')
481 .then((_) => cleanup()) 485 .then((_) => cleanup())
482 .then((_) => asyncDone()); 486 .then((_) => asyncDone());
483 } 487 }
484 488
485 /// Get the path to the root "util/test/pub" directory containing the pub 489 /// Get the path to the root "util/test/pub" directory containing the pub
486 /// tests. 490 /// tests.
487 String get testDirectory { 491 String get testDirectory {
488 var dir = new Options().script; 492 var dir = new Options().script;
489 while (basename(dir) != 'pub') dir = dirname(dir); 493 while (basename(dir) != 'pub') dir = dirname(dir);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 _doPub(startProcess, sandboxDir, args, tokenEndpoint)); 545 _doPub(startProcess, sandboxDir, args, tokenEndpoint));
542 return new ScheduledProcess("pub", process); 546 return new ScheduledProcess("pub", process);
543 } 547 }
544 548
545 /// Like [startPub], but runs `pub lish` in particular with [server] used both 549 /// Like [startPub], but runs `pub lish` in particular with [server] used both
546 /// as the OAuth2 server (with "/token" as the token endpoint) and as the 550 /// as the OAuth2 server (with "/token" as the token endpoint) and as the
547 /// package server. 551 /// package server.
548 /// 552 ///
549 /// Any futures in [args] will be resolved before the process is started. 553 /// Any futures in [args] will be resolved before the process is started.
550 ScheduledProcess startPubLish(ScheduledServer server, {List args}) { 554 ScheduledProcess startPubLish(ScheduledServer server, {List args}) {
551 var tokenEndpoint = server.url.transform((url) => 555 var tokenEndpoint = server.url.then((url) =>
552 url.resolve('/token').toString()); 556 url.resolve('/token').toString());
553 if (args == null) args = []; 557 if (args == null) args = [];
554 args = flatten(['lish', '--server', tokenEndpoint, args]); 558 args = flatten(['lish', '--server', tokenEndpoint, args]);
555 return startPub(args: args, tokenEndpoint: tokenEndpoint); 559 return startPub(args: args, tokenEndpoint: tokenEndpoint);
556 } 560 }
557 561
558 /// Handles the beginning confirmation process for uploading a packages. 562 /// Handles the beginning confirmation process for uploading a packages.
559 /// Ensures that the right output is shown and then enters "y" to confirm the 563 /// Ensures that the right output is shown and then enters "y" to confirm the
560 /// upload. 564 /// upload.
561 void confirmPublish(ScheduledProcess pub) { 565 void confirmPublish(ScheduledProcess pub) {
(...skipping 13 matching lines...) Expand all
575 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn] 579 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
576 /// should have the same signature as [startProcess], except that the returned 580 /// should have the same signature as [startProcess], except that the returned
577 /// [Future] may have a type other than [Process]. 581 /// [Future] may have a type other than [Process].
578 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) { 582 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
579 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); 583 String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
580 584
581 return Futures.wait([ 585 return Futures.wait([
582 ensureDir(pathInSandbox(appPath)), 586 ensureDir(pathInSandbox(appPath)),
583 _awaitObject(args), 587 _awaitObject(args),
584 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint 588 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
585 ]).chain((results) { 589 ]).then((results) {
586 var args = results[1]; 590 var args = results[1];
587 var tokenEndpoint = results[2]; 591 var tokenEndpoint = results[2];
588 // Find a Dart executable we can use to spawn. Use the same one that was 592 // Find a Dart executable we can use to spawn. Use the same one that was
589 // used to run this script itself. 593 // used to run this script itself.
590 var dartBin = new Options().executable; 594 var dartBin = new Options().executable;
591 595
592 // If the executable looks like a path, get its full path. That way we 596 // If the executable looks like a path, get its full path. That way we
593 // can still find it when we spawn it with a different working directory. 597 // can still find it when we spawn it with a different working directory.
594 if (dartBin.contains(Platform.pathSeparator)) { 598 if (dartBin.contains(Platform.pathSeparator)) {
595 dartBin = new File(dartBin).fullPathSync(); 599 dartBin = new File(dartBin).fullPathSync();
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled 1157 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled
1154 /// Future that contains the erros and warnings produced by that validator. 1158 /// Future that contains the erros and warnings produced by that validator.
1155 Future<Pair<List<String>, List<String>>> schedulePackageValidation( 1159 Future<Pair<List<String>, List<String>>> schedulePackageValidation(
1156 ValidatorCreator fn) { 1160 ValidatorCreator fn) {
1157 return _scheduleValue((sandboxDir) { 1161 return _scheduleValue((sandboxDir) {
1158 var cache = new SystemCache.withSources( 1162 var cache = new SystemCache.withSources(
1159 join(sandboxDir, cachePath), 1163 join(sandboxDir, cachePath),
1160 join(sandboxDir, sdkPath)); 1164 join(sandboxDir, sdkPath));
1161 1165
1162 return Entrypoint.load(join(sandboxDir, appPath), cache) 1166 return Entrypoint.load(join(sandboxDir, appPath), cache)
1163 .chain((entrypoint) { 1167 .then((entrypoint) {
1164 var validator = fn(entrypoint); 1168 var validator = fn(entrypoint);
1165 return validator.validate().then((_) { 1169 return validator.validate().then((_) {
1166 return new Pair(validator.errors, validator.warnings); 1170 return new Pair(validator.errors, validator.warnings);
1167 }); 1171 });
1168 }); 1172 });
1169 }); 1173 });
1170 } 1174 }
1171 1175
1172 /// A matcher that matches a Pair. 1176 /// A matcher that matches a Pair.
1173 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) => 1177 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) =>
(...skipping 26 matching lines...) Expand all
1200 /// 1204 ///
1201 /// Before running the test, either [shouldExit] or [kill] must be called on 1205 /// Before running the test, either [shouldExit] or [kill] must be called on
1202 /// this to ensure that the process terminates when expected. 1206 /// this to ensure that the process terminates when expected.
1203 /// 1207 ///
1204 /// If the test fails, this will automatically print out any remaining stdout 1208 /// If the test fails, this will automatically print out any remaining stdout
1205 /// and stderr from the process to aid debugging. 1209 /// and stderr from the process to aid debugging.
1206 class ScheduledProcess { 1210 class ScheduledProcess {
1207 /// The name of the process. Used for error reporting. 1211 /// The name of the process. Used for error reporting.
1208 final String name; 1212 final String name;
1209 1213
1210 /// The process that's scheduled to run. 1214 /// The process future that's scheduled to run.
1211 final Future<Process> _process; 1215 Future<Process> _processFuture;
1216
1217 /// The process that's scheduled to run. It may be null.
1218 Process _process;
1219
1220 /// The exit code of the scheduled program. It may be null.
1221 int _exitCode;
1212 1222
1213 /// A [StringInputStream] wrapping the stdout of the process that's scheduled 1223 /// A [StringInputStream] wrapping the stdout of the process that's scheduled
1214 /// to run. 1224 /// to run.
1215 final Future<StringInputStream> _stdout; 1225 final Future<StringInputStream> _stdoutFuture;
1216 1226
1217 /// A [StringInputStream] wrapping the stderr of the process that's scheduled 1227 /// A [StringInputStream] wrapping the stderr of the process that's scheduled
1218 /// to run. 1228 /// to run.
1219 final Future<StringInputStream> _stderr; 1229 final Future<StringInputStream> _stderrFuture;
1220 1230
1221 /// The exit code of the process that's scheduled to run. This will naturally 1231 /// The exit code of the process that's scheduled to run. This will naturally
1222 /// only complete once the process has terminated. 1232 /// only complete once the process has terminated.
1223 Future<int> get _exitCode => _exitCodeCompleter.future; 1233 Future<int> get _exitCodeFuture => _exitCodeCompleter.future;
1224 1234
1225 /// The completer for [_exitCode]. 1235 /// The completer for [_exitCode].
1226 final Completer<int> _exitCodeCompleter = new Completer(); 1236 final Completer<int> _exitCodeCompleter = new Completer();
1227 1237
1228 /// Whether the user has scheduled the end of this process by calling either 1238 /// Whether the user has scheduled the end of this process by calling either
1229 /// [shouldExit] or [kill]. 1239 /// [shouldExit] or [kill].
1230 bool _endScheduled = false; 1240 bool _endScheduled = false;
1231 1241
1232 /// Whether the process is expected to terminate at this point. 1242 /// Whether the process is expected to terminate at this point.
1233 bool _endExpected = false; 1243 bool _endExpected = false;
1234 1244
1235 /// Wraps a [Process] [Future] in a scheduled process. 1245 /// Wraps a [Process] [Future] in a scheduled process.
1236 ScheduledProcess(this.name, Future<Process> process) 1246 ScheduledProcess(this.name, Future<Process> process)
1237 : _process = process, 1247 : _processFuture = process,
1238 _stdout = process.then((p) => new StringInputStream(p.stdout)), 1248 _stdoutFuture = process.then((p) => new StringInputStream(p.stdout)),
1239 _stderr = process.then((p) => new StringInputStream(p.stderr)) { 1249 _stderrFuture = process.then((p) => new StringInputStream(p.stderr)) {
1250 process.then((p) {
1251 _process = p;
1252 });
1240 1253
1241 _schedule((_) { 1254 _schedule((_) {
1242 if (!_endScheduled) { 1255 if (!_endScheduled) {
1243 throw new StateError("Scheduled process $name must have shouldExit() " 1256 throw new StateError("Scheduled process $name must have shouldExit() "
1244 "or kill() called before the test is run."); 1257 "or kill() called before the test is run.");
1245 } 1258 }
1246 1259
1247 return _process.then((p) { 1260 return process.then((p) {
1248 p.onExit = (c) { 1261 p.onExit = (c) {
1249 if (_endExpected) { 1262 if (_endExpected) {
1263 _exitCode = c;
1250 _exitCodeCompleter.complete(c); 1264 _exitCodeCompleter.complete(c);
1251 return; 1265 return;
1252 } 1266 }
1253 1267
1254 // Sleep for half a second in case _endExpected is set in the next 1268 // Sleep for half a second in case _endExpected is set in the next
1255 // scheduled event. 1269 // scheduled event.
1256 sleep(500).then((_) { 1270 sleep(500).then((_) {
1257 if (_endExpected) { 1271 if (_endExpected) {
1258 _exitCodeCompleter.complete(c); 1272 _exitCodeCompleter.complete(c);
1259 return; 1273 return;
1260 } 1274 }
1261 1275
1262 _printStreams().then((_) { 1276 _printStreams().then((_) {
1263 registerException(new ExpectException("Process $name ended " 1277 registerException(new ExpectException("Process $name ended "
1264 "earlier than scheduled with exit code $c")); 1278 "earlier than scheduled with exit code $c"));
1265 }); 1279 });
1266 }); 1280 });
1267 }; 1281 };
1268 }); 1282 });
1269 }); 1283 });
1270 1284
1271 _scheduleOnException((_) { 1285 _scheduleOnException((_) {
1272 if (!_process.hasValue) return; 1286 if (_process == null) return;
1273 1287
1274 if (!_exitCode.hasValue) { 1288 if (_exitCode == null) {
1275 print("\nKilling process $name prematurely."); 1289 print("\nKilling process $name prematurely.");
1276 _endExpected = true; 1290 _endExpected = true;
1277 _process.value.kill(); 1291 _process.kill();
1278 } 1292 }
1279 1293
1280 return _printStreams(); 1294 return _printStreams();
1281 }); 1295 });
1282 1296
1283 _scheduleCleanup((_) { 1297 _scheduleCleanup((_) {
1284 if (!_process.hasValue) return; 1298 if (_process == null) return;
1285 // Ensure that the process is dead and we aren't waiting on any IO. 1299 // Ensure that the process is dead and we aren't waiting on any IO.
1286 var process = _process.value; 1300 _process.kill();
1287 process.kill(); 1301 _process.stdout.close();
1288 process.stdout.close(); 1302 _process.stderr.close();
1289 process.stderr.close();
1290 }); 1303 });
1291 } 1304 }
1292 1305
1293 /// Reads the next line of stdout from the process. 1306 /// Reads the next line of stdout from the process.
1294 Future<String> nextLine() { 1307 Future<String> nextLine() {
1295 return _scheduleValue((_) { 1308 return _scheduleValue((_) {
1296 return timeout(_stdout.chain((stream) => readLine(stream)), 1309 return timeout(_stdoutFuture.then((stream) => readLine(stream)),
1297 _SCHEDULE_TIMEOUT, 1310 _SCHEDULE_TIMEOUT,
1298 "waiting for the next stdout line from process $name"); 1311 "waiting for the next stdout line from process $name");
1299 }); 1312 });
1300 } 1313 }
1301 1314
1302 /// Reads the next line of stderr from the process. 1315 /// Reads the next line of stderr from the process.
1303 Future<String> nextErrLine() { 1316 Future<String> nextErrLine() {
1304 return _scheduleValue((_) { 1317 return _scheduleValue((_) {
1305 return timeout(_stderr.chain((stream) => readLine(stream)), 1318 return timeout(_stderrFuture.then((stream) => readLine(stream)),
1306 _SCHEDULE_TIMEOUT, 1319 _SCHEDULE_TIMEOUT,
1307 "waiting for the next stderr line from process $name"); 1320 "waiting for the next stderr line from process $name");
1308 }); 1321 });
1309 } 1322 }
1310 1323
1311 /// Reads the remaining stdout from the process. This should only be called 1324 /// Reads the remaining stdout from the process. This should only be called
1312 /// after kill() or shouldExit(). 1325 /// after kill() or shouldExit().
1313 Future<String> remainingStdout() { 1326 Future<String> remainingStdout() {
1314 if (!_endScheduled) { 1327 if (!_endScheduled) {
1315 throw new StateError("remainingStdout() should only be called after " 1328 throw new StateError("remainingStdout() should only be called after "
1316 "kill() or shouldExit()."); 1329 "kill() or shouldExit().");
1317 } 1330 }
1318 1331
1319 return _scheduleValue((_) { 1332 return _scheduleValue((_) {
1320 return timeout(_stdout.chain(consumeStringInputStream), _SCHEDULE_TIMEOUT, 1333 return timeout(_stdoutFuture.then(consumeStringInputStream),
1334 _SCHEDULE_TIMEOUT,
1321 "waiting for the last stdout line from process $name"); 1335 "waiting for the last stdout line from process $name");
1322 }); 1336 });
1323 } 1337 }
1324 1338
1325 /// Reads the remaining stderr from the process. This should only be called 1339 /// Reads the remaining stderr from the process. This should only be called
1326 /// after kill() or shouldExit(). 1340 /// after kill() or shouldExit().
1327 Future<String> remainingStderr() { 1341 Future<String> remainingStderr() {
1328 if (!_endScheduled) { 1342 if (!_endScheduled) {
1329 throw new StateError("remainingStderr() should only be called after " 1343 throw new StateError("remainingStderr() should only be called after "
1330 "kill() or shouldExit()."); 1344 "kill() or shouldExit().");
1331 } 1345 }
1332 1346
1333 return _scheduleValue((_) { 1347 return _scheduleValue((_) {
1334 return timeout(_stderr.chain(consumeStringInputStream), _SCHEDULE_TIMEOUT, 1348 return timeout(_stderrFuture.then(consumeStringInputStream),
1349 _SCHEDULE_TIMEOUT,
1335 "waiting for the last stderr line from process $name"); 1350 "waiting for the last stderr line from process $name");
1336 }); 1351 });
1337 } 1352 }
1338 1353
1339 /// Writes [line] to the process as stdin. 1354 /// Writes [line] to the process as stdin.
1340 void writeLine(String line) { 1355 void writeLine(String line) {
1341 _schedule((_) => _process.then((p) => p.stdin.writeString('$line\n'))); 1356 _schedule((_) => _processFuture.then(
1357 (p) => p.stdin.writeString('$line\n')));
1342 } 1358 }
1343 1359
1344 /// Kills the process, and waits until it's dead. 1360 /// Kills the process, and waits until it's dead.
1345 void kill() { 1361 void kill() {
1346 _endScheduled = true; 1362 _endScheduled = true;
1347 _schedule((_) { 1363 _schedule((_) {
1348 _endExpected = true; 1364 _endExpected = true;
1349 return _process.chain((p) { 1365 _process.kill();
1350 p.kill(); 1366 timeout(_exitCodeCompleter.future, _SCHEDULE_TIMEOUT,
1351 return timeout(_exitCode, _SCHEDULE_TIMEOUT, 1367 "waiting for process $name to die");
1352 "waiting for process $name to die");
1353 });
1354 }); 1368 });
1355 } 1369 }
1356 1370
1357 /// Waits for the process to exit, and verifies that the exit code matches 1371 /// Waits for the process to exit, and verifies that the exit code matches
1358 /// [expectedExitCode] (if given). 1372 /// [expectedExitCode] (if given).
1359 void shouldExit([int expectedExitCode]) { 1373 void shouldExit([int expectedExitCode]) {
1360 _endScheduled = true; 1374 _endScheduled = true;
1361 _schedule((_) { 1375 _schedule((_) {
1362 _endExpected = true; 1376 _endExpected = true;
1363 return timeout(_exitCode, _SCHEDULE_TIMEOUT, 1377 return timeout(_exitCodeCompleter.future, _SCHEDULE_TIMEOUT,
1364 "waiting for process $name to exit").then((exitCode) { 1378 "waiting for process $name to exit").then((exitCode) {
1365 if (expectedExitCode != null) { 1379 if (expectedExitCode != null) {
1366 expect(exitCode, equals(expectedExitCode)); 1380 expect(exitCode, equals(expectedExitCode));
1367 } 1381 }
1368 }); 1382 });
1369 }); 1383 });
1370 } 1384 }
1371 1385
1372 /// Prints the remaining data in the process's stdout and stderr streams. 1386 /// Prints the remaining data in the process's stdout and stderr streams.
1373 /// Prints nothing if the straems are empty. 1387 /// Prints nothing if the straems are empty.
1374 Future _printStreams() { 1388 Future _printStreams() {
1375 Future printStream(String streamName, StringInputStream stream) { 1389 Future printStream(String streamName, StringInputStream stream) {
1376 return consumeStringInputStream(stream).then((output) { 1390 return consumeStringInputStream(stream).then((output) {
1377 if (output.isEmpty) return; 1391 if (output.isEmpty) return;
1378 1392
1379 print('\nProcess $name $streamName:'); 1393 print('\nProcess $name $streamName:');
1380 for (var line in output.trim().split("\n")) { 1394 for (var line in output.trim().split("\n")) {
1381 print('| $line'); 1395 print('| $line');
1382 } 1396 }
1383 return; 1397 return;
1384 }); 1398 });
1385 } 1399 }
1386 1400
1387 return printStream('stdout', _stdout.value) 1401 return _stdoutFuture.then((stdout) {
1388 .chain((_) => printStream('stderr', _stderr.value)); 1402 return _stderrFuture.then((stderr) {
1403 return printStream('stdout', stdout)
1404 .then((_) => printStream('stderr', stderr));
1405 });
1406 });
1389 } 1407 }
1390 } 1408 }
1391 1409
1392 /// A class representing an [HttpServer] that's scheduled to run in the course 1410 /// A class representing an [HttpServer] that's scheduled to run in the course
1393 /// of the test. This class allows the server's request handling to be 1411 /// of the test. This class allows the server's request handling to be
1394 /// scheduled synchronously. All operations on this class are scheduled. 1412 /// scheduled synchronously. All operations on this class are scheduled.
1395 class ScheduledServer { 1413 class ScheduledServer {
1396 /// The wrapped server. 1414 /// The wrapped server.
1397 final Future<HttpServer> _server; 1415 final Future<HttpServer> _server;
1398 1416
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 } 1467 }
1450 1468
1451 /// Ignore all requests with the given [method] and [path]. If one is 1469 /// Ignore all requests with the given [method] and [path]. If one is
1452 /// received, don't respond to it. 1470 /// received, don't respond to it.
1453 void ignore(String method, String path) => 1471 void ignore(String method, String path) =>
1454 _ignored.add(new Pair(method, path)); 1472 _ignored.add(new Pair(method, path));
1455 1473
1456 /// Raises an error complaining of an unexpected request. 1474 /// Raises an error complaining of an unexpected request.
1457 void _awaitHandle(HttpRequest request, HttpResponse response) { 1475 void _awaitHandle(HttpRequest request, HttpResponse response) {
1458 if (_ignored.contains(new Pair(request.method, request.path))) return; 1476 if (_ignored.contains(new Pair(request.method, request.path))) return;
1459 var future = timeout(new Future.immediate(null).chain((_) { 1477 var future = timeout(new Future.immediate(null).then((_) {
1460 if (_handlers.isEmpty) { 1478 if (_handlers.isEmpty) {
1461 fail('Unexpected ${request.method} request to ${request.path}.'); 1479 fail('Unexpected ${request.method} request to ${request.path}.');
1462 } 1480 }
1463 return _handlers.removeFirst(); 1481 return _handlers.removeFirst();
1464 }).then((handler) { 1482 }).then((handler) {
1465 handler(request, response); 1483 handler(request, response);
1466 }), _SCHEDULE_TIMEOUT, "waiting for a handler for ${request.method} " 1484 }), _SCHEDULE_TIMEOUT, "waiting for a handler for ${request.method} "
1467 "${request.path}"); 1485 "${request.path}");
1468 expect(future, completes); 1486 expect(future, completes);
1469 } 1487 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 /// calling [completion] is unnecessary. 1551 /// calling [completion] is unnecessary.
1534 void expectLater(Future actual, matcher, {String reason, 1552 void expectLater(Future actual, matcher, {String reason,
1535 FailureHandler failureHandler, bool verbose: false}) { 1553 FailureHandler failureHandler, bool verbose: false}) {
1536 _schedule((_) { 1554 _schedule((_) {
1537 return actual.then((value) { 1555 return actual.then((value) {
1538 expect(value, matcher, reason: reason, failureHandler: failureHandler, 1556 expect(value, matcher, reason: reason, failureHandler: failureHandler,
1539 verbose: false); 1557 verbose: false);
1540 }); 1558 });
1541 }); 1559 });
1542 } 1560 }
OLDNEW
« no previous file with comments | « utils/tests/pub/pub_uploader_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698