Merge ~cjwatson/launchpad:remove-lp-testing-run-script into launchpad:master
- Git
- lp:~cjwatson/launchpad
- remove-lp-testing-run-script
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 73ee6eb63e28166a23a7216a6d272dfde9f26b8d |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:remove-lp-testing-run-script |
Merge into: | launchpad:master |
Diff against target: |
711 lines (+161/-114) 15 files modified
lib/lp/answers/tests/test_questionjob.py (+10/-5) lib/lp/archivepublisher/tests/test_publish_ftpmaster.py (+5/-2) lib/lp/codehosting/scripts/tests/test_upgrade_all_branches.py (+9/-6) lib/lp/registry/tests/test_distributionmirror_prober.py (+17/-7) lib/lp/registry/tests/test_membership_notification_job.py (+10/-9) lib/lp/registry/tests/test_person_merge_job.py (+10/-4) lib/lp/registry/tests/test_productjob.py (+10/-5) lib/lp/registry/tests/test_sharingjob.py (+10/-9) lib/lp/services/scripts/tests/test_all_scripts.py (+3/-3) lib/lp/soyuz/tests/test_packagecopyjob.py (+7/-4) lib/lp/soyuz/tests/test_packagediffjob.py (+10/-4) lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py (+10/-9) lib/lp/soyuz/tests/test_processacceptedbugsjob.py (+8/-4) lib/lp/testing/__init__.py (+2/-34) lib/lp/testing/script.py (+40/-9) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Guruprasad | Approve | ||
Review via email: mp+436843@code.launchpad.net |
Commit message
Remove lp.testing.
Description of the change
`lp.testing.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/lp/answers/tests/test_questionjob.py b/lib/lp/answers/tests/test_questionjob.py |
2 | index 214b83a..3c3a7f7 100644 |
3 | --- a/lib/lp/answers/tests/test_questionjob.py |
4 | +++ b/lib/lp/answers/tests/test_questionjob.py |
5 | @@ -3,6 +3,8 @@ |
6 | |
7 | """Tests for QuestionJobs classes.""" |
8 | |
9 | +import os |
10 | + |
11 | import transaction |
12 | from testtools.content import text_content |
13 | from zope.component import getUtility |
14 | @@ -26,9 +28,10 @@ from lp.services.mail import stub |
15 | from lp.services.mail.sendmail import format_address, format_address_for_person |
16 | from lp.services.scripts import log |
17 | from lp.services.worlddata.interfaces.language import ILanguageSet |
18 | -from lp.testing import TestCaseWithFactory, person_logged_in, run_script |
19 | +from lp.testing import TestCaseWithFactory, person_logged_in |
20 | from lp.testing.dbuser import dbuser |
21 | from lp.testing.layers import CeleryJobLayer, DatabaseFunctionalLayer |
22 | +from lp.testing.script import run_script |
23 | |
24 | |
25 | class QuestionJobTestCase(TestCaseWithFactory): |
26 | @@ -352,9 +355,12 @@ class QuestionEmailJobTestCase(TestCaseWithFactory): |
27 | question.target.addAnswerContact(user, user) |
28 | transaction.commit() |
29 | |
30 | - out, err, exit_code = run_script( |
31 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
32 | - % (IQuestionEmailJobSource.getName()) |
33 | + env = os.environ.copy() |
34 | + env["LP_DEBUG_SQL"] = "1" |
35 | + exit_code, out, err = run_script( |
36 | + "cronscripts/process-job-source.py", |
37 | + args=["-vv", IQuestionEmailJobSource.getName()], |
38 | + env=env, |
39 | ) |
40 | self.addDetail("stdout", text_content(out)) |
41 | self.addDetail("stderr", text_content(err)) |
42 | @@ -372,7 +378,6 @@ class QuestionEmailJobTestCase(TestCaseWithFactory): |
43 | |
44 | |
45 | class TestViaCelery(TestCaseWithFactory): |
46 | - |
47 | layer = CeleryJobLayer |
48 | |
49 | def test_run(self): |
50 | diff --git a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py |
51 | index 5f686ad..770c667 100644 |
52 | --- a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py |
53 | +++ b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py |
54 | @@ -45,9 +45,10 @@ from lp.soyuz.enums import ( |
55 | PackageUploadCustomFormat, |
56 | ) |
57 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
58 | -from lp.testing import TestCase, TestCaseWithFactory, run_script |
59 | +from lp.testing import TestCase, TestCaseWithFactory |
60 | from lp.testing.fakemethod import FakeMethod |
61 | from lp.testing.layers import LaunchpadZopelessLayer |
62 | +from lp.testing.script import run_script |
63 | |
64 | |
65 | def path_exists(*path_components): |
66 | @@ -229,7 +230,9 @@ class TestPublishFTPMasterScript( |
67 | def test_script_runs_successfully(self): |
68 | self.prepareUbuntu() |
69 | self.layer.txn.commit() |
70 | - stdout, stderr, retval = run_script(self.SCRIPT_PATH + " -d ubuntu") |
71 | + retval, stdout, stderr = run_script( |
72 | + self.SCRIPT_PATH, args=["-d", "ubuntu"] |
73 | + ) |
74 | self.assertEqual(0, retval, "Script failure:\n" + stderr) |
75 | |
76 | def test_getConfigs_maps_distro_and_purpose_to_matching_config(self): |
77 | diff --git a/lib/lp/codehosting/scripts/tests/test_upgrade_all_branches.py b/lib/lp/codehosting/scripts/tests/test_upgrade_all_branches.py |
78 | index 87752a6..fe9590e 100644 |
79 | --- a/lib/lp/codehosting/scripts/tests/test_upgrade_all_branches.py |
80 | +++ b/lib/lp/codehosting/scripts/tests/test_upgrade_all_branches.py |
81 | @@ -12,8 +12,9 @@ from fixtures import TempDir |
82 | from lp.code.bzr import branch_changed |
83 | from lp.codehosting.upgrade import Upgrader |
84 | from lp.services.config import config |
85 | -from lp.testing import TestCaseWithFactory, person_logged_in, run_script |
86 | +from lp.testing import TestCaseWithFactory, person_logged_in |
87 | from lp.testing.layers import AppServerLayer |
88 | +from lp.testing.script import run_script |
89 | |
90 | |
91 | class TestUpgradeAllBranchesScript(TestCaseWithFactory): |
92 | @@ -29,11 +30,13 @@ class TestUpgradeAllBranchesScript(TestCaseWithFactory): |
93 | """Run the script to upgrade all branches.""" |
94 | transaction.commit() |
95 | if finish: |
96 | - flags = " --finish " |
97 | + flags = ["--finish"] |
98 | else: |
99 | - flags = " " |
100 | + flags = [] |
101 | return run_script( |
102 | - "scripts/upgrade_all_branches.py" + flags + target, cwd=self.cwd |
103 | + "scripts/upgrade_all_branches.py", |
104 | + args=flags + [target], |
105 | + cwd=self.cwd, |
106 | ) |
107 | |
108 | def prepare(self): |
109 | @@ -52,7 +55,7 @@ class TestUpgradeAllBranchesScript(TestCaseWithFactory): |
110 | def test_start_upgrade(self): |
111 | """Test that starting the upgrade behaves as expected.""" |
112 | upgrader = self.prepare() |
113 | - stdout, stderr, retcode = self.upgrade_all_branches( |
114 | + retcode, stdout, stderr = self.upgrade_all_branches( |
115 | upgrader.target_dir |
116 | ) |
117 | self.assertIn( |
118 | @@ -68,7 +71,7 @@ class TestUpgradeAllBranchesScript(TestCaseWithFactory): |
119 | """Test that finishing the upgrade behaves as expected.""" |
120 | upgrader = self.prepare() |
121 | upgrader.start_upgrade() |
122 | - stdout, stderr, retcode = self.upgrade_all_branches( |
123 | + retcode, stdout, stderr = self.upgrade_all_branches( |
124 | upgrader.target_dir, finish=True |
125 | ) |
126 | self.assertIn( |
127 | diff --git a/lib/lp/registry/tests/test_distributionmirror_prober.py b/lib/lp/registry/tests/test_distributionmirror_prober.py |
128 | index 11cbc98..4b4203f 100644 |
129 | --- a/lib/lp/registry/tests/test_distributionmirror_prober.py |
130 | +++ b/lib/lp/registry/tests/test_distributionmirror_prober.py |
131 | @@ -84,13 +84,13 @@ from lp.testing import ( |
132 | TestCaseWithFactory, |
133 | admin_logged_in, |
134 | clean_up_reactor, |
135 | - run_script, |
136 | ) |
137 | from lp.testing.layers import ( |
138 | LaunchpadZopelessLayer, |
139 | TwistedLayer, |
140 | ZopelessDatabaseLayer, |
141 | ) |
142 | +from lp.testing.script import run_script |
143 | |
144 | |
145 | class HTTPServerTestSetup(TacTestSetup): |
146 | @@ -1324,9 +1324,14 @@ class TestDistroMirrorProberFunctional(TestCaseWithFactory): |
147 | mirror = self.makeMirror(content_type=MirrorContent.RELEASE) |
148 | transaction.commit() |
149 | |
150 | - out, err, exit_code = run_script( |
151 | - "cronscripts/distributionmirror-prober.py --no-remote-hosts " |
152 | - "--content-type=cdimage --no-owner-notification --force" |
153 | + exit_code, out, err = run_script( |
154 | + "cronscripts/distributionmirror-prober.py", |
155 | + args=[ |
156 | + "--no-remote-hosts", |
157 | + "--content-type=cdimage", |
158 | + "--no-owner-notification", |
159 | + "--force", |
160 | + ], |
161 | ) |
162 | self.assertEqual(0, exit_code, err) |
163 | |
164 | @@ -1376,9 +1381,14 @@ class TestDistroMirrorProberFunctional(TestCaseWithFactory): |
165 | ) |
166 | transaction.commit() |
167 | |
168 | - out, err, exit_code = run_script( |
169 | - "cronscripts/distributionmirror-prober.py --no-remote-hosts " |
170 | - "--content-type=archive --no-owner-notification --force" |
171 | + exit_code, out, err = run_script( |
172 | + "cronscripts/distributionmirror-prober.py", |
173 | + args=[ |
174 | + "--no-remote-hosts", |
175 | + "--content-type=archive", |
176 | + "--no-owner-notification", |
177 | + "--force", |
178 | + ], |
179 | ) |
180 | self.assertEqual(0, exit_code, err) |
181 | |
182 | diff --git a/lib/lp/registry/tests/test_membership_notification_job.py b/lib/lp/registry/tests/test_membership_notification_job.py |
183 | index ef9d7e4..9becfe6 100644 |
184 | --- a/lib/lp/registry/tests/test_membership_notification_job.py |
185 | +++ b/lib/lp/registry/tests/test_membership_notification_job.py |
186 | @@ -3,6 +3,8 @@ |
187 | |
188 | """Tests of `MembershipNotificationJob`.""" |
189 | |
190 | +import os |
191 | + |
192 | import transaction |
193 | from testtools.content import text_content |
194 | from zope.component import getUtility |
195 | @@ -19,14 +21,10 @@ from lp.registry.model.persontransferjob import MembershipNotificationJob |
196 | from lp.services.features.testing import FeatureFixture |
197 | from lp.services.job.interfaces.job import JobStatus |
198 | from lp.services.job.tests import block_on_job, pop_remote_notifications |
199 | -from lp.testing import ( |
200 | - TestCaseWithFactory, |
201 | - login_person, |
202 | - person_logged_in, |
203 | - run_script, |
204 | -) |
205 | +from lp.testing import TestCaseWithFactory, login_person, person_logged_in |
206 | from lp.testing.layers import CeleryJobLayer, DatabaseFunctionalLayer |
207 | from lp.testing.sampledata import ADMIN_EMAIL |
208 | +from lp.testing.script import run_script |
209 | |
210 | |
211 | class MembershipNotificationJobTest(TestCaseWithFactory): |
212 | @@ -116,9 +114,12 @@ class MembershipNotificationJobTest(TestCaseWithFactory): |
213 | ) |
214 | job_repr = repr(job) |
215 | transaction.commit() |
216 | - out, err, exit_code = run_script( |
217 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
218 | - % (IMembershipNotificationJobSource.getName()) |
219 | + env = os.environ.copy() |
220 | + env["LP_DEBUG_SQL"] = "1" |
221 | + exit_code, out, err = run_script( |
222 | + "cronscripts/process-job-source.py", |
223 | + args=["-vv", IMembershipNotificationJobSource.getName()], |
224 | + env=env, |
225 | ) |
226 | self.addDetail("stdout", text_content(out)) |
227 | self.addDetail("stderr", text_content(err)) |
228 | diff --git a/lib/lp/registry/tests/test_person_merge_job.py b/lib/lp/registry/tests/test_person_merge_job.py |
229 | index 1a39e6b..c536471 100644 |
230 | --- a/lib/lp/registry/tests/test_person_merge_job.py |
231 | +++ b/lib/lp/registry/tests/test_person_merge_job.py |
232 | @@ -3,6 +3,8 @@ |
233 | |
234 | """Tests of `PersonMergeJob`.""" |
235 | |
236 | +import os |
237 | + |
238 | import transaction |
239 | from testtools.content import text_content |
240 | from zope.component import getUtility |
241 | @@ -23,9 +25,10 @@ from lp.services.job.tests import block_on_job |
242 | from lp.services.log.logger import BufferLogger |
243 | from lp.services.mail.sendmail import format_address_for_person |
244 | from lp.services.scripts import log |
245 | -from lp.testing import TestCaseWithFactory, person_logged_in, run_script |
246 | +from lp.testing import TestCaseWithFactory, person_logged_in |
247 | from lp.testing.dbuser import dbuser |
248 | from lp.testing.layers import CeleryJobLayer, DatabaseFunctionalLayer |
249 | +from lp.testing.script import run_script |
250 | |
251 | |
252 | def create_job(factory): |
253 | @@ -141,9 +144,12 @@ class TestPersonMergeJob(TestCaseWithFactory): |
254 | ) |
255 | transaction.commit() |
256 | |
257 | - out, err, exit_code = run_script( |
258 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
259 | - % (IPersonMergeJobSource.getName()) |
260 | + env = os.environ.copy() |
261 | + env["LP_DEBUG_SQL"] = "1" |
262 | + exit_code, out, err = run_script( |
263 | + "cronscripts/process-job-source.py", |
264 | + args=["-vv", IPersonMergeJobSource.getName()], |
265 | + env=env, |
266 | ) |
267 | |
268 | self.addDetail("stdout", text_content(out)) |
269 | diff --git a/lib/lp/registry/tests/test_productjob.py b/lib/lp/registry/tests/test_productjob.py |
270 | index 5de315e..bec594c 100644 |
271 | --- a/lib/lp/registry/tests/test_productjob.py |
272 | +++ b/lib/lp/registry/tests/test_productjob.py |
273 | @@ -3,6 +3,7 @@ |
274 | |
275 | """Tests for ProductJobs.""" |
276 | |
277 | +import os |
278 | from datetime import datetime, timedelta, timezone |
279 | |
280 | import transaction |
281 | @@ -46,13 +47,14 @@ from lp.services.job.interfaces.job import JobStatus |
282 | from lp.services.log.logger import BufferLogger |
283 | from lp.services.propertycache import clear_property_cache |
284 | from lp.services.webapp.publisher import canonical_url |
285 | -from lp.testing import TestCaseWithFactory, person_logged_in, run_script |
286 | +from lp.testing import TestCaseWithFactory, person_logged_in |
287 | from lp.testing.layers import ( |
288 | DatabaseFunctionalLayer, |
289 | LaunchpadZopelessLayer, |
290 | ZopelessAppServerLayer, |
291 | ) |
292 | from lp.testing.mail_helpers import pop_notifications |
293 | +from lp.testing.script import run_script |
294 | |
295 | |
296 | class CommercialHelpers: |
297 | @@ -150,7 +152,7 @@ class DailyProductJobsTestCase(TestCaseWithFactory, CommercialHelpers): |
298 | # ProductJobManagerTestCase.test_createAllDailyJobs |
299 | self.make_test_products() |
300 | transaction.commit() |
301 | - stdout, stderr, retcode = run_script( |
302 | + retcode, stdout, stderr = run_script( |
303 | "cronscripts/daily_product_jobs.py" |
304 | ) |
305 | self.addDetail("stdout", text_content(stdout)) |
306 | @@ -621,9 +623,12 @@ class CommericialExpirationMixin(CommercialHelpers): |
307 | proprietary_job = self.JOB_CLASS.create(proprietary_product, reviewer) |
308 | transaction.commit() |
309 | |
310 | - out, err, exit_code = run_script( |
311 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
312 | - % self.JOB_SOURCE_INTERFACE.getName() |
313 | + env = os.environ.copy() |
314 | + env["LP_DEBUG_SQL"] = "1" |
315 | + exit_code, out, err = run_script( |
316 | + "cronscripts/process-job-source.py", |
317 | + args=["-vv", self.JOB_SOURCE_INTERFACE.getName()], |
318 | + env=env, |
319 | ) |
320 | self.addDetail("stdout", text_content(out)) |
321 | self.addDetail("stderr", text_content(err)) |
322 | diff --git a/lib/lp/registry/tests/test_sharingjob.py b/lib/lp/registry/tests/test_sharingjob.py |
323 | index e017e72..a088b02 100644 |
324 | --- a/lib/lp/registry/tests/test_sharingjob.py |
325 | +++ b/lib/lp/registry/tests/test_sharingjob.py |
326 | @@ -3,6 +3,8 @@ |
327 | |
328 | """Tests for SharingJobs.""" |
329 | |
330 | +import os |
331 | + |
332 | import transaction |
333 | from testtools.content import text_content |
334 | from zope.component import getUtility |
335 | @@ -42,17 +44,13 @@ from lp.services.job.interfaces.job import JobStatus |
336 | from lp.services.job.tests import block_on_job |
337 | from lp.services.mail.sendmail import format_address_for_person |
338 | from lp.snappy.interfaces.snap import SNAP_TESTING_FLAGS |
339 | -from lp.testing import ( |
340 | - TestCaseWithFactory, |
341 | - login_person, |
342 | - person_logged_in, |
343 | - run_script, |
344 | -) |
345 | +from lp.testing import TestCaseWithFactory, login_person, person_logged_in |
346 | from lp.testing.layers import ( |
347 | CeleryJobLayer, |
348 | DatabaseFunctionalLayer, |
349 | LaunchpadZopelessLayer, |
350 | ) |
351 | +from lp.testing.script import run_script |
352 | |
353 | |
354 | class SharingJobTestCase(TestCaseWithFactory): |
355 | @@ -266,9 +264,12 @@ class TestRunViaCron(TestCaseWithFactory): |
356 | ) |
357 | transaction.commit() |
358 | |
359 | - out, err, exit_code = run_script( |
360 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
361 | - % (job_type) |
362 | + env = os.environ.copy() |
363 | + env["LP_DEBUG_SQL"] = "1" |
364 | + exit_code, out, err = run_script( |
365 | + "cronscripts/process-job-source.py", |
366 | + args=["-vv", job_type], |
367 | + env=env, |
368 | ) |
369 | self.addDetail("stdout", text_content(out)) |
370 | self.addDetail("stderr", text_content(err)) |
371 | diff --git a/lib/lp/services/scripts/tests/test_all_scripts.py b/lib/lp/services/scripts/tests/test_all_scripts.py |
372 | index fc3be73..a5e770c 100644 |
373 | --- a/lib/lp/services/scripts/tests/test_all_scripts.py |
374 | +++ b/lib/lp/services/scripts/tests/test_all_scripts.py |
375 | @@ -10,7 +10,8 @@ from testscenarios import WithScenarios, load_tests_apply_scenarios |
376 | from testtools.matchers import DocTestMatches |
377 | |
378 | from lp.services.scripts.tests import find_lp_scripts |
379 | -from lp.testing import TestCase, run_script |
380 | +from lp.testing import TestCase |
381 | +from lp.testing.script import run_script |
382 | |
383 | |
384 | def make_id(script_path): |
385 | @@ -27,8 +28,7 @@ class ScriptsTestCase(WithScenarios, TestCase): |
386 | |
387 | def test_script(self): |
388 | # Run self.script_path with '-h' to make sure it runs cleanly. |
389 | - cmd_line = self.script_path + " -h" |
390 | - out, err, returncode = run_script(cmd_line) |
391 | + returncode, out, err = run_script(self.script_path, args=["-h"]) |
392 | self.assertThat(err, DocTestMatches("", doctest.REPORT_NDIFF)) |
393 | self.assertEqual("", err) |
394 | self.assertEqual(os.EX_OK, returncode) |
395 | diff --git a/lib/lp/soyuz/tests/test_packagecopyjob.py b/lib/lp/soyuz/tests/test_packagecopyjob.py |
396 | index f4d2e53..c0f3a85 100644 |
397 | --- a/lib/lp/soyuz/tests/test_packagecopyjob.py |
398 | +++ b/lib/lp/soyuz/tests/test_packagecopyjob.py |
399 | @@ -63,7 +63,6 @@ from lp.testing import ( |
400 | TestCaseWithFactory, |
401 | admin_logged_in, |
402 | person_logged_in, |
403 | - run_script, |
404 | verifyObject, |
405 | ) |
406 | from lp.testing.dbuser import dbuser, switch_dbuser |
407 | @@ -76,6 +75,7 @@ from lp.testing.layers import ( |
408 | ) |
409 | from lp.testing.mail_helpers import pop_notifications |
410 | from lp.testing.matchers import Provides |
411 | +from lp.testing.script import run_script |
412 | |
413 | |
414 | def get_dsd_comments(dsd): |
415 | @@ -726,9 +726,12 @@ class PlainPackageCopyJobTests(TestCaseWithFactory, LocalTestHelper): |
416 | archive2.newComponentUploader(requester, "main") |
417 | transaction.commit() |
418 | |
419 | - out, err, exit_code = run_script( |
420 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
421 | - % (IPlainPackageCopyJobSource.getName()) |
422 | + env = os.environ.copy() |
423 | + env["LP_DEBUG_SQL"] = "1" |
424 | + exit_code, out, err = run_script( |
425 | + "cronscripts/process-job-source.py", |
426 | + args=["-vv", IPlainPackageCopyJobSource.getName()], |
427 | + env=env, |
428 | ) |
429 | |
430 | self.addDetail("stdout", text_content(out)) |
431 | diff --git a/lib/lp/soyuz/tests/test_packagediffjob.py b/lib/lp/soyuz/tests/test_packagediffjob.py |
432 | index b3d9b2c..54c5a65 100644 |
433 | --- a/lib/lp/soyuz/tests/test_packagediffjob.py |
434 | +++ b/lib/lp/soyuz/tests/test_packagediffjob.py |
435 | @@ -1,6 +1,8 @@ |
436 | # Copyright 2013-2018 Canonical Ltd. This software is licensed under the |
437 | # GNU Affero General Public License version 3 (see the file LICENSE). |
438 | |
439 | +import os |
440 | + |
441 | import transaction |
442 | from testtools.content import text_content |
443 | from zope.component import getUtility |
444 | @@ -18,9 +20,10 @@ from lp.soyuz.interfaces.packagediffjob import ( |
445 | ) |
446 | from lp.soyuz.model.packagediffjob import PackageDiffJob |
447 | from lp.soyuz.tests.test_packagediff import create_proper_job |
448 | -from lp.testing import TestCaseWithFactory, run_script, verifyObject |
449 | +from lp.testing import TestCaseWithFactory, verifyObject |
450 | from lp.testing.fakemethod import FakeMethod |
451 | from lp.testing.layers import CeleryJobLayer, LaunchpadZopelessLayer |
452 | +from lp.testing.script import run_script |
453 | |
454 | |
455 | class TestPackageDiffJob(TestCaseWithFactory): |
456 | @@ -76,9 +79,12 @@ class TestPackageDiffJob(TestCaseWithFactory): |
457 | def test_smoke(self): |
458 | diff = create_proper_job(self.factory) |
459 | transaction.commit() |
460 | - out, err, exit_code = run_script( |
461 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
462 | - % (IPackageDiffJobSource.getName()) |
463 | + env = os.environ.copy() |
464 | + env["LP_DEBUG_SQL"] = "1" |
465 | + exit_code, out, err = run_script( |
466 | + "cronscripts/process-job-source.py", |
467 | + args=["-vv", IPackageDiffJobSource.getName()], |
468 | + env=env, |
469 | ) |
470 | |
471 | self.addDetail("stdout", text_content(out)) |
472 | diff --git a/lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py b/lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py |
473 | index 6564fe4..650f39d 100644 |
474 | --- a/lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py |
475 | +++ b/lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py |
476 | @@ -1,6 +1,8 @@ |
477 | # Copyright 2013-2018 Canonical Ltd. This software is licensed under the |
478 | # GNU Affero General Public License version 3 (see the file LICENSE). |
479 | |
480 | +import os |
481 | + |
482 | import transaction |
483 | from testtools.content import text_content |
484 | from zope.component import getUtility |
485 | @@ -18,15 +20,11 @@ from lp.soyuz.interfaces.packagetranslationsuploadjob import ( |
486 | from lp.soyuz.model.packagetranslationsuploadjob import ( |
487 | PackageTranslationsUploadJob, |
488 | ) |
489 | -from lp.testing import ( |
490 | - TestCaseWithFactory, |
491 | - person_logged_in, |
492 | - run_script, |
493 | - verifyObject, |
494 | -) |
495 | +from lp.testing import TestCaseWithFactory, person_logged_in, verifyObject |
496 | from lp.testing.dbuser import dbuser |
497 | from lp.testing.fakemethod import FakeMethod |
498 | from lp.testing.layers import CeleryJobLayer, LaunchpadZopelessLayer |
499 | +from lp.testing.script import run_script |
500 | from lp.translations.interfaces.translationimportqueue import ( |
501 | ITranslationImportQueue, |
502 | ) |
503 | @@ -132,9 +130,12 @@ class TestPackageTranslationsUploadJob(LocalTestHelper): |
504 | } |
505 | spr, sp, job = self.makeJob(tar_content=tar_content) |
506 | transaction.commit() |
507 | - out, err, exit_code = run_script( |
508 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
509 | - % (IPackageTranslationsUploadJobSource.getName()) |
510 | + env = os.environ.copy() |
511 | + env["LP_DEBUG_SQL"] = "1" |
512 | + exit_code, out, err = run_script( |
513 | + "cronscripts/process-job-source.py", |
514 | + args=["-vv", IPackageTranslationsUploadJobSource.getName()], |
515 | + env=env, |
516 | ) |
517 | |
518 | self.addDetail("stdout", text_content(out)) |
519 | diff --git a/lib/lp/soyuz/tests/test_processacceptedbugsjob.py b/lib/lp/soyuz/tests/test_processacceptedbugsjob.py |
520 | index 6ed8b1d..f2e29bf 100644 |
521 | --- a/lib/lp/soyuz/tests/test_processacceptedbugsjob.py |
522 | +++ b/lib/lp/soyuz/tests/test_processacceptedbugsjob.py |
523 | @@ -4,6 +4,7 @@ |
524 | """Tests for jobs to close bugs for accepted package uploads.""" |
525 | |
526 | import io |
527 | +import os |
528 | from itertools import product |
529 | from textwrap import dedent |
530 | |
531 | @@ -38,7 +39,6 @@ from lp.testing import ( |
532 | TestCaseWithFactory, |
533 | celebrity_logged_in, |
534 | person_logged_in, |
535 | - run_script, |
536 | verifyObject, |
537 | ) |
538 | from lp.testing.fakemethod import FakeMethod |
539 | @@ -47,6 +47,7 @@ from lp.testing.layers import ( |
540 | DatabaseFunctionalLayer, |
541 | LaunchpadZopelessLayer, |
542 | ) |
543 | +from lp.testing.script import run_script |
544 | |
545 | |
546 | class TestBugIDsFromChangesFile(TestCaseWithFactory): |
547 | @@ -447,9 +448,12 @@ class TestProcessAcceptedBugsJob(TestCaseWithFactory): |
548 | self.makeJob(spr=spr, bug_ids=[bug.id]) |
549 | transaction.commit() |
550 | |
551 | - out, err, exit_code = run_script( |
552 | - "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" |
553 | - % (IProcessAcceptedBugsJobSource.getName()) |
554 | + env = os.environ.copy() |
555 | + env["LP_DEBUG_SQL"] = "1" |
556 | + exit_code, out, err = run_script( |
557 | + "cronscripts/process-job-source.py", |
558 | + args=["-vv", IProcessAcceptedBugsJobSource.getName()], |
559 | + env=env, |
560 | ) |
561 | |
562 | self.addDetail("stdout", text_content(out)) |
563 | diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py |
564 | index 7bf98a4..bde4117 100644 |
565 | --- a/lib/lp/testing/__init__.py |
566 | +++ b/lib/lp/testing/__init__.py |
567 | @@ -33,7 +33,6 @@ __all__ = [ |
568 | "record_statements", |
569 | "reset_logging", |
570 | "run_process", |
571 | - "run_script", |
572 | "run_with_login", |
573 | "run_with_storm_debug", |
574 | "RunIsolatedTest", |
575 | @@ -1366,42 +1365,11 @@ def time_counter(origin=None, delta=timedelta(seconds=5)): |
576 | now += delta |
577 | |
578 | |
579 | -def run_script(cmd_line, env=None, cwd=None, universal_newlines=True): |
580 | - """Run the given command line as a subprocess. |
581 | - |
582 | - :param cmd_line: A command line suitable for passing to |
583 | - `subprocess.Popen`. |
584 | - :param env: An optional environment dict. If none is given, the |
585 | - script will get a copy of your present environment. Either way, |
586 | - PYTHONPATH will be removed from it because it will break the |
587 | - script. |
588 | - :param universal_newlines: If True, return stdout and stderr as text. |
589 | - Defaults to True. |
590 | - :return: A 3-tuple of stdout, stderr, and the process' return code. |
591 | - """ |
592 | - if env is None: |
593 | - env = os.environ.copy() |
594 | - env.pop("PYTHONPATH", None) |
595 | - process = subprocess.Popen( |
596 | - cmd_line, |
597 | - shell=True, |
598 | - stdin=subprocess.PIPE, |
599 | - stdout=subprocess.PIPE, |
600 | - stderr=subprocess.PIPE, |
601 | - env=env, |
602 | - cwd=cwd, |
603 | - universal_newlines=universal_newlines, |
604 | - ) |
605 | - (out, err) = process.communicate() |
606 | - return out, err, process.returncode |
607 | - |
608 | - |
609 | def run_process(cmd, env=None, universal_newlines=True): |
610 | """Run the given command as a subprocess. |
611 | |
612 | - This differs from `run_script` in that it does not execute via a shell and |
613 | - it explicitly connects stdin to /dev/null so that processes will not be |
614 | - able to hang, waiting for user input. |
615 | + This explicitly connects stdin to /dev/null so that processes will not |
616 | + be able to hang, waiting for user input. |
617 | |
618 | :param cmd_line: A command suitable for passing to `subprocess.Popen`. |
619 | :param env: An optional environment dict. If none is given, the script |
620 | diff --git a/lib/lp/testing/script.py b/lib/lp/testing/script.py |
621 | index ee010dc..4f4e5e9 100644 |
622 | --- a/lib/lp/testing/script.py |
623 | +++ b/lib/lp/testing/script.py |
624 | @@ -8,16 +8,28 @@ __all__ = [ |
625 | "run_script", |
626 | ] |
627 | |
628 | +import os |
629 | import subprocess |
630 | -import sys |
631 | +from typing import Dict, List, Optional, Union |
632 | |
633 | |
634 | -def run_command(command, args=None, input=None, universal_newlines=True): |
635 | +# XXX cjwatson 2023-02-03: This type could be stricter: the type of `input` |
636 | +# depends on the value of `universal_newlines`. |
637 | +def run_command( |
638 | + command: str, |
639 | + args: Optional[List[str]] = None, |
640 | + env: Optional[Dict[str, str]] = None, |
641 | + cwd: Optional[str] = None, |
642 | + input: Optional[Union[bytes, str]] = None, |
643 | + universal_newlines: bool = True, |
644 | +): |
645 | """Run an external command in a separate process. |
646 | |
647 | :param command: executable to run. |
648 | :param args: optional list of command-line arguments. |
649 | :param input: optional text to feed to command's standard input. |
650 | + :param env: optional, passed to `subprocess.Popen`. |
651 | + :param cwd: optional, passed to `subprocess.Popen`. |
652 | :param universal_newlines: passed to `subprocess.Popen`, defaulting to |
653 | True. |
654 | :return: tuple of returncode, standard output, and standard error. |
655 | @@ -35,6 +47,8 @@ def run_command(command, args=None, input=None, universal_newlines=True): |
656 | stdin=stdin, |
657 | stdout=subprocess.PIPE, |
658 | stderr=subprocess.PIPE, |
659 | + env=env, |
660 | + cwd=cwd, |
661 | universal_newlines=universal_newlines, |
662 | ) |
663 | stdout, stderr = child.communicate(input) |
664 | @@ -42,23 +56,40 @@ def run_command(command, args=None, input=None, universal_newlines=True): |
665 | return (returncode, stdout, stderr) |
666 | |
667 | |
668 | -def run_script(script, args=None, input=None, universal_newlines=True): |
669 | +# XXX cjwatson 2023-02-03: This type could be stricter: the type of `input` |
670 | +# depends on the value of `universal_newlines`. |
671 | +def run_script( |
672 | + script: str, |
673 | + args: Optional[List[str]] = None, |
674 | + env: Optional[Dict[str, str]] = None, |
675 | + cwd: Optional[str] = None, |
676 | + input: Optional[Union[bytes, str]] = None, |
677 | + universal_newlines: bool = True, |
678 | +): |
679 | """Run a Python script in a child process, using current interpreter. |
680 | |
681 | :param script: Python script to run. |
682 | :param args: optional list of command-line arguments. |
683 | + :param env: optional environment dict; if none is given, the script will |
684 | + get a copy of the environment of the calling process. In either |
685 | + case, `PYTHONPATH` is removed since inheriting it may break some |
686 | + scripts. |
687 | + :param env: optional, passed to `subprocess.Popen`. |
688 | + :param cwd: optional, passed to `subprocess.Popen`. |
689 | :param input: optional string to feed to standard input. |
690 | :param universal_newlines: passed to `subprocess.Popen`, defaulting to |
691 | True. |
692 | :return: tuple of return value, standard output, and standard error. |
693 | """ |
694 | - interpreter_args = [script] |
695 | - if args: |
696 | - interpreter_args.extend(args) |
697 | + if env is None: |
698 | + env = os.environ.copy() |
699 | + env.pop("PYTHONPATH", None) |
700 | |
701 | return run_command( |
702 | - sys.executable, |
703 | - interpreter_args, |
704 | - input, |
705 | + script, |
706 | + args=args, |
707 | + env=env, |
708 | + cwd=cwd, |
709 | + input=input, |
710 | universal_newlines=universal_newlines, |
711 | ) |
LGTM 👍