Merge lp:~cjwatson/launchpad-buildd/gather-results-via-backend into lp:launchpad-buildd

Proposed by Colin Watson
Status: Merged
Merged at revision: 259
Proposed branch: lp:~cjwatson/launchpad-buildd/gather-results-via-backend
Merge into: lp:launchpad-buildd
Prerequisite: lp:~cjwatson/launchpad-buildd/fake-backend
Diff against target: 737 lines (+287/-90)
13 files modified
lpbuildd/livefs.py (+5/-11)
lpbuildd/slave.py (+11/-0)
lpbuildd/snap.py (+5/-11)
lpbuildd/target/apt.py (+2/-0)
lpbuildd/target/backend.py (+54/-1)
lpbuildd/target/chroot.py (+18/-5)
lpbuildd/target/tests/test_apt.py (+5/-4)
lpbuildd/target/tests/test_chroot.py (+91/-0)
lpbuildd/tests/fakeslave.py (+50/-2)
lpbuildd/tests/test_livefs.py (+15/-18)
lpbuildd/tests/test_snap.py (+15/-20)
lpbuildd/tests/test_translationtemplatesbuildmanager.py (+13/-12)
lpbuildd/translationtemplates.py (+3/-6)
To merge this branch: bzr merge lp:~cjwatson/launchpad-buildd/gather-results-via-backend
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+328624@code.launchpad.net

Commit message

Gather results via the backend abstraction rather than by direct filesystem access.

Description of the change

Current exceptions are binarypackage (because sbuild handles its own backend access) and sourcepackagerecipe (which needs some further refactoring first).

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)
258. By Colin Watson

Merge trunk.

259. By Colin Watson

Preserve timestamps in Chroot.copy_out, but not ownership/permissions.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lpbuildd/livefs.py'
2--- lpbuildd/livefs.py 2017-07-28 13:57:47 +0000
3+++ lpbuildd/livefs.py 2017-08-22 16:03:15 +0000
4@@ -4,12 +4,10 @@
5 __metaclass__ = type
6
7 import os
8-import shutil
9
10 from lpbuildd.debian import (
11 DebianBuildManager,
12 DebianBuildState,
13- get_build_path,
14 )
15
16
17@@ -33,11 +31,6 @@
18
19 def initiate(self, files, chroot, extra_args):
20 """Initiate a build with a given set of files and chroot."""
21- self.build_path = get_build_path(
22- self.home, self._buildid, "chroot-autobuild", "build")
23- if os.path.isdir(self.build_path):
24- shutil.rmtree(self.build_path)
25-
26 self.subarch = extra_args.get("subarch")
27 self.project = extra_args["project"]
28 self.subproject = extra_args.get("subproject")
29@@ -100,7 +93,8 @@
30
31 def gatherResults(self):
32 """Gather the results of the build and add them to the file cache."""
33- for entry in sorted(os.listdir(self.build_path)):
34- path = os.path.join(self.build_path, entry)
35- if entry.startswith("livecd.") and not os.path.islink(path):
36- self._slave.addWaitingFile(path)
37+ for entry in sorted(self.backend.listdir("/build")):
38+ path = os.path.join("/build", entry)
39+ if (entry.startswith("livecd.") and
40+ not self.backend.islink(path)):
41+ self.addWaitingFileFromBackend(path)
42
43=== modified file 'lpbuildd/slave.py'
44--- lpbuildd/slave.py 2017-08-22 14:46:10 +0000
45+++ lpbuildd/slave.py 2017-08-22 16:03:15 +0000
46@@ -12,6 +12,8 @@
47 import hashlib
48 import os
49 import re
50+import shutil
51+import tempfile
52 import urllib2
53 import xmlrpclib
54
55@@ -307,6 +309,15 @@
56 self._subprocess.ignore = True
57 self._subprocess.transport.loseConnection()
58
59+ def addWaitingFileFromBackend(self, path):
60+ fetched_dir = tempfile.mkdtemp()
61+ try:
62+ fetched_path = os.path.join(fetched_dir, os.path.basename(path))
63+ self.backend.copy_out(path, fetched_path)
64+ self._slave.addWaitingFile(fetched_path)
65+ finally:
66+ shutil.rmtree(fetched_dir)
67+
68
69 class BuilderStatus:
70 """Status values for the builder."""
71
72=== modified file 'lpbuildd/snap.py'
73--- lpbuildd/snap.py 2017-04-03 12:30:15 +0000
74+++ lpbuildd/snap.py 2017-08-22 16:03:15 +0000
75@@ -7,7 +7,6 @@
76
77 import json
78 import os
79-import shutil
80 import sys
81
82 from lpbuildd.debian import (
83@@ -41,11 +40,6 @@
84
85 def initiate(self, files, chroot, extra_args):
86 """Initiate a build with a given set of files and chroot."""
87- self.build_path = get_build_path(
88- self.home, self._buildid, "chroot-autobuild", "build")
89- if os.path.isdir(self.build_path):
90- shutil.rmtree(self.build_path)
91-
92 self.name = extra_args["name"]
93 self.branch = extra_args.get("branch")
94 self.git_repository = extra_args.get("git_repository")
95@@ -113,12 +107,12 @@
96
97 def gatherResults(self):
98 """Gather the results of the build and add them to the file cache."""
99- output_path = os.path.join(self.build_path, self.name)
100- if not os.path.exists(output_path):
101+ output_path = os.path.join("/build", self.name)
102+ if not self.backend.path_exists(output_path):
103 return
104- for entry in sorted(os.listdir(output_path)):
105+ for entry in sorted(self.backend.listdir(output_path)):
106 path = os.path.join(output_path, entry)
107- if os.path.islink(path):
108+ if self.backend.islink(path):
109 continue
110 if entry.endswith(".snap") or entry.endswith(".manifest"):
111- self._slave.addWaitingFile(path)
112+ self.addWaitingFileFromBackend(path)
113
114=== modified file 'lpbuildd/target/apt.py'
115--- lpbuildd/target/apt.py 2017-08-22 13:48:08 +0000
116+++ lpbuildd/target/apt.py 2017-08-22 16:03:15 +0000
117@@ -6,6 +6,7 @@
118 __metaclass__ = type
119
120 import logging
121+import os
122 import subprocess
123 import sys
124 import tempfile
125@@ -34,6 +35,7 @@
126 for archive in self.args.archives:
127 print(archive, file=sources_list)
128 sources_list.flush()
129+ os.fchmod(sources_list.fileno(), 0o644)
130 self.backend.copy_in(sources_list.name, "/etc/apt/sources.list")
131 return 0
132
133
134=== modified file 'lpbuildd/target/backend.py'
135--- lpbuildd/target/backend.py 2017-08-22 15:09:09 +0000
136+++ lpbuildd/target/backend.py 2017-08-22 16:03:15 +0000
137@@ -36,12 +36,14 @@
138 """
139 raise NotImplementedError
140
141- def run(self, args, env=None, input_text=None, **kwargs):
142+ def run(self, args, env=None, input_text=None, get_output=False,
143+ **kwargs):
144 """Run a command in the target environment.
145
146 :param args: the command and arguments to run.
147 :param env: additional environment variables to set.
148 :param input_text: input text to pass on the command's stdin.
149+ :param get_output: if True, return the output from the command.
150 :param kwargs: additional keyword arguments for `subprocess.Popen`.
151 """
152 raise NotImplementedError
153@@ -60,6 +62,57 @@
154 """
155 raise NotImplementedError
156
157+ def copy_out(self, source_path, target_path):
158+ """Copy a file out of the target environment.
159+
160+ The target file will have the same permission mode as the source
161+ file.
162+
163+ :param source_path: the path to the file that should be copied,
164+ relative to the target environment's root.
165+ :param target_path: the path where the file should be installed in
166+ the host system.
167+ """
168+ raise NotImplementedError
169+
170+ def path_exists(self, path):
171+ """Test whether a path exists in the target environment.
172+
173+ :param path: the path to the file to test, relative to the target
174+ environment's root.
175+ """
176+ try:
177+ self.run(["test", "-e", path])
178+ return True
179+ except subprocess.CalledProcessError:
180+ return False
181+
182+ def islink(self, path):
183+ """Test whether a file is a symbolic link in the target environment.
184+
185+ :param path: the path to the file to test, relative to the target
186+ environment's root.
187+ """
188+ try:
189+ self.run(["test", "-h", path])
190+ return True
191+ except subprocess.CalledProcessError:
192+ return False
193+
194+ def listdir(self, path):
195+ """List a directory in the target environment.
196+
197+ :param path: the path to the directory to list, relative to the
198+ target environment's root.
199+ """
200+ paths = self.run(
201+ ["find", path, "-mindepth", "1", "-maxdepth", "1",
202+ "-printf", "%P\\0"],
203+ get_output=True).rstrip(b"\0").split(b"\0")
204+ # XXX cjwatson 2017-08-04: Use `os.fsdecode` instead once we're on
205+ # Python 3.
206+ return [path.decode("UTF-8") for path in paths]
207+
208 def kill_processes(self):
209 """Kill any processes left running in the target.
210
211
212=== modified file 'lpbuildd/target/chroot.py'
213--- lpbuildd/target/chroot.py 2017-08-04 13:08:31 +0000
214+++ lpbuildd/target/chroot.py 2017-08-22 16:03:15 +0000
215@@ -52,7 +52,8 @@
216 for path in ("/etc/hosts", "/etc/hostname", "/etc/resolv.conf"):
217 self.copy_in(path, path)
218
219- def run(self, args, env=None, input_text=None, **kwargs):
220+ def run(self, args, env=None, input_text=None, get_output=False,
221+ **kwargs):
222 """See `Backend`."""
223 if env:
224 args = ["env"] + [
225@@ -61,14 +62,17 @@
226 if self.arch is not None:
227 args = set_personality(args, self.arch, series=self.series)
228 cmd = ["sudo", "/usr/sbin/chroot", self.chroot_path] + args
229- if input_text is None:
230+ if input_text is None and not get_output:
231 subprocess.check_call(cmd, cwd=self.chroot_path, **kwargs)
232 else:
233- proc = subprocess.Popen(
234- cmd, stdin=subprocess.PIPE, universal_newlines=True, **kwargs)
235- proc.communicate(input_text)
236+ if get_output:
237+ kwargs["stdout"] = subprocess.PIPE
238+ proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, **kwargs)
239+ output, _ = proc.communicate(input_text)
240 if proc.returncode:
241 raise subprocess.CalledProcessError(proc.returncode, cmd)
242+ if get_output:
243+ return output
244
245 def copy_in(self, source_path, target_path):
246 """See `Backend`."""
247@@ -82,6 +86,15 @@
248 ["sudo", "install", "-o", "root", "-g", "root", "-m", "%o" % mode,
249 source_path, full_target_path])
250
251+ def copy_out(self, source_path, target_path):
252+ # We can just use a plain copy here, since the file ownership in the
253+ # host system isn't important.
254+ full_source_path = os.path.join(
255+ self.chroot_path, source_path.lstrip("/"))
256+ subprocess.check_call(
257+ ["sudo", "cp", "--preserve=timestamps",
258+ full_source_path, target_path])
259+
260 def kill_processes(self):
261 """See `Backend`."""
262 prefix = os.path.realpath(self.chroot_path)
263
264=== modified file 'lpbuildd/target/tests/test_apt.py'
265--- lpbuildd/target/tests/test_apt.py 2017-08-22 15:09:09 +0000
266+++ lpbuildd/target/tests/test_apt.py 2017-08-22 16:03:15 +0000
267@@ -4,6 +4,7 @@
268 __metaclass__ = type
269
270 import io
271+import stat
272 import subprocess
273 from textwrap import dedent
274 import time
275@@ -45,12 +46,12 @@
276 ]
277 override_sources_list = parse_args(args=args).operation
278 self.assertEqual(0, override_sources_list.run())
279- self.assertEqual({
280- "/etc/apt/sources.list": dedent("""\
281+ self.assertEqual(
282+ (dedent("""\
283 deb http://archive.ubuntu.com/ubuntu xenial main
284 deb http://ppa.launchpad.net/launchpad/ppa/ubuntu xenial main
285- """).encode("UTF-8"),
286- }, override_sources_list.backend.copied_in)
287+ """).encode("UTF-8"), stat.S_IFREG | 0o644),
288+ override_sources_list.backend.backend_fs["/etc/apt/sources.list"])
289
290
291 class TestAddTrustedKeys(TestCase):
292
293=== modified file 'lpbuildd/target/tests/test_chroot.py'
294--- lpbuildd/target/tests/test_chroot.py 2017-08-04 13:08:31 +0000
295+++ lpbuildd/target/tests/test_chroot.py 2017-08-22 16:03:15 +0000
296@@ -3,6 +3,7 @@
297
298 __metaclass__ = type
299
300+import io
301 import os.path
302 import signal
303 from textwrap import dedent
304@@ -97,6 +98,25 @@
305 expected_args,
306 [proc._args["args"] for proc in processes_fixture.procs])
307
308+ def test_run_get_output(self):
309+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
310+ processes_fixture = self.useFixture(FakeProcesses())
311+ processes_fixture.add(
312+ lambda _: {"stdout": io.BytesIO(b"hello\n")}, name="sudo")
313+ self.assertEqual(
314+ "hello\n",
315+ Chroot("1", "xenial", "amd64").run(
316+ ["echo", "hello"], get_output=True))
317+
318+ expected_args = [
319+ ["sudo", "/usr/sbin/chroot",
320+ "/expected/home/build-1/chroot-autobuild",
321+ "linux64", "echo", "hello"],
322+ ]
323+ self.assertEqual(
324+ expected_args,
325+ [proc._args["args"] for proc in processes_fixture.procs])
326+
327 def test_copy_in(self):
328 self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
329 source_dir = self.useFixture(TempDir()).path
330@@ -119,6 +139,77 @@
331 expected_args,
332 [proc._args["args"] for proc in processes_fixture.procs])
333
334+ def test_copy_out(self):
335+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
336+ processes_fixture = self.useFixture(FakeProcesses())
337+ processes_fixture.add(lambda _: {}, name="sudo")
338+ Chroot("1", "xenial", "amd64").copy_out(
339+ "/path/to/source", "/path/to/target")
340+
341+ expected_args = [
342+ ["sudo", "cp", "--preserve=timestamps",
343+ "/expected/home/build-1/chroot-autobuild/path/to/source",
344+ "/path/to/target"],
345+ ]
346+ self.assertEqual(
347+ expected_args,
348+ [proc._args["args"] for proc in processes_fixture.procs])
349+
350+ def test_path_exists(self):
351+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
352+ processes_fixture = self.useFixture(FakeProcesses())
353+ test_proc_infos = iter([{}, {"returncode": 1}])
354+ processes_fixture.add(lambda _: next(test_proc_infos), name="sudo")
355+ self.assertTrue(Chroot("1", "xenial", "amd64").path_exists("/present"))
356+ self.assertFalse(Chroot("1", "xenial", "amd64").path_exists("/absent"))
357+
358+ expected_args = [
359+ ["sudo", "/usr/sbin/chroot",
360+ "/expected/home/build-1/chroot-autobuild",
361+ "linux64", "test", "-e", path]
362+ for path in ("/present", "/absent")
363+ ]
364+ self.assertEqual(
365+ expected_args,
366+ [proc._args["args"] for proc in processes_fixture.procs])
367+
368+ def test_islink(self):
369+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
370+ processes_fixture = self.useFixture(FakeProcesses())
371+ test_proc_infos = iter([{}, {"returncode": 1}])
372+ processes_fixture.add(lambda _: next(test_proc_infos), name="sudo")
373+ self.assertTrue(Chroot("1", "xenial", "amd64").islink("/link"))
374+ self.assertFalse(Chroot("1", "xenial", "amd64").islink("/file"))
375+
376+ expected_args = [
377+ ["sudo", "/usr/sbin/chroot",
378+ "/expected/home/build-1/chroot-autobuild",
379+ "linux64", "test", "-h", path]
380+ for path in ("/link", "/file")
381+ ]
382+ self.assertEqual(
383+ expected_args,
384+ [proc._args["args"] for proc in processes_fixture.procs])
385+
386+ def test_listdir(self):
387+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
388+ processes_fixture = self.useFixture(FakeProcesses())
389+ processes_fixture.add(
390+ lambda _: {"stdout": io.BytesIO(b"foo\0bar\0baz\0")}, name="sudo")
391+ self.assertEqual(
392+ ["foo", "bar", "baz"],
393+ Chroot("1", "xenial", "amd64").listdir("/path"))
394+
395+ expected_args = [
396+ ["sudo", "/usr/sbin/chroot",
397+ "/expected/home/build-1/chroot-autobuild",
398+ "linux64", "find", "/path", "-mindepth", "1", "-maxdepth", "1",
399+ "-printf", "%P\\0"],
400+ ]
401+ self.assertEqual(
402+ expected_args,
403+ [proc._args["args"] for proc in processes_fixture.procs])
404+
405 def test_kill_processes(self):
406 self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
407 fs_fixture = self.useFixture(FakeFilesystem())
408
409=== modified file 'lpbuildd/tests/fakeslave.py'
410--- lpbuildd/tests/fakeslave.py 2017-08-05 00:09:13 +0000
411+++ lpbuildd/tests/fakeslave.py 2017-08-22 16:03:15 +0000
412@@ -10,6 +10,7 @@
413 import hashlib
414 import os
415 import shutil
416+import stat
417
418 from lpbuildd.target.backend import Backend
419
420@@ -117,8 +118,55 @@
421 )
422 for fake_method in fake_methods:
423 setattr(self, fake_method, FakeMethod())
424- self.copied_in = {}
425+ self.backend_fs = {}
426+
427+ def _add_inode(self, path, contents, full_mode):
428+ path = os.path.normpath(path)
429+ parent = os.path.dirname(path)
430+ if parent != path and parent not in self.backend_fs:
431+ self.add_dir(parent)
432+ self.backend_fs[path] = (contents, full_mode)
433+
434+ def add_dir(self, path, mode=0o755):
435+ self._add_inode(path, None, stat.S_IFDIR | mode)
436+
437+ def add_file(self, path, contents, mode=0o644):
438+ self._add_inode(path, contents, stat.S_IFREG | mode)
439+
440+ def add_link(self, path, target):
441+ self._add_inode(path, target, stat.S_IFLNK | 0o777)
442
443 def copy_in(self, source_path, target_path):
444 with open(source_path, "rb") as source:
445- self.copied_in[target_path] = source.read()
446+ self.add_file(
447+ target_path, source.read(), os.fstat(source.fileno()).st_mode)
448+
449+ def _get_inode(self, path):
450+ while True:
451+ contents, mode = self.backend_fs[path]
452+ if not stat.S_ISLNK(mode):
453+ return contents, mode
454+ path = os.path.normpath(
455+ os.path.join(os.path.dirname(path), contents))
456+
457+ def copy_out(self, source_path, target_path):
458+ contents, mode = self._get_inode(source_path)
459+ with open(target_path, "wb") as target:
460+ target.write(contents)
461+ os.fchmod(target.fileno(), stat.S_IMODE(mode))
462+
463+ def path_exists(self, path):
464+ try:
465+ self._get_inode(path)
466+ return True
467+ except KeyError:
468+ return False
469+
470+ def islink(self, path):
471+ _, mode = self.backend_fs.get(path, (b"", 0))
472+ return stat.S_ISLNK(mode)
473+
474+ def listdir(self, path):
475+ return [
476+ os.path.basename(p) for p in self.backend_fs
477+ if os.path.dirname(p) == path]
478
479=== modified file 'lpbuildd/tests/test_livefs.py'
480--- lpbuildd/tests/test_livefs.py 2017-08-22 14:53:29 +0000
481+++ lpbuildd/tests/test_livefs.py 2017-08-22 16:03:15 +0000
482@@ -4,9 +4,11 @@
483 __metaclass__ = type
484
485 import os
486-import shutil
487-import tempfile
488
489+from fixtures import (
490+ EnvironmentVariable,
491+ TempDir,
492+ )
493 from testtools import TestCase
494
495 from lpbuildd.livefs import (
496@@ -35,19 +37,16 @@
497 """Run LiveFilesystemBuildManager through its iteration steps."""
498 def setUp(self):
499 super(TestLiveFilesystemBuildManagerIteration, self).setUp()
500- self.working_dir = tempfile.mkdtemp()
501- self.addCleanup(lambda: shutil.rmtree(self.working_dir))
502+ self.working_dir = self.useFixture(TempDir()).path
503 slave_dir = os.path.join(self.working_dir, "slave")
504 home_dir = os.path.join(self.working_dir, "home")
505 for dir in (slave_dir, home_dir):
506 os.mkdir(dir)
507+ self.useFixture(EnvironmentVariable("HOME", home_dir))
508 self.slave = FakeSlave(slave_dir)
509 self.buildid = "123"
510 self.buildmanager = MockBuildManager(self.slave, self.buildid)
511- self.buildmanager.home = home_dir
512 self.buildmanager._cachepath = self.slave._cachepath
513- self.build_dir = os.path.join(
514- home_dir, "build-%s" % self.buildid, "chroot-autobuild", "build")
515
516 def getState(self):
517 """Retrieve build manager's state."""
518@@ -62,7 +61,10 @@
519 "pocket": "release",
520 "arch_tag": "i386",
521 }
522+ original_backend_name = self.buildmanager.backend_name
523+ self.buildmanager.backend_name = "fake"
524 self.buildmanager.initiate({}, "chroot.tar.gz", extra_args)
525+ self.buildmanager.backend_name = original_backend_name
526
527 # Skip states that are done in DebianBuildManager to the state
528 # directly before BUILD_LIVEFS.
529@@ -90,10 +92,8 @@
530 with open(log_path, "w") as log:
531 log.write("I am a build log.")
532
533- os.makedirs(self.build_dir)
534- manifest_path = os.path.join(self.build_dir, "livecd.ubuntu.manifest")
535- with open(manifest_path, "w") as manifest:
536- manifest.write("I am a manifest file.")
537+ self.buildmanager.backend.add_file(
538+ "/build/livecd.ubuntu.manifest", b"I am a manifest file.")
539
540 # After building the package, reap processes.
541 self.buildmanager.iterate(0)
542@@ -135,13 +135,10 @@
543 with open(log_path, "w") as log:
544 log.write("I am a build log.")
545
546- os.makedirs(self.build_dir)
547- target_path = os.path.join(
548- self.build_dir, "livecd.ubuntu.kernel-generic")
549- with open(target_path, "w") as target:
550- target.write("I am a kernel.")
551- link_path = os.path.join(self.build_dir, "livecd.ubuntu.kernel")
552- os.symlink("livecd.ubuntu.kernel-generic", link_path)
553+ self.buildmanager.backend.add_file(
554+ "/build/livecd.ubuntu.kernel-generic", b"I am a kernel.")
555+ self.buildmanager.backend.add_link(
556+ "/build/livecd.ubuntu.kernel", "livefs.ubuntu.kernel-generic")
557
558 self.buildmanager.iterate(0)
559 self.assertThat(self.slave, HasWaitingFiles.byEquality({
560
561=== modified file 'lpbuildd/tests/test_snap.py'
562--- lpbuildd/tests/test_snap.py 2017-08-22 14:53:29 +0000
563+++ lpbuildd/tests/test_snap.py 2017-08-22 16:03:15 +0000
564@@ -4,9 +4,11 @@
565 __metaclass__ = type
566
567 import os
568-import shutil
569-import tempfile
570
571+from fixtures import (
572+ EnvironmentVariable,
573+ TempDir,
574+ )
575 from testtools import TestCase
576
577 from lpbuildd.snap import (
578@@ -35,19 +37,16 @@
579 """Run SnapBuildManager through its iteration steps."""
580 def setUp(self):
581 super(TestSnapBuildManagerIteration, self).setUp()
582- self.working_dir = tempfile.mkdtemp()
583- self.addCleanup(lambda: shutil.rmtree(self.working_dir))
584+ self.working_dir = self.useFixture(TempDir()).path
585 slave_dir = os.path.join(self.working_dir, "slave")
586 home_dir = os.path.join(self.working_dir, "home")
587 for dir in (slave_dir, home_dir):
588 os.mkdir(dir)
589+ self.useFixture(EnvironmentVariable("HOME", home_dir))
590 self.slave = FakeSlave(slave_dir)
591 self.buildid = "123"
592 self.buildmanager = MockBuildManager(self.slave, self.buildid)
593- self.buildmanager.home = home_dir
594 self.buildmanager._cachepath = self.slave._cachepath
595- self.build_dir = os.path.join(
596- home_dir, "build-%s" % self.buildid, "chroot-autobuild", "build")
597
598 def getState(self):
599 """Retrieve build manager's state."""
600@@ -63,7 +62,10 @@
601 "git_repository": "https://git.launchpad.dev/~example/+git/snap",
602 "git_path": "master",
603 }
604+ original_backend_name = self.buildmanager.backend_name
605+ self.buildmanager.backend_name = "fake"
606 self.buildmanager.initiate({}, "chroot.tar.gz", extra_args)
607+ self.buildmanager.backend_name = original_backend_name
608
609 # Skip states that are done in DebianBuildManager to the state
610 # directly before BUILD_SNAP.
611@@ -102,11 +104,8 @@
612 with open(log_path, "w") as log:
613 log.write("I am a build log.")
614
615- output_dir = os.path.join(self.build_dir, "test-snap")
616- os.makedirs(output_dir)
617- snap_path = os.path.join(output_dir, "test-snap_0_all.snap")
618- with open(snap_path, "w") as snap:
619- snap.write("I am a snap package.")
620+ self.buildmanager.backend.add_file(
621+ "/build/test-snap/test-snap_0_all.snap", b"I am a snap package.")
622
623 # After building the package, reap processes.
624 self.buildmanager.iterate(0)
625@@ -148,14 +147,10 @@
626 with open(log_path, "w") as log:
627 log.write("I am a build log.")
628
629- output_dir = os.path.join(self.build_dir, "test-snap")
630- os.makedirs(output_dir)
631- snap_path = os.path.join(output_dir, "test-snap_0_all.snap")
632- with open(snap_path, "w") as snap:
633- snap.write("I am a snap package.")
634- manifest_path = os.path.join(output_dir, "test-snap_0_all.manifest")
635- with open(manifest_path, "w") as manifest:
636- manifest.write("I am a manifest.")
637+ self.buildmanager.backend.add_file(
638+ "/build/test-snap/test-snap_0_all.snap", b"I am a snap package.")
639+ self.buildmanager.backend.add_file(
640+ "/build/test-snap/test-snap_0_all.manifest", b"I am a manifest.")
641
642 # After building the package, reap processes.
643 self.buildmanager.iterate(0)
644
645=== modified file 'lpbuildd/tests/test_translationtemplatesbuildmanager.py'
646--- lpbuildd/tests/test_translationtemplatesbuildmanager.py 2017-08-22 14:53:29 +0000
647+++ lpbuildd/tests/test_translationtemplatesbuildmanager.py 2017-08-22 16:03:15 +0000
648@@ -4,9 +4,11 @@
649 __metaclass__ = type
650
651 import os
652-import shutil
653-import tempfile
654
655+from fixtures import (
656+ EnvironmentVariable,
657+ TempDir,
658+ )
659 from testtools import TestCase
660
661 from lpbuildd.tests.fakeslave import FakeSlave
662@@ -35,16 +37,15 @@
663 """Run TranslationTemplatesBuildManager through its iteration steps."""
664 def setUp(self):
665 super(TestTranslationTemplatesBuildManagerIteration, self).setUp()
666- self.working_dir = tempfile.mkdtemp()
667- self.addCleanup(lambda: shutil.rmtree(self.working_dir))
668+ self.working_dir = self.useFixture(TempDir()).path
669 slave_dir = os.path.join(self.working_dir, 'slave')
670 home_dir = os.path.join(self.working_dir, 'home')
671 for dir in (slave_dir, home_dir):
672 os.mkdir(dir)
673+ self.useFixture(EnvironmentVariable("HOME", home_dir))
674 self.slave = FakeSlave(slave_dir)
675 self.buildid = '123'
676 self.buildmanager = MockBuildManager(self.slave, self.buildid)
677- self.buildmanager.home = home_dir
678 self.chrootdir = os.path.join(
679 home_dir, 'build-%s' % self.buildid, 'chroot-autobuild')
680
681@@ -57,8 +58,11 @@
682 url = 'lp:~my/branch'
683 # The build manager's iterate() kicks off the consecutive states
684 # after INIT.
685+ original_backend_name = self.buildmanager.backend_name
686+ self.buildmanager.backend_name = "fake"
687 self.buildmanager.initiate(
688 {}, 'chroot.tar.gz', {'series': 'xenial', 'branch_url': url})
689+ self.buildmanager.backend_name = original_backend_name
690
691 # Skip states that are done in DebianBuildManager to the state
692 # directly before INSTALL.
693@@ -94,12 +98,9 @@
694 self.assertFalse(self.slave.wasCalled('chrootFail'))
695
696 outfile_path = os.path.join(
697- self.chrootdir, self.buildmanager.home[1:],
698- self.buildmanager._resultname)
699- os.makedirs(os.path.dirname(outfile_path))
700-
701- with open(outfile_path, 'w') as outfile:
702- outfile.write("I am a template tarball. Seriously.")
703+ self.buildmanager.home, self.buildmanager._resultname)
704+ self.buildmanager.backend.add_file(
705+ outfile_path, b"I am a template tarball. Seriously.")
706
707 # After generating templates, reap processes.
708 self.buildmanager.iterate(0)
709@@ -169,7 +170,7 @@
710 self.buildmanager.initiate(
711 {}, 'chroot.tar.gz', {'series': 'xenial', 'branch_url': url})
712
713- # Skip states to the INSTALL state.
714+ # Skip states to the GENERATE state.
715 self.buildmanager._state = TranslationTemplatesBuildState.GENERATE
716
717 # The buildmanager fails and reaps processes.
718
719=== modified file 'lpbuildd/translationtemplates.py'
720--- lpbuildd/translationtemplates.py 2015-05-11 05:39:25 +0000
721+++ lpbuildd/translationtemplates.py 2017-08-22 16:03:15 +0000
722@@ -64,12 +64,9 @@
723 """Gather the results of the build and add them to the file cache."""
724 # The file is inside the chroot, in the home directory of the buildd
725 # user. Should be safe to assume the home dirs are named identically.
726- assert self.home.startswith('/'), "home directory must be absolute."
727-
728- path = os.path.join(
729- self._chroot_path, self.home[1:], self._resultname)
730- if os.access(path, os.F_OK):
731- self._slave.addWaitingFile(path)
732+ path = os.path.join(self.home, self._resultname)
733+ if self.backend.path_exists(path):
734+ self.addWaitingFileFromBackend(path)
735
736 def iterate_INSTALL(self, success):
737 """Installation was done."""

Subscribers

People subscribed via source and target branches

to all changes: