Merge lp:~gary/launchpad/lazr-dist into lp:launchpad
- lazr-dist
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Edwin Grubbs |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~gary/launchpad/lazr-dist |
Merge into: | lp:launchpad |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~gary/launchpad/lazr-dist |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Edwin Grubbs (community) | code | Approve | |
Review via email: mp+10770@code.launchpad.net |
Commit message
Description of the change
Gary Poster (gary) wrote : | # |
Edwin Grubbs (edwin-grubbs) wrote : | # |
Hi Gary,
This branch looks good. I only have suggestions for minor changes and
fixing the lint items that are possible.
merge-conditional
-Edwin
{{{
= Launchpad lint =
== Pyflakes notices ==
lib/canonical/
28: 'urlparse' imported but unused
lib/canonical/
75: 'HTTPPublication' imported but unused
Traceback (most recent call last):
File "/usr/bin/
sys.
File "/usr/lib/
warnings += checkPath(arg)
TypeError
unsupported operand type(s) for +=: 'int' and 'NoneType'
== Pylint notices ==
lib/lazr/
1: [F0001] No module named lib/lazr/__init__
lib/canonical/
621: [C0301] Line too long (79/78)
42: [F0401] Unable to import 'lazr.restful.
55: [E1002, UnstickyCookieH
63: [E1002, UnstickyCookieH
71: [E1002, UnstickyCookieH
28: [W0611] Unused import urlparse
lib/canonical/
75: [W0611] Unused import HTTPPublication
}}}
>=== modified file 'lib/canonical/
>--- lib/canonical/
>+++ lib/canonical/
>@@ -5,9 +5,8 @@
> confusion when one program runs as different users, this is
> implemented as a redirect to that person's canonical URL.
>
>- >>> print webservice.
>+ >>> print webservice.
> HTTP/1.1 303 See Other
> ...
> Location: http://
> ...
>-
>
>=== modified file 'lib/canonical/
>--- lib/canonical/
>+++ lib/canonical/
>@@ -537,7 +537,7 @@
> Accessing the raw submission data yields a redirect to a Librarian URL.
>
> >>> print webservice.
>- HTTP/1.1 303 See Other
>+ HTTP/1.1 303 See Other...
> Content-Length: 0
> Content-Type: text/plain
> Location: http://
>@@ -769,7 +769,7 @@
>
> A vendor ID can be accessed by via its database ID.
>
>- >>> vendor_id = webservice.
>+ >>> vendor_id = webservice.
> >>> pprint_
> bus: u'System'
> id: 1
>
>=== modified file 'lib/canonical/
>--- lib/canonical/
>+++ lib/canonical/
>@@ -387,7 +387,7 @@
> ... u'wikiname': 'MrExample'}
> >>> response = webservice.patch(
> ... wiki_name[
Gary Poster (gary) wrote : | # |
On Aug 27, 2009, at 12:19 AM, Edwin Grubbs wrote:
> Review: Approve code
> Hi Gary,
>
> This branch looks good. I only have suggestions for minor changes and
> fixing the lint items that are possible.
Thank you Edwin!
I fixed all the lint issues except for pylint not findling
lazr.restful. I glanced at that; looks like somebody has already
tried to improve this, but its not quite there yet, and I could not
make it better with a quick fly-by.
I'm only responding to the questions in-line, and then putting the
incremental diff at the end.
>> def addHeadersTo(self, full_url, full_headers):
>> if (self.consumer is not None and self.access_token is not
>> None):
>> @@ -123,6 +120,8 @@
>> request.
>> self.consumer, self.access_token)
>> full_headers.
>> + if not self.handle_errors:
>> + full_headers[
>
>
>
> Is this why the webservice object in tests no longer raises an
> exception?
No, that's because we were relying on jsonBody raising an exception,
and it still does, but now it is a "this isn't json!" exception rather
than a useful report of the response status and the server's traceback.
> def extract_
>> @@ -619,7 +618,7 @@
>> access_token = request_
>> logout()
>> return LaunchpadWebSer
>> - consumer_key, access_token.key, port=9000)
>> + consumer_key, access_token.key) # "port=9000" was ignored,
>> now not sent
>
>
> I don't think this comment is necessary. If it needs to stay, it's
> too long, needs a period, and I've been dinged for using eol comments,
> although I don't see anything in the style guide about that.
:-) Cool. Removed.
...
>>
>> === modified file 'lib/canonical/
>> --- lib/canonical/
>> +++ lib/canonical/
>> @@ -69,7 +69,10 @@
>> import psycopg2
>> from storm.zope.
>> import transaction
>> +import wsgi_intercept
>>
>> +from zope.app.
>> +from zope.app.
>> import zope.app.
>> from zope.app.
>> ZopePublication
>> from zope.component import getUtility, provideUtility
>> @@ -752,6 +755,47 @@
>> "DELETE FROM SessionData")
>>
>>
>> +def wsgi_applicatio
>> + """This is a wsgi application for Zope functional testing.
>> +
>> + We use it with wsgi_intercept, which is itself mostly
>> interesting
>> + for our webservice (lazr.restful) tests.
>> + """
>> + # Committing work done up to now is a convenience that the Zope
>> + # zope.app.
>> replacing that bit,
>> + # so it is easiest to follow that lead, even if it feels a
>> little loose.
>> + transaction.
>> + # Let's support post-mortem debugging.
>> + if environ.
Preview Diff
1 | === modified file 'lib/canonical/launchpad/pagetests/webservice/root.txt' |
2 | --- lib/canonical/launchpad/pagetests/webservice/root.txt 2009-03-18 17:20:01 +0000 |
3 | +++ lib/canonical/launchpad/pagetests/webservice/root.txt 2009-08-20 04:46:48 +0000 |
4 | @@ -5,9 +5,8 @@ |
5 | confusion when one program runs as different users, this is |
6 | implemented as a redirect to that person's canonical URL. |
7 | |
8 | - >>> print webservice.get('/people/+me').getOutput() |
9 | + >>> print webservice.get('/people/+me') |
10 | HTTP/1.1 303 See Other |
11 | ... |
12 | Location: http://.../~salgado |
13 | ... |
14 | - |
15 | |
16 | === modified file 'lib/canonical/launchpad/pagetests/webservice/xx-hwdb.txt' |
17 | --- lib/canonical/launchpad/pagetests/webservice/xx-hwdb.txt 2009-08-14 13:03:36 +0000 |
18 | +++ lib/canonical/launchpad/pagetests/webservice/xx-hwdb.txt 2009-08-21 19:49:18 +0000 |
19 | @@ -537,7 +537,7 @@ |
20 | Accessing the raw submission data yields a redirect to a Librarian URL. |
21 | |
22 | >>> print webservice.get(submission['raw_submission_link']) |
23 | - HTTP/1.1 303 See Other |
24 | + HTTP/1.1 303 See Other... |
25 | Content-Length: 0 |
26 | Content-Type: text/plain |
27 | Location: http://localhost:58000/92/sample-submission-2.xml |
28 | @@ -769,7 +769,7 @@ |
29 | |
30 | A vendor ID can be accessed by via its database ID. |
31 | |
32 | - >>> vendor_id = webservice.get('+hwdb/+hwvendorid/1').jsonBody() |
33 | + >>> vendor_id = webservice.get('/+hwdb/+hwvendorid/1').jsonBody() |
34 | >>> pprint_entry(vendor_id) |
35 | bus: u'System' |
36 | id: 1 |
37 | |
38 | === modified file 'lib/canonical/launchpad/pagetests/webservice/xx-person.txt' |
39 | --- lib/canonical/launchpad/pagetests/webservice/xx-person.txt 2009-08-13 15:12:16 +0000 |
40 | +++ lib/canonical/launchpad/pagetests/webservice/xx-person.txt 2009-08-21 19:49:18 +0000 |
41 | @@ -387,7 +387,7 @@ |
42 | ... u'wikiname': 'MrExample'} |
43 | >>> response = webservice.patch( |
44 | ... wiki_name['self_link'], 'application/json', dumps(patch)) |
45 | - >>> print response.getOutput() |
46 | + >>> print response |
47 | HTTP/1.1 400 Bad Request |
48 | ... |
49 | wiki: The URI scheme "javascript" is not allowed. |
50 | |
51 | === modified file 'lib/canonical/launchpad/pagetests/webservice/xx-private-membership.txt' |
52 | --- lib/canonical/launchpad/pagetests/webservice/xx-private-membership.txt 2009-07-15 09:42:45 +0000 |
53 | +++ lib/canonical/launchpad/pagetests/webservice/xx-private-membership.txt 2009-08-20 04:46:48 +0000 |
54 | @@ -101,7 +101,7 @@ |
55 | ... simplejson.dumps(representation), |
56 | ... headers) |
57 | |
58 | - >>> print modify_team('~my-new-team', {'visibility' : 'Private Membership'}, |
59 | + >>> print modify_team('/~my-new-team', {'visibility' : 'Private Membership'}, |
60 | ... 'PATCH', comm_webservice) |
61 | HTTP/1.1 209 Content Returned |
62 | ... |
63 | @@ -116,7 +116,7 @@ |
64 | |
65 | As an admin, Salgado can also change the team's visibility. |
66 | |
67 | - >>> print modify_team('~my-new-team', {'visibility' : 'Public'}, |
68 | + >>> print modify_team('/~my-new-team', {'visibility' : 'Public'}, |
69 | ... 'PATCH', webservice) |
70 | HTTP/1.1 209 Content Returned |
71 | ... |
72 | @@ -131,7 +131,7 @@ |
73 | |
74 | An unprivileged user is not able to change the visibility. |
75 | |
76 | - >>> print modify_team('~my-new-team', {'visibility' : 'Private Membership'}, |
77 | + >>> print modify_team('/~my-new-team', {'visibility' : 'Private Membership'}, |
78 | ... 'PATCH', user_webservice) |
79 | HTTP/1.1 401 Unauthorized |
80 | ... |
81 | |
82 | === modified file 'lib/canonical/launchpad/pagetests/webservice/xx-project-registry.txt' |
83 | --- lib/canonical/launchpad/pagetests/webservice/xx-project-registry.txt 2009-08-13 15:12:16 +0000 |
84 | +++ lib/canonical/launchpad/pagetests/webservice/xx-project-registry.txt 2009-08-21 19:49:18 +0000 |
85 | @@ -173,10 +173,8 @@ |
86 | name. As a convenience, requests for projects using the wrong case |
87 | are redirected to the correct location. |
88 | |
89 | - >>> firefox = webservice.get('/FireFox').jsonBody() |
90 | - Traceback (most recent call last): |
91 | - ... |
92 | - ValueError: HTTP/1.1 301 Moved Permanently |
93 | + >>> print webservice.get('/FireFox') |
94 | + HTTP/1.1 301 Moved Permanently |
95 | ... |
96 | Location: http://api.launchpad.dev/beta/firefox |
97 | ... |
98 | @@ -578,15 +576,17 @@ |
99 | Mega Money Maker |
100 | |
101 | The use of "licensing_search" is restricted to commercial admins. |
102 | -Attempting to access it as a normal users results in an exception. |
103 | +Attempting to access it as a normal users is unauthorized. |
104 | |
105 | - >>> proprietary = user_webservice.named_get( |
106 | + >>> print user_webservice.named_get( |
107 | ... "/projects", "licensing_search", |
108 | - ... licenses=["Other/Proprietary"]).jsonBody() |
109 | + ... licenses=["Other/Proprietary"]) |
110 | + HTTP/1.1 401 Unauthorized |
111 | + ... |
112 | Traceback (most recent call last): |
113 | ... |
114 | - ValueError: HTTP/1.1 401 Unauthorized |
115 | - ... |
116 | + Unauthorized: (...) |
117 | + <BLANKLINE> |
118 | |
119 | The project collection has a method for creating a new project. |
120 | |
121 | @@ -996,14 +996,14 @@ |
122 | >>> url = '/firefox/trunk/0.9.2/+file/firefox-0.9.2.orig.tar.gz/file' |
123 | >>> response = webservice.put(url, 'application/x-tar-gz', 'fakefiledata') |
124 | >>> print response |
125 | - HTTP/1.1 405 Method Not Allowed |
126 | + HTTP/1.1 405 Method Not Allowed... |
127 | Allow: GET |
128 | ... |
129 | |
130 | >>> url = '/firefox/trunk/0.9.2/+file/firefox-0.9.2.orig.tar.gz/signature' |
131 | >>> response = webservice.put(url, 'pgpapplication/data', 'signaturedata') |
132 | >>> print response |
133 | - HTTP/1.1 405 Method Not Allowed |
134 | + HTTP/1.1 405 Method Not Allowed... |
135 | Allow: GET |
136 | ... |
137 | |
138 | |
139 | === modified file 'lib/canonical/launchpad/pagetests/webservice/xx-service.txt' |
140 | --- lib/canonical/launchpad/pagetests/webservice/xx-service.txt 2009-07-16 22:15:11 +0000 |
141 | +++ lib/canonical/launchpad/pagetests/webservice/xx-service.txt 2009-08-20 04:46:48 +0000 |
142 | @@ -77,6 +77,7 @@ |
143 | request to http://api.launchpad.net/beta/, but with the links pointing |
144 | to a different host. |
145 | |
146 | + >>> webservice.domain = 'bugs.launchpad.dev' |
147 | >>> root = webservice.get( |
148 | ... 'http://bugs.launchpad.dev/api/beta/').jsonBody() |
149 | >>> print root['people_collection_link'] |
150 | @@ -87,7 +88,8 @@ |
151 | |
152 | >>> from canonical.launchpad.testing.pages import ( |
153 | ... LaunchpadWebServiceCaller) |
154 | - >>> noauth_webservice = LaunchpadWebServiceCaller() |
155 | + >>> noauth_webservice = LaunchpadWebServiceCaller( |
156 | + ... domain='bugs.launchpad.dev') |
157 | >>> sample_auth = 'Basic %s' % 'test@canonical.com:test'.encode('base64') |
158 | >>> print noauth_webservice.get( |
159 | ... 'http://bugs.launchpad.dev/api/beta/people/+me', |
160 | @@ -100,9 +102,9 @@ |
161 | But the regular authentication still doesn't work on the normal API |
162 | virtual host: |
163 | |
164 | + >>> noauth_webservice.domain = 'api.launchpad.dev' |
165 | >>> print noauth_webservice.get( |
166 | ... 'http://api.launchpad.dev/beta/people/+me', |
167 | ... headers={'Authorization': sample_auth}) |
168 | HTTP/1.1 401 Unauthorized |
169 | ... |
170 | - |
171 | |
172 | === modified file 'lib/canonical/launchpad/pagetests/webservice/xx-wadl.txt' |
173 | --- lib/canonical/launchpad/pagetests/webservice/xx-wadl.txt 2009-06-12 16:36:02 +0000 |
174 | +++ lib/canonical/launchpad/pagetests/webservice/xx-wadl.txt 2009-08-20 04:46:48 +0000 |
175 | @@ -10,7 +10,7 @@ |
176 | canonical/launchpad/apidoc/wadl-development.xml. |
177 | |
178 | >>> test_wadl = webservice.get( |
179 | - ... '/', 'application/vd.sun.wadl+xml').getBody() |
180 | + ... '/', 'application/vd.sun.wadl+xml').body |
181 | >>> print test_wadl |
182 | <?xml version="1.0"?> |
183 | <wadl:application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
184 | @@ -32,7 +32,7 @@ |
185 | >>> WebServiceApplication.cached_wadl = None |
186 | |
187 | >>> wadl = webservice.get( |
188 | - ... '/', 'application/vd.sun.wadl+xml').getBody() |
189 | + ... '/', 'application/vd.sun.wadl+xml').body |
190 | >>> wadl = wadl.decode('UTF-8') |
191 | |
192 | The real file is much bigger than the test file. |
193 | |
194 | === modified file 'lib/canonical/launchpad/testing/googletestservice.py' |
195 | --- lib/canonical/launchpad/testing/googletestservice.py 2009-06-25 05:30:52 +0000 |
196 | +++ lib/canonical/launchpad/testing/googletestservice.py 2009-08-25 21:39:10 +0000 |
197 | @@ -108,7 +108,7 @@ |
198 | sock.close() # Clean up. |
199 | |
200 | |
201 | -def wait_for_service(timeout=10.0): |
202 | +def wait_for_service(timeout=15.0): |
203 | """Poll the service and BLOCK until we can connect to it. |
204 | |
205 | :param timeout: The socket should timeout after this many seconds. |
206 | |
207 | === modified file 'lib/canonical/launchpad/testing/pages.py' |
208 | --- lib/canonical/launchpad/testing/pages.py 2009-08-20 06:53:22 +0000 |
209 | +++ lib/canonical/launchpad/testing/pages.py 2009-08-21 19:49:18 +0000 |
210 | @@ -25,7 +25,7 @@ |
211 | BeautifulSoup, Comment, Declaration, NavigableString, PageElement, |
212 | ProcessingInstruction, SoupStrainer, Tag) |
213 | from contrib.oauth import OAuthRequest, OAuthSignatureMethod_PLAINTEXT |
214 | -from urlparse import urljoin |
215 | +from urlparse import urljoin, urlparse |
216 | |
217 | from zope.app.testing.functional import HTTPCaller, SimpleCookie |
218 | from zope.component import getUtility |
219 | @@ -87,10 +87,9 @@ |
220 | class LaunchpadWebServiceCaller(WebServiceCaller): |
221 | """A class for making calls to Launchpad web services.""" |
222 | |
223 | - base_url = 'http://api.launchpad.dev' |
224 | - |
225 | def __init__(self, oauth_consumer_key=None, oauth_access_key=None, |
226 | - handle_errors=True, *args, **kwargs): |
227 | + handle_errors=True, domain='api.launchpad.dev', |
228 | + protocol='http'): |
229 | """Create a LaunchpadWebServiceCaller. |
230 | :param oauth_consumer_key: The OAuth consumer key to use. |
231 | :param oauth_access_key: The OAuth access key to use for the request. |
232 | @@ -111,9 +110,7 @@ |
233 | self.access_token = None |
234 | |
235 | self.handle_errors = handle_errors |
236 | - |
237 | - # Set up a delegate to make the actual HTTP calls. |
238 | - self.http_caller = UnstickyCookieHTTPCaller(*args, **kwargs) |
239 | + WebServiceCaller.__init__(self, handle_errors, domain, protocol) |
240 | |
241 | def addHeadersTo(self, full_url, full_headers): |
242 | if (self.consumer is not None and self.access_token is not None): |
243 | @@ -123,6 +120,8 @@ |
244 | request.sign_request(OAuthSignatureMethod_PLAINTEXT(), |
245 | self.consumer, self.access_token) |
246 | full_headers.update(request.to_header(OAUTH_REALM)) |
247 | + if not self.handle_errors: |
248 | + full_headers['X_Zope_handle_errors'] = 'False' |
249 | |
250 | |
251 | def extract_url_parameter(url, parameter): |
252 | @@ -619,7 +618,7 @@ |
253 | access_token = request_token.createAccessToken() |
254 | logout() |
255 | return LaunchpadWebServiceCaller( |
256 | - consumer_key, access_token.key, port=9000) |
257 | + consumer_key, access_token.key) # "port=9000" was ignored, now not sent |
258 | |
259 | |
260 | def stop(): |
261 | |
262 | === modified file 'lib/canonical/lazr/testing/layers.py' |
263 | --- lib/canonical/lazr/testing/layers.py 2009-06-25 05:30:52 +0000 |
264 | +++ lib/canonical/lazr/testing/layers.py 2009-08-17 19:16:23 +0000 |
265 | @@ -1,9 +1,20 @@ |
266 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
267 | # GNU Affero General Public License version 3 (see the file LICENSE). |
268 | - |
269 | -# Re-import code from lazr.restful until it can be refactored into a |
270 | -# utility module. |
271 | -__all__ = [] |
272 | -import lazr.restful.testing.layers |
273 | -__all__.extend(lazr.restful.testing.layers.__all__) |
274 | -from lazr.restful.testing.layers import * |
275 | +"""Miscellaneous testing helpers.""" |
276 | + |
277 | +__metaclass__ = type |
278 | +__all__ = [ |
279 | + 'MockRootFolder', |
280 | +] |
281 | + |
282 | +class MockRootFolder: |
283 | + """Implement the minimum functionality required by Z3 ZODB dependencies |
284 | + |
285 | + Installed as part of FunctionalLayer.testSetUp() to allow the http() |
286 | + method (zope.app.testing.functional.HTTPCaller) to work. |
287 | + """ |
288 | + @property |
289 | + def _p_jar(self): |
290 | + return self |
291 | + def sync(self): |
292 | + pass |
293 | |
294 | === modified file 'lib/canonical/testing/layers.py' |
295 | --- lib/canonical/testing/layers.py 2009-08-21 19:38:21 +0000 |
296 | +++ lib/canonical/testing/layers.py 2009-08-25 19:09:14 +0000 |
297 | @@ -69,7 +69,10 @@ |
298 | import psycopg2 |
299 | from storm.zope.interfaces import IZStorm |
300 | import transaction |
301 | +import wsgi_intercept |
302 | |
303 | +from zope.app.publication.httpfactory import chooseClasses |
304 | +from zope.app.publication.http import HTTPPublication |
305 | import zope.app.testing.functional |
306 | from zope.app.testing.functional import FunctionalTestSetup, ZopePublication |
307 | from zope.component import getUtility, provideUtility |
308 | @@ -752,6 +755,47 @@ |
309 | "DELETE FROM SessionData") |
310 | |
311 | |
312 | +def wsgi_application(environ, start_response): |
313 | + """This is a wsgi application for Zope functional testing. |
314 | + |
315 | + We use it with wsgi_intercept, which is itself mostly interesting |
316 | + for our webservice (lazr.restful) tests. |
317 | + """ |
318 | + # Committing work done up to now is a convenience that the Zope |
319 | + # zope.app.testing.functional.HTTPCaller does. We're replacing that bit, |
320 | + # so it is easiest to follow that lead, even if it feels a little loose. |
321 | + transaction.commit() |
322 | + # Let's support post-mortem debugging. |
323 | + if environ.get('HTTP_X_ZOPE_HANDLE_ERRORS') == 'False': |
324 | + environ['wsgi.handleErrors'] = False |
325 | + if 'HTTP_X_ZOPE_HANDLE_ERRORS' in environ: |
326 | + del environ['HTTP_X_ZOPE_HANDLE_ERRORS'] |
327 | + handle_errors = environ.get('wsgi.handleErrors', True) |
328 | + # Now we do the proper dance to get the desired request. This is an |
329 | + # almalgam of code from zope.app.testing.functional.HTTPCaller and |
330 | + # zope.publisher.paste.Application. |
331 | + request_cls, publication_cls = chooseClasses( |
332 | + environ['REQUEST_METHOD'], environ) |
333 | + publication = publication_cls(FunctionalTestSetup().db) |
334 | + request = request_cls(environ['wsgi.input'], environ) |
335 | + request.setPublication(publication) |
336 | + # The rest of this function is an amalgam of |
337 | + # zope.publisher.paste.Application.__call__ and van.testing.layers. |
338 | + request = zope.publisher.publish.publish( |
339 | + request, handle_errors=handle_errors) |
340 | + response = request.response |
341 | + # We sort these, and then put the status first, because |
342 | + # zope.testbrowser.testing does--and because it makes it easier to write |
343 | + # reliable tests. |
344 | + headers = sorted(response.getHeaders()) |
345 | + status = response.getStatusString() |
346 | + headers.insert(0, ('Status', status)) |
347 | + # Start the WSGI server response. |
348 | + start_response(status, headers) |
349 | + # Return the result body iterable. |
350 | + return response.consumeBodyIter() |
351 | + |
352 | + |
353 | class FunctionalLayer(BaseLayer): |
354 | """Loads the Zope3 component architecture in appserver mode.""" |
355 | |
356 | @@ -773,11 +817,14 @@ |
357 | # they're defined by Python code, we need to call that code |
358 | # here. |
359 | register_launchpad_request_publication_factories() |
360 | + wsgi_intercept.add_wsgi_intercept( |
361 | + 'localhost', 80, lambda: wsgi_application) |
362 | |
363 | @classmethod |
364 | @profiled |
365 | def tearDown(cls): |
366 | FunctionalLayer.isSetUp = False |
367 | + wsgi_intercept.remove_wsgi_intercept('localhost', 80) |
368 | # Signal Layer cannot be torn down fully |
369 | raise NotImplementedError |
370 | |
371 | @@ -1279,6 +1326,11 @@ |
372 | access_logger.log(MockHTTPTask(response._response, first_line)) |
373 | return response |
374 | |
375 | + # Setting STAGGER_RETRIES makes tests like notfound-traversals.txt go |
376 | + # much, much faster by avoiding calls to time.sleep() |
377 | + cls._original_stagger_retries = zope.publisher.http.STAGGER_RETRIES |
378 | + zope.publisher.http.STAGGER_RETRIES = False |
379 | + |
380 | PageTestLayer.orig__call__ = ( |
381 | zope.app.testing.functional.HTTPCaller.__call__) |
382 | zope.app.testing.functional.HTTPCaller.__call__ = my__call__ |
383 | @@ -1290,6 +1342,7 @@ |
384 | PageTestLayer.resetBetweenTests(True) |
385 | zope.app.testing.functional.HTTPCaller.__call__ = ( |
386 | PageTestLayer.orig__call__) |
387 | + zope.publisher.http.STAGGER_RETRIES = cls._original_stagger_retries |
388 | if PageTestLayer.profiler: |
389 | PageTestLayer.profiler.dump_stats( |
390 | os.environ.get('PROFILE_PAGETESTS_REQUESTS')) |
391 | |
392 | === removed directory 'lib/lazr' |
393 | === removed file 'lib/lazr/__init__.py' |
394 | --- lib/lazr/__init__.py 2009-06-02 08:20:49 +0000 |
395 | +++ lib/lazr/__init__.py 1970-01-01 00:00:00 +0000 |
396 | @@ -1,10 +0,0 @@ |
397 | -# This is a namespace package for lazr.* packages. We should absolutely get rid |
398 | -# of this once we are using eggs. |
399 | -import warnings |
400 | -warnings.filterwarnings( |
401 | - 'ignore', |
402 | - 'Module .+ was already imported from .+, but .+ is being added.*', |
403 | - UserWarning) |
404 | - |
405 | -import pkg_resources |
406 | -pkg_resources.declare_namespace('lazr') |
407 | |
408 | === removed symlink 'lib/lazr/batchnavigator' |
409 | === target was u'../../sourcecode/lazr.batchnavigator/src/lazr/batchnavigator' |
410 | === removed symlink 'lib/lazr/config' |
411 | === target was u'../../sourcecode/lazr.config/src/lazr/config' |
412 | === removed symlink 'lib/lazr/delegates' |
413 | === target was u'../../sourcecode/lazr.delegates/src/lazr/delegates' |
414 | === removed symlink 'lib/lazr/enum' |
415 | === target was u'../../sourcecode/lazr.enum/src/lazr/enum' |
416 | === removed symlink 'lib/lazr/lifecycle' |
417 | === target was u'../../sourcecode/lazr.lifecycle/src/lazr/lifecycle' |
418 | === removed symlink 'lib/lazr/restful' |
419 | === target was u'../../sourcecode/lazr.restful/src/lazr/restful/' |
420 | === modified file 'lib/lp/bugs/stories/webservice/xx-bug-target.txt' |
421 | --- lib/lp/bugs/stories/webservice/xx-bug-target.txt 2009-06-12 16:36:02 +0000 |
422 | +++ lib/lp/bugs/stories/webservice/xx-bug-target.txt 2009-08-20 04:46:48 +0000 |
423 | @@ -30,8 +30,8 @@ |
424 | ... u'Include your credit-card details, mwuh'} |
425 | >>> response = user_webservice.patch( |
426 | ... product['self_link'], 'application/json', dumps(patch)) |
427 | - >>> print response.getOutput() |
428 | - HTTP/1.1 401 Unauthorized |
429 | + >>> print response |
430 | + HTTP/1.1 401 Unauthorized... |
431 | Content-Length: ... |
432 | Content-Type: text/plain |
433 | X-Lazr-Oopsid: OOPS-... |
434 | @@ -117,4 +117,3 @@ |
435 | ... '/testix', 'application/json', |
436 | ... dumps({'official_bug_tags': [u'foo', u'bar']})) |
437 | HTTP/1.1 209 Content Returned... |
438 | - |
439 | |
440 | === modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt' |
441 | --- lib/lp/bugs/stories/webservice/xx-bug.txt 2009-08-22 16:01:03 +0000 |
442 | +++ lib/lp/bugs/stories/webservice/xx-bug.txt 2009-08-25 19:09:14 +0000 |
443 | @@ -245,7 +245,7 @@ |
444 | There is no top-level collection of messages; they only exist in |
445 | relation to some bug. |
446 | |
447 | - >>> webservice.get("/messages").getStatus() |
448 | + >>> webservice.get("/messages").status |
449 | 404 |
450 | |
451 | We can add a new message to a bug by calling the newMessage method. |
452 | @@ -254,7 +254,7 @@ |
453 | ... "/bugs/5", 'newMessage', |
454 | ... subject='A new message', |
455 | ... content='This is a new message added through the webservice API.') |
456 | - HTTP/1.1 201 Created |
457 | + HTTP/1.1 201 Created... |
458 | Content-Length: 0 |
459 | Content-Type: text/plain |
460 | Location: http://api.launchpad.dev/beta/firefox/+bug/5/comments/1 |
461 | @@ -273,7 +273,7 @@ |
462 | >>> print webservice.named_post( |
463 | ... "/bugs/5", 'newMessage', |
464 | ... content='This is a new message with no subject.') |
465 | - HTTP/1.1 201 Created |
466 | + HTTP/1.1 201 Created... |
467 | Content-Length: 0 |
468 | Content-Type: text/plain |
469 | Location: http://api.launchpad.dev/beta/firefox/+bug/5/comments/2 |
470 | @@ -334,7 +334,7 @@ |
471 | |
472 | The collection of bug tasks is not exposed as a resource: |
473 | |
474 | - >>> webservice.get("/bug_tasks").getStatus() |
475 | + >>> webservice.get("/bug_tasks").status |
476 | 404 |
477 | |
478 | It's possible to change the task's assignee. |
479 | @@ -823,7 +823,7 @@ |
480 | |
481 | The collection of bug watches is not exposed as a resource: |
482 | |
483 | - >>> webservice.get("/bug_watches").getStatus() |
484 | + >>> webservice.get("/bug_watches").status |
485 | 404 |
486 | |
487 | We can modify the remote bug. |
488 | @@ -844,8 +844,8 @@ |
489 | >>> patch = {u'url': u'http://www.example.com/'} |
490 | >>> response = webservice.patch( |
491 | ... bug_watch_2000['self_link'], 'application/json', dumps(patch)) |
492 | - >>> print response.getOutput() |
493 | - HTTP/1.1 400 Bad Request |
494 | + >>> print response |
495 | + HTTP/1.1 400 Bad Request... |
496 | Content-Length: 47 |
497 | Content-Type: text/plain |
498 | ... |
499 | @@ -860,8 +860,8 @@ |
500 | ... bug_tracker=webservice.getAbsoluteUrl( |
501 | ... '/bugs/bugtrackers/mozilla.org'), |
502 | ... remote_bug='9876') |
503 | - >>> print response.getOutput() |
504 | - HTTP/1.1 201 Created |
505 | + >>> print response |
506 | + HTTP/1.1 201 Created... |
507 | Content-Length: 0 |
508 | Content-Type: text/plain |
509 | Location: http://.../bugs/1/+watch/13 |
510 | @@ -922,8 +922,8 @@ |
511 | ... } |
512 | >>> response = webservice.patch( |
513 | ... bug_tracker['self_link'], 'application/json', dumps(patch)) |
514 | - >>> print response.getOutput() |
515 | - HTTP/1.1 301 Moved Permanently |
516 | + >>> print response |
517 | + HTTP/1.1 301 Moved Permanently... |
518 | Content-Length: 0 |
519 | Content-Type: text/plain |
520 | Location: http://.../bugs/bugtrackers/bob |
521 | @@ -932,8 +932,8 @@ |
522 | Note the 301 response. We changed the name, so the API URL at which |
523 | the bug tracker can be found has changed. |
524 | |
525 | - >>> print webservice.get(bug_tracker['self_link']).getOutput() |
526 | - HTTP/1.1 404 Not Found |
527 | + >>> print webservice.get(bug_tracker['self_link']) |
528 | + HTTP/1.1 404 Not Found... |
529 | Content-Length: ... |
530 | Content-Type: text/plain |
531 | X-Lazr-Oopsid: OOPS-... |
532 | @@ -969,10 +969,13 @@ |
533 | |
534 | >>> print public_webservice.patch( |
535 | ... bug_tracker_path, 'application/json', |
536 | - ... dumps(dict(active=False))).jsonBody() |
537 | + ... dumps(dict(active=False))) |
538 | + HTTP/1.1 401 Unauthorized |
539 | + ... |
540 | Traceback (most recent call last): |
541 | - ... |
542 | - ValueError: HTTP/1.1 401 Unauthorized... |
543 | + ... |
544 | + Unauthorized: (<BugTracker at ...>, 'active', 'launchpad.Admin') |
545 | + <BLANKLINE> |
546 | |
547 | Admins can, however. |
548 | |
549 | @@ -1002,8 +1005,8 @@ |
550 | ... bug_one['self_link'], 'addAttachment', |
551 | ... data="12345", filename="numbers.txt", content_type='foo/bar', |
552 | ... comment="The numbers you asked for.") |
553 | - >>> print response.getOutput() |
554 | - HTTP/1.1 201 Created |
555 | + >>> print response |
556 | + HTTP/1.1 201 Created... |
557 | Content-Length: 0 |
558 | Content-Type: text/plain |
559 | Location: http://.../bugs/1/+attachment/1 |
560 | @@ -1043,8 +1046,8 @@ |
561 | we must follow to download the data. |
562 | |
563 | >>> data_response = webservice.get(attachment['data_link']) |
564 | - >>> print data_response.getOutput() |
565 | - HTTP/1.1 303 See Other |
566 | + >>> print data_response |
567 | + HTTP/1.1 303 See Other... |
568 | Content-Length: 0 |
569 | Content-Type: text/plain |
570 | Location: http://localhost:58000/.../numbers.txt |
571 | @@ -1098,7 +1101,7 @@ |
572 | |
573 | >>> response = webservice.put( |
574 | ... attachment['data_link'], 'text/text', 'abcdefg') |
575 | - >>> print response.getOutput() |
576 | + >>> print response |
577 | HTTP/1.1 405 Method Not Allowed |
578 | ... |
579 | |
580 | @@ -1116,7 +1119,7 @@ |
581 | |
582 | >>> response = webservice.named_post( |
583 | ... attachment['self_link'], 'removeFromBug') |
584 | - >>> print response.getOutput() |
585 | + >>> print response |
586 | HTTP/1.1 200 Ok |
587 | ... |
588 | |
589 | |
590 | === modified file 'lib/lp/bugs/tests/test_bugs_webservice.py' |
591 | --- lib/lp/bugs/tests/test_bugs_webservice.py 2009-07-24 12:32:28 +0000 |
592 | +++ lib/lp/bugs/tests/test_bugs_webservice.py 2009-08-20 04:46:48 +0000 |
593 | @@ -40,7 +40,7 @@ |
594 | |
595 | def findBugDescription(self, response): |
596 | """Find the bug description field in an XHTML document fragment.""" |
597 | - soup = BeautifulSoup(response.consumeBody()) |
598 | + soup = BeautifulSoup(response.body) |
599 | dt = soup.find('dt', text="description").parent |
600 | dd = dt.findNextSibling('dd') |
601 | return str(dd.contents.pop()) |
602 | @@ -49,8 +49,7 @@ |
603 | response = self.webservice.get( |
604 | '/bugs/' + str(self.bug_two.id), |
605 | 'application/xhtml+xml') |
606 | - |
607 | - self.assertEqual(response.getStatus(), 200) |
608 | + self.assertEqual(response.status, 200) |
609 | |
610 | self.assertEqual( |
611 | self.findBugDescription(response), |
612 | @@ -70,7 +69,7 @@ |
613 | dumps(dict(description=new_description)), |
614 | headers=dict(accept='application/xhtml+xml')) |
615 | |
616 | - self.assertEqual(response.getStatus(), 209) |
617 | + self.assertEqual(response.status, 209) |
618 | |
619 | self.assertEqual( |
620 | self.findBugDescription(response), |
621 | @@ -118,9 +117,9 @@ |
622 | response = self.webservice.get( |
623 | self.message_path, 'application/xhtml+xml') |
624 | |
625 | - self.assertEqual(response.getStatus(), 200) |
626 | + self.assertEqual(response.status, 200) |
627 | |
628 | - rendered_comment = response.consumeBody() |
629 | + rendered_comment = response.body |
630 | # XXX Bjorn Tillenius 2009-05-15 bug=377003 |
631 | # The current request is a web service request when rendering |
632 | # the HTML, causing canonical_url to produce links pointing to the |
633 | @@ -137,4 +136,3 @@ |
634 | |
635 | def test_suite(): |
636 | return unittest.TestLoader().loadTestsFromName(__name__) |
637 | - |
638 | |
639 | === modified file 'lib/lp/code/stories/webservice/xx-branchmergeproposal.txt' |
640 | --- lib/lp/code/stories/webservice/xx-branchmergeproposal.txt 2009-08-07 02:48:00 +0000 |
641 | +++ lib/lp/code/stories/webservice/xx-branchmergeproposal.txt 2009-08-20 04:46:48 +0000 |
642 | @@ -208,9 +208,9 @@ |
643 | ... diff_content=diff_content, |
644 | ... diff_stat='M fooix.txt', source_revision_id='rev-a', |
645 | ... target_revision_id='rev-b', conflicts='oh, no conflicts') |
646 | - >>> print response.getOutput() |
647 | + >>> print response |
648 | HTTP/1.1 200 Ok |
649 | - Content-Length: ... |
650 | + ... |
651 | Content-Type: application/json |
652 | Vary: ... |
653 | ... |
654 | @@ -245,9 +245,9 @@ |
655 | ... diff_content='', |
656 | ... diff_stat='', source_revision_id='rev-c', |
657 | ... target_revision_id='rev-d', conflicts=None) |
658 | - >>> print response.getOutput() |
659 | + >>> print response |
660 | HTTP/1.1 200 Ok |
661 | - Content-Length: ... |
662 | + ... |
663 | Content-Type: application/json |
664 | Vary: ... |
665 | ... |
666 | |
667 | === modified file 'lib/lp/soyuz/stories/webservice/xx-archive.txt' |
668 | --- lib/lp/soyuz/stories/webservice/xx-archive.txt 2009-08-13 15:12:16 +0000 |
669 | +++ lib/lp/soyuz/stories/webservice/xx-archive.txt 2009-08-21 19:49:18 +0000 |
670 | @@ -1,4 +1,5 @@ |
671 | -= Archives = |
672 | +Archives |
673 | +======== |
674 | |
675 | Representations for IArchive can be fetch via the API for PPAs and |
676 | distribution archives. |
677 | @@ -101,12 +102,14 @@ |
678 | |
679 | Attempting to grab a non-existent archive will result in a 404 error: |
680 | |
681 | - >>> bogus_archive = "ubuntutest/+archive/bogus" |
682 | - >>> webservice.get(bogus_archive).jsonBody() |
683 | + >>> bogus_archive = "http://api.launchpad.dev/beta/ubuntutest/+archive/bogus" |
684 | + >>> print webservice.get(bogus_archive) |
685 | + HTTP/1.1 404 Not Found |
686 | + ... |
687 | Traceback (most recent call last): |
688 | ... |
689 | - ValueError: HTTP/1.1 404 Not Found |
690 | - ... |
691 | + NotFound: Object: ..., name: u'bogus' |
692 | + <BLANKLINE> |
693 | |
694 | |
695 | = Archive Permissions = |
696 | @@ -224,7 +227,7 @@ |
697 | |
698 | >>> print webservice.named_get( |
699 | ... ubuntu['main_archive_link'], 'getUploadersForPackage', |
700 | - ... source_package_name="badpackage").getOutput() |
701 | + ... source_package_name="badpackage") |
702 | HTTP/1.1 400 Bad Request |
703 | ... |
704 | |
705 | @@ -236,7 +239,7 @@ |
706 | ... ubuntu['main_archive_link'], 'newPackageUploader', {}, |
707 | ... person=name12['self_link'], |
708 | ... source_package_name='mozilla-firefox') |
709 | - >>> print response.getOutput() |
710 | + >>> print response |
711 | HTTP/1.1 201 Created |
712 | ... |
713 | |
714 | @@ -279,7 +282,7 @@ |
715 | |
716 | >>> print webservice.named_get( |
717 | ... ubuntu['main_archive_link'], 'getUploadersForComponent', |
718 | - ... component_name="badcomponent").getOutput() |
719 | + ... component_name="badcomponent") |
720 | HTTP/1.1 400 Bad Request |
721 | ... |
722 | |
723 | @@ -297,7 +300,7 @@ |
724 | ... ubuntu['main_archive_link'], 'newComponentUploader', {}, |
725 | ... person=name12['self_link'], |
726 | ... component_name='restricted') |
727 | - >>> print response.getOutput() |
728 | + >>> print response |
729 | HTTP/1.1 201 Created |
730 | ... |
731 | |
732 | @@ -318,7 +321,7 @@ |
733 | >>> response = webservice.named_post( |
734 | ... cprov_archive['self_link'], 'newComponentUploader', {}, |
735 | ... person=name12['self_link'], component_name='restricted') |
736 | - >>> print response.getOutput() |
737 | + >>> print response |
738 | HTTP/1.1 400 Bad Request |
739 | ... |
740 | InvalidComponent: Component for PPAs should be 'main' |
741 | @@ -327,7 +330,7 @@ |
742 | >>> response = webservice.named_post( |
743 | ... cprov_archive['self_link'], 'newComponentUploader', {}, |
744 | ... person=name12['self_link'], component_name='main') |
745 | - >>> print response.getOutput() |
746 | + >>> print response |
747 | HTTP/1.1 201 Created |
748 | ... |
749 | |
750 | @@ -382,7 +385,7 @@ |
751 | ... ubuntu['main_archive_link'], 'newQueueAdmin', {}, |
752 | ... person=name12['self_link'], |
753 | ... component_name='partner') |
754 | - >>> print response.getOutput() |
755 | + >>> print response |
756 | HTTP/1.1 201 Created |
757 | ... |
758 | |
759 | @@ -425,7 +428,7 @@ |
760 | |
761 | >>> missing_type_url = '/ubuntu/+archive/primary/+upload/name12?item=firefox' |
762 | >>> this_will_fail = webservice.get(missing_type_url) |
763 | - >>> print this_will_fail.getOutput() |
764 | + >>> print this_will_fail |
765 | HTTP/1.1 404 Not Found |
766 | ... |
767 | |
768 | @@ -434,7 +437,7 @@ |
769 | |
770 | >>> wrong_type_url = '/ubuntu/+archive/primary/+upload/name12?type=packageset&item=firefox&type=Integer' |
771 | >>> this_will_fail = webservice.get(missing_type_url) |
772 | - >>> print this_will_fail.getOutput() |
773 | + >>> print this_will_fail |
774 | HTTP/1.1 404 Not Found |
775 | ... |
776 | |
777 | @@ -442,7 +445,7 @@ |
778 | |
779 | >>> missing_item_url = '/ubuntu/+archive/primary/+upload/name12?type=packageset' |
780 | >>> this_will_fail = webservice.get(missing_type_url) |
781 | - >>> print this_will_fail.getOutput() |
782 | + >>> print this_will_fail |
783 | HTTP/1.1 404 Not Found |
784 | ... |
785 | |
786 | @@ -451,7 +454,7 @@ |
787 | |
788 | >>> wrong_type_url = '/ubuntu/+archive/primary/+upload/name12?type=packageset&item=firefox&item=vapourware' |
789 | >>> this_will_fail = webservice.get(missing_type_url) |
790 | - >>> print this_will_fail.getOutput() |
791 | + >>> print this_will_fail |
792 | HTTP/1.1 404 Not Found |
793 | ... |
794 | |
795 | @@ -626,7 +629,7 @@ |
796 | syncSources is invoked directly by the client, and any problems are |
797 | the client's fault. Therefore, there's no need to record an OOPS. |
798 | |
799 | - >>> 'X-Lazr-Oopsid' in already_copied.getOutput() |
800 | + >>> 'X-Lazr-Oopsid' in str(already_copied) |
801 | False |
802 | |
803 | 'syncSources' behaves trasactionally, i.e. it will only synchronise |
804 | @@ -749,7 +752,7 @@ |
805 | >>> response = mark_webservice.named_post( |
806 | ... mark_archive['self_link'], 'newSubscription', |
807 | ... subscriber=cprov_archive['owner_link']) |
808 | - >>> print response.getOutput() |
809 | + >>> print response |
810 | HTTP/1.1 400 Bad Request |
811 | ... |
812 | ArchiveNotPrivate: Only private archives can have subscriptions. |
813 | @@ -763,7 +766,7 @@ |
814 | ... cprov_archive['self_link'], 'newSubscription', |
815 | ... subscriber=mark['self_link']) |
816 | |
817 | - >>> print response.getOutput() |
818 | + >>> print response |
819 | HTTP/1.1 201 Created |
820 | ... |
821 | |
822 | @@ -789,7 +792,7 @@ |
823 | |
824 | >>> response = user_webservice.get( |
825 | ... response.getHeader('Location')) |
826 | - >>> print response.getOutput() |
827 | + >>> print response |
828 | HTTP/1.1 401 Unauthorized |
829 | ... |
830 | |
831 | @@ -800,7 +803,7 @@ |
832 | >>> response = user_webservice.named_post( |
833 | ... cprov_archive['self_link'], 'newSubscription', |
834 | ... subscriber=cprov_archive['owner_link']) |
835 | - >>> print response.getOutput() |
836 | + >>> print response |
837 | HTTP/1.1 401 Unauthorized |
838 | ... |
839 | |
840 | @@ -810,7 +813,7 @@ |
841 | >>> response = cprov_webservice.named_post( |
842 | ... cprov_archive['self_link'], 'newSubscription', |
843 | ... subscriber=mark['self_link']) |
844 | - >>> print response.getOutput() |
845 | + >>> print response |
846 | HTTP/1.1 400 Bad Request |
847 | ... |
848 | AlreadySubscribed: Mark Shuttleworth already has a current subscription |
849 | |
850 | === modified file 'lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt' |
851 | --- lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt 2009-04-28 12:59:43 +0000 |
852 | +++ lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt 2009-08-20 04:46:48 +0000 |
853 | @@ -110,7 +110,7 @@ |
854 | |
855 | >>> cprov_bins_response = webservice.named_get( |
856 | ... cprov_archive['self_link'], 'getPublishedBinaries') |
857 | - >>> print cprov_bins_response.getOutput() |
858 | + >>> print cprov_bins_response |
859 | HTTP/1.1 200 Ok |
860 | ... |
861 | |
862 | @@ -118,7 +118,7 @@ |
863 | |
864 | >>> response = user_webservice.named_get( |
865 | ... cprov_archive['self_link'], 'getPublishedBinaries') |
866 | - >>> print response.getOutput() |
867 | + >>> print response |
868 | HTTP/1.1 401 Unauthorized |
869 | ... |
870 | |
871 | @@ -127,7 +127,6 @@ |
872 | |
873 | >>> private_publication_url = pubs['entries'][0]['self_link'] |
874 | >>> response = user_webservice.get(private_publication_url) |
875 | - >>> print response.getOutput() |
876 | + >>> print response |
877 | HTTP/1.1 401 Unauthorized |
878 | ... |
879 | - |
880 | |
881 | === modified file 'lib/lp/soyuz/stories/webservice/xx-packageset.txt' |
882 | --- lib/lp/soyuz/stories/webservice/xx-packageset.txt 2009-07-25 16:33:39 +0000 |
883 | +++ lib/lp/soyuz/stories/webservice/xx-packageset.txt 2009-08-20 04:46:48 +0000 |
884 | @@ -12,7 +12,7 @@ |
885 | |
886 | The actual package set *functionality* is tested in much greater detail |
887 | here: |
888 | - |
889 | + |
890 | lib/lp/soyuz/doc/packageset.txt |
891 | |
892 | Please refer to the tests contained in the file above if you are really |
893 | @@ -29,7 +29,7 @@ |
894 | ... '/package-sets', 'new', {}, |
895 | ... name=u'umbrella', description=u'Contains all source packages', |
896 | ... owner=name12['self_link']) |
897 | - >>> print response.getOutput() |
898 | + >>> print response |
899 | HTTP/1.1 201 Created |
900 | ... |
901 | |
902 | @@ -67,7 +67,7 @@ |
903 | |
904 | >>> response = webservice.named_get( |
905 | ... '/package-sets', 'getByName', {}, name=u'not-found') |
906 | - >>> print response.getOutput() |
907 | + >>> print response |
908 | HTTP/1.1 400 Bad Request |
909 | ... |
910 | NoSuchPackageSet: No such packageset: 'not-found'. |
911 | @@ -83,7 +83,7 @@ |
912 | >>> response = webservice.named_post( |
913 | ... '/package-sets/umbrella', 'addSources', {}, |
914 | ... names=[spn.name for spn in all_spns]) |
915 | - >>> print response.getOutput() |
916 | + >>> print response |
917 | HTTP/1.1 200 Ok |
918 | ... |
919 | |
920 | @@ -93,7 +93,7 @@ |
921 | >>> response = webservice.named_post( |
922 | ... '/package-sets/umbrella', 'addSources', {}, |
923 | ... names=[u'does-not-exist']) |
924 | - >>> print response.getOutput() |
925 | + >>> print response |
926 | HTTP/1.1 200 Ok |
927 | ... |
928 | null |
929 | @@ -101,7 +101,7 @@ |
930 | >>> response = webservice.named_post( |
931 | ... '/package-sets/umbrella', 'removeSources', {}, |
932 | ... names=[u'does-not-exist']) |
933 | - >>> print response.getOutput() |
934 | + >>> print response |
935 | HTTP/1.1 200 Ok |
936 | ... |
937 | null |
938 | @@ -110,7 +110,7 @@ |
939 | |
940 | >>> response = webservice.named_get( |
941 | ... '/package-sets/umbrella', 'getSourcesIncluded', {}) |
942 | - >>> print response.getOutput() |
943 | + >>> print response |
944 | HTTP/1.1 200 Ok |
945 | ... |
946 | ["a52dec", |
947 | @@ -138,7 +138,7 @@ |
948 | >>> response = webservice.named_post( |
949 | ... '/package-sets/umbrella', 'removeSources', {}, |
950 | ... names=["foobar", "iceweasel"]) |
951 | - >>> print response.getOutput() |
952 | + >>> print response |
953 | HTTP/1.1 200 Ok |
954 | ... |
955 | |
956 | @@ -147,7 +147,7 @@ |
957 | |
958 | >>> response = webservice.named_get( |
959 | ... '/package-sets/umbrella', 'getSourcesIncluded', {}) |
960 | - >>> print response.getOutput() |
961 | + >>> print response |
962 | HTTP/1.1 200 Ok |
963 | ... |
964 | ["a52dec", |
965 | @@ -183,7 +183,7 @@ |
966 | |
967 | >>> response = webservice.named_get( |
968 | ... '/package-sets/umbrella', 'setsIncluded', {}) |
969 | - >>> print response.getOutput() |
970 | + >>> print response |
971 | HTTP/1.1 200 Ok |
972 | ... |
973 | {"total_size": 0, "start": null, "entries": []} |
974 | @@ -194,7 +194,7 @@ |
975 | ... '/package-sets', 'new', {}, |
976 | ... name=u'gnome', description=u'Contains all gnome packages', |
977 | ... owner=name12['self_link']) |
978 | - >>> print response.getOutput() |
979 | + >>> print response |
980 | HTTP/1.1 201 Created |
981 | ... |
982 | |
983 | @@ -202,7 +202,7 @@ |
984 | ... '/package-sets', 'new', {}, |
985 | ... name=u'mozilla', description=u'Contains all mozilla packages', |
986 | ... owner=name12['self_link']) |
987 | - >>> print response.getOutput() |
988 | + >>> print response |
989 | HTTP/1.1 201 Created |
990 | ... |
991 | |
992 | @@ -210,7 +210,7 @@ |
993 | ... '/package-sets', 'new', {}, |
994 | ... name=u'firefox', description=u'Contains all firefox packages', |
995 | ... owner=name12['self_link']) |
996 | - >>> print response.getOutput() |
997 | + >>> print response |
998 | HTTP/1.1 201 Created |
999 | ... |
1000 | |
1001 | @@ -219,7 +219,7 @@ |
1002 | ... name=u'thunderbird', |
1003 | ... description=u'Contains all thunderbird packages', |
1004 | ... owner=name12['self_link']) |
1005 | - >>> print response.getOutput() |
1006 | + >>> print response |
1007 | HTTP/1.1 201 Created |
1008 | ... |
1009 | |
1010 | @@ -228,7 +228,7 @@ |
1011 | ... name=u'languagepack', |
1012 | ... description=u'Contains all languagepack packages', |
1013 | ... owner=name12['self_link']) |
1014 | - >>> print response.getOutput() |
1015 | + >>> print response |
1016 | HTTP/1.1 201 Created |
1017 | ... |
1018 | |
1019 | @@ -247,27 +247,27 @@ |
1020 | >>> response = webservice.named_post( |
1021 | ... '/package-sets/umbrella', 'addSubsets', {}, |
1022 | ... names=[u'gnome', u'mozilla']) |
1023 | - >>> print response.getOutput() |
1024 | + >>> print response |
1025 | HTTP/1.1 200 Ok |
1026 | ... |
1027 | |
1028 | >>> response = webservice.named_post( |
1029 | ... '/package-sets/gnome', 'addSubsets', {}, names=[u'languagepack']) |
1030 | - >>> print response.getOutput() |
1031 | + >>> print response |
1032 | HTTP/1.1 200 Ok |
1033 | ... |
1034 | |
1035 | >>> response = webservice.named_post( |
1036 | ... '/package-sets/thunderbird', 'addSubsets', {}, |
1037 | ... names=[u'languagepack']) |
1038 | - >>> print response.getOutput() |
1039 | + >>> print response |
1040 | HTTP/1.1 200 Ok |
1041 | ... |
1042 | |
1043 | >>> response = webservice.named_post( |
1044 | ... '/package-sets/mozilla', 'addSubsets', {}, |
1045 | ... names=[u'firefox', u'thunderbird']) |
1046 | - >>> print response.getOutput() |
1047 | + >>> print response |
1048 | HTTP/1.1 200 Ok |
1049 | ... |
1050 | |
1051 | @@ -277,7 +277,7 @@ |
1052 | >>> response = webservice.named_post( |
1053 | ... '/package-sets/thunderbird', 'addSubsets', {}, |
1054 | ... names=[u'does-not-exist']) |
1055 | - >>> print response.getOutput() |
1056 | + >>> print response |
1057 | HTTP/1.1 200 Ok |
1058 | ... |
1059 | null |
1060 | @@ -285,7 +285,7 @@ |
1061 | >>> response = webservice.named_post( |
1062 | ... '/package-sets/thunderbird', 'removeSubsets', {}, |
1063 | ... names=[u'does-not-exist']) |
1064 | - >>> print response.getOutput() |
1065 | + >>> print response |
1066 | HTTP/1.1 200 Ok |
1067 | ... |
1068 | null |
1069 | @@ -337,7 +337,7 @@ |
1070 | >>> response = webservice.named_post( |
1071 | ... '/package-sets/thunderbird', 'removeSubsets', {}, |
1072 | ... names=[u'languagepack']) |
1073 | - >>> print response.getOutput() |
1074 | + >>> print response |
1075 | HTTP/1.1 200 Ok |
1076 | ... |
1077 | |
1078 | @@ -355,13 +355,13 @@ |
1079 | >>> response = webservice.named_post( |
1080 | ... '/package-sets/firefox', 'addSources', {}, |
1081 | ... names=['at', 'mozilla-firefox', 'language-pack-de']) |
1082 | - >>> print response.getOutput() |
1083 | + >>> print response |
1084 | HTTP/1.1 200 Ok |
1085 | ... |
1086 | |
1087 | >>> response = webservice.named_get( |
1088 | ... '/package-sets/firefox', 'getSourcesIncluded', {}) |
1089 | - >>> print response.getOutput() |
1090 | + >>> print response |
1091 | HTTP/1.1 200 Ok |
1092 | ... |
1093 | ["at", "language-pack-de", "mozilla-firefox"] |
1094 | @@ -369,13 +369,13 @@ |
1095 | >>> response = webservice.named_post( |
1096 | ... '/package-sets/thunderbird', 'addSources', {}, |
1097 | ... names=['at', 'cnews', 'thunderbird', 'language-pack-de']) |
1098 | - >>> print response.getOutput() |
1099 | + >>> print response |
1100 | HTTP/1.1 200 Ok |
1101 | ... |
1102 | |
1103 | >>> response = webservice.named_get( |
1104 | ... '/package-sets/thunderbird', 'getSourcesIncluded', {}) |
1105 | - >>> print response.getOutput() |
1106 | + >>> print response |
1107 | HTTP/1.1 200 Ok |
1108 | ... |
1109 | ["at", "cnews", "language-pack-de", "thunderbird"] |
1110 | @@ -405,7 +405,7 @@ |
1111 | >>> response = webservice.named_get( |
1112 | ... '/package-sets/', 'setsIncludingSource', {}, |
1113 | ... sourcepackagename=u'does-not-exist') |
1114 | - >>> print response.getOutput() |
1115 | + >>> print response |
1116 | HTTP/1.1 400 Bad Request |
1117 | ... |
1118 | No such source package: 'does-not-exist'. |
1119 | @@ -418,7 +418,7 @@ |
1120 | >>> response = webservice.named_get( |
1121 | ... '/package-sets/firefox', 'getSourcesSharedBy', {}, |
1122 | ... other_package_set=thunderbird['self_link']) |
1123 | - >>> print response.getOutput() |
1124 | + >>> print response |
1125 | HTTP/1.1 200 Ok |
1126 | ... |
1127 | ["at", "language-pack-de"] |
1128 | @@ -428,7 +428,7 @@ |
1129 | >>> response = webservice.named_get( |
1130 | ... '/package-sets/firefox', 'getSourcesNotSharedBy', {}, |
1131 | ... other_package_set=thunderbird['self_link']) |
1132 | - >>> print response.getOutput() |
1133 | + >>> print response |
1134 | HTTP/1.1 200 Ok |
1135 | ... |
1136 | ["mozilla-firefox"] |
1137 | @@ -437,7 +437,7 @@ |
1138 | >>> response = webservice.named_get( |
1139 | ... '/package-sets/thunderbird', 'getSourcesNotSharedBy', {}, |
1140 | ... other_package_set=firefox['self_link']) |
1141 | - >>> print response.getOutput() |
1142 | + >>> print response |
1143 | HTTP/1.1 200 Ok |
1144 | ... |
1145 | ["cnews", "thunderbird"] |
1146 | @@ -462,7 +462,7 @@ |
1147 | ... ubuntu['main_archive_link'], 'newPackagesetUploader', {}, |
1148 | ... person=name12['self_link'], |
1149 | ... packageset='firefox') |
1150 | - >>> print response.getOutput() |
1151 | + >>> print response |
1152 | HTTP/1.1 201 Created |
1153 | ... |
1154 | |
1155 | @@ -490,7 +490,7 @@ |
1156 | ... ubuntu['main_archive_link'], 'newPackagesetUploader', {}, |
1157 | ... person=name12['self_link'], |
1158 | ... packageset='mozilla') |
1159 | - >>> print response.getOutput() |
1160 | + >>> print response |
1161 | HTTP/1.1 201 Created |
1162 | ... |
1163 | |
1164 | @@ -519,7 +519,7 @@ |
1165 | ... ubuntu['main_archive_link'], 'deletePackagesetUploader', {}, |
1166 | ... person=name12['self_link'], |
1167 | ... packageset='mozilla') |
1168 | - >>> print response.getOutput() |
1169 | + >>> print response |
1170 | HTTP/1.1 200 Ok |
1171 | ... |
1172 | |
1173 | @@ -539,7 +539,7 @@ |
1174 | ... ubuntu['main_archive_link'], 'newPackagesetUploader', {}, |
1175 | ... person=cprov['self_link'], |
1176 | ... packageset='mozilla') |
1177 | - >>> print response.getOutput() |
1178 | + >>> print response |
1179 | HTTP/1.1 201 Created |
1180 | ... |
1181 | |
1182 | @@ -547,7 +547,7 @@ |
1183 | ... ubuntu['main_archive_link'], 'newPackagesetUploader', {}, |
1184 | ... person=cprov['self_link'], |
1185 | ... packageset='thunderbird') |
1186 | - >>> print response.getOutput() |
1187 | + >>> print response |
1188 | HTTP/1.1 201 Created |
1189 | ... |
1190 | |
1191 | |
1192 | === modified file 'lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt' |
1193 | --- lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2009-07-10 09:14:41 +0000 |
1194 | +++ lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2009-08-20 04:46:48 +0000 |
1195 | @@ -179,7 +179,7 @@ |
1196 | |
1197 | >>> cprov_srcs_response = webservice.named_get( |
1198 | ... cprov_archive['self_link'], 'getPublishedSources') |
1199 | - >>> print cprov_srcs_response.getOutput() |
1200 | + >>> print cprov_srcs_response |
1201 | HTTP/1.1 200 Ok |
1202 | ... |
1203 | |
1204 | @@ -187,7 +187,7 @@ |
1205 | |
1206 | >>> response = user_webservice.named_get( |
1207 | ... cprov_archive['self_link'], 'getPublishedSources') |
1208 | - >>> print response.getOutput() |
1209 | + >>> print response |
1210 | HTTP/1.1 401 Unauthorized |
1211 | ... |
1212 | |
1213 | @@ -196,7 +196,7 @@ |
1214 | |
1215 | >>> private_publication_url = pubs['entries'][0]['self_link'] |
1216 | >>> response = user_webservice.get(private_publication_url) |
1217 | - >>> print response.getOutput() |
1218 | + >>> print response |
1219 | HTTP/1.1 401 Unauthorized |
1220 | ... |
1221 | |
1222 | @@ -252,7 +252,7 @@ |
1223 | >>> cprov_srcs = cprov_srcs_response.jsonBody() |
1224 | >>> src_link = cprov_srcs['entries'][0]['self_link'] |
1225 | |
1226 | -The src_link will be of the form: |
1227 | +The src_link will be of the form: |
1228 | u'http://api.launchpad.dev/beta/~cprov/+archive/ppa/+sourcepub/27' |
1229 | so: |
1230 | |
1231 | @@ -283,4 +283,3 @@ |
1232 | >>> print_build_summaries(build_summaries) |
1233 | Source ID 27: FAILEDTOBUILD ([u'i386']) |
1234 | Source ID 28: FULLYBUILT_PENDING ([u'i386']) |
1235 | - |
1236 | |
1237 | === modified file 'setup.py' |
1238 | --- setup.py 2009-08-05 18:52:52 +0000 |
1239 | +++ setup.py 2009-08-17 19:16:23 +0000 |
1240 | @@ -30,6 +30,12 @@ |
1241 | 'feedvalidator', |
1242 | 'funkload', |
1243 | 'launchpadlib', |
1244 | + 'lazr.batchnavigator', |
1245 | + 'lazr.config', |
1246 | + 'lazr.delegates', |
1247 | + 'lazr.enum', |
1248 | + 'lazr.lifecycle', |
1249 | + 'lazr.restful', |
1250 | 'lazr.smtptest', |
1251 | 'lazr.uri', |
1252 | 'mechanize', |
1253 | |
1254 | === modified file 'utilities/sourcedeps.conf' |
1255 | --- utilities/sourcedeps.conf 2009-08-14 17:26:21 +0000 |
1256 | +++ utilities/sourcedeps.conf 2009-08-17 19:16:23 +0000 |
1257 | @@ -3,13 +3,7 @@ |
1258 | bzr-svn=lp:~launchpad-pqm/bzr-svn/devel/ |
1259 | dulwich=lp:~launchpad-pqm/dulwich/devel/ |
1260 | launchpad-loggerhead=lp:~launchpad-pqm/launchpad-loggerhead/devel/ |
1261 | -lazr.batchnavigator=lp:~launchpad-pqm/lazr.batchnavigator/trunk/ |
1262 | -lazr.config=lp:~launchpad-pqm/lazr.config/devel/ |
1263 | -lazr.delegates=lp:~launchpad-pqm/lazr.delegates/devel/ |
1264 | -lazr.enum=lp:~launchpad-pqm/lazr.enum/trunk/ |
1265 | lazr-js=lp:~launchpad-pqm/lazr-js/toolchain/ |
1266 | -lazr.lifecycle=lp:~launchpad-pqm/lazr.lifecycle/trunk/ |
1267 | -lazr.restful=lp:~launchpad-pqm/lazr.restful/trunk/ |
1268 | loggerhead=lp:~launchpad-pqm/loggerhead/devel/ |
1269 | mailman=lp:~launchpad-pqm/mailman/2.1/ |
1270 | pygpgme=lp:~launchpad-pqm/pygpgme/devel/ |
1271 | |
1272 | === modified file 'versions.cfg' |
1273 | --- versions.cfg 2009-08-24 21:21:35 +0000 |
1274 | +++ versions.cfg 2009-08-25 21:39:10 +0000 |
1275 | @@ -11,14 +11,20 @@ |
1276 | ctypes = 1.0.2 |
1277 | docutils = 0.5 |
1278 | elementtree = 1.2.6-20050316 |
1279 | +epydoc = 3.0.1 |
1280 | feedvalidator = 0.0.0DEV-r1049 |
1281 | functest = 0.8.7 |
1282 | funkload = 1.10.0 |
1283 | httplib2 = 0.4.0 |
1284 | ipython = 0.9.1 |
1285 | -jquery.javascript = 1.0.0 |
1286 | -jquery.layer = 1.0.0 |
1287 | -launchpadlib = 1.0.3 |
1288 | +launchpadlib = 1.5.1 |
1289 | +lazr.batchnavigator = 1.0 |
1290 | +lazr.config = 1.1.3 |
1291 | +lazr.delegates = 1.0.1 |
1292 | +lazr.enum = 1.1.1 |
1293 | +lazr.lifecycle = 0.1 |
1294 | +lazr.restful = 0.9.5 |
1295 | +lazr.restfulclient = 0.9.4 |
1296 | lazr.smtptest = 1.1 |
1297 | lazr.uri = 1.0.1 |
1298 | mechanize = 0.1.7b |
1299 | @@ -30,6 +36,7 @@ |
1300 | python-openid = 2.2.1 |
1301 | pytz = 2009j |
1302 | RestrictedPython = 3.4.2 |
1303 | +roman = 1.4.0 |
1304 | setuptools = 0.6c9 |
1305 | simplejson = 2.0.9 |
1306 | simplesettings = 0.4 |
1307 | @@ -38,10 +45,12 @@ |
1308 | storm = 0.15 |
1309 | transaction = 1.0a1 |
1310 | uuid = 1.30 |
1311 | -wadllib = 0.1 |
1312 | +van.testing = 2.0.1 |
1313 | +wadllib = 1.1.3 |
1314 | webunit = 1.3.8 |
1315 | windmill = 1.2 |
1316 | wsgi-fileserver = 0.2.7 |
1317 | +wsgi-intercept = 0.4 |
1318 | wsgi-jsonrpc = 0.2.8 |
1319 | wsgi-xmlrpc = 0.2.7 |
1320 | z3c.coverage = 1.1.2 |
1321 | @@ -153,7 +162,6 @@ |
1322 | zope.pagetemplate = 3.4.0 |
1323 | zope.proxy = 3.5.0 |
1324 | zope.publisher = 3.5.6 |
1325 | -zope.rdb = 3.4.0 |
1326 | zope.schema = 3.5.4 |
1327 | zope.security = 3.7.1 |
1328 | zope.securitypolicy = 3.4.1 |
1329 | @@ -167,6 +175,5 @@ |
1330 | zope.testbrowser = 3.4.2 |
1331 | zope.testing = 3.8.1 |
1332 | zope.thread = 3.4 |
1333 | -# zope.traversing = 3.5.2 |
1334 | zope.traversing = 3.4.1 |
1335 | zope.viewlet = 3.4.2 |
This branch converts us to using the newest versions of our own packages, via Python disributions:
launchpadlib
lazr.batchnavigator
lazr.config
lazr.delegates
lazr.enum
lazr.lifecycle
lazr.restful
lazr.restfulclient
wadllib
Many of the lines in the diff are because the underlying machinery of the lazr.restful testing helpers changed. It moved from relying on a zope functional testing framework to wsgi_intercept. This meant that I had to add some new testing helpers in the launchpad layer machinery (see lib/canonical/ testing/ layers. py); and the API of the webservice test helper (and its results) changed, so tests changed.
As an interesting side result, it's quite possible that we will be able to use launchpadlib within our functional tests now, or with a two line change to hook up wsgi_intercept in a different way.
An aspect of this worth particular note is that the webservice needs to have its domain set explicitly if you change domains. You can see this in the xx-service.txt diff, for instance.
I increased the timeout in lib/canonical/ launchpad/ testing/ googletestservi ce.py because it helped me on my machine. I'm willing to change it back, but it seems pretty harmless to me.
In lib/canonical/ launchpad/ testing/ pages.py, I remove "port" from calling the LaunchpadWebSer viceCaller. It was ignored before, and I didn't see any reason to add it back. Perhaps the comment that explains its absence is unnecessary, though.
The MockRootFolder is added back to lib/canonical/ lazr/testing/ layers. py because it is no longer found in lazr.restful.
The STAGGER_RETRIES code in lib/canonical/ testing/ layers. py was something I removed in my earlier zbuildout branch but should be added back. We can't remove it until we move to a newer version of zope.publisher, which we can't do yet because of other issues I won't get into right now.