Merge lp:~jml/pkgme-service/actually-run-pkgme into lp:pkgme-service
- actually-run-pkgme
- Merge into trunk
Proposed by
Jonathan Lange
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | James Westby | ||||
Approved revision: | 35 | ||||
Merged at revision: | 15 | ||||
Proposed branch: | lp:~jml/pkgme-service/actually-run-pkgme | ||||
Merge into: | lp:pkgme-service | ||||
Diff against target: |
488 lines (+239/-46) 9 files modified
fabtasks/django.py (+0/-3) setup.py (+11/-10) src/djpkgme/models.py (+21/-0) src/djpkgme/tasks.py (+44/-3) src/djpkgme/tests/factory.py (+58/-5) src/djpkgme/tests/test_handlers.py (+6/-2) src/djpkgme/tests/test_models.py (+18/-2) src/djpkgme/tests/test_tasks.py (+74/-19) test-dependencies.txt (+7/-2) |
||||
To merge this branch: | bzr merge lp:~jml/pkgme-service/actually-run-pkgme | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Westby (community) | Approve | ||
Review via email: mp+83024@code.launchpad.net |
Commit message
Description of the change
At long last, actually running pkgme-binary from pkgme-service.
I'm a little too zonked to provide much more details right now, but happy to answer questions.
To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote : | # |
Merged. Filed bug 893675, bug 893674 and bug 893563.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'fabtasks/django.py' | |||
2 | --- fabtasks/django.py 2011-08-30 17:41:11 +0000 | |||
3 | +++ fabtasks/django.py 2011-11-22 14:09:24 +0000 | |||
4 | @@ -1,6 +1,3 @@ | |||
5 | 1 | import os | ||
6 | 2 | import os.path | ||
7 | 3 | |||
8 | 4 | from fabric.api import local | 1 | from fabric.api import local |
9 | 5 | 2 | ||
10 | 6 | 3 | ||
11 | 7 | 4 | ||
12 | === modified file 'setup.py' | |||
13 | --- setup.py 2011-11-09 11:14:13 +0000 | |||
14 | +++ setup.py 2011-11-22 14:09:24 +0000 | |||
15 | @@ -1,22 +1,23 @@ | |||
16 | 1 | from setuptools import setup, find_packages | 1 | from setuptools import setup, find_packages |
17 | 2 | 2 | ||
18 | 3 | setup( | 3 | setup( |
25 | 4 | name = "django-pkgme", | 4 | name="django-pkgme", |
26 | 5 | version = "0.1", | 5 | version="0.1", |
27 | 6 | author = "Canonical Consumer Applications", | 6 | author="Canonical Consumer Applications", |
28 | 7 | author_email = "canonical-consumer-applications@lists.launchpad.net", | 7 | author_email="canonical-consumer-applications@lists.launchpad.net", |
29 | 8 | license = "AGPL3", | 8 | license="AGPL3", |
30 | 9 | install_requires = [ | 9 | install_requires=[ |
31 | 10 | 'django==1.3', | 10 | 'django==1.3', |
32 | 11 | 'django-piston', | 11 | 'django-piston', |
33 | 12 | # XXX: Until https://github.com/ask/django-celery/pull/88 is fixed, we | 12 | # XXX: Until https://github.com/ask/django-celery/pull/88 is fixed, we |
34 | 13 | # have to use the older release. Review this when django-celery | 13 | # have to use the older release. Review this when django-celery |
35 | 14 | # releases the version after 2.4.1. -- jml | 14 | # releases the version after 2.4.1. -- jml |
36 | 15 | 'django-celery==2.4.0', | 15 | 'django-celery==2.4.0', |
37 | 16 | 'fixtures', | ||
38 | 16 | 'south==0.7.3', | 17 | 'south==0.7.3', |
39 | 17 | 'oauth', | 18 | 'oauth', |
44 | 18 | ], | 19 | ], |
45 | 19 | zip_safe = False, | 20 | zip_safe=False, |
46 | 20 | packages = find_packages('src'), | 21 | packages=find_packages('src'), |
47 | 21 | package_dir = {'': 'src'}, | 22 | package_dir={'': 'src'}, |
48 | 22 | ) | 23 | ) |
49 | 23 | 24 | ||
50 | === modified file 'src/djpkgme/models.py' | |||
51 | --- src/djpkgme/models.py 2011-09-01 21:46:47 +0000 | |||
52 | +++ src/djpkgme/models.py 2011-11-22 14:09:24 +0000 | |||
53 | @@ -2,6 +2,11 @@ | |||
54 | 2 | from django.db import models | 2 | from django.db import models |
55 | 3 | from datetime import datetime | 3 | from datetime import datetime |
56 | 4 | 4 | ||
57 | 5 | from devportalbinary.binary import ( | ||
58 | 6 | CATEGORIES, | ||
59 | 7 | PACKAGE_NAME, | ||
60 | 8 | TAGLINE, | ||
61 | 9 | ) | ||
62 | 5 | 10 | ||
63 | 6 | class AppMetadata(models.Model): | 11 | class AppMetadata(models.Model): |
64 | 7 | # ID of the app, according to myapps | 12 | # ID of the app, according to myapps |
65 | @@ -16,8 +21,12 @@ | |||
66 | 16 | categories = models.CharField(max_length=128, blank=True) | 21 | categories = models.CharField(max_length=128, blank=True) |
67 | 17 | department = models.CharField(max_length=64, blank=True) | 22 | department = models.CharField(max_length=64, blank=True) |
68 | 18 | keywords = models.TextField(blank=True, default='') | 23 | keywords = models.TextField(blank=True, default='') |
69 | 24 | # XXX: We *think* this is the URL to the tarball that contains the app | ||
70 | 25 | # that we are packaging. | ||
71 | 19 | package_url = models.CharField(max_length=256) | 26 | package_url = models.CharField(max_length=256) |
72 | 20 | icon_url = models.CharField(max_length=256) | 27 | icon_url = models.CharField(max_length=256) |
73 | 28 | # XXX: This should not be required, or even sent. It's not part of the | ||
74 | 29 | # package. | ||
75 | 21 | screenshot_url = models.CharField(max_length=256) | 30 | screenshot_url = models.CharField(max_length=256) |
76 | 22 | price = models.DecimalField(max_digits=7, decimal_places=2, null=True) | 31 | price = models.DecimalField(max_digits=7, decimal_places=2, null=True) |
77 | 23 | callback_url = models.CharField(max_length=256) | 32 | callback_url = models.CharField(max_length=256) |
78 | @@ -35,6 +44,18 @@ | |||
79 | 35 | # Location of the built package | 44 | # Location of the built package |
80 | 36 | packaged_app_url = models.CharField(max_length=256) | 45 | packaged_app_url = models.CharField(max_length=256) |
81 | 37 | 46 | ||
82 | 47 | def as_dict(self): | ||
83 | 48 | """Return this metadata as a dict. | ||
84 | 49 | |||
85 | 50 | The contents of that dict should be suitable for dumping as JSON into | ||
86 | 51 | devportal-metadata.json (see lp:pkgme-binary). | ||
87 | 52 | """ | ||
88 | 53 | return { | ||
89 | 54 | CATEGORIES: self.categories, | ||
90 | 55 | PACKAGE_NAME: self.package_name, | ||
91 | 56 | TAGLINE: self.tagline, | ||
92 | 57 | } | ||
93 | 58 | |||
94 | 38 | def update_guesses(self, guesses): | 59 | def update_guesses(self, guesses): |
95 | 39 | """Updates the guess fields based on a result from pkgme.""" | 60 | """Updates the guess fields based on a result from pkgme.""" |
96 | 40 | other = {} | 61 | other = {} |
97 | 41 | 62 | ||
98 | === modified file 'src/djpkgme/tasks.py' | |||
99 | --- src/djpkgme/tasks.py 2011-09-01 21:46:47 +0000 | |||
100 | +++ src/djpkgme/tasks.py 2011-11-22 14:09:24 +0000 | |||
101 | @@ -1,4 +1,8 @@ | |||
102 | 1 | import json | 1 | import json |
103 | 2 | import os | ||
104 | 3 | import shutil | ||
105 | 4 | import tarfile | ||
106 | 5 | |||
107 | 2 | from celery.registry import tasks | 6 | from celery.registry import tasks |
108 | 3 | from celery.task import Task | 7 | from celery.task import Task |
109 | 4 | from django.conf import settings | 8 | from django.conf import settings |
110 | @@ -10,7 +14,13 @@ | |||
111 | 10 | OAuthSignatureMethod_PLAINTEXT, | 14 | OAuthSignatureMethod_PLAINTEXT, |
112 | 11 | ) | 15 | ) |
113 | 12 | 16 | ||
115 | 13 | import djpkgme.mock_pkgme as pkgme | 17 | from devportalbinary.binary import METADATA_FILE |
116 | 18 | from devportalbinary.database import download_file | ||
117 | 19 | from fixtures import TempDir | ||
118 | 20 | from pkgme import write_packaging | ||
119 | 21 | from pkgme.debuild import build_source_package | ||
120 | 22 | |||
121 | 23 | from djpkgme import mock_pkgme | ||
122 | 14 | 24 | ||
123 | 15 | 25 | ||
124 | 16 | def oauth_sign_request(url): | 26 | def oauth_sign_request(url): |
125 | @@ -34,7 +44,7 @@ | |||
126 | 34 | 44 | ||
127 | 35 | class GuessPackagingDetailsTask(Task): | 45 | class GuessPackagingDetailsTask(Task): |
128 | 36 | def run(self, metadata): | 46 | def run(self, metadata): |
130 | 37 | result = pkgme.guess(metadata) | 47 | result = mock_pkgme.guess(metadata) |
131 | 38 | metadata.update_guesses(result) | 48 | metadata.update_guesses(result) |
132 | 39 | submit_pkgme_info(metadata) | 49 | submit_pkgme_info(metadata) |
133 | 40 | return result | 50 | return result |
134 | @@ -42,8 +52,39 @@ | |||
135 | 42 | 52 | ||
136 | 43 | 53 | ||
137 | 44 | class BuildPackageTask(Task): | 54 | class BuildPackageTask(Task): |
138 | 55 | |||
139 | 56 | def build_package(self, metadata, overrides, output_tar_path): | ||
140 | 57 | """Build packaging for 'metadata' and store it all in 'output_tar_path'. | ||
141 | 58 | """ | ||
142 | 59 | with TempDir() as temp_dir: | ||
143 | 60 | # Download, extract and remove the tarball. | ||
144 | 61 | output_dir = temp_dir.path | ||
145 | 62 | path = download_file(metadata.package_url, output_dir) | ||
146 | 63 | # XXX: 'package' is an arbitrary name. Maybe we should pick a | ||
147 | 64 | # better arbitrary name? | ||
148 | 65 | extraction_path = os.path.join(output_dir, 'package') | ||
149 | 66 | with tarfile.open(path) as t: | ||
150 | 67 | t.extractall(extraction_path) | ||
151 | 68 | os.unlink(path) | ||
152 | 69 | # Write the metadata out to a special file, where the binary | ||
153 | 70 | # backend will find it. | ||
154 | 71 | metadata_filename = os.path.join(extraction_path, METADATA_FILE) | ||
155 | 72 | with open(metadata_filename, 'w') as metadata_file: | ||
156 | 73 | json.dump(metadata.as_dict(), metadata_file) | ||
157 | 74 | # Run pkgme: generate the packaging and build a source package. | ||
158 | 75 | write_packaging(extraction_path, allowed_backend_names=['binary']) | ||
159 | 76 | build_source_package(extraction_path, False) | ||
160 | 77 | # Create a new tarball containing the source package and the | ||
161 | 78 | # metadata file. | ||
162 | 79 | os.rename( | ||
163 | 80 | metadata_filename, os.path.join(output_dir, METADATA_FILE)) | ||
164 | 81 | shutil.rmtree(extraction_path) | ||
165 | 82 | with tarfile.open(output_tar_path, 'w') as t: | ||
166 | 83 | for name in os.listdir(output_dir): | ||
167 | 84 | t.add(os.path.join(output_dir, name), name) | ||
168 | 85 | |||
169 | 45 | def run(self, metadata, overrides): | 86 | def run(self, metadata, overrides): |
171 | 46 | result = pkgme.build_package(metadata, overrides) | 87 | result = self.build_package(metadata, overrides) |
172 | 47 | metadata.packaged_app_url = result | 88 | metadata.packaged_app_url = result |
173 | 48 | metadata.save() | 89 | metadata.save() |
174 | 49 | submit_pkgme_info(metadata) | 90 | submit_pkgme_info(metadata) |
175 | 50 | 91 | ||
176 | === modified file 'src/djpkgme/tests/factory.py' | |||
177 | --- src/djpkgme/tests/factory.py 2011-09-01 20:35:22 +0000 | |||
178 | +++ src/djpkgme/tests/factory.py 2011-11-22 14:09:24 +0000 | |||
179 | @@ -1,9 +1,24 @@ | |||
180 | 1 | from django.test import TestCase | ||
181 | 2 | from itertools import count | 1 | from itertools import count |
183 | 3 | 2 | import os | |
184 | 3 | |||
185 | 4 | from django.test import TestCase as DjangoTestCase | ||
186 | 5 | from fixtures import ( | ||
187 | 6 | EnvironmentVariableFixture, | ||
188 | 7 | Fixture, | ||
189 | 8 | TempDir, | ||
190 | 9 | ) | ||
191 | 10 | from testtools import ( | ||
192 | 11 | RunTest, | ||
193 | 12 | TestCase, | ||
194 | 13 | ) | ||
195 | 14 | |||
196 | 15 | from devportalbinary.database import PackageDatabase | ||
197 | 4 | from djpkgme.models import AppMetadata | 16 | from djpkgme.models import AppMetadata |
198 | 5 | 17 | ||
200 | 6 | __all__ = ['TestCaseWithFactory'] | 18 | __all__ = [ |
201 | 19 | 'EmptyBinaryPackageDatabase', | ||
202 | 20 | 'TestCaseWithFactory', | ||
203 | 21 | ] | ||
204 | 7 | 22 | ||
205 | 8 | 23 | ||
206 | 9 | class PkgmeObjectFactory(object): | 24 | class PkgmeObjectFactory(object): |
207 | @@ -20,7 +35,9 @@ | |||
208 | 20 | return prefix + str(self.get_unique_integer()) | 35 | return prefix + str(self.get_unique_integer()) |
209 | 21 | 36 | ||
210 | 22 | def make_metadata(self, myapps_id=None, callback_url=None, | 37 | def make_metadata(self, myapps_id=None, callback_url=None, |
212 | 23 | with_guesses=False): | 38 | with_guesses=False, package_name=None): |
213 | 39 | if package_name is None: | ||
214 | 40 | package_name = self.get_unique_string('package-name') | ||
215 | 24 | if myapps_id is None: | 41 | if myapps_id is None: |
216 | 25 | myapps_id = self.get_unique_integer() | 42 | myapps_id = self.get_unique_integer() |
217 | 26 | if callback_url is None: | 43 | if callback_url is None: |
218 | @@ -39,7 +56,43 @@ | |||
219 | 39 | return AppMetadata.objects.create(myapps_id=myapps_id, | 56 | return AppMetadata.objects.create(myapps_id=myapps_id, |
220 | 40 | executable=executable, distroarchseries=distroarchseries, | 57 | executable=executable, distroarchseries=distroarchseries, |
221 | 41 | dependencies=dependencies, other_guesses=other_guesses, | 58 | dependencies=dependencies, other_guesses=other_guesses, |
223 | 42 | callback_url=callback_url) | 59 | callback_url=callback_url, package_name=package_name) |
224 | 60 | |||
225 | 61 | |||
226 | 62 | class DjangoRunner(RunTest): | ||
227 | 63 | """Use with run_tests_with to run Django tests. | ||
228 | 64 | |||
229 | 65 | Django's test case has a couple of hooks that it runs before and after | ||
230 | 66 | tests to isolate transactions and do other fun things | ||
231 | 67 | <https://docs.djangoproject.com/en/dev/topics/testing/#django.test.TestCase>. | ||
232 | 68 | |||
233 | 69 | Use this runner to get that same effect with testtools. | ||
234 | 70 | """ | ||
235 | 71 | |||
236 | 72 | class MyDjangoTestCase(DjangoTestCase): | ||
237 | 73 | def test_foo(self): | ||
238 | 74 | pass | ||
239 | 75 | |||
240 | 76 | def __init__(self, case, handlers=None): | ||
241 | 77 | super(DjangoRunner, self).__init__(case, handlers=handlers) | ||
242 | 78 | self._django_case = self.MyDjangoTestCase('test_foo') | ||
243 | 79 | |||
244 | 80 | def _run_core(self): | ||
245 | 81 | self._run_user(self._django_case._pre_setup) | ||
246 | 82 | super(DjangoRunner, self)._run_core() | ||
247 | 83 | self._run_user(self._django_case._post_teardown) | ||
248 | 84 | |||
249 | 85 | |||
250 | 86 | class EmptyBinaryPackageDatabase(Fixture): | ||
251 | 87 | |||
252 | 88 | def setUp(self): | ||
253 | 89 | super(EmptyBinaryPackageDatabase, self).setUp() | ||
254 | 90 | db_directory = self.useFixture(TempDir()).path | ||
255 | 91 | db_path = os.path.join(db_directory, 'test.db') | ||
256 | 92 | self.useFixture( | ||
257 | 93 | EnvironmentVariableFixture(PackageDatabase.ENV_VAR, db_path)) | ||
258 | 94 | |||
259 | 43 | 95 | ||
260 | 44 | class TestCaseWithFactory(TestCase): | 96 | class TestCaseWithFactory(TestCase): |
261 | 45 | factory = PkgmeObjectFactory() | 97 | factory = PkgmeObjectFactory() |
262 | 98 | run_tests_with = DjangoRunner | ||
263 | 46 | 99 | ||
264 | === modified file 'src/djpkgme/tests/test_handlers.py' | |||
265 | --- src/djpkgme/tests/test_handlers.py 2011-09-01 20:35:22 +0000 | |||
266 | +++ src/djpkgme/tests/test_handlers.py 2011-11-22 14:09:24 +0000 | |||
267 | @@ -78,16 +78,20 @@ | |||
268 | 78 | 78 | ||
269 | 79 | 79 | ||
270 | 80 | @patch('httplib2.Http.request') | 80 | @patch('httplib2.Http.request') |
272 | 81 | def test_no_overrides_success(self, mock_request): | 81 | @patch('djpkgme.tasks.BuildPackageTask.build_package') |
273 | 82 | def test_no_overrides_success(self, mock_build_package, mock_request): | ||
274 | 82 | request = Mock() | 83 | request = Mock() |
275 | 84 | mock_build_package.return_value = 'foo' | ||
276 | 83 | request.data = {'metadata': test_metadata, 'overrides': {}} | 85 | request.data = {'metadata': test_metadata, 'overrides': {}} |
277 | 84 | handler = PackageHandler() | 86 | handler = PackageHandler() |
278 | 85 | response = handler.create(request) | 87 | response = handler.create(request) |
279 | 86 | self.assertEqual({'status': 'success'}, response) | 88 | self.assertEqual({'status': 'success'}, response) |
280 | 87 | 89 | ||
281 | 88 | @patch('httplib2.Http.request') | 90 | @patch('httplib2.Http.request') |
283 | 89 | def test_overrides_success(self, mock_request): | 91 | @patch('djpkgme.tasks.BuildPackageTask.build_package') |
284 | 92 | def test_overrides_success(self, mock_build_package, mock_request): | ||
285 | 90 | request = Mock() | 93 | request = Mock() |
286 | 94 | mock_build_package.return_value = 'foo' | ||
287 | 91 | request.data = {'metadata': test_metadata, 'overrides': { | 95 | request.data = {'metadata': test_metadata, 'overrides': { |
288 | 92 | 'executable': 'bin/foo', | 96 | 'executable': 'bin/foo', |
289 | 93 | 'deps': ['libfoo', 'libbar'], | 97 | 'deps': ['libfoo', 'libbar'], |
290 | 94 | 98 | ||
291 | === modified file 'src/djpkgme/tests/test_models.py' | |||
292 | --- src/djpkgme/tests/test_models.py 2011-09-01 21:46:47 +0000 | |||
293 | +++ src/djpkgme/tests/test_models.py 2011-11-22 14:09:24 +0000 | |||
294 | @@ -1,6 +1,13 @@ | |||
296 | 1 | from factory import TestCaseWithFactory | 1 | from djpkgme.tests.factory import TestCaseWithFactory |
297 | 2 | |||
298 | 3 | from devportalbinary.binary import ( | ||
299 | 4 | CATEGORIES, | ||
300 | 5 | PACKAGE_NAME, | ||
301 | 6 | TAGLINE, | ||
302 | 7 | ) | ||
303 | 2 | 8 | ||
304 | 3 | class AppMetadataTestCase(TestCaseWithFactory): | 9 | class AppMetadataTestCase(TestCaseWithFactory): |
305 | 10 | |||
306 | 4 | def test_update_guesses_doesnt_mutate_argument(self): | 11 | def test_update_guesses_doesnt_mutate_argument(self): |
307 | 5 | """Calling update_guesses doesn't modify the dict we pass in.""" | 12 | """Calling update_guesses doesn't modify the dict we pass in.""" |
308 | 6 | metadata = self.factory.make_metadata(with_guesses=True) | 13 | metadata = self.factory.make_metadata(with_guesses=True) |
309 | @@ -50,4 +57,13 @@ | |||
310 | 50 | 57 | ||
311 | 51 | expected = ['dependencies', 'pkgme_distro_arch_series', | 58 | expected = ['dependencies', 'pkgme_distro_arch_series', |
312 | 52 | 'pkgme_extra_data', 'packaged_app_url'] | 59 | 'pkgme_extra_data', 'packaged_app_url'] |
313 | 53 | self.assertEquals(set(expected), set(info)) | ||
314 | 54 | \ No newline at end of file | 60 | \ No newline at end of file |
315 | 61 | self.assertEquals(set(expected), set(info)) | ||
316 | 62 | |||
317 | 63 | def test_as_dict(self): | ||
318 | 64 | metadata = self.factory.make_metadata() | ||
319 | 65 | expected = { | ||
320 | 66 | CATEGORIES: metadata.categories, | ||
321 | 67 | PACKAGE_NAME: metadata.package_name, | ||
322 | 68 | TAGLINE: metadata.tagline, | ||
323 | 69 | } | ||
324 | 70 | self.assertEqual(expected, metadata.as_dict()) | ||
325 | 55 | 71 | ||
326 | === modified file 'src/djpkgme/tests/test_tasks.py' | |||
327 | --- src/djpkgme/tests/test_tasks.py 2011-09-01 21:46:47 +0000 | |||
328 | +++ src/djpkgme/tests/test_tasks.py 2011-11-22 14:09:24 +0000 | |||
329 | @@ -1,15 +1,29 @@ | |||
331 | 1 | # Run tasks eagerly for tests. Taken from | 1 | # Run tasks eagerly for tests. Taken from |
332 | 2 | # http://ask.github.com/celery/cookbook/unit-testing.html | 2 | # http://ask.github.com/celery/cookbook/unit-testing.html |
333 | 3 | 3 | ||
334 | 4 | import json | 4 | import json |
335 | 5 | import os | ||
336 | 6 | import shutil | ||
337 | 7 | import tarfile | ||
338 | 8 | |||
339 | 9 | from fixtures import TempDir | ||
340 | 5 | from mock import patch | 10 | from mock import patch |
341 | 6 | 11 | ||
344 | 7 | from djpkgme.tasks import GuessPackagingDetailsTask, BuildPackageTask | 12 | from devportalbinary.binary import METADATA_FILE |
345 | 8 | from djpkgme.tests.factory import TestCaseWithFactory | 13 | from djpkgme import tasks |
346 | 14 | from djpkgme.tasks import ( | ||
347 | 15 | BuildPackageTask, | ||
348 | 16 | GuessPackagingDetailsTask, | ||
349 | 17 | ) | ||
350 | 18 | from djpkgme.tests.factory import ( | ||
351 | 19 | EmptyBinaryPackageDatabase, | ||
352 | 20 | TestCaseWithFactory, | ||
353 | 21 | ) | ||
354 | 22 | |||
355 | 9 | 23 | ||
356 | 10 | class GuessPackagingDetailsTaskTestCase(TestCaseWithFactory): | 24 | class GuessPackagingDetailsTaskTestCase(TestCaseWithFactory): |
357 | 11 | @patch('httplib2.Http.request') | 25 | @patch('httplib2.Http.request') |
359 | 12 | @patch('djpkgme.tasks.pkgme') | 26 | @patch('djpkgme.tasks.mock_pkgme') |
360 | 13 | def test_guess_details_is_called(self, mock_pkgme, mock_request): | 27 | def test_guess_details_is_called(self, mock_pkgme, mock_request): |
361 | 14 | mock_request.return_value = ({}, '') | 28 | mock_request.return_value = ({}, '') |
362 | 15 | mock_pkgme.guess.return_value = {} | 29 | mock_pkgme.guess.return_value = {} |
363 | @@ -23,7 +37,7 @@ | |||
364 | 23 | self.assertEqual(1, mock_pkgme.guess.call_count) | 37 | self.assertEqual(1, mock_pkgme.guess.call_count) |
365 | 24 | 38 | ||
366 | 25 | @patch('httplib2.Http.request') | 39 | @patch('httplib2.Http.request') |
368 | 26 | @patch('djpkgme.tasks.pkgme') | 40 | @patch('djpkgme.tasks.mock_pkgme') |
369 | 27 | def test_result_is_submitted(self, mock_pkgme, mock_request): | 41 | def test_result_is_submitted(self, mock_pkgme, mock_request): |
370 | 28 | mock_request.return_value = ({}, '') | 42 | mock_request.return_value = ({}, '') |
371 | 29 | mock_pkgme.guess.return_value = {} | 43 | mock_pkgme.guess.return_value = {} |
372 | @@ -35,20 +49,21 @@ | |||
373 | 35 | "pkgme_extra_data": {"pkgme_id": 1, "executable": ""} | 49 | "pkgme_extra_data": {"pkgme_id": 1, "executable": ""} |
374 | 36 | } | 50 | } |
375 | 37 | 51 | ||
377 | 38 | result = GuessPackagingDetailsTask.delay(metadata) | 52 | GuessPackagingDetailsTask.delay(metadata) |
378 | 39 | 53 | ||
379 | 40 | self.assertEqual(1, mock_request.call_count) | 54 | self.assertEqual(1, mock_request.call_count) |
380 | 41 | args, kwargs = mock_request.call_args | 55 | args, kwargs = mock_request.call_args |
384 | 42 | self.assertEqual((metadata.callback_url,), args) | 56 | self.assertEqual(args, (metadata.callback_url,)) |
385 | 43 | self.assertEqual(json.loads(kwargs['body']), expected) | 57 | self.assertEqual(expected, json.loads(kwargs['body'])) |
386 | 44 | 58 | ||
387 | 45 | 59 | ||
388 | 46 | class BuildPackageTaskTestCase(TestCaseWithFactory): | 60 | class BuildPackageTaskTestCase(TestCaseWithFactory): |
389 | 61 | |||
390 | 47 | @patch('httplib2.Http.request') | 62 | @patch('httplib2.Http.request') |
393 | 48 | @patch('djpkgme.tasks.pkgme') | 63 | @patch('djpkgme.tasks.BuildPackageTask.build_package') |
394 | 49 | def test_guess_details_is_called(self, mock_pkgme, mock_request): | 64 | def test_build_package_is_called(self, mock_build_package, mock_request): |
395 | 50 | mock_request.return_value = ({}, '') | 65 | mock_request.return_value = ({}, '') |
397 | 51 | mock_pkgme.build_package.return_value = "foo" | 66 | mock_build_package.return_value = "foo" |
398 | 52 | 67 | ||
399 | 53 | metadata = self.factory.make_metadata() | 68 | metadata = self.factory.make_metadata() |
400 | 54 | overrides = {} | 69 | overrides = {} |
401 | @@ -57,18 +72,18 @@ | |||
402 | 57 | 72 | ||
403 | 58 | self.assertEqual('foo', result.get()) | 73 | self.assertEqual('foo', result.get()) |
404 | 59 | self.assertTrue(result.successful()) | 74 | self.assertTrue(result.successful()) |
406 | 60 | self.assertEqual(1, mock_pkgme.build_package.call_count) | 75 | self.assertEqual(1, mock_build_package.call_count) |
407 | 61 | 76 | ||
408 | 62 | @patch('httplib2.Http.request') | 77 | @patch('httplib2.Http.request') |
411 | 63 | @patch('djpkgme.tasks.pkgme') | 78 | @patch('djpkgme.tasks.BuildPackageTask.build_package') |
412 | 64 | def test_result_is_submitted(self, mock_pkgme, mock_request): | 79 | def test_result_is_submitted(self, mock_build_package, mock_request): |
413 | 65 | mock_request.return_value = ({}, '') | 80 | mock_request.return_value = ({}, '') |
415 | 66 | mock_pkgme.build_package.return_value = "foo" | 81 | mock_build_package.return_value = "foo" |
416 | 67 | 82 | ||
417 | 68 | metadata = self.factory.make_metadata() | 83 | metadata = self.factory.make_metadata() |
418 | 69 | overrides = {} | 84 | overrides = {} |
419 | 70 | 85 | ||
421 | 71 | result = BuildPackageTask.delay(metadata, overrides) | 86 | BuildPackageTask.delay(metadata, overrides) |
422 | 72 | 87 | ||
423 | 73 | self.assertEqual(1, mock_request.call_count) | 88 | self.assertEqual(1, mock_request.call_count) |
424 | 74 | args, kwargs = mock_request.call_args | 89 | args, kwargs = mock_request.call_args |
425 | @@ -78,5 +93,45 @@ | |||
426 | 78 | "pkgme_distro_arch_series": [], | 93 | "pkgme_distro_arch_series": [], |
427 | 79 | "pkgme_extra_data": {"pkgme_id": 1, "executable": ""} | 94 | "pkgme_extra_data": {"pkgme_id": 1, "executable": ""} |
428 | 80 | } | 95 | } |
431 | 81 | self.assertEqual((metadata.callback_url,), args) | 96 | self.assertEqual(args, (metadata.callback_url,)) |
432 | 82 | self.assertEqual(json.loads(kwargs['body']), expected) | 97 | self.assertEqual(expected, json.loads(kwargs['body'])) |
433 | 98 | |||
434 | 99 | def download_file(self, url, directory): | ||
435 | 100 | # For the moment, the test we just want to create a valid tarball in | ||
436 | 101 | # the directory. | ||
437 | 102 | import acceptance | ||
438 | 103 | binary_path = os.path.join( | ||
439 | 104 | os.path.dirname(acceptance.__file__), 'data', 'gtk', 'test_gtk') | ||
440 | 105 | temp_dir = self.useFixture(TempDir()).path | ||
441 | 106 | nothing_file_path = os.path.join(temp_dir, 'binary-file') | ||
442 | 107 | shutil.copyfile(binary_path, nothing_file_path) | ||
443 | 108 | tarball_path = os.path.join(directory, 'tarball.tar.gz') | ||
444 | 109 | tarball = tarfile.open(tarball_path, 'w') | ||
445 | 110 | tarball.add(nothing_file_path, os.path.basename(nothing_file_path)) | ||
446 | 111 | tarball.close() | ||
447 | 112 | return tarball_path | ||
448 | 113 | |||
449 | 114 | def test_writes_packaging_for_tarball(self): | ||
450 | 115 | # BuildPackageTask.build_package runs pkgme to build the package and | ||
451 | 116 | # outputs a tarball to the given path. Here we're testing the happy | ||
452 | 117 | # case. | ||
453 | 118 | metadata = self.factory.make_metadata() | ||
454 | 119 | task = BuildPackageTask() | ||
455 | 120 | self.patch(tasks, 'download_file', self.download_file) | ||
456 | 121 | self.useFixture(EmptyBinaryPackageDatabase()) | ||
457 | 122 | temp_dir = self.useFixture(TempDir()).path | ||
458 | 123 | output_tar_path = os.path.join(temp_dir, 'output.tar.gz') | ||
459 | 124 | task.build_package(metadata, {}, output_tar_path) | ||
460 | 125 | with tarfile.open(output_tar_path) as output_tar: | ||
461 | 126 | self.assertEqual( | ||
462 | 127 | sorted( | ||
463 | 128 | ['%s_0.dsc' % (metadata.package_name,), | ||
464 | 129 | '%s_0.tar.gz' % (metadata.package_name,), | ||
465 | 130 | '%s_0_source.build' % (metadata.package_name,), | ||
466 | 131 | '%s_0_source.changes' % (metadata.package_name,), | ||
467 | 132 | METADATA_FILE, | ||
468 | 133 | ]), | ||
469 | 134 | sorted(output_tar.getnames())) | ||
470 | 135 | |||
471 | 136 | # XXX: Write a test directly for the contents of METADATA_FILE? | ||
472 | 137 | # XXX: Check the contents of the tarball in the source package? | ||
473 | 83 | 138 | ||
474 | === modified file 'test-dependencies.txt' | |||
475 | --- test-dependencies.txt 2011-11-09 11:14:13 +0000 | |||
476 | +++ test-dependencies.txt 2011-11-22 14:09:24 +0000 | |||
477 | @@ -1,4 +1,9 @@ | |||
478 | 1 | coverage | ||
479 | 1 | django-kombu | 2 | django-kombu |
481 | 2 | coverage | 3 | mock |
482 | 3 | piston-mini-client | 4 | piston-mini-client |
484 | 4 | mock | 5 | testtools |
485 | 6 | # These aren't test requirements, but we want to fetch these dependencies from | ||
486 | 7 | # bzr and this is the only way I can figure out how to do this -- jml | ||
487 | 8 | -e bzr+ssh://bazaar.launchpad.net/+branch/pkgme#egg=pkgme | ||
488 | 9 | -e bzr+ssh://bazaar.launchpad.net/+branch/pkgme-binary#egg=pkgme-binary |
Hi,
This broadly looks good, and is certainly an improvement.
As it stands this test will only work when run from source:
437 + import acceptance
as pkgme-binary doesn't include this when installed. We could move
it in to the devportalbinary namespace?
Thanks,
James