Chromium Code Reviews| Index: utils/tests/pub/test_pub.dart |
| diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart |
| index 067343330b8ecc5aa0269a8636a0ca35673f1067..683b6857093ee26a6c6715be0c1fa7c40768e925 100644 |
| --- a/utils/tests/pub/test_pub.dart |
| +++ b/utils/tests/pub/test_pub.dart |
| @@ -60,20 +60,35 @@ TarFileDescriptor tar(Pattern name, [List<Descriptor> contents]) => |
| */ |
| var _server; |
| +/** The cached value for [_portCompleter]. */ |
| +Completer<int> _portCompleterCache; |
| + |
| +/** The completer for [port]. */ |
| +Completer<int> get _portCompleter() { |
|
Bob Nystrom
2012/08/23 21:49:13
New getter syntax. :)
nweiz
2012/08/23 22:25:49
Done.
|
| + if (_portCompleterCache != null) return _portCompleterCache; |
| + _portCompleterCache = new Completer<int>(); |
| + _scheduleCleanup((_) { |
| + _portCompleterCache = null; |
| + }); |
| + return _portCompleterCache; |
| +} |
| + |
| +/** |
| + * A future that will complete to the port used for the current server. |
| + */ |
| +Future<int> get port() => _portCompleter.future; |
| + |
| /** |
| * Creates an HTTP server to serve [contents] as static files. This server will |
| * exist only for the duration of the pub run. |
| * |
| * Subsequent calls to [serve] will replace the previous server. |
| */ |
| -void serve(String host, int port, [List<Descriptor> contents]) { |
| +void serve([List<Descriptor> contents]) { |
| var baseDir = dir("serve-dir", contents); |
| - if (host == 'localhost') { |
| - host = '127.0.0.1'; |
| - } |
| _schedule((_) { |
| - _closeServer().transform((_) { |
| + _closeServer().transform((resolvedPort) { |
| _server = new HttpServer(); |
| _server.defaultRequestHandler = (request, response) { |
| var path = request.uri.replaceFirst("/", "").split("/"); |
| @@ -103,7 +118,8 @@ void serve(String host, int port, [List<Descriptor> contents]) { |
| response.outputStream.close(); |
| }); |
| }; |
| - _server.listen(host, port); |
| + _server.listen("127.0.0.1", 0); |
| + _portCompleter.complete(_server.port); |
| _scheduleCleanup((_) => _closeServer()); |
| return null; |
| }); |
| @@ -118,6 +134,7 @@ Future _closeServer() { |
| if (_server == null) return new Future.immediate(null); |
| _server.close(); |
| _server = null; |
| + _portCompleterCache = null; |
| // TODO(nweiz): Remove this once issue 4155 is fixed. Pumping the event loop |
| // *seems* to be enough to ensure that the server is actually closed, but I'm |
| // putting this at 10ms to be safe. |
| @@ -125,37 +142,70 @@ Future _closeServer() { |
| } |
| /** |
| + * The [DirectoryDescriptor] describing the server layout of packages that are |
| + * being served via [servePackages]. This is `null` if [servePackages] has not |
| + * yet been called for this test. |
| + */ |
| +DirectoryDescriptor _servedPackageDir; |
| + |
| +/** |
| + * A map from package names to version numbers to YAML-serialized pubspecs for |
| + * those packagesk. This represents the packages currently being served by |
|
Bob Nystrom
2012/08/23 21:49:13
"packagesk" -> "packages".
nweiz
2012/08/23 22:25:49
Done.
|
| + * [servePackages], and is `null` if [servePackages] has not yet been called for |
| + * this test. |
| + */ |
| +Map<String, Map<String, String>> _servedPackages; |
| + |
| +/** |
| * Creates an HTTP server that replicates the structure of pub.dartlang.org. |
| * [pubspecs] is a list of unserialized pubspecs representing the packages to |
| * serve. |
| + * |
| + * Subsequent calls to [servePackages] will add to the set of packages that are |
| + * being served. Previous packages will continue to be served. |
| */ |
| -void servePackages(String host, int port, List<Map> pubspecs) { |
| - var packages = <String, Map<String, String>>{}; |
| - for (var spec in pubspecs) { |
| - var name = spec['name']; |
| - var version = spec['version']; |
| - packages.putIfAbsent(name, () => <String, String>{})[version] = yaml(spec); |
| +void servePackages(List<Map> pubspecs) { |
| + if (_servedPackages == null || _servedPackageDir) { |
| + _servedPackages = <String, Map<String, String>>{}; |
| + _servedPackageDir = dir('packages', []); |
| + serve([_servedPackageDir]); |
| + |
| + _scheduleCleanup((_) { |
| + _servedPackages = null; |
| + _servedPackageDir = null; |
| + }); |
| } |
| - serve(host, port, [ |
| - dir('packages', flatten(packages.getKeys().map((name) { |
| - return [ |
| - file('$name.json', |
| - JSON.stringify({'versions': packages[name].getKeys()})), |
| - dir(name, [ |
| - dir('versions', flatten(packages[name].getKeys().map((version) { |
| - return [ |
| - file('$version.yaml', packages[name][version]), |
| - tar('$version.tar.gz', [ |
| - file('pubspec.yaml', packages[name][version]), |
| - file('$name.dart', 'main() => print("$name $version");') |
| - ]) |
| - ]; |
| - }))) |
| - ]) |
| - ]; |
| - }))) |
| - ]); |
| + _schedule((_) { |
| + return Futures.wait(pubspecs.map(_awaitObject)) |
|
Bob Nystrom
2012/08/23 21:49:13
Can you just do _awaitObject(pubspects)?
nweiz
2012/08/23 22:25:49
Done.
|
| + .transform((resolvedPubspecs) { |
| + for (var spec in resolvedPubspecs) { |
| + var name = spec['name']; |
| + var version = spec['version']; |
| + var versions = _servedPackages.putIfAbsent(name, () => <String, String>{}); |
|
Bob Nystrom
2012/08/23 21:49:13
Long line.
nweiz
2012/08/23 22:25:49
Done.
|
| + versions[version] = yaml(spec); |
| + } |
| + |
| + _servedPackageDir.contents.clear(); |
| + for (var name in _servedPackages.getKeys()) { |
| + _servedPackageDir.contents.addAll([ |
| + file('$name.json', |
| + JSON.stringify({'versions': _servedPackages[name].getKeys()})), |
|
Bob Nystrom
2012/08/23 21:49:13
+2
nweiz
2012/08/23 22:25:49
Done.
|
| + dir(name, [ |
| + dir('versions', flatten(_servedPackages[name].getKeys().map((version) { |
|
Bob Nystrom
2012/08/23 21:49:13
Lone line.
nweiz
2012/08/23 22:25:49
Done.
|
| + return [ |
| + file('$version.yaml', _servedPackages[name][version]), |
| + tar('$version.tar.gz', [ |
| + file('pubspec.yaml', _servedPackages[name][version]), |
| + file('$name.dart', 'main() => print("$name $version");') |
| + ]) |
| + ]; |
| + }))) |
| + ]) |
| + ]); |
| + } |
| + }); |
| + }); |
| } |
| /** Converts [value] into a YAML string. */ |
| @@ -204,7 +254,8 @@ Map package(String name, String version, [List dependencies]) { |
| * repository. |
| */ |
| Map dependency(String name, [String versionConstraint]) { |
| - var dependency = {"repo": {"name": name, "url": "http://localhost:3123"}}; |
| + var url = port.transform((p) => "http://localhost:$p"); |
| + var dependency = {"repo": {"name": name, "url": url}}; |
| if (versionConstraint != null) dependency["version"] = versionConstraint; |
| return dependency; |
| } |
| @@ -271,7 +322,9 @@ DirectoryDescriptor cacheDir(Map packages) { |
| } |
| }); |
| return dir(cachePath, [ |
| - dir('repo', [dir('localhost%583123', contents)]) |
| + dir('repo', [ |
| + async(port.transform((p) => dir('localhost%58$p', contents))) |
| + ]) |
| ]); |
| } |