Merge ~cjwatson/launchpad-buildd:refactor-run-build-command into launchpad-buildd:master
- Git
- lp:~cjwatson/launchpad-buildd
- refactor-run-build-command
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | ca5728728945d74a1499726e159ac08a00b645a3 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad-buildd:refactor-run-build-command |
Merge into: | launchpad-buildd:master |
Diff against target: |
688 lines (+153/-297) 12 files modified
lpbuildd/target/build_charm.py (+0/-17) lpbuildd/target/build_livefs.py (+0/-8) lpbuildd/target/build_oci.py (+0/-16) lpbuildd/target/build_snap.py (+0/-15) lpbuildd/target/operation.py (+19/-1) lpbuildd/target/tests/matchers.py (+59/-0) lpbuildd/target/tests/test_build_charm.py (+5/-39) lpbuildd/target/tests/test_build_livefs.py (+5/-58) lpbuildd/target/tests/test_build_oci.py (+5/-43) lpbuildd/target/tests/test_build_snap.py (+6/-70) lpbuildd/target/tests/test_generate_translation_templates.py (+18/-30) lpbuildd/target/tests/test_operation.py (+36/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ioana Lasc (community) | Approve | ||
Review via email: mp+413166@code.launchpad.net |
Commit message
Refactor multiple implementations of operation command helpers
Description of the change
We had several nearly-identical implementations of `run_build_command` and related testtools matchers floating around. Much of launchpad-buildd is glue between other programs, so it makes sense for it to have very careful checks on which subprocesses it runs, but it doesn't need to have quite so much duplicated code in the process; consolidate all these into common locations.
To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lpbuildd/target/build_charm.py b/lpbuildd/target/build_charm.py |
2 | index 23562e0..1bdd807 100644 |
3 | --- a/lpbuildd/target/build_charm.py |
4 | +++ b/lpbuildd/target/build_charm.py |
5 | @@ -5,7 +5,6 @@ from __future__ import print_function |
6 | |
7 | __metaclass__ = type |
8 | |
9 | -from collections import OrderedDict |
10 | import logging |
11 | import os |
12 | |
13 | @@ -49,22 +48,6 @@ class BuildCharm(BuilderProxyOperationMixin, VCSOperationMixin, |
14 | super(BuildCharm, self).__init__(args, parser) |
15 | self.buildd_path = os.path.join("/home/buildd", self.args.name) |
16 | |
17 | - def run_build_command(self, args, env=None, **kwargs): |
18 | - """Run a build command in the target. |
19 | - |
20 | - :param args: the command and arguments to run. |
21 | - :param env: dictionary of additional environment variables to set. |
22 | - :param kwargs: any other keyword arguments to pass to Backend.run. |
23 | - """ |
24 | - full_env = OrderedDict() |
25 | - full_env["LANG"] = "C.UTF-8" |
26 | - full_env["SHELL"] = "/bin/sh" |
27 | - if env: |
28 | - full_env.update(env) |
29 | - cwd = kwargs.pop('cwd', self.buildd_path) |
30 | - return self.backend.run( |
31 | - args, cwd=cwd, env=full_env, **kwargs) |
32 | - |
33 | def install(self): |
34 | logger.info("Running install phase") |
35 | deps = [] |
36 | diff --git a/lpbuildd/target/build_livefs.py b/lpbuildd/target/build_livefs.py |
37 | index 57f61e1..00707ae 100644 |
38 | --- a/lpbuildd/target/build_livefs.py |
39 | +++ b/lpbuildd/target/build_livefs.py |
40 | @@ -81,14 +81,6 @@ class BuildLiveFS(SnapStoreOperationMixin, Operation): |
41 | "--debug", default=False, action="store_true", |
42 | help="enable detailed live-build debugging") |
43 | |
44 | - def run_build_command(self, args, **kwargs): |
45 | - """Run a build command in the chroot. |
46 | - |
47 | - :param args: the command and arguments to run. |
48 | - :param kwargs: any other keyword arguments to pass to Backend.run. |
49 | - """ |
50 | - return self.backend.run(args, cwd="/build", **kwargs) |
51 | - |
52 | def install(self): |
53 | deps = ["livecd-rootfs"] |
54 | if self.args.backend == "lxd": |
55 | diff --git a/lpbuildd/target/build_oci.py b/lpbuildd/target/build_oci.py |
56 | index e328698..896c5a0 100644 |
57 | --- a/lpbuildd/target/build_oci.py |
58 | +++ b/lpbuildd/target/build_oci.py |
59 | @@ -5,7 +5,6 @@ from __future__ import print_function |
60 | |
61 | __metaclass__ = type |
62 | |
63 | -from collections import OrderedDict |
64 | import logging |
65 | import os.path |
66 | import tempfile |
67 | @@ -67,21 +66,6 @@ class BuildOCI(BuilderProxyOperationMixin, VCSOperationMixin, |
68 | systemd_file.flush() |
69 | self.backend.copy_in(systemd_file.name, file_path) |
70 | |
71 | - def run_build_command(self, args, env=None, **kwargs): |
72 | - """Run a build command in the target. |
73 | - |
74 | - :param args: the command and arguments to run. |
75 | - :param env: dictionary of additional environment variables to set. |
76 | - :param kwargs: any other keyword arguments to pass to Backend.run. |
77 | - """ |
78 | - full_env = OrderedDict() |
79 | - full_env["LANG"] = "C.UTF-8" |
80 | - full_env["SHELL"] = "/bin/sh" |
81 | - if env: |
82 | - full_env.update(env) |
83 | - return self.backend.run( |
84 | - args, cwd=self.buildd_path, env=full_env, **kwargs) |
85 | - |
86 | def install(self): |
87 | logger.info("Running install phase...") |
88 | deps = [] |
89 | diff --git a/lpbuildd/target/build_snap.py b/lpbuildd/target/build_snap.py |
90 | index 44e6391..09032e5 100644 |
91 | --- a/lpbuildd/target/build_snap.py |
92 | +++ b/lpbuildd/target/build_snap.py |
93 | @@ -6,7 +6,6 @@ from __future__ import print_function |
94 | __metaclass__ = type |
95 | |
96 | import argparse |
97 | -from collections import OrderedDict |
98 | import json |
99 | import logging |
100 | import os.path |
101 | @@ -80,20 +79,6 @@ class BuildSnap(BuilderProxyOperationMixin, VCSOperationMixin, |
102 | help="build a private snap") |
103 | parser.add_argument("name", help="name of snap to build") |
104 | |
105 | - def run_build_command(self, args, env=None, **kwargs): |
106 | - """Run a build command in the target. |
107 | - |
108 | - :param args: the command and arguments to run. |
109 | - :param env: dictionary of additional environment variables to set. |
110 | - :param kwargs: any other keyword arguments to pass to Backend.run. |
111 | - """ |
112 | - full_env = OrderedDict() |
113 | - full_env["LANG"] = "C.UTF-8" |
114 | - full_env["SHELL"] = "/bin/sh" |
115 | - if env: |
116 | - full_env.update(env) |
117 | - return self.backend.run(args, env=full_env, **kwargs) |
118 | - |
119 | def install_svn_servers(self): |
120 | proxy = urlparse(self.args.proxy_url) |
121 | svn_servers = dedent("""\ |
122 | diff --git a/lpbuildd/target/operation.py b/lpbuildd/target/operation.py |
123 | index 2f9fe64..bbc17cc 100644 |
124 | --- a/lpbuildd/target/operation.py |
125 | +++ b/lpbuildd/target/operation.py |
126 | @@ -1,10 +1,12 @@ |
127 | -# Copyright 2017 Canonical Ltd. This software is licensed under the |
128 | +# Copyright 2017-2021 Canonical Ltd. This software is licensed under the |
129 | # GNU Affero General Public License version 3 (see the file LICENSE). |
130 | |
131 | from __future__ import print_function |
132 | |
133 | __metaclass__ = type |
134 | |
135 | +from collections import OrderedDict |
136 | + |
137 | from lpbuildd.target.backend import make_backend |
138 | |
139 | |
140 | @@ -12,6 +14,7 @@ class Operation: |
141 | """An operation to perform on the target environment.""" |
142 | |
143 | description = "An unidentified operation." |
144 | + buildd_path = "/build" |
145 | |
146 | @classmethod |
147 | def add_arguments(cls, parser): |
148 | @@ -31,5 +34,20 @@ class Operation: |
149 | self.args.backend, self.args.build_id, |
150 | series=self.args.series, arch=self.args.arch) |
151 | |
152 | + def run_build_command(self, args, env=None, **kwargs): |
153 | + """Run a build command in the target. |
154 | + |
155 | + :param args: the command and arguments to run. |
156 | + :param env: dictionary of additional environment variables to set. |
157 | + :param kwargs: any other keyword arguments to pass to Backend.run. |
158 | + """ |
159 | + full_env = OrderedDict() |
160 | + full_env["LANG"] = "C.UTF-8" |
161 | + full_env["SHELL"] = "/bin/sh" |
162 | + if env: |
163 | + full_env.update(env) |
164 | + cwd = kwargs.pop("cwd", self.buildd_path) |
165 | + return self.backend.run(args, cwd=cwd, env=full_env, **kwargs) |
166 | + |
167 | def run(self): |
168 | raise NotImplementedError |
169 | diff --git a/lpbuildd/target/tests/matchers.py b/lpbuildd/target/tests/matchers.py |
170 | new file mode 100644 |
171 | index 0000000..fbecb05 |
172 | --- /dev/null |
173 | +++ b/lpbuildd/target/tests/matchers.py |
174 | @@ -0,0 +1,59 @@ |
175 | +# Copyright 2021 Canonical Ltd. This software is licensed under the |
176 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
177 | + |
178 | +__metaclass__ = type |
179 | + |
180 | +from testtools.matchers import ( |
181 | + Equals, |
182 | + Is, |
183 | + MatchesDict, |
184 | + MatchesListwise, |
185 | + ) |
186 | + |
187 | + |
188 | +class RanCommand(MatchesListwise): |
189 | + |
190 | + def __init__(self, args, echo=None, cwd=None, input_text=None, |
191 | + stdout=None, stderr=None, get_output=None, |
192 | + universal_newlines=None, **env): |
193 | + kwargs_matcher = {} |
194 | + if echo is not None: |
195 | + kwargs_matcher["echo"] = Is(echo) |
196 | + if cwd: |
197 | + kwargs_matcher["cwd"] = Equals(cwd) |
198 | + if input_text: |
199 | + kwargs_matcher["input_text"] = Equals(input_text) |
200 | + if stdout is not None: |
201 | + kwargs_matcher["stdout"] = Equals(stdout) |
202 | + if stderr is not None: |
203 | + kwargs_matcher["stderr"] = Equals(stderr) |
204 | + if get_output is not None: |
205 | + kwargs_matcher["get_output"] = Is(get_output) |
206 | + if universal_newlines is not None: |
207 | + kwargs_matcher["universal_newlines"] = Is(universal_newlines) |
208 | + if env: |
209 | + kwargs_matcher["env"] = MatchesDict( |
210 | + {key: Equals(value) for key, value in env.items()}) |
211 | + super(RanCommand, self).__init__( |
212 | + [Equals((args,)), MatchesDict(kwargs_matcher)]) |
213 | + |
214 | + |
215 | +class RanAptGet(RanCommand): |
216 | + |
217 | + def __init__(self, *args): |
218 | + super(RanAptGet, self).__init__(["apt-get", "-y"] + list(args)) |
219 | + |
220 | + |
221 | +class RanSnap(RanCommand): |
222 | + |
223 | + def __init__(self, *args): |
224 | + super(RanSnap, self).__init__(["snap"] + list(args)) |
225 | + |
226 | + |
227 | +class RanBuildCommand(RanCommand): |
228 | + |
229 | + def __init__(self, args, **kwargs): |
230 | + kwargs.setdefault("cwd", "/build") |
231 | + kwargs.setdefault("LANG", "C.UTF-8") |
232 | + kwargs.setdefault("SHELL", "/bin/sh") |
233 | + super(RanBuildCommand, self).__init__(args, **kwargs) |
234 | diff --git a/lpbuildd/target/tests/test_build_charm.py b/lpbuildd/target/tests/test_build_charm.py |
235 | index a095f8b..cd4ebca 100644 |
236 | --- a/lpbuildd/target/tests/test_build_charm.py |
237 | +++ b/lpbuildd/target/tests/test_build_charm.py |
238 | @@ -17,10 +17,7 @@ import responses |
239 | from systemfixtures import FakeFilesystem |
240 | from testtools.matchers import ( |
241 | AnyMatch, |
242 | - Equals, |
243 | - Is, |
244 | MatchesAll, |
245 | - MatchesDict, |
246 | MatchesListwise, |
247 | ) |
248 | from testtools.testcase import TestCase |
249 | @@ -36,42 +33,11 @@ from lpbuildd.target.tests.test_build_snap import ( |
250 | RanSnap, |
251 | ) |
252 | from lpbuildd.target.cli import parse_args |
253 | - |
254 | - |
255 | -class RanCommand(MatchesListwise): |
256 | - |
257 | - def __init__(self, args, echo=None, cwd=None, input_text=None, |
258 | - get_output=None, universal_newlines=None, **env): |
259 | - kwargs_matcher = {} |
260 | - if echo is not None: |
261 | - kwargs_matcher["echo"] = Is(echo) |
262 | - if cwd: |
263 | - kwargs_matcher["cwd"] = Equals(cwd) |
264 | - if input_text: |
265 | - kwargs_matcher["input_text"] = Equals(input_text) |
266 | - if get_output is not None: |
267 | - kwargs_matcher["get_output"] = Is(get_output) |
268 | - if universal_newlines is not None: |
269 | - kwargs_matcher["universal_newlines"] = Is(universal_newlines) |
270 | - if env: |
271 | - kwargs_matcher["env"] = MatchesDict( |
272 | - {key: Equals(value) for key, value in env.items()}) |
273 | - super(RanCommand, self).__init__( |
274 | - [Equals((args,)), MatchesDict(kwargs_matcher)]) |
275 | - |
276 | - |
277 | -class RanAptGet(RanCommand): |
278 | - |
279 | - def __init__(self, *args): |
280 | - super(RanAptGet, self).__init__(["apt-get", "-y"] + list(args)) |
281 | - |
282 | - |
283 | -class RanBuildCommand(RanCommand): |
284 | - |
285 | - def __init__(self, args, **kwargs): |
286 | - kwargs.setdefault("LANG", "C.UTF-8") |
287 | - kwargs.setdefault("SHELL", "/bin/sh") |
288 | - super(RanBuildCommand, self).__init__(args, **kwargs) |
289 | +from lpbuildd.target.tests.matchers import ( |
290 | + RanAptGet, |
291 | + RanBuildCommand, |
292 | + RanCommand, |
293 | + ) |
294 | |
295 | |
296 | class TestBuildCharm(TestCase): |
297 | diff --git a/lpbuildd/target/tests/test_build_livefs.py b/lpbuildd/target/tests/test_build_livefs.py |
298 | index 06ae149..2fb2b19 100644 |
299 | --- a/lpbuildd/target/tests/test_build_livefs.py |
300 | +++ b/lpbuildd/target/tests/test_build_livefs.py |
301 | @@ -11,10 +11,7 @@ import responses |
302 | from testtools import TestCase |
303 | from testtools.matchers import ( |
304 | AnyMatch, |
305 | - Equals, |
306 | - Is, |
307 | MatchesAll, |
308 | - MatchesDict, |
309 | MatchesListwise, |
310 | ) |
311 | |
312 | @@ -23,66 +20,16 @@ from lpbuildd.target.build_livefs import ( |
313 | RETCODE_FAILURE_INSTALL, |
314 | ) |
315 | from lpbuildd.target.cli import parse_args |
316 | +from lpbuildd.target.tests.matchers import ( |
317 | + RanAptGet, |
318 | + RanBuildCommand, |
319 | + RanCommand, |
320 | + ) |
321 | from lpbuildd.tests.fakebuilder import FakeMethod |
322 | |
323 | |
324 | -class RanCommand(MatchesListwise): |
325 | - |
326 | - def __init__(self, args, echo=None, cwd=None, input_text=None, |
327 | - get_output=None, **env): |
328 | - kwargs_matcher = {} |
329 | - if echo is not None: |
330 | - kwargs_matcher["echo"] = Is(echo) |
331 | - if cwd: |
332 | - kwargs_matcher["cwd"] = Equals(cwd) |
333 | - if input_text: |
334 | - kwargs_matcher["input_text"] = Equals(input_text) |
335 | - if get_output is not None: |
336 | - kwargs_matcher["get_output"] = Is(get_output) |
337 | - if env: |
338 | - kwargs_matcher["env"] = MatchesDict( |
339 | - {key: Equals(value) for key, value in env.items()}) |
340 | - super(RanCommand, self).__init__( |
341 | - [Equals((args,)), MatchesDict(kwargs_matcher)]) |
342 | - |
343 | - |
344 | -class RanAptGet(RanCommand): |
345 | - |
346 | - def __init__(self, *args): |
347 | - super(RanAptGet, self).__init__(["apt-get", "-y"] + list(args)) |
348 | - |
349 | - |
350 | -class RanBuildCommand(RanCommand): |
351 | - |
352 | - def __init__(self, args, **kwargs): |
353 | - super(RanBuildCommand, self).__init__(args, cwd="/build", **kwargs) |
354 | - |
355 | - |
356 | class TestBuildLiveFS(TestCase): |
357 | |
358 | - def test_run_build_command_no_env(self): |
359 | - args = [ |
360 | - "buildlivefs", |
361 | - "--backend=fake", "--series=xenial", "--arch=amd64", "1", |
362 | - ] |
363 | - build_livefs = parse_args(args=args).operation |
364 | - build_livefs.run_build_command(["echo", "hello world"]) |
365 | - self.assertThat(build_livefs.backend.run.calls, MatchesListwise([ |
366 | - RanBuildCommand(["echo", "hello world"]), |
367 | - ])) |
368 | - |
369 | - def test_run_build_command_env(self): |
370 | - args = [ |
371 | - "buildlivefs", |
372 | - "--backend=fake", "--series=xenial", "--arch=amd64", "1", |
373 | - ] |
374 | - build_livefs = parse_args(args=args).operation |
375 | - build_livefs.run_build_command( |
376 | - ["echo", "hello world"], env={"FOO": "bar baz"}) |
377 | - self.assertThat(build_livefs.backend.run.calls, MatchesListwise([ |
378 | - RanBuildCommand(["echo", "hello world"], FOO="bar baz"), |
379 | - ])) |
380 | - |
381 | def test_install(self): |
382 | args = [ |
383 | "buildlivefs", |
384 | diff --git a/lpbuildd/target/tests/test_build_oci.py b/lpbuildd/target/tests/test_build_oci.py |
385 | index 3a9a12e..199d3b3 100644 |
386 | --- a/lpbuildd/target/tests/test_build_oci.py |
387 | +++ b/lpbuildd/target/tests/test_build_oci.py |
388 | @@ -17,10 +17,7 @@ from systemfixtures import FakeFilesystem |
389 | from testtools import TestCase |
390 | from testtools.matchers import ( |
391 | AnyMatch, |
392 | - Equals, |
393 | - Is, |
394 | MatchesAll, |
395 | - MatchesDict, |
396 | MatchesListwise, |
397 | ) |
398 | |
399 | @@ -30,49 +27,14 @@ from lpbuildd.target.build_oci import ( |
400 | RETCODE_FAILURE_INSTALL, |
401 | ) |
402 | from lpbuildd.target.cli import parse_args |
403 | +from lpbuildd.target.tests.matchers import ( |
404 | + RanAptGet, |
405 | + RanBuildCommand, |
406 | + RanCommand, |
407 | + ) |
408 | from lpbuildd.tests.fakebuilder import FakeMethod |
409 | |
410 | |
411 | -class RanCommand(MatchesListwise): |
412 | - |
413 | - def __init__(self, args, echo=None, cwd=None, input_text=None, |
414 | - get_output=None, **env): |
415 | - kwargs_matcher = {} |
416 | - if echo is not None: |
417 | - kwargs_matcher["echo"] = Is(echo) |
418 | - if cwd: |
419 | - kwargs_matcher["cwd"] = Equals(cwd) |
420 | - if input_text: |
421 | - kwargs_matcher["input_text"] = Equals(input_text) |
422 | - if get_output is not None: |
423 | - kwargs_matcher["get_output"] = Is(get_output) |
424 | - if env: |
425 | - kwargs_matcher["env"] = MatchesDict( |
426 | - {key: Equals(value) for key, value in env.items()}) |
427 | - super(RanCommand, self).__init__( |
428 | - [Equals((args,)), MatchesDict(kwargs_matcher)]) |
429 | - |
430 | - |
431 | -class RanAptGet(RanCommand): |
432 | - |
433 | - def __init__(self, *args): |
434 | - super(RanAptGet, self).__init__(["apt-get", "-y"] + list(args)) |
435 | - |
436 | - |
437 | -class RanSnap(RanCommand): |
438 | - |
439 | - def __init__(self, *args, **kwargs): |
440 | - super(RanSnap, self).__init__(["snap"] + list(args), **kwargs) |
441 | - |
442 | - |
443 | -class RanBuildCommand(RanCommand): |
444 | - |
445 | - def __init__(self, args, **kwargs): |
446 | - kwargs.setdefault("LANG", "C.UTF-8") |
447 | - kwargs.setdefault("SHELL", "/bin/sh") |
448 | - super(RanBuildCommand, self).__init__(args, **kwargs) |
449 | - |
450 | - |
451 | class TestBuildOCI(TestCase): |
452 | |
453 | def test_run_build_command_no_env(self): |
454 | diff --git a/lpbuildd/target/tests/test_build_snap.py b/lpbuildd/target/tests/test_build_snap.py |
455 | index 52b1867..2bda8bb 100644 |
456 | --- a/lpbuildd/target/tests/test_build_snap.py |
457 | +++ b/lpbuildd/target/tests/test_build_snap.py |
458 | @@ -18,10 +18,7 @@ from systemfixtures import FakeFilesystem |
459 | from testtools import TestCase |
460 | from testtools.matchers import ( |
461 | AnyMatch, |
462 | - Equals, |
463 | - Is, |
464 | MatchesAll, |
465 | - MatchesDict, |
466 | MatchesListwise, |
467 | ) |
468 | |
469 | @@ -30,51 +27,15 @@ from lpbuildd.target.build_snap import ( |
470 | RETCODE_FAILURE_INSTALL, |
471 | ) |
472 | from lpbuildd.target.cli import parse_args |
473 | +from lpbuildd.target.tests.matchers import ( |
474 | + RanAptGet, |
475 | + RanBuildCommand, |
476 | + RanCommand, |
477 | + RanSnap, |
478 | + ) |
479 | from lpbuildd.tests.fakebuilder import FakeMethod |
480 | |
481 | |
482 | -class RanCommand(MatchesListwise): |
483 | - |
484 | - def __init__(self, args, echo=None, cwd=None, input_text=None, |
485 | - get_output=None, universal_newlines=None, **env): |
486 | - kwargs_matcher = {} |
487 | - if echo is not None: |
488 | - kwargs_matcher["echo"] = Is(echo) |
489 | - if cwd: |
490 | - kwargs_matcher["cwd"] = Equals(cwd) |
491 | - if input_text: |
492 | - kwargs_matcher["input_text"] = Equals(input_text) |
493 | - if get_output is not None: |
494 | - kwargs_matcher["get_output"] = Is(get_output) |
495 | - if universal_newlines is not None: |
496 | - kwargs_matcher["universal_newlines"] = Is(universal_newlines) |
497 | - if env: |
498 | - kwargs_matcher["env"] = MatchesDict( |
499 | - {key: Equals(value) for key, value in env.items()}) |
500 | - super(RanCommand, self).__init__( |
501 | - [Equals((args,)), MatchesDict(kwargs_matcher)]) |
502 | - |
503 | - |
504 | -class RanAptGet(RanCommand): |
505 | - |
506 | - def __init__(self, *args): |
507 | - super(RanAptGet, self).__init__(["apt-get", "-y"] + list(args)) |
508 | - |
509 | - |
510 | -class RanSnap(RanCommand): |
511 | - |
512 | - def __init__(self, *args): |
513 | - super(RanSnap, self).__init__(["snap"] + list(args)) |
514 | - |
515 | - |
516 | -class RanBuildCommand(RanCommand): |
517 | - |
518 | - def __init__(self, args, **kwargs): |
519 | - kwargs.setdefault("LANG", "C.UTF-8") |
520 | - kwargs.setdefault("SHELL", "/bin/sh") |
521 | - super(RanBuildCommand, self).__init__(args, **kwargs) |
522 | - |
523 | - |
524 | class FakeRevisionID(FakeMethod): |
525 | |
526 | def __init__(self, revision_id): |
527 | @@ -90,31 +51,6 @@ class FakeRevisionID(FakeMethod): |
528 | |
529 | class TestBuildSnap(TestCase): |
530 | |
531 | - def test_run_build_command_no_env(self): |
532 | - args = [ |
533 | - "buildsnap", |
534 | - "--backend=fake", "--series=xenial", "--arch=amd64", "1", |
535 | - "--branch", "lp:foo", "test-snap", |
536 | - ] |
537 | - build_snap = parse_args(args=args).operation |
538 | - build_snap.run_build_command(["echo", "hello world"]) |
539 | - self.assertThat(build_snap.backend.run.calls, MatchesListwise([ |
540 | - RanBuildCommand(["echo", "hello world"]), |
541 | - ])) |
542 | - |
543 | - def test_run_build_command_env(self): |
544 | - args = [ |
545 | - "buildsnap", |
546 | - "--backend=fake", "--series=xenial", "--arch=amd64", "1", |
547 | - "--branch", "lp:foo", "test-snap", |
548 | - ] |
549 | - build_snap = parse_args(args=args).operation |
550 | - build_snap.run_build_command( |
551 | - ["echo", "hello world"], env={"FOO": "bar baz"}) |
552 | - self.assertThat(build_snap.backend.run.calls, MatchesListwise([ |
553 | - RanBuildCommand(["echo", "hello world"], FOO="bar baz"), |
554 | - ])) |
555 | - |
556 | def test_install_bzr(self): |
557 | args = [ |
558 | "buildsnap", |
559 | diff --git a/lpbuildd/target/tests/test_generate_translation_templates.py b/lpbuildd/target/tests/test_generate_translation_templates.py |
560 | index 12ec2b3..d9dfe38 100644 |
561 | --- a/lpbuildd/target/tests/test_generate_translation_templates.py |
562 | +++ b/lpbuildd/target/tests/test_generate_translation_templates.py |
563 | @@ -6,6 +6,10 @@ __metaclass__ = type |
564 | import os |
565 | import subprocess |
566 | import tarfile |
567 | +try: |
568 | + from unittest import mock |
569 | +except ImportError: |
570 | + import mock |
571 | |
572 | from fixtures import ( |
573 | EnvironmentVariable, |
574 | @@ -14,38 +18,16 @@ from fixtures import ( |
575 | ) |
576 | from testtools import TestCase |
577 | from testtools.matchers import ( |
578 | - ContainsDict, |
579 | Equals, |
580 | - Is, |
581 | - MatchesDict, |
582 | MatchesListwise, |
583 | MatchesSetwise, |
584 | ) |
585 | |
586 | from lpbuildd.target.cli import parse_args |
587 | - |
588 | - |
589 | -class RanCommand(MatchesListwise): |
590 | - |
591 | - def __init__(self, args, get_output=None, echo=None, cwd=None, **env): |
592 | - kwargs_matcher = {} |
593 | - if get_output is not None: |
594 | - kwargs_matcher["get_output"] = Is(get_output) |
595 | - if echo is not None: |
596 | - kwargs_matcher["echo"] = Is(echo) |
597 | - if cwd: |
598 | - kwargs_matcher["cwd"] = Equals(cwd) |
599 | - if env: |
600 | - kwargs_matcher["env"] = MatchesDict( |
601 | - {key: Equals(value) for key, value in env.items()}) |
602 | - super(RanCommand, self).__init__( |
603 | - [Equals((args,)), ContainsDict(kwargs_matcher)]) |
604 | - |
605 | - |
606 | -class RanAptGet(RanCommand): |
607 | - |
608 | - def __init__(self, *args): |
609 | - super(RanAptGet, self).__init__(["apt-get", "-y"] + list(args)) |
610 | +from lpbuildd.target.tests.matchers import ( |
611 | + RanAptGet, |
612 | + RanCommand, |
613 | + ) |
614 | |
615 | |
616 | class TestGenerateTranslationTemplates(TestCase): |
617 | @@ -234,9 +216,12 @@ class TestGenerateTranslationTemplates(TestCase): |
618 | ["rm", "-f", |
619 | os.path.join(po_dir, "missing"), |
620 | os.path.join(po_dir, "notexist")]), |
621 | - RanCommand(["/usr/bin/intltool-update", "-m"], cwd=po_dir), |
622 | RanCommand( |
623 | - ["/usr/bin/intltool-update", "-p", "-g", "test"], cwd=po_dir), |
624 | + ["/usr/bin/intltool-update", "-m"], |
625 | + stdout=mock.ANY, stderr=mock.ANY, cwd=po_dir), |
626 | + RanCommand( |
627 | + ["/usr/bin/intltool-update", "-p", "-g", "test"], |
628 | + stdout=mock.ANY, stderr=mock.ANY, cwd=po_dir), |
629 | RanCommand( |
630 | ["tar", "-C", branch_dir, "-czf", result_path, "po/test.pot"]), |
631 | ])) |
632 | @@ -270,9 +255,12 @@ class TestGenerateTranslationTemplates(TestCase): |
633 | ["rm", "-f", |
634 | os.path.join(po_dir, "missing"), |
635 | os.path.join(po_dir, "notexist")]), |
636 | - RanCommand(["/usr/bin/intltool-update", "-m"], cwd=po_dir), |
637 | RanCommand( |
638 | - ["/usr/bin/intltool-update", "-p", "-g", "test"], cwd=po_dir), |
639 | + ["/usr/bin/intltool-update", "-m"], |
640 | + stdout=mock.ANY, stderr=mock.ANY, cwd=po_dir), |
641 | + RanCommand( |
642 | + ["/usr/bin/intltool-update", "-p", "-g", "test"], |
643 | + stdout=mock.ANY, stderr=mock.ANY, cwd=po_dir), |
644 | RanCommand( |
645 | ["tar", "-C", branch_dir, "-czf", result_path, "po/test.pot"]), |
646 | ])) |
647 | diff --git a/lpbuildd/target/tests/test_operation.py b/lpbuildd/target/tests/test_operation.py |
648 | new file mode 100644 |
649 | index 0000000..00ee29a |
650 | --- /dev/null |
651 | +++ b/lpbuildd/target/tests/test_operation.py |
652 | @@ -0,0 +1,36 @@ |
653 | +# Copyright 2017-2021 Canonical Ltd. This software is licensed under the |
654 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
655 | + |
656 | +__metaclass__ = type |
657 | + |
658 | +from argparse import ArgumentParser |
659 | + |
660 | +from testtools import TestCase |
661 | +from testtools.matchers import MatchesListwise |
662 | + |
663 | +from lpbuildd.target.operation import Operation |
664 | +from lpbuildd.target.tests.matchers import RanBuildCommand |
665 | + |
666 | + |
667 | +class TestOperation(TestCase): |
668 | + |
669 | + def test_run_build_command_no_env(self): |
670 | + parser = ArgumentParser() |
671 | + Operation.add_arguments(parser) |
672 | + args = ["--backend=fake", "--series=xenial", "--arch=amd64", "1"] |
673 | + operation = Operation(parser.parse_args(args=args), parser) |
674 | + operation.run_build_command(["echo", "hello world"]) |
675 | + self.assertThat(operation.backend.run.calls, MatchesListwise([ |
676 | + RanBuildCommand(["echo", "hello world"]), |
677 | + ])) |
678 | + |
679 | + def test_run_build_command_env(self): |
680 | + parser = ArgumentParser() |
681 | + Operation.add_arguments(parser) |
682 | + args = ["--backend=fake", "--series=xenial", "--arch=amd64", "1"] |
683 | + operation = Operation(parser.parse_args(args=args), parser) |
684 | + operation.run_build_command( |
685 | + ["echo", "hello world"], env={"FOO": "bar baz"}) |
686 | + self.assertThat(operation.backend.run.calls, MatchesListwise([ |
687 | + RanBuildCommand(["echo", "hello world"], FOO="bar baz"), |
688 | + ])) |