Chromium Code Reviews| OLD | NEW |
|---|---|
| 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. | 5 /// Test infrastructure for testing pub. |
| 6 /// | 6 /// |
| 7 /// Unlike typical unit tests, most pub tests are integration tests that stage | 7 /// Unlike typical unit tests, most pub tests are integration tests that stage |
| 8 /// some stuff on the file system, run pub, and then validate the results. This | 8 /// some stuff on the file system, run pub, and then validate the results. This |
| 9 /// library provides an API to build tests like that. | 9 /// library provides an API to build tests like that. |
| 10 library test_pub; | 10 library test_pub; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 import 'package:pub/src/system_cache.dart'; | 36 import 'package:pub/src/system_cache.dart'; |
| 37 import 'package:pub/src/utils.dart'; | 37 import 'package:pub/src/utils.dart'; |
| 38 import 'package:pub/src/validator.dart'; | 38 import 'package:pub/src/validator.dart'; |
| 39 import 'package:pub_semver/pub_semver.dart'; | 39 import 'package:pub_semver/pub_semver.dart'; |
| 40 import 'package:scheduled_test/scheduled_process.dart'; | 40 import 'package:scheduled_test/scheduled_process.dart'; |
| 41 import 'package:scheduled_test/scheduled_server.dart'; | 41 import 'package:scheduled_test/scheduled_server.dart'; |
| 42 import 'package:scheduled_test/scheduled_stream.dart'; | 42 import 'package:scheduled_test/scheduled_stream.dart'; |
| 43 import 'package:scheduled_test/scheduled_test.dart' hide fail; | 43 import 'package:scheduled_test/scheduled_test.dart' hide fail; |
| 44 import 'package:shelf/shelf.dart' as shelf; | 44 import 'package:shelf/shelf.dart' as shelf; |
| 45 import 'package:shelf/shelf_io.dart' as shelf_io; | 45 import 'package:shelf/shelf_io.dart' as shelf_io; |
| 46 import 'package:unittest/compact_vm_config.dart'; | |
| 47 import 'package:yaml/yaml.dart'; | 46 import 'package:yaml/yaml.dart'; |
| 48 | 47 |
| 49 import 'descriptor.dart' as d; | 48 import 'descriptor.dart' as d; |
| 50 import 'serve_packages.dart'; | 49 import 'serve_packages.dart'; |
| 51 | 50 |
| 52 export 'serve_packages.dart'; | 51 export 'serve_packages.dart'; |
| 53 | 52 |
| 54 /// This should be called at the top of a test file to set up an appropriate | |
| 55 /// test configuration for the machine running the tests. | |
| 56 initConfig() { | |
| 57 useCompactVMConfiguration(); | |
| 58 filterStacks = true; | |
| 59 unittestConfiguration.timeout = null; | |
| 60 } | |
|
Bob Nystrom
2015/06/26 23:04:10
\o/
| |
| 61 | |
| 62 /// The current [HttpServer] created using [serve]. | 53 /// The current [HttpServer] created using [serve]. |
| 63 var _server; | 54 var _server; |
| 64 | 55 |
| 65 /// The list of paths that have been requested from the server since the last | 56 /// The list of paths that have been requested from the server since the last |
| 66 /// call to [getRequestedPaths]. | 57 /// call to [getRequestedPaths]. |
| 67 final _requestedPaths = <String>[]; | 58 final _requestedPaths = <String>[]; |
| 68 | 59 |
| 69 /// The cached value for [_portCompleter]. | 60 /// The cached value for [_portCompleter]. |
| 70 Completer<int> _portCompleterCache; | 61 Completer<int> _portCompleterCache; |
| 71 | 62 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 /// This server will exist only for the duration of the pub run. Subsequent | 194 /// This server will exist only for the duration of the pub run. Subsequent |
| 204 /// calls to [serve] replace the previous server. | 195 /// calls to [serve] replace the previous server. |
| 205 void serve([List<d.Descriptor> contents]) { | 196 void serve([List<d.Descriptor> contents]) { |
| 206 var baseDir = d.dir("serve-dir", contents); | 197 var baseDir = d.dir("serve-dir", contents); |
| 207 | 198 |
| 208 _hasServer = true; | 199 _hasServer = true; |
| 209 | 200 |
| 210 schedule(() { | 201 schedule(() { |
| 211 return _closeServer().then((_) { | 202 return _closeServer().then((_) { |
| 212 return shelf_io.serve((request) { | 203 return shelf_io.serve((request) { |
| 213 currentSchedule.heartbeat(); | |
| 214 var path = p.posix.fromUri(request.url.path.replaceFirst("/", "")); | 204 var path = p.posix.fromUri(request.url.path.replaceFirst("/", "")); |
| 215 _requestedPaths.add(path); | 205 _requestedPaths.add(path); |
| 216 | 206 |
| 217 return validateStream(baseDir.load(path)) | 207 return validateStream(baseDir.load(path)) |
| 218 .then((stream) => new shelf.Response.ok(stream)) | 208 .then((stream) => new shelf.Response.ok(stream)) |
| 219 .catchError((error) { | 209 .catchError((error) { |
| 220 return new shelf.Response.notFound('File "$path" not found.'); | 210 return new shelf.Response.notFound('File "$path" not found.'); |
| 221 }); | 211 }); |
| 222 }, 'localhost', 0).then((server) { | 212 }, 'localhost', 0).then((server) { |
| 223 _server = server; | 213 _server = server; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 /// asynchronously. | 354 /// asynchronously. |
| 365 void integration(String description, void body()) => | 355 void integration(String description, void body()) => |
| 366 _integration(description, body, test); | 356 _integration(description, body, test); |
| 367 | 357 |
| 368 /// Like [integration], but causes only this test to run. | 358 /// Like [integration], but causes only this test to run. |
| 369 void solo_integration(String description, void body()) => | 359 void solo_integration(String description, void body()) => |
| 370 _integration(description, body, solo_test); | 360 _integration(description, body, solo_test); |
| 371 | 361 |
| 372 void _integration(String description, void body(), [Function testFn]) { | 362 void _integration(String description, void body(), [Function testFn]) { |
| 373 testFn(description, () { | 363 testFn(description, () { |
| 374 // TODO(nweiz): remove this when issue 15362 is fixed. | |
| 375 currentSchedule.timeout *= 2; | |
| 376 | |
| 377 // The windows bots are very slow, so we increase the default timeout. | |
| 378 if (Platform.operatingSystem == "windows") { | |
| 379 currentSchedule.timeout *= 2; | |
| 380 } | |
| 381 | |
| 382 _sandboxDir = createSystemTempDir(); | 364 _sandboxDir = createSystemTempDir(); |
| 383 d.defaultRoot = sandboxDir; | 365 d.defaultRoot = sandboxDir; |
| 384 currentSchedule.onComplete.schedule(() => deleteEntry(_sandboxDir), | 366 currentSchedule.onComplete.schedule(() => deleteEntry(_sandboxDir), |
| 385 'deleting the sandbox directory'); | 367 'deleting the sandbox directory'); |
| 386 | 368 |
| 387 // Schedule the test. | 369 // Schedule the test. |
| 388 body(); | 370 body(); |
| 389 }); | 371 }); |
| 390 } | 372 } |
| 391 | 373 |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 643 | 625 |
| 644 /// Fails the current test if Git is not installed. | 626 /// Fails the current test if Git is not installed. |
| 645 /// | 627 /// |
| 646 /// We require machines running these tests to have git installed. This | 628 /// We require machines running these tests to have git installed. This |
| 647 /// validation gives an easier-to-understand error when that requirement isn't | 629 /// validation gives an easier-to-understand error when that requirement isn't |
| 648 /// met than just failing in the middle of a test when pub invokes git. | 630 /// met than just failing in the middle of a test when pub invokes git. |
| 649 /// | 631 /// |
| 650 /// This also increases the [Schedule] timeout to 30 seconds on Windows, | 632 /// This also increases the [Schedule] timeout to 30 seconds on Windows, |
| 651 /// where Git runs really slowly. | 633 /// where Git runs really slowly. |
| 652 void ensureGit() { | 634 void ensureGit() { |
| 653 if (Platform.operatingSystem == "windows") { | |
| 654 currentSchedule.timeout = new Duration(seconds: 30); | |
| 655 } | |
| 656 | |
| 657 if (!gitlib.isInstalled) { | 635 if (!gitlib.isInstalled) { |
| 658 throw new Exception("Git must be installed to run this test."); | 636 throw new Exception("Git must be installed to run this test."); |
| 659 } | 637 } |
| 660 } | 638 } |
| 661 | 639 |
| 662 /// Schedules activating a global package [package] without running | 640 /// Schedules activating a global package [package] without running |
| 663 /// "pub global activate". | 641 /// "pub global activate". |
| 664 /// | 642 /// |
| 665 /// This is useful because global packages must be hosted, but the test hosted | 643 /// This is useful because global packages must be hosted, but the test hosted |
| 666 /// server doesn't serve barback. The other parameters here follow | 644 /// server doesn't serve barback. The other parameters here follow |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 992 _lastMatcher.matches(item.last, matchState); | 970 _lastMatcher.matches(item.last, matchState); |
| 993 } | 971 } |
| 994 | 972 |
| 995 Description describe(Description description) { | 973 Description describe(Description description) { |
| 996 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); | 974 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); |
| 997 } | 975 } |
| 998 } | 976 } |
| 999 | 977 |
| 1000 /// A [StreamMatcher] that matches multiple lines of output. | 978 /// A [StreamMatcher] that matches multiple lines of output. |
| 1001 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); | 979 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); |
| OLD | NEW |