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

Side by Side Diff: test/package_server.dart

Issue 1664563002: Refactor test servers to make them less global. (Closed) Base URL: git@github.com:dart-lang/pub.git@master
Patch Set: Code review changes Created 4 years, 10 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 | « test/list_package_dirs/lists_dependency_directories_test.dart ('k') | test/serve_packages.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:convert'; 6 import 'dart:convert';
7 7
8 import 'package:path/path.dart' as p; 8 import 'package:path/path.dart' as p;
9 import 'package:pub/src/io.dart'; 9 import 'package:pub/src/io.dart';
10 import 'package:pub/src/utils.dart'; 10 import 'package:pub/src/utils.dart';
11 import 'package:pub_semver/pub_semver.dart'; 11 import 'package:pub_semver/pub_semver.dart';
12 import 'package:scheduled_test/scheduled_test.dart'; 12 import 'package:scheduled_test/scheduled_test.dart';
13 import 'package:yaml/yaml.dart'; 13 import 'package:yaml/yaml.dart';
14 14
15 import 'descriptor.dart' as d; 15 import 'descriptor.dart' as d;
16 import 'test_pub.dart'; 16 import 'test_pub.dart';
17 17
18 /// The [d.DirectoryDescriptor] describing the server layout of `/api/packages` 18 /// The current global [PackageServer].
19 /// on the test server. 19 PackageServer get globalPackageServer => _globalPackageServer;
20 /// 20 PackageServer _globalPackageServer;
21 /// This contains metadata for packages that are being served via
22 /// [servePackages]. It's `null` if [servePackages] has not yet been called for
23 /// this test.
24 d.DirectoryDescriptor _servedApiPackageDir;
25 21
26 /// The [d.DirectoryDescriptor] describing the server layout of `/packages` on 22 /// Creates an HTTP server that replicates the structure of pub.dartlang.org and
27 /// the test server. 23 /// makes it the current [globalServer].
28 ///
29 /// This contains the tarballs for packages that are being served via
30 /// [servePackages]. It's `null` if [servePackages] has not yet been called for
31 /// this test.
32 d.DirectoryDescriptor _servedPackageDir;
33
34 /// The current [PackageServerBuilder] that a user uses to specify which package
35 /// to serve.
36 ///
37 /// This is preserved over multiple calls to [servePackages] within the same
38 /// test so that additional packages can be added.
39 PackageServerBuilder _builder;
40
41 /// Creates an HTTP server that replicates the structure of pub.dartlang.org.
42 /// 24 ///
43 /// Calls [callback] with a [PackageServerBuilder] that's used to specify 25 /// Calls [callback] with a [PackageServerBuilder] that's used to specify
44 /// which packages to serve. 26 /// which packages to serve.
27 void servePackages(void callback(PackageServerBuilder builder)) {
28 _globalPackageServer = new PackageServer(callback);
29 globalServer = _globalPackageServer._inner;
30
31 currentSchedule.onComplete.schedule(() {
32 _globalPackageServer = null;
33 }, 'clearing the global package server');
34 }
35
36 /// Like [servePackages], but instead creates an empty server with no packages
37 /// registered.
45 /// 38 ///
46 /// If [replace] is false, subsequent calls to [servePackages] will add to the 39 /// This will always replace a previous server.
47 /// set of packages that are being served. Previous packages will continue to be 40 void serveNoPackages() => servePackages((_) {}, replace: true);
48 /// served. Otherwise, the previous packages will no longer be served. 41
49 void servePackages(void callback(PackageServerBuilder builder), 42 /// A shortcut for [servePackages] that serves the version of barback used by
50 {bool replace: false}) { 43 /// pub.
51 if (_servedPackageDir == null) { 44 void serveBarback() {
52 _builder = new PackageServerBuilder(); 45 servePackages((builder) {
53 _servedApiPackageDir = d.dir('packages', []); 46 builder.serveRealPackage('barback');
54 _servedPackageDir = d.dir('packages', []); 47 });
55 serve([ 48 }
49
50 class PackageServer {
51 /// The inner [DescriptorServer] that this uses to serve its descriptors.
52 DescriptorServer _inner;
53
54 /// The [d.DirectoryDescriptor] describing the server layout of
55 /// `/api/packages` on the test server.
56 ///
57 /// This contains metadata for packages that are being served via
58 /// [servePackages].
59 final _servedApiPackageDir = d.dir('packages', []);
60
61 /// The [d.DirectoryDescriptor] describing the server layout of `/packages` on
62 /// the test server.
63 ///
64 /// This contains the tarballs for packages that are being served via
65 /// [servePackages].
66 final _servedPackageDir = d.dir('packages', []);
67
68 /// The current [PackageServerBuilder] that a user uses to specify which
69 /// package to serve.
70 ///
71 /// This is preserved so that additional packages can be added.
72 var _builder = new PackageServerBuilder._();
73
74 /// Creates an HTTP server that replicates the structure of pub.dartlang.org.
75 ///
76 /// Calls [callback] with a [PackageServerBuilder] that's used to specify
77 /// which packages to serve.
78 PackageServer(void callback(PackageServerBuilder builder)) {
79 _inner = new DescriptorServer([
56 d.dir('api', [_servedApiPackageDir]), 80 d.dir('api', [_servedApiPackageDir]),
57 _servedPackageDir 81 _servedPackageDir
58 ]); 82 ]);
59 83
60 currentSchedule.onComplete.schedule(() { 84 add(callback);
61 _builder = null;
62 _servedApiPackageDir = null;
63 _servedPackageDir = null;
64 }, 'cleaning up served packages');
65 } 85 }
66 86
67 schedule(() { 87 /// Add to the current set of packages that are being served.
68 if (replace) _builder = new PackageServerBuilder(); 88 void add(void callback(PackageServerBuilder builder)) {
69 callback(_builder); 89 schedule(() async {
70 return _builder._await().then((resolvedPubspecs) { 90 callback(_builder);
91
92 await _builder._await();
71 _servedApiPackageDir.contents.clear(); 93 _servedApiPackageDir.contents.clear();
72 _servedPackageDir.contents.clear(); 94 _servedPackageDir.contents.clear();
95
73 _builder._packages.forEach((name, versions) { 96 _builder._packages.forEach((name, versions) {
74 _servedApiPackageDir.contents.addAll([ 97 _servedApiPackageDir.contents.addAll([
75 d.file('$name', JSON.encode({ 98 d.file('$name', JSON.encode({
76 'name': name, 99 'name': name,
77 'uploaders': ['nweiz@google.com'], 100 'uploaders': ['nweiz@google.com'],
78 'versions': versions.map((version) => 101 'versions': versions.map((version) =>
79 packageVersionApiMap(version.pubspec)).toList() 102 packageVersionApiMap(version.pubspec)).toList()
80 })), 103 })),
81 d.dir(name, [ 104 d.dir(name, [
82 d.dir('versions', versions.map((version) { 105 d.dir('versions', versions.map((version) {
83 return d.file(version.version.toString(), JSON.encode( 106 return d.file(version.version.toString(), JSON.encode(
84 packageVersionApiMap(version.pubspec, full: true))); 107 packageVersionApiMap(version.pubspec, full: true)));
85 })) 108 }))
86 ]) 109 ])
87 ]); 110 ]);
88 111
89 _servedPackageDir.contents.add(d.dir(name, [ 112 _servedPackageDir.contents.add(d.dir(name, [
90 d.dir('versions', versions.map((version) => 113 d.dir('versions', versions.map((version) =>
91 d.tar('${version.version}.tar.gz', version.contents))) 114 d.tar('${version.version}.tar.gz', version.contents)))
92 ])); 115 ]));
93 }); 116 });
94 }); 117 }, 'adding packages to the package server');
95 }, 'initializing the package server'); 118 }
96 }
97 119
98 /// Like [servePackages], but instead creates an empty server with no packages 120 /// Replace the current set of packages that are being served.
99 /// registered. 121 void replace(void callback(PackageServerBuilder builder)) {
100 /// 122 schedule(() => _builder._clear(), "clearing builder");
101 /// This will always replace a previous server. 123 add(callback);
102 void serveNoPackages() => servePackages((_) {}, replace: true); 124 }
103
104 /// A shortcut for [servePackages] that serves the version of barback used by
105 /// pub.
106 void serveBarback() {
107 servePackages((builder) {
108 builder.serveRealPackage('barback');
109 });
110 } 125 }
111 126
112 /// A builder for specifying which packages should be served by [servePackages]. 127 /// A builder for specifying which packages should be served by [servePackages].
113 class PackageServerBuilder { 128 class PackageServerBuilder {
114 /// A map from package names to a list of concrete packages to serve. 129 /// A map from package names to a list of concrete packages to serve.
115 final _packages = new Map<String, List<_ServedPackage>>(); 130 final _packages = new Map<String, List<_ServedPackage>>();
116 131
117 /// A group of futures from [serve] calls. 132 /// A group of futures from [serve] calls.
118 /// 133 ///
119 /// This should be accessed by calling [_awair]. 134 /// This should be accessed by calling [_awair].
120 var _futures = new FutureGroup(); 135 var _futures = new FutureGroup();
121 136
137 PackageServerBuilder._();
138
122 /// Specifies that a package named [name] with [version] should be served. 139 /// Specifies that a package named [name] with [version] should be served.
123 /// 140 ///
124 /// If [deps] is passed, it's used as the "dependencies" field of the pubspec. 141 /// If [deps] is passed, it's used as the "dependencies" field of the pubspec.
125 /// If [pubspec] is passed, it's used as the rest of the pubspec. Either of 142 /// If [pubspec] is passed, it's used as the rest of the pubspec. Either of
126 /// these may recursively contain Futures. 143 /// these may recursively contain Futures.
127 /// 144 ///
128 /// If [contents] is passed, it's used as the contents of the package. By 145 /// If [contents] is passed, it's used as the contents of the package. By
129 /// default, a package just contains a dummy lib directory. 146 /// default, a package just contains a dummy lib directory.
130 void serve(String name, String version, {Map deps, Map pubspec, 147 void serve(String name, String version, {Map deps, Map pubspec,
131 Iterable<d.Descriptor> contents}) { 148 Iterable<d.Descriptor> contents}) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 } 198 }
182 199
183 /// Returns a Future that completes once all the [serve] calls have been fully 200 /// Returns a Future that completes once all the [serve] calls have been fully
184 /// processed. 201 /// processed.
185 Future _await() { 202 Future _await() {
186 if (_futures.futures.isEmpty) return new Future.value(); 203 if (_futures.futures.isEmpty) return new Future.value();
187 return _futures.future.then((_) { 204 return _futures.future.then((_) {
188 _futures = new FutureGroup(); 205 _futures = new FutureGroup();
189 }); 206 });
190 } 207 }
208
209 /// Clears all existing packages from this builder.
210 void _clear() {
211 _packages.clear();
212 }
191 } 213 }
192 214
193 /// A package that's intended to be served. 215 /// A package that's intended to be served.
194 class _ServedPackage { 216 class _ServedPackage {
195 final Map pubspec; 217 final Map pubspec;
196 final List<d.Descriptor> contents; 218 final List<d.Descriptor> contents;
197 219
198 Version get version => new Version.parse(pubspec['version']); 220 Version get version => new Version.parse(pubspec['version']);
199 221
200 _ServedPackage(this.pubspec, this.contents); 222 _ServedPackage(this.pubspec, this.contents);
201 } 223 }
OLDNEW
« no previous file with comments | « test/list_package_dirs/lists_dependency_directories_test.dart ('k') | test/serve_packages.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698