Merge ~cjwatson/launchpad:faster-soyuz-webservice-tests into launchpad:master
- Git
- lp:~cjwatson/launchpad
- faster-soyuz-webservice-tests
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 90f34cf271d86317770e4a2c5357f7d2fd6ffbf9 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:faster-soyuz-webservice-tests |
Merge into: | launchpad:master |
Prerequisite: | ~cjwatson/launchpad:faster-bugs-webservice-tests |
Diff against target: |
748 lines (+294/-204) 1 file modified
lib/lp/soyuz/browser/tests/test_archive_webservice.py (+294/-204) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Thiago F. Pappacena (community) | Approve | ||
Review via email:
|
Commit message
Stop using launchpadlib in Soyuz webservice tests
Port the Soyuz webservice tests to use in-process webservice calls
rather than launchpadlib and AppServerLayer. This takes the test time
for these test suites from 198 seconds to 52 seconds on my laptop.
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Otto Co-Pilot (otto-copilot) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/lp/soyuz/browser/tests/test_archive_webservice.py b/lib/lp/soyuz/browser/tests/test_archive_webservice.py |
2 | index 44aaa41..48cb911 100644 |
3 | --- a/lib/lp/soyuz/browser/tests/test_archive_webservice.py |
4 | +++ b/lib/lp/soyuz/browser/tests/test_archive_webservice.py |
5 | @@ -6,19 +6,17 @@ from __future__ import absolute_import, print_function, unicode_literals |
6 | __metaclass__ = type |
7 | |
8 | from datetime import timedelta |
9 | +import json |
10 | |
11 | -from lazr.restfulclient.errors import ( |
12 | - BadRequest, |
13 | - HTTPError, |
14 | - NotFound, |
15 | - Unauthorized as LRUnauthorized, |
16 | - ) |
17 | -from testtools import ExpectedException |
18 | from testtools.matchers import ( |
19 | + Contains, |
20 | + ContainsDict, |
21 | + EndsWith, |
22 | Equals, |
23 | + MatchesListwise, |
24 | + MatchesRegex, |
25 | MatchesStructure, |
26 | ) |
27 | -import transaction |
28 | from zope.component import getUtility |
29 | |
30 | from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
31 | @@ -34,12 +32,12 @@ from lp.soyuz.interfaces.packagecopyjob import IPlainPackageCopyJobSource |
32 | from lp.soyuz.model.archivepermission import ArchivePermission |
33 | from lp.testing import ( |
34 | admin_logged_in, |
35 | + ANONYMOUS, |
36 | api_url, |
37 | - launchpadlib_for, |
38 | + login, |
39 | person_logged_in, |
40 | record_two_runs, |
41 | TestCaseWithFactory, |
42 | - WebServiceTestCase, |
43 | ) |
44 | from lp.testing.layers import DatabaseFunctionalLayer |
45 | from lp.testing.matchers import HasQueryCount |
46 | @@ -54,46 +52,35 @@ class TestArchiveWebservice(TestCaseWithFactory): |
47 | |
48 | def setUp(self): |
49 | super(TestArchiveWebservice, self).setUp() |
50 | - with admin_logged_in(): |
51 | + with admin_logged_in() as _admin: |
52 | + admin = _admin |
53 | self.archive = self.factory.makeArchive( |
54 | purpose=ArchivePurpose.PRIMARY) |
55 | distroseries = self.factory.makeDistroSeries( |
56 | distribution=self.archive.distribution) |
57 | person = self.factory.makePerson() |
58 | - distro_name = self.archive.distribution.name |
59 | - distroseries_name = distroseries.name |
60 | - person_name = person.name |
61 | - |
62 | - self.launchpad = launchpadlib_for( |
63 | - "archive test", "salgado", "WRITE_PUBLIC") |
64 | - self.distribution = self.launchpad.distributions[distro_name] |
65 | - self.distroseries = self.distribution.getSeries( |
66 | - name_or_version=distroseries_name) |
67 | - self.main_archive = self.distribution.main_archive |
68 | - self.person = self.launchpad.people[person_name] |
69 | + self.main_archive_url = api_url(self.archive) |
70 | + self.distroseries_url = api_url(distroseries) |
71 | + self.person_url = api_url(person) |
72 | + self.ws = webservice_for_person( |
73 | + admin, permission=OAuthPermission.WRITE_PUBLIC, |
74 | + default_api_version="devel") |
75 | |
76 | def test_checkUpload_bad_pocket(self): |
77 | # Make sure a 403 error and not an OOPS is returned when |
78 | # CannotUploadToPocket is raised when calling checkUpload. |
79 | - |
80 | - # When we're on Python 2.7, this code will be much nicer as |
81 | - # assertRaises is a context manager so you can do something like |
82 | - # with self.assertRaises(HTTPError) as cm; do_something |
83 | - # .... then you have cm.exception available. |
84 | - def _do_check(): |
85 | - self.main_archive.checkUpload( |
86 | - distroseries=self.distroseries, |
87 | - sourcepackagename="mozilla-firefox", |
88 | - pocket="Updates", |
89 | - component="restricted", |
90 | - person=self.person) |
91 | - |
92 | - e = self.assertRaises(HTTPError, _do_check) |
93 | - |
94 | - self.assertEqual(403, e.response.status) |
95 | - self.assertIn( |
96 | - "Not permitted to upload to the UPDATES pocket in a series " |
97 | - "in the 'DEVELOPMENT' state.", e.content) |
98 | + response = self.ws.named_get( |
99 | + self.main_archive_url, "checkUpload", |
100 | + distroseries=self.distroseries_url, |
101 | + sourcepackagename="mozilla-firefox", |
102 | + pocket="Updates", |
103 | + component="restricted", |
104 | + person=self.person_url) |
105 | + self.assertThat(response, MatchesStructure.byEquality( |
106 | + status=403, |
107 | + body=( |
108 | + b"Not permitted to upload to the UPDATES pocket in a series " |
109 | + b"in the 'DEVELOPMENT' state."))) |
110 | |
111 | def test_getAllPermissions_constant_query_count(self): |
112 | # getAllPermissions has a query count constant in the number of |
113 | @@ -106,7 +93,7 @@ class TestArchiveWebservice(TestCaseWithFactory): |
114 | permission=ArchivePermissionType.UPLOAD) |
115 | |
116 | def get_permissions(): |
117 | - list(self.main_archive.getAllPermissions()) |
118 | + self.ws.named_get(self.main_archive_url, "getAllPermissions") |
119 | |
120 | recorder1, recorder2 = record_two_runs( |
121 | get_permissions, create_permission, 1) |
122 | @@ -117,21 +104,20 @@ class TestArchiveWebservice(TestCaseWithFactory): |
123 | ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA) |
124 | ppa_url = api_url(ppa) |
125 | ws = webservice_for_person( |
126 | - ppa.owner, permission=OAuthPermission.WRITE_PRIVATE) |
127 | + ppa.owner, permission=OAuthPermission.WRITE_PRIVATE, |
128 | + default_api_version="devel") |
129 | |
130 | # DELETE on an archive resource doesn't actually remove it |
131 | # immediately, but it asks the publisher to delete it later. |
132 | self.assertEqual( |
133 | - 'Active', |
134 | - ws.get(ppa_url, api_version='devel').jsonBody()['status']) |
135 | - self.assertEqual(200, ws.delete(ppa_url, api_version='devel').status) |
136 | + 'Active', self.getWebserviceJSON(ws, ppa_url)['status']) |
137 | + self.assertEqual(200, ws.delete(ppa_url).status) |
138 | self.assertEqual( |
139 | - 'Deleting', |
140 | - ws.get(ppa_url, api_version='devel').jsonBody()['status']) |
141 | + 'Deleting', self.getWebserviceJSON(ws, ppa_url)['status']) |
142 | |
143 | # Deleting the PPA again fails. |
144 | self.assertThat( |
145 | - ws.delete(ppa_url, api_version='devel'), |
146 | + ws.delete(ppa_url), |
147 | MatchesStructure.byEquality( |
148 | status=400, body="Archive already deleted.")) |
149 | |
150 | @@ -141,89 +127,132 @@ class TestArchiveWebservice(TestCaseWithFactory): |
151 | ppa_url = api_url(ppa) |
152 | ws = webservice_for_person( |
153 | self.factory.makePerson(), |
154 | - permission=OAuthPermission.WRITE_PRIVATE) |
155 | + permission=OAuthPermission.WRITE_PRIVATE, |
156 | + default_api_version="devel") |
157 | |
158 | # A random user can't delete someone else's PPA. |
159 | - self.assertEqual(401, ws.delete(ppa_url, api_version='devel').status) |
160 | + self.assertEqual(401, ws.delete(ppa_url).status) |
161 | + |
162 | |
163 | +class TestExternalDependencies(TestCaseWithFactory): |
164 | |
165 | -class TestExternalDependencies(WebServiceTestCase): |
166 | + layer = DatabaseFunctionalLayer |
167 | |
168 | def test_external_dependencies_random_user(self): |
169 | """Normal users can look but not touch.""" |
170 | archive = self.factory.makeArchive() |
171 | - transaction.commit() |
172 | - ws_archive = self.wsObject(archive) |
173 | - self.assertIs(None, ws_archive.external_dependencies) |
174 | - ws_archive.external_dependencies = "random" |
175 | - with ExpectedException(LRUnauthorized, '.*'): |
176 | - ws_archive.lp_save() |
177 | + archive_url = api_url(archive) |
178 | + ws = webservice_for_person( |
179 | + self.factory.makePerson(), permission=OAuthPermission.WRITE_PUBLIC) |
180 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
181 | + self.assertIsNone(ws_archive["external_dependencies"]) |
182 | + response = ws.patch( |
183 | + archive_url, "application/json", |
184 | + json.dumps({"external_dependencies": "random"})) |
185 | + self.assertEqual(401, response.status) |
186 | |
187 | def test_external_dependencies_owner(self): |
188 | """Normal archive owners can look but not touch.""" |
189 | archive = self.factory.makeArchive() |
190 | - transaction.commit() |
191 | - ws_archive = self.wsObject(archive, archive.owner) |
192 | - self.assertIs(None, ws_archive.external_dependencies) |
193 | - ws_archive.external_dependencies = "random" |
194 | - with ExpectedException(LRUnauthorized, '.*'): |
195 | - ws_archive.lp_save() |
196 | + archive_url = api_url(archive) |
197 | + ws = webservice_for_person( |
198 | + archive.owner, permission=OAuthPermission.WRITE_PUBLIC) |
199 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
200 | + self.assertIsNone(ws_archive["external_dependencies"]) |
201 | + response = ws.patch( |
202 | + archive_url, "application/json", |
203 | + json.dumps({"external_dependencies": "random"})) |
204 | + self.assertEqual(401, response.status) |
205 | |
206 | def test_external_dependencies_ppa_owner_invalid(self): |
207 | """PPA admins can look and touch.""" |
208 | ppa_admin_team = getUtility(ILaunchpadCelebrities).ppa_admin |
209 | ppa_admin = self.factory.makePerson(member_of=[ppa_admin_team]) |
210 | archive = self.factory.makeArchive(owner=ppa_admin) |
211 | - transaction.commit() |
212 | - ws_archive = self.wsObject(archive, archive.owner) |
213 | - self.assertIs(None, ws_archive.external_dependencies) |
214 | - ws_archive.external_dependencies = "random" |
215 | - regex = '(\n|.)*Invalid external dependencies(\n|.)*' |
216 | - with ExpectedException(BadRequest, regex): |
217 | - ws_archive.lp_save() |
218 | + archive_url = api_url(archive) |
219 | + ws = webservice_for_person( |
220 | + archive.owner, permission=OAuthPermission.WRITE_PUBLIC) |
221 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
222 | + self.assertIsNone(ws_archive["external_dependencies"]) |
223 | + response = ws.patch( |
224 | + archive_url, "application/json", |
225 | + json.dumps({"external_dependencies": "random"})) |
226 | + self.assertThat(response, MatchesStructure( |
227 | + status=Equals(400), |
228 | + body=Contains(b"Invalid external dependencies"))) |
229 | |
230 | def test_external_dependencies_ppa_owner_valid(self): |
231 | """PPA admins can look and touch.""" |
232 | ppa_admin_team = getUtility(ILaunchpadCelebrities).ppa_admin |
233 | ppa_admin = self.factory.makePerson(member_of=[ppa_admin_team]) |
234 | archive = self.factory.makeArchive(owner=ppa_admin) |
235 | - transaction.commit() |
236 | - ws_archive = self.wsObject(archive, archive.owner) |
237 | - self.assertIs(None, ws_archive.external_dependencies) |
238 | - ws_archive.external_dependencies = ( |
239 | - "deb http://example.org suite components") |
240 | - ws_archive.lp_save() |
241 | + archive_url = api_url(archive) |
242 | + ws = webservice_for_person( |
243 | + archive.owner, permission=OAuthPermission.WRITE_PUBLIC) |
244 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
245 | + self.assertIsNone(ws_archive["external_dependencies"]) |
246 | + response = ws.patch( |
247 | + archive_url, "application/json", |
248 | + json.dumps({ |
249 | + "external_dependencies": |
250 | + "deb http://example.org suite components", |
251 | + })) |
252 | + self.assertEqual(209, response.status) |
253 | |
254 | |
255 | -class TestArchiveDependencies(WebServiceTestCase): |
256 | +class TestArchiveDependencies(TestCaseWithFactory): |
257 | + |
258 | + layer = DatabaseFunctionalLayer |
259 | |
260 | def test_addArchiveDependency_random_user(self): |
261 | """Normal users cannot add archive dependencies.""" |
262 | archive = self.factory.makeArchive() |
263 | dependency = self.factory.makeArchive() |
264 | - transaction.commit() |
265 | - ws_archive = self.wsObject(archive) |
266 | - ws_dependency = self.wsObject(dependency) |
267 | - self.assertContentEqual([], ws_archive.dependencies) |
268 | - failure_regex = '(.|\n)*addArchiveDependency.*launchpad.Edit(.|\n)*' |
269 | - with ExpectedException(LRUnauthorized, failure_regex): |
270 | - dependency = ws_archive.addArchiveDependency( |
271 | - dependency=ws_dependency, pocket='Release', component='main') |
272 | + archive_url = api_url(archive) |
273 | + dependency_url = api_url(dependency) |
274 | + ws = webservice_for_person( |
275 | + self.factory.makePerson(), permission=OAuthPermission.WRITE_PUBLIC, |
276 | + default_api_version="devel") |
277 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
278 | + ws_dependencies = self.getWebserviceJSON( |
279 | + ws, ws_archive["dependencies_collection_link"]) |
280 | + self.assertEqual([], ws_dependencies["entries"]) |
281 | + response = ws.named_post( |
282 | + archive_url, "addArchiveDependency", |
283 | + dependency=dependency_url, pocket="Release", component="main") |
284 | + self.assertThat(response, MatchesStructure( |
285 | + status=Equals(401), |
286 | + body=MatchesRegex(br".*addArchiveDependency.*launchpad.Edit.*"))) |
287 | |
288 | def test_addArchiveDependency_owner(self): |
289 | - """Normal users cannot add archive dependencies.""" |
290 | + """Archive owners can add archive dependencies.""" |
291 | archive = self.factory.makeArchive() |
292 | dependency = self.factory.makeArchive() |
293 | - transaction.commit() |
294 | - ws_archive = self.wsObject(archive, archive.owner) |
295 | - ws_dependency = self.wsObject(dependency) |
296 | - self.assertContentEqual([], ws_archive.dependencies) |
297 | - with ExpectedException(NotFound, '(.|\n)*asdf(.|\n)*'): |
298 | - ws_archive.addArchiveDependency( |
299 | - dependency=ws_dependency, pocket='Release', component='asdf') |
300 | - dependency = ws_archive.addArchiveDependency( |
301 | - dependency=ws_dependency, pocket='Release', component='main') |
302 | - self.assertContentEqual([dependency], ws_archive.dependencies) |
303 | + archive_url = api_url(archive) |
304 | + dependency_url = api_url(dependency) |
305 | + ws = webservice_for_person( |
306 | + archive.owner, permission=OAuthPermission.WRITE_PUBLIC, |
307 | + default_api_version="devel") |
308 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
309 | + ws_dependencies = self.getWebserviceJSON( |
310 | + ws, ws_archive["dependencies_collection_link"]) |
311 | + self.assertEqual([], ws_dependencies["entries"]) |
312 | + response = ws.named_post( |
313 | + archive_url, "addArchiveDependency", |
314 | + dependency=dependency_url, pocket="Release", component="asdf") |
315 | + self.assertThat( |
316 | + response, |
317 | + MatchesStructure(status=Equals(404), body=Contains(b"asdf"))) |
318 | + response = ws.named_post( |
319 | + archive_url, "addArchiveDependency", |
320 | + dependency=dependency_url, pocket="Release", component="main") |
321 | + self.assertEqual(201, response.status) |
322 | + archive_dependency_url = response.getHeader("Location") |
323 | + ws_dependencies = self.getWebserviceJSON( |
324 | + ws, ws_archive["dependencies_collection_link"]) |
325 | + self.assertThat(ws_dependencies["entries"], MatchesListwise([ |
326 | + ContainsDict({"self_link": Equals(archive_dependency_url)}), |
327 | + ])) |
328 | |
329 | def test_addArchiveDependency_invalid(self): |
330 | """Invalid requests generate a BadRequest error.""" |
331 | @@ -232,79 +261,98 @@ class TestArchiveDependencies(WebServiceTestCase): |
332 | with person_logged_in(archive.owner): |
333 | archive.addArchiveDependency( |
334 | dependency, PackagePublishingPocket.RELEASE) |
335 | - transaction.commit() |
336 | - ws_archive = self.wsObject(archive, archive.owner) |
337 | - ws_dependency = self.wsObject(dependency) |
338 | - expected_re = '(.|\n)*This dependency is already registered(.|\n)*' |
339 | - with ExpectedException(BadRequest, expected_re): |
340 | - ws_archive.addArchiveDependency( |
341 | - dependency=ws_dependency, pocket='Release') |
342 | + archive_url = api_url(archive) |
343 | + dependency_url = api_url(dependency) |
344 | + ws = webservice_for_person( |
345 | + archive.owner, permission=OAuthPermission.WRITE_PUBLIC, |
346 | + default_api_version="devel") |
347 | + response = ws.named_post( |
348 | + archive_url, "addArchiveDependency", |
349 | + dependency=dependency_url, pocket="Release") |
350 | + self.assertThat(response, MatchesStructure.byEquality( |
351 | + status=400, body=b"This dependency is already registered.")) |
352 | |
353 | def test_removeArchiveDependency_random_user(self): |
354 | - """Normal users can remove archive dependencies.""" |
355 | + """Normal users cannot remove archive dependencies.""" |
356 | archive = self.factory.makeArchive() |
357 | dependency = self.factory.makeArchive() |
358 | with person_logged_in(archive.owner): |
359 | archive.addArchiveDependency( |
360 | dependency, PackagePublishingPocket.RELEASE) |
361 | - transaction.commit() |
362 | - ws_archive = self.wsObject(archive) |
363 | - ws_dependency = self.wsObject(dependency) |
364 | - failure_regex = '(.|\n)*remove.*Dependency.*launchpad.Edit(.|\n)*' |
365 | - with ExpectedException(LRUnauthorized, failure_regex): |
366 | - ws_archive.removeArchiveDependency(dependency=ws_dependency) |
367 | + archive_url = api_url(archive) |
368 | + dependency_url = api_url(dependency) |
369 | + ws = webservice_for_person( |
370 | + self.factory.makePerson(), permission=OAuthPermission.WRITE_PUBLIC, |
371 | + default_api_version="devel") |
372 | + response = ws.named_post( |
373 | + archive_url, "removeArchiveDependency", dependency=dependency_url) |
374 | + self.assertThat(response, MatchesStructure( |
375 | + status=Equals(401), |
376 | + body=MatchesRegex( |
377 | + br".*removeArchiveDependency.*launchpad.Edit.*"))) |
378 | |
379 | def test_removeArchiveDependency_owner(self): |
380 | - """Normal users can remove archive dependencies.""" |
381 | + """Archive owners can remove archive dependencies.""" |
382 | archive = self.factory.makeArchive() |
383 | dependency = self.factory.makeArchive() |
384 | with person_logged_in(archive.owner): |
385 | archive.addArchiveDependency( |
386 | dependency, PackagePublishingPocket.RELEASE) |
387 | - transaction.commit() |
388 | - ws_archive = self.wsObject(archive, archive.owner) |
389 | - ws_dependency = self.wsObject(dependency) |
390 | - ws_archive.removeArchiveDependency(dependency=ws_dependency) |
391 | - self.assertContentEqual([], ws_archive.dependencies) |
392 | + archive_url = api_url(archive) |
393 | + dependency_url = api_url(dependency) |
394 | + ws = webservice_for_person( |
395 | + archive.owner, permission=OAuthPermission.WRITE_PUBLIC, |
396 | + default_api_version="devel") |
397 | + response = ws.named_post( |
398 | + archive_url, "removeArchiveDependency", dependency=dependency_url) |
399 | + self.assertEqual(200, response.status) |
400 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
401 | + ws_dependencies = self.getWebserviceJSON( |
402 | + ws, ws_archive["dependencies_collection_link"]) |
403 | + self.assertEqual([], ws_dependencies["entries"]) |
404 | |
405 | |
406 | -class TestProcessors(WebServiceTestCase): |
407 | +class TestProcessors(TestCaseWithFactory): |
408 | """Test the enabled_restricted_processors property and methods.""" |
409 | |
410 | + layer = DatabaseFunctionalLayer |
411 | + |
412 | def test_erpNotAvailableInBeta(self): |
413 | """The enabled_restricted_processors property is not in beta.""" |
414 | - self.ws_version = 'beta' |
415 | archive = self.factory.makeArchive() |
416 | ppa_admin_team = getUtility(ILaunchpadCelebrities).ppa_admin |
417 | ppa_admin = self.factory.makePerson(member_of=[ppa_admin_team]) |
418 | - transaction.commit() |
419 | - ws_archive = self.wsObject(archive, user=ppa_admin) |
420 | - expected_re = ( |
421 | - "(.|\n)*object has no attribute " |
422 | - "'enabled_restricted_processors'(.|\n)*") |
423 | - with ExpectedException(AttributeError, expected_re): |
424 | - ws_archive.enabled_restricted_processors |
425 | + archive_url = api_url(archive) |
426 | + ws = webservice_for_person(ppa_admin, default_api_version="beta") |
427 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
428 | + self.assertNotIn( |
429 | + "enabled_restricted_processors_collection_link", ws_archive) |
430 | |
431 | def test_erpAvailableInDevel(self): |
432 | """The enabled_restricted_processors property is in devel.""" |
433 | - self.ws_version = 'devel' |
434 | archive = self.factory.makeArchive() |
435 | ppa_admin_team = getUtility(ILaunchpadCelebrities).ppa_admin |
436 | ppa_admin = self.factory.makePerson(member_of=[ppa_admin_team]) |
437 | - transaction.commit() |
438 | - ws_archive = self.wsObject(archive, user=ppa_admin) |
439 | - self.assertContentEqual([], ws_archive.enabled_restricted_processors) |
440 | + archive_url = api_url(archive) |
441 | + ws = webservice_for_person(ppa_admin, default_api_version="devel") |
442 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
443 | + ws_erp = self.getWebserviceJSON( |
444 | + ws, ws_archive["enabled_restricted_processors_collection_link"]) |
445 | + self.assertEqual([], ws_erp["entries"]) |
446 | |
447 | def test_processors(self): |
448 | """Attributes about processors are available.""" |
449 | - self.ws_version = 'devel' |
450 | self.factory.makeProcessor( |
451 | 'new-arm', 'New ARM Title', 'New ARM Description') |
452 | - transaction.commit() |
453 | - ws_proc = self.service.processors.getByName(name='new-arm') |
454 | - self.assertEqual('new-arm', ws_proc.name) |
455 | - self.assertEqual('New ARM Title', ws_proc.title) |
456 | - self.assertEqual('New ARM Description', ws_proc.description) |
457 | + ws = webservice_for_person( |
458 | + self.factory.makePerson(), default_api_version="devel") |
459 | + response = ws.named_get("/+processors", "getByName", name="new-arm") |
460 | + self.assertEqual(200, response.status) |
461 | + self.assertThat(response.jsonBody(), ContainsDict({ |
462 | + "name": Equals("new-arm"), |
463 | + "title": Equals("New ARM Title"), |
464 | + "description": Equals("New ARM Description"), |
465 | + })) |
466 | |
467 | def setProcessors(self, user, archive_url, names): |
468 | ws = webservice_for_person( |
469 | @@ -382,63 +430,80 @@ class TestProcessors(WebServiceTestCase): |
470 | |
471 | def test_enableRestrictedProcessor(self): |
472 | """A new processor can be added to the enabled restricted set.""" |
473 | - self.ws_version = 'devel' |
474 | archive = self.factory.makeArchive() |
475 | - self.factory.makeProcessor( |
476 | + arm = self.factory.makeProcessor( |
477 | name='arm', restricted=True, build_by_default=False) |
478 | ppa_admin_team = getUtility(ILaunchpadCelebrities).ppa_admin |
479 | ppa_admin = self.factory.makePerson(member_of=[ppa_admin_team]) |
480 | - transaction.commit() |
481 | - ws_arm = self.service.processors.getByName(name='arm') |
482 | - ws_archive = self.wsObject(archive, user=ppa_admin) |
483 | - self.assertContentEqual([], ws_archive.enabled_restricted_processors) |
484 | - ws_archive.enableRestrictedProcessor(processor=ws_arm) |
485 | - self.assertContentEqual( |
486 | - [ws_arm], ws_archive.enabled_restricted_processors) |
487 | + archive_url = api_url(archive) |
488 | + arm_url = api_url(arm) |
489 | + ws = webservice_for_person( |
490 | + ppa_admin, permission=OAuthPermission.WRITE_PUBLIC, |
491 | + default_api_version="devel") |
492 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
493 | + ws_erp = self.getWebserviceJSON( |
494 | + ws, ws_archive["enabled_restricted_processors_collection_link"]) |
495 | + self.assertEqual([], ws_erp["entries"]) |
496 | + response = ws.named_post( |
497 | + archive_url, "enableRestrictedProcessor", processor=arm_url) |
498 | + self.assertEqual(200, response.status) |
499 | + ws_erp = self.getWebserviceJSON( |
500 | + ws, ws_archive["enabled_restricted_processors_collection_link"]) |
501 | + self.assertThat(ws_erp["entries"], MatchesListwise([ |
502 | + ContainsDict({"self_link": EndsWith(arm_url)}), |
503 | + ])) |
504 | |
505 | def test_enableRestrictedProcessor_owner(self): |
506 | """A new processor can be added to the enabled restricted set. |
507 | |
508 | An unauthorized user, even the archive owner, is not allowed. |
509 | """ |
510 | - self.ws_version = 'devel' |
511 | archive = self.factory.makeArchive() |
512 | - self.factory.makeProcessor( |
513 | + arm = self.factory.makeProcessor( |
514 | name='arm', restricted=True, build_by_default=False) |
515 | - transaction.commit() |
516 | - ws_arm = self.service.processors.getByName(name='arm') |
517 | - ws_archive = self.wsObject(archive, user=archive.owner) |
518 | - self.assertContentEqual([], ws_archive.enabled_restricted_processors) |
519 | - expected_re = ( |
520 | - "(.|\n)*'launchpad\.Admin'(.|\n)*") |
521 | - with ExpectedException(LRUnauthorized, expected_re): |
522 | - ws_archive.enableRestrictedProcessor(processor=ws_arm) |
523 | + archive_url = api_url(archive) |
524 | + arm_url = api_url(arm) |
525 | + ws = webservice_for_person( |
526 | + archive.owner, permission=OAuthPermission.WRITE_PUBLIC, |
527 | + default_api_version="devel") |
528 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
529 | + ws_erp = self.getWebserviceJSON( |
530 | + ws, ws_archive["enabled_restricted_processors_collection_link"]) |
531 | + self.assertEqual([], ws_erp["entries"]) |
532 | + response = ws.named_post( |
533 | + archive_url, "enableRestrictedProcessor", processor=arm_url) |
534 | + self.assertThat(response, MatchesStructure( |
535 | + status=Equals(401), body=Contains(b"'launchpad.Admin'"))) |
536 | |
537 | def test_enableRestrictedProcessor_nonPrivUser(self): |
538 | """A new processor can be added to the enabled restricted set. |
539 | |
540 | An unauthorized user, some regular user, is not allowed. |
541 | """ |
542 | - self.ws_version = 'devel' |
543 | archive = self.factory.makeArchive() |
544 | - self.factory.makeProcessor( |
545 | + arm = self.factory.makeProcessor( |
546 | name='arm', restricted=True, build_by_default=False) |
547 | - just_some_guy = self.factory.makePerson() |
548 | - transaction.commit() |
549 | - ws_arm = self.service.processors.getByName(name='arm') |
550 | - ws_archive = self.wsObject(archive, user=just_some_guy) |
551 | - self.assertContentEqual([], ws_archive.enabled_restricted_processors) |
552 | - expected_re = ( |
553 | - "(.|\n)*'launchpad\.Admin'(.|\n)*") |
554 | - with ExpectedException(LRUnauthorized, expected_re): |
555 | - ws_archive.enableRestrictedProcessor(processor=ws_arm) |
556 | - |
557 | - |
558 | -class TestCopyPackage(WebServiceTestCase): |
559 | + archive_url = api_url(archive) |
560 | + arm_url = api_url(arm) |
561 | + ws = webservice_for_person( |
562 | + self.factory.makePerson(), permission=OAuthPermission.WRITE_PUBLIC, |
563 | + default_api_version="devel") |
564 | + ws_archive = self.getWebserviceJSON(ws, archive_url) |
565 | + ws_erp = self.getWebserviceJSON( |
566 | + ws, ws_archive["enabled_restricted_processors_collection_link"]) |
567 | + self.assertEqual([], ws_erp["entries"]) |
568 | + response = ws.named_post( |
569 | + archive_url, "enableRestrictedProcessor", processor=arm_url) |
570 | + self.assertThat(response, MatchesStructure( |
571 | + status=Equals(401), body=Contains(b"'launchpad.Admin'"))) |
572 | + |
573 | + |
574 | +class TestCopyPackage(TestCaseWithFactory): |
575 | """Webservice test cases for the copyPackage/copyPackages methods""" |
576 | |
577 | + layer = DatabaseFunctionalLayer |
578 | + |
579 | def setup_data(self): |
580 | - self.ws_version = "devel" |
581 | uploader_dude = self.factory.makePerson() |
582 | sponsored_dude = self.factory.makePerson() |
583 | source_archive = self.factory.makeArchive() |
584 | @@ -453,7 +518,6 @@ class TestCopyPackage(WebServiceTestCase): |
585 | distribution=target_archive.distribution) |
586 | with person_logged_in(target_archive.owner): |
587 | target_archive.newComponentUploader(uploader_dude, "universe") |
588 | - transaction.commit() |
589 | return (source, source_archive, source_name, target_archive, |
590 | to_pocket, to_series, uploader_dude, sponsored_dude, version) |
591 | |
592 | @@ -463,17 +527,22 @@ class TestCopyPackage(WebServiceTestCase): |
593 | to_series, uploader_dude, sponsored_dude, |
594 | version) = self.setup_data() |
595 | |
596 | - ws_target_archive = self.wsObject(target_archive, user=uploader_dude) |
597 | - ws_source_archive = self.wsObject(source_archive) |
598 | - ws_sponsored_dude = self.wsObject(sponsored_dude) |
599 | + target_archive_url = api_url(target_archive) |
600 | + source_archive_url = api_url(source_archive) |
601 | + sponsored_dude_url = api_url(sponsored_dude) |
602 | + ws = webservice_for_person( |
603 | + uploader_dude, permission=OAuthPermission.WRITE_PUBLIC, |
604 | + default_api_version="devel") |
605 | |
606 | - ws_target_archive.copyPackage( |
607 | + response = ws.named_post( |
608 | + target_archive_url, "copyPackage", |
609 | source_name=source_name, version=version, |
610 | - from_archive=ws_source_archive, to_pocket=to_pocket.name, |
611 | + from_archive=source_archive_url, to_pocket=to_pocket.name, |
612 | to_series=to_series.name, include_binaries=False, |
613 | - sponsored=ws_sponsored_dude) |
614 | - transaction.commit() |
615 | + sponsored=sponsored_dude_url) |
616 | + self.assertEqual(200, response.status) |
617 | |
618 | + login(ANONYMOUS) |
619 | job_source = getUtility(IPlainPackageCopyJobSource) |
620 | copy_job = job_source.getActiveJobs(target_archive).one() |
621 | self.assertEqual(target_archive, copy_job.target_archive) |
622 | @@ -483,53 +552,68 @@ class TestCopyPackage(WebServiceTestCase): |
623 | (source, source_archive, source_name, target_archive, to_pocket, |
624 | to_series, uploader_dude, sponsored_dude, |
625 | version) = self.setup_data() |
626 | + from_series = source.distroseries |
627 | |
628 | - ws_target_archive = self.wsObject(target_archive, user=uploader_dude) |
629 | - ws_source_archive = self.wsObject(source_archive) |
630 | - ws_sponsored_dude = self.wsObject(sponsored_dude) |
631 | + target_archive_url = api_url(target_archive) |
632 | + source_archive_url = api_url(source_archive) |
633 | + sponsored_dude_url = api_url(sponsored_dude) |
634 | + ws = webservice_for_person( |
635 | + uploader_dude, permission=OAuthPermission.WRITE_PUBLIC, |
636 | + default_api_version="devel") |
637 | |
638 | - ws_target_archive.copyPackages( |
639 | - source_names=[source_name], from_archive=ws_source_archive, |
640 | + response = ws.named_post( |
641 | + target_archive_url, "copyPackages", |
642 | + source_names=[source_name], from_archive=source_archive_url, |
643 | to_pocket=to_pocket.name, to_series=to_series.name, |
644 | - from_series=source.distroseries.name, include_binaries=False, |
645 | - sponsored=ws_sponsored_dude) |
646 | - transaction.commit() |
647 | + from_series=from_series.name, include_binaries=False, |
648 | + sponsored=sponsored_dude_url) |
649 | + self.assertEqual(200, response.status) |
650 | |
651 | + login(ANONYMOUS) |
652 | job_source = getUtility(IPlainPackageCopyJobSource) |
653 | copy_job = job_source.getActiveJobs(target_archive).one() |
654 | self.assertEqual(target_archive, copy_job.target_archive) |
655 | |
656 | |
657 | -class TestgetPublishedBinaries(WebServiceTestCase): |
658 | - """test getPublishedSources.""" |
659 | +class TestGetPublishedBinaries(TestCaseWithFactory): |
660 | + """Test getPublishedBinaries.""" |
661 | + |
662 | + layer = DatabaseFunctionalLayer |
663 | |
664 | def setUp(self): |
665 | super(TestgetPublishedBinaries, self).setUp() |
666 | - self.ws_version = 'beta' |
667 | self.person = self.factory.makePerson() |
668 | self.archive = self.factory.makeArchive() |
669 | + self.person_url = api_url(self.person) |
670 | + self.archive_url = api_url(self.archive) |
671 | |
672 | def test_getPublishedBinaries(self): |
673 | self.factory.makeBinaryPackagePublishingHistory(archive=self.archive) |
674 | - ws_archive = self.wsObject(self.archive, user=self.person) |
675 | - self.assertEqual(1, len(ws_archive.getPublishedBinaries())) |
676 | + ws = webservice_for_person(self.person, default_api_version="beta") |
677 | + response = ws.named_get(self.archive_url, "getPublishedBinaries") |
678 | + self.assertEqual(200, response.status) |
679 | + self.assertEqual(1, response.jsonBody()["total_size"]) |
680 | |
681 | def test_getPublishedBinaries_created_since_date(self): |
682 | datecreated = self.factory.getUniqueDate() |
683 | later_date = datecreated + timedelta(minutes=1) |
684 | self.factory.makeBinaryPackagePublishingHistory( |
685 | - archive=self.archive, datecreated=datecreated) |
686 | - ws_archive = self.wsObject(self.archive, user=self.person) |
687 | - publications = ws_archive.getPublishedBinaries( |
688 | - created_since_date=later_date) |
689 | - self.assertEqual(0, len(publications)) |
690 | + archive=self.archive, datecreated=datecreated) |
691 | + ws = webservice_for_person(self.person, default_api_version="beta") |
692 | + response = ws.named_get( |
693 | + self.archive_url, "getPublishedBinaries", |
694 | + created_since_date=later_date.isoformat()) |
695 | + self.assertEqual(200, response.status) |
696 | + self.assertEqual(0, response.jsonBody()["total_size"]) |
697 | |
698 | def test_getPublishedBinaries_no_ordering(self): |
699 | self.factory.makeBinaryPackagePublishingHistory(archive=self.archive) |
700 | self.factory.makeBinaryPackagePublishingHistory(archive=self.archive) |
701 | - ws_archive = self.wsObject(self.archive, user=self.person) |
702 | - publications = ws_archive.getPublishedBinaries(ordered=False) |
703 | - self.assertEqual(2, len(publications)) |
704 | + ws = webservice_for_person(self.person, default_api_version="beta") |
705 | + response = ws.named_get( |
706 | + self.archive_url, "getPublishedBinaries", ordered=False) |
707 | + self.assertEqual(200, response.status) |
708 | + self.assertEqual(2, response.jsonBody()["total_size"]) |
709 | |
710 | def test_getPublishedBinaries_query_count(self): |
711 | # getPublishedBinaries has a query count constant in the number of |
712 | @@ -577,14 +661,16 @@ class TestgetPublishedBinaries(WebServiceTestCase): |
713 | recorder2, HasQueryCount(Equals(recorder1.count + 3), recorder1)) |
714 | |
715 | |
716 | -class TestremoveCopyNotification(WebServiceTestCase): |
717 | +class TestRemoveCopyNotification(TestCaseWithFactory): |
718 | """Test removeCopyNotification.""" |
719 | |
720 | + layer = DatabaseFunctionalLayer |
721 | + |
722 | def setUp(self): |
723 | super(TestremoveCopyNotification, self).setUp() |
724 | - self.ws_version = 'devel' |
725 | self.person = self.factory.makePerson() |
726 | self.archive = self.factory.makeArchive(owner=self.person) |
727 | + self.archive_url = api_url(self.archive) |
728 | |
729 | def test_removeCopyNotification(self): |
730 | distroseries = self.factory.makeDistroSeries() |
731 | @@ -600,10 +686,14 @@ class TestremoveCopyNotification(WebServiceTestCase): |
732 | job.start() |
733 | job.fail() |
734 | |
735 | - ws_archive = self.wsObject(self.archive, user=self.person) |
736 | - ws_archive.removeCopyNotification(job_id=job.id) |
737 | - transaction.commit() |
738 | + ws = webservice_for_person( |
739 | + self.person, permission=OAuthPermission.WRITE_PUBLIC, |
740 | + default_api_version="devel") |
741 | + response = ws.named_post( |
742 | + self.archive_url, "removeCopyNotification", job_id=job.id) |
743 | + self.assertEqual(200, response.status) |
744 | |
745 | + login(ANONYMOUS) |
746 | source = getUtility(IPlainPackageCopyJobSource) |
747 | self.assertEqual( |
748 | None, source.getIncompleteJobsForArchive(self.archive).any()) |
LGTM