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. 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 }); | 84 }); |
85 } | 85 } |
86 | 86 |
87 /// Creates an HTTP server to serve [contents] as static files. This server will | 87 /// Creates an HTTP server to serve [contents] as static files. This server will |
88 /// exist only for the duration of the pub run. | 88 /// exist only for the duration of the pub run. |
89 /// | 89 /// |
90 /// Subsequent calls to [serve] will replace the previous server. | 90 /// Subsequent calls to [serve] will replace the previous server. |
91 void serve([List<d.Descriptor> contents]) { | 91 void serve([List<d.Descriptor> contents]) { |
92 var baseDir = d.dir("serve-dir", contents); | 92 var baseDir = d.dir("serve-dir", contents); |
93 | 93 |
| 94 _hasServer = true; |
| 95 |
94 schedule(() { | 96 schedule(() { |
95 return _closeServer().then((_) { | 97 return _closeServer().then((_) { |
96 return SafeHttpServer.bind("localhost", 0).then((server) { | 98 return SafeHttpServer.bind("localhost", 0).then((server) { |
97 _server = server; | 99 _server = server; |
98 server.listen((request) { | 100 server.listen((request) { |
99 currentSchedule.heartbeat(); | 101 currentSchedule.heartbeat(); |
100 var response = request.response; | 102 var response = request.response; |
101 try { | 103 try { |
102 var path = request.uri.path.replaceFirst("/", ""); | 104 var path = request.uri.path.replaceFirst("/", ""); |
103 _requestedPaths.add(path); | 105 _requestedPaths.add(path); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 if (_server == null) return new Future.value(); | 139 if (_server == null) return new Future.value(); |
138 _server.close(); | 140 _server.close(); |
139 _server = null; | 141 _server = null; |
140 _portCompleterCache = null; | 142 _portCompleterCache = null; |
141 // TODO(nweiz): Remove this once issue 4155 is fixed. Pumping the event loop | 143 // TODO(nweiz): Remove this once issue 4155 is fixed. Pumping the event loop |
142 // *seems* to be enough to ensure that the server is actually closed, but I'm | 144 // *seems* to be enough to ensure that the server is actually closed, but I'm |
143 // putting this at 10ms to be safe. | 145 // putting this at 10ms to be safe. |
144 return sleep(10); | 146 return sleep(10); |
145 } | 147 } |
146 | 148 |
| 149 /// `true` if the current test spins up an HTTP server. |
| 150 bool _hasServer = false; |
| 151 |
147 /// The [d.DirectoryDescriptor] describing the server layout of `/api/packages` | 152 /// The [d.DirectoryDescriptor] describing the server layout of `/api/packages` |
148 /// on the test server. | 153 /// on the test server. |
149 /// | 154 /// |
150 /// This contains metadata for packages that are being served via | 155 /// This contains metadata for packages that are being served via |
151 /// [servePackages]. It's `null` if [servePackages] has not yet been called for | 156 /// [servePackages]. It's `null` if [servePackages] has not yet been called for |
152 /// this test. | 157 /// this test. |
153 d.DirectoryDescriptor _servedApiPackageDir; | 158 d.DirectoryDescriptor _servedApiPackageDir; |
154 | 159 |
155 /// The [d.DirectoryDescriptor] describing the server layout of `/packages` on | 160 /// The [d.DirectoryDescriptor] describing the server layout of `/packages` on |
156 /// the test server. | 161 /// the test server. |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 if (tokenEndpoint == null) tokenEndpoint = new Future.value(); | 456 if (tokenEndpoint == null) tokenEndpoint = new Future.value(); |
452 var environmentFuture = tokenEndpoint.then((tokenEndpoint) { | 457 var environmentFuture = tokenEndpoint.then((tokenEndpoint) { |
453 var environment = {}; | 458 var environment = {}; |
454 environment['_PUB_TESTING'] = 'true'; | 459 environment['_PUB_TESTING'] = 'true'; |
455 environment['PUB_CACHE'] = pathInSandbox(cachePath); | 460 environment['PUB_CACHE'] = pathInSandbox(cachePath); |
456 environment['DART_SDK'] = pathInSandbox(sdkPath); | 461 environment['DART_SDK'] = pathInSandbox(sdkPath); |
457 if (tokenEndpoint != null) { | 462 if (tokenEndpoint != null) { |
458 environment['_PUB_TEST_TOKEN_ENDPOINT'] = | 463 environment['_PUB_TEST_TOKEN_ENDPOINT'] = |
459 tokenEndpoint.toString(); | 464 tokenEndpoint.toString(); |
460 } | 465 } |
| 466 |
| 467 // If there is a server running, tell pub what its URL is so hosted |
| 468 // dependencies will look there. |
| 469 if (_hasServer) { |
| 470 return port.then((p) { |
| 471 environment['PUB_HOSTED_URL'] = "http://localhost:$p"; |
| 472 return environment; |
| 473 }); |
| 474 } |
| 475 |
461 return environment; | 476 return environment; |
462 }); | 477 }); |
463 | 478 |
464 return new PubProcess.start(dartBin, dartArgs, environment: environmentFuture, | 479 return new PubProcess.start(dartBin, dartArgs, environment: environmentFuture, |
465 workingDirectory: pathInSandbox(appPath), | 480 workingDirectory: pathInSandbox(appPath), |
466 description: args.isEmpty ? 'pub' : 'pub ${args.first}'); | 481 description: args.isEmpty ? 'pub' : 'pub ${args.first}'); |
467 } | 482 } |
468 | 483 |
469 /// A subclass of [ScheduledProcess] that parses pub's verbose logging output | 484 /// A subclass of [ScheduledProcess] that parses pub's verbose logging output |
470 /// and makes [nextLine], [nextErrLine], [remainingStdout], and | 485 /// and makes [nextLine], [nextErrLine], [remainingStdout], and |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 }; | 617 }; |
603 if (dependencies != null) { | 618 if (dependencies != null) { |
604 package["dependencies"] = dependencyListToMap(dependencies); | 619 package["dependencies"] = dependencyListToMap(dependencies); |
605 } | 620 } |
606 return package; | 621 return package; |
607 } | 622 } |
608 | 623 |
609 /// Describes a map representing a dependency on a package in the package | 624 /// Describes a map representing a dependency on a package in the package |
610 /// repository. | 625 /// repository. |
611 Map dependencyMap(String name, [String versionConstraint]) { | 626 Map dependencyMap(String name, [String versionConstraint]) { |
612 var url = port.then((p) => "http://localhost:$p"); | 627 var dependency = {"hosted": name}; |
613 var dependency = {"hosted": {"name": name, "url": url}}; | |
614 if (versionConstraint != null) dependency["version"] = versionConstraint; | 628 if (versionConstraint != null) dependency["version"] = versionConstraint; |
615 return dependency; | 629 return dependency; |
616 } | 630 } |
617 | 631 |
618 /// Converts a list of dependencies as passed to [package] into a hash as used | 632 /// Converts a list of dependencies as passed to [package] into a hash as used |
619 /// in a pubspec. | 633 /// in a pubspec. |
620 Future<Map> dependencyListToMap(List<Map> dependencies) { | 634 Future<Map> dependencyListToMap(List<Map> dependencies) { |
621 return awaitObject(dependencies).then((resolvedDependencies) { | 635 return awaitObject(dependencies).then((resolvedDependencies) { |
622 var result = <String, Map>{}; | 636 var result = <String, Map>{}; |
623 for (var dependency in resolvedDependencies) { | 637 for (var dependency in resolvedDependencies) { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 bool matches(item, Map matchState) { | 805 bool matches(item, Map matchState) { |
792 if (item is! Pair) return false; | 806 if (item is! Pair) return false; |
793 return _firstMatcher.matches(item.first, matchState) && | 807 return _firstMatcher.matches(item.first, matchState) && |
794 _lastMatcher.matches(item.last, matchState); | 808 _lastMatcher.matches(item.last, matchState); |
795 } | 809 } |
796 | 810 |
797 Description describe(Description description) { | 811 Description describe(Description description) { |
798 description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); | 812 description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); |
799 } | 813 } |
800 } | 814 } |
OLD | NEW |