Merge ~cjwatson/launchpad-buildd:refactor-run-build-command into launchpad-buildd: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)
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
1diff --git a/lpbuildd/target/build_charm.py b/lpbuildd/target/build_charm.py
2index 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 = []
36diff --git a/lpbuildd/target/build_livefs.py b/lpbuildd/target/build_livefs.py
37index 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":
55diff --git a/lpbuildd/target/build_oci.py b/lpbuildd/target/build_oci.py
56index 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 = []
89diff --git a/lpbuildd/target/build_snap.py b/lpbuildd/target/build_snap.py
90index 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("""\
122diff --git a/lpbuildd/target/operation.py b/lpbuildd/target/operation.py
123index 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
169diff --git a/lpbuildd/target/tests/matchers.py b/lpbuildd/target/tests/matchers.py
170new file mode 100644
171index 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)
234diff --git a/lpbuildd/target/tests/test_build_charm.py b/lpbuildd/target/tests/test_build_charm.py
235index 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):
297diff --git a/lpbuildd/target/tests/test_build_livefs.py b/lpbuildd/target/tests/test_build_livefs.py
298index 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",
384diff --git a/lpbuildd/target/tests/test_build_oci.py b/lpbuildd/target/tests/test_build_oci.py
385index 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):
454diff --git a/lpbuildd/target/tests/test_build_snap.py b/lpbuildd/target/tests/test_build_snap.py
455index 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",
559diff --git a/lpbuildd/target/tests/test_generate_translation_templates.py b/lpbuildd/target/tests/test_generate_translation_templates.py
560index 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 ]))
647diff --git a/lpbuildd/target/tests/test_operation.py b/lpbuildd/target/tests/test_operation.py
648new file mode 100644
649index 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+ ]))

Subscribers

People subscribed via source and target branches