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

Side by Side Diff: sdk/lib/_internal/pub/test/test_pub.dart

Issue 14593010: Log verbose output when testing pub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « sdk/lib/_internal/pub/test/oauth2/utils.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 15 matching lines...) Expand all
26 26
27 import '../lib/src/entrypoint.dart'; 27 import '../lib/src/entrypoint.dart';
28 // TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides 28 // TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides
29 // with the git descriptor method. Maybe we should try to clean up the top level 29 // with the git descriptor method. Maybe we should try to clean up the top level
30 // scope a bit? 30 // scope a bit?
31 import '../lib/src/git.dart' as gitlib; 31 import '../lib/src/git.dart' as gitlib;
32 import '../lib/src/git_source.dart'; 32 import '../lib/src/git_source.dart';
33 import '../lib/src/hosted_source.dart'; 33 import '../lib/src/hosted_source.dart';
34 import '../lib/src/http.dart'; 34 import '../lib/src/http.dart';
35 import '../lib/src/io.dart'; 35 import '../lib/src/io.dart';
36 import '../lib/src/log.dart' as log;
36 import '../lib/src/path_source.dart'; 37 import '../lib/src/path_source.dart';
37 import '../lib/src/safe_http_server.dart'; 38 import '../lib/src/safe_http_server.dart';
38 import '../lib/src/system_cache.dart'; 39 import '../lib/src/system_cache.dart';
39 import '../lib/src/utils.dart'; 40 import '../lib/src/utils.dart';
40 import '../lib/src/validator.dart'; 41 import '../lib/src/validator.dart';
41 import 'command_line_config.dart'; 42 import 'command_line_config.dart';
42 import 'descriptor.dart' as d; 43 import 'descriptor.dart' as d;
43 44
44 /// This should be called at the top of a test file to set up an appropriate 45 /// This should be called at the top of a test file to set up an appropriate
45 /// test configuration for the machine running the tests. 46 /// test configuration for the machine running the tests.
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 /// upload. 327 /// upload.
327 void confirmPublish(ScheduledProcess pub) { 328 void confirmPublish(ScheduledProcess pub) {
328 // TODO(rnystrom): This is overly specific and inflexible regarding different 329 // TODO(rnystrom): This is overly specific and inflexible regarding different
329 // test packages. Should validate this a little more loosely. 330 // test packages. Should validate this a little more loosely.
330 expect(pub.nextLine(), completion(equals('Publishing "test_pkg" 1.0.0:'))); 331 expect(pub.nextLine(), completion(equals('Publishing "test_pkg" 1.0.0:')));
331 expect(pub.nextLine(), completion(equals("|-- LICENSE"))); 332 expect(pub.nextLine(), completion(equals("|-- LICENSE")));
332 expect(pub.nextLine(), completion(equals("|-- lib"))); 333 expect(pub.nextLine(), completion(equals("|-- lib")));
333 expect(pub.nextLine(), completion(equals("| '-- test_pkg.dart"))); 334 expect(pub.nextLine(), completion(equals("| '-- test_pkg.dart")));
334 expect(pub.nextLine(), completion(equals("'-- pubspec.yaml"))); 335 expect(pub.nextLine(), completion(equals("'-- pubspec.yaml")));
335 expect(pub.nextLine(), completion(equals(""))); 336 expect(pub.nextLine(), completion(equals("")));
337 expect(pub.nextLine(), completion(equals('Looks great! Are you ready to '
338 'upload your package (y/n)?')));
336 339
337 pub.writeLine("y"); 340 pub.writeLine("y");
338 } 341 }
339 342
340 /// Starts a Pub process and returns a [ScheduledProcess] that supports 343 /// Starts a Pub process and returns a [ScheduledProcess] that supports
341 /// interaction with that process. 344 /// interaction with that process.
342 /// 345 ///
343 /// Any futures in [args] will be resolved before the process is started. 346 /// Any futures in [args] will be resolved before the process is started.
344 ScheduledProcess startPub({List args, Future<Uri> tokenEndpoint}) { 347 ScheduledProcess startPub({List args, Future<Uri> tokenEndpoint}) {
345 String pathInSandbox(String relPath) { 348 String pathInSandbox(String relPath) {
346 return path.join(path.absolute(sandboxDir), relPath); 349 return path.join(path.absolute(sandboxDir), relPath);
347 } 350 }
348 351
349 ensureDir(pathInSandbox(appPath)); 352 ensureDir(pathInSandbox(appPath));
350 353
351 // Find a Dart executable we can use to spawn. Use the same one that was 354 // Find a Dart executable we can use to spawn. Use the same one that was
352 // used to run this script itself. 355 // used to run this script itself.
353 var dartBin = new Options().executable; 356 var dartBin = new Options().executable;
354 357
355 // If the executable looks like a path, get its full path. That way we 358 // If the executable looks like a path, get its full path. That way we
356 // can still find it when we spawn it with a different working directory. 359 // can still find it when we spawn it with a different working directory.
357 if (dartBin.contains(Platform.pathSeparator)) { 360 if (dartBin.contains(Platform.pathSeparator)) {
358 dartBin = path.absolute(dartBin); 361 dartBin = path.absolute(dartBin);
359 } 362 }
360 363
361 // Find the main pub entrypoint. 364 // Find the main pub entrypoint.
362 var pubPath = path.join(testDirectory, '..', 'bin', 'pub.dart'); 365 var pubPath = path.join(testDirectory, '..', 'bin', 'pub.dart');
363 366
364 var dartArgs = ['--package-root=$_packageRoot/', '--checked', pubPath, 367 var dartArgs = ['--package-root=$_packageRoot/', '--checked', pubPath,
365 '--trace']; 368 '--verbose'];
366 dartArgs.addAll(args); 369 dartArgs.addAll(args);
367 370
368 if (tokenEndpoint == null) tokenEndpoint = new Future.value(); 371 if (tokenEndpoint == null) tokenEndpoint = new Future.value();
369 var optionsFuture = tokenEndpoint.then((tokenEndpoint) { 372 var optionsFuture = tokenEndpoint.then((tokenEndpoint) {
370 var options = new ProcessOptions(); 373 var options = new ProcessOptions();
371 options.workingDirectory = pathInSandbox(appPath); 374 options.workingDirectory = pathInSandbox(appPath);
372 // TODO(nweiz): remove this when issue 9294 is fixed. 375 // TODO(nweiz): remove this when issue 9294 is fixed.
373 options.environment = new Map.from(Platform.environment); 376 options.environment = new Map.from(Platform.environment);
374 options.environment['_PUB_TESTING'] = 'true'; 377 options.environment['_PUB_TESTING'] = 'true';
375 options.environment['PUB_CACHE'] = pathInSandbox(cachePath); 378 options.environment['PUB_CACHE'] = pathInSandbox(cachePath);
376 options.environment['DART_SDK'] = pathInSandbox(sdkPath); 379 options.environment['DART_SDK'] = pathInSandbox(sdkPath);
377 if (tokenEndpoint != null) { 380 if (tokenEndpoint != null) {
378 options.environment['_PUB_TEST_TOKEN_ENDPOINT'] = 381 options.environment['_PUB_TEST_TOKEN_ENDPOINT'] =
379 tokenEndpoint.toString(); 382 tokenEndpoint.toString();
380 } 383 }
381 return options; 384 return options;
382 }); 385 });
383 386
384 return new ScheduledProcess.start(dartBin, dartArgs, options: optionsFuture, 387 return new PubProcess.start(dartBin, dartArgs, options: optionsFuture,
385 description: args.isEmpty ? 'pub' : 'pub ${args.first}'); 388 description: args.isEmpty ? 'pub' : 'pub ${args.first}');
386 } 389 }
387 390
391 /// A subclass of [ScheduledProcess] that parses pub's verbose logging output
392 /// and makes [nextLine], [nextErrLine], [remainingStdout], and
393 /// [remainingStderr] work as though pub weren't running in verbose mode.
394 class PubProcess extends ScheduledProcess {
395 Stream<Pair<log.Level, String>> _log;
396 Stream<String> _stdout;
397 Stream<String> _stderr;
398
399 PubProcess.start(executable, arguments,
400 {options, String description, Encoding encoding: Encoding.UTF_8})
401 : super.start(executable, arguments,
402 options: options,
403 description: description,
404 encoding: encoding);
405
406 Stream<Pair<log.Level, String>> _logStream() {
407 if (_log == null) {
408 _log = mergeStreams(
409 _outputToLog(super.stdoutStream(), log.Level.MESSAGE),
410 _outputToLog(super.stderrStream(), log.Level.ERROR));
411 }
412
413 var pair = tee(_log);
414 _log = pair.first;
415 return pair.last;
416 }
417
418 final _logLineRegExp = new RegExp(r"^([A-Z ]{4})[:|] (.*)$");
419 final _logLevels = [
420 log.Level.ERROR, log.Level.WARNING, log.Level.MESSAGE, log.Level.IO,
421 log.Level.SOLVER, log.Level.FINE
422 ].fold(<String, log.Level>{}, (levels, level) {
423 levels[level.name] = level;
424 return levels;
425 });
426
427 Stream<Pair<log.Level, String>> _outputToLog(Stream<String> stream,
428 log.Level defaultLevel) {
429 var lastLevel;
430 return stream.map((line) {
431 var match = _logLineRegExp.firstMatch(line);
432 if (match == null) return new Pair<log.Level, String>(defaultLevel, line);
433
434 var level = _logLevels[match[1]];
435 if (level == null) level = lastLevel;
436 lastLevel = level;
437 return new Pair<log.Level, String>(level, match[2]);
438 });
439 }
440
441 Stream<String> stdoutStream() {
442 if (_stdout == null) {
443 _stdout = _logStream().expand((entry) {
444 if (entry.first != log.Level.MESSAGE) return [];
445 return [entry.last];
446 });
447 }
448
449 var pair = tee(_stdout);
450 _stdout = pair.first;
451 return pair.last;
452 }
453
454 Stream<String> stderrStream() {
455 if (_stderr == null) {
456 _stderr = _logStream().expand((entry) {
457 if (entry.first != log.Level.ERROR && entry.first != log.Level.WARNING) {
458 return [];
459 }
460 return [entry.last];
461 });
462 }
463
464 var pair = tee(_stderr);
465 _stderr = pair.first;
466 return pair.last;
467 }
468 }
469
388 // TODO(nweiz): use the built-in mechanism for accessing this once it exists 470 // TODO(nweiz): use the built-in mechanism for accessing this once it exists
389 // (issue 9119). 471 // (issue 9119).
390 /// The path to the `packages` directory from which pub loads its dependencies. 472 /// The path to the `packages` directory from which pub loads its dependencies.
391 String get _packageRoot { 473 String get _packageRoot {
392 return path.absolute(path.join( 474 return path.absolute(path.join(
393 path.dirname(new Options().executable), '..', '..', 'packages')); 475 path.dirname(new Options().executable), '..', '..', 'packages'));
394 } 476 }
395 477
396 /// Skips the current test if Git is not installed. This validates that the 478 /// Skips the current test if Git is not installed. This validates that the
397 /// current test is running on a buildbot in which case we expect git to be 479 /// current test is running on a buildbot in which case we expect git to be
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 bool matches(item, MatchState matchState) { 694 bool matches(item, MatchState matchState) {
613 if (item is! Pair) return false; 695 if (item is! Pair) return false;
614 return _firstMatcher.matches(item.first, matchState) && 696 return _firstMatcher.matches(item.first, matchState) &&
615 _lastMatcher.matches(item.last, matchState); 697 _lastMatcher.matches(item.last, matchState);
616 } 698 }
617 699
618 Description describe(Description description) { 700 Description describe(Description description) {
619 description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); 701 description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]);
620 } 702 }
621 } 703 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/pub/test/oauth2/utils.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698