launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #21792
[Merge] lp:~cjwatson/launchpad-buildd/gather-results-via-backend into lp:launchpad-buildd
Colin Watson has proposed merging lp:~cjwatson/launchpad-buildd/gather-results-via-backend into lp:launchpad-buildd with lp:~cjwatson/launchpad-buildd/fake-backend as a prerequisite.
Commit message:
Gather results via the backend abstraction rather than by direct filesystem access.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad-buildd/gather-results-via-backend/+merge/328624
Current exceptions are binarypackage (because sbuild handles its own backend access) and sourcepackagerecipe (which needs some further refactoring first).
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad-buildd/gather-results-via-backend into lp:launchpad-buildd.
=== modified file 'lpbuildd/livefs.py'
--- lpbuildd/livefs.py 2017-07-28 13:57:47 +0000
+++ lpbuildd/livefs.py 2017-08-05 09:47:12 +0000
@@ -4,12 +4,10 @@
__metaclass__ = type
import os
-import shutil
from lpbuildd.debian import (
DebianBuildManager,
DebianBuildState,
- get_build_path,
)
@@ -33,11 +31,6 @@
def initiate(self, files, chroot, extra_args):
"""Initiate a build with a given set of files and chroot."""
- self.build_path = get_build_path(
- self.home, self._buildid, "chroot-autobuild", "build")
- if os.path.isdir(self.build_path):
- shutil.rmtree(self.build_path)
-
self.subarch = extra_args.get("subarch")
self.project = extra_args["project"]
self.subproject = extra_args.get("subproject")
@@ -100,7 +93,8 @@
def gatherResults(self):
"""Gather the results of the build and add them to the file cache."""
- for entry in sorted(os.listdir(self.build_path)):
- path = os.path.join(self.build_path, entry)
- if entry.startswith("livecd.") and not os.path.islink(path):
- self._slave.addWaitingFile(path)
+ for entry in sorted(self.backend.listdir("/build")):
+ path = os.path.join("/build", entry)
+ if (entry.startswith("livecd.") and
+ not self.backend.islink(path)):
+ self.addWaitingFileFromBackend(path)
=== modified file 'lpbuildd/slave.py'
--- lpbuildd/slave.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/slave.py 2017-08-05 09:47:12 +0000
@@ -12,6 +12,8 @@
import hashlib
import os
import re
+import shutil
+import tempfile
import urllib2
import xmlrpclib
@@ -310,6 +312,15 @@
self._subprocess.ignore = True
self._subprocess.transport.loseConnection()
+ def addWaitingFileFromBackend(self, path):
+ fetched_dir = tempfile.mkdtemp()
+ try:
+ fetched_path = os.path.join(fetched_dir, os.path.basename(path))
+ self.backend.copy_out(path, fetched_path)
+ self._slave.addWaitingFile(fetched_path)
+ finally:
+ shutil.rmtree(fetched_dir)
+
class BuilderStatus:
"""Status values for the builder."""
=== modified file 'lpbuildd/snap.py'
--- lpbuildd/snap.py 2017-04-03 12:30:15 +0000
+++ lpbuildd/snap.py 2017-08-05 09:47:12 +0000
@@ -7,7 +7,6 @@
import json
import os
-import shutil
import sys
from lpbuildd.debian import (
@@ -41,11 +40,6 @@
def initiate(self, files, chroot, extra_args):
"""Initiate a build with a given set of files and chroot."""
- self.build_path = get_build_path(
- self.home, self._buildid, "chroot-autobuild", "build")
- if os.path.isdir(self.build_path):
- shutil.rmtree(self.build_path)
-
self.name = extra_args["name"]
self.branch = extra_args.get("branch")
self.git_repository = extra_args.get("git_repository")
@@ -113,12 +107,12 @@
def gatherResults(self):
"""Gather the results of the build and add them to the file cache."""
- output_path = os.path.join(self.build_path, self.name)
- if not os.path.exists(output_path):
+ output_path = os.path.join("/build", self.name)
+ if not self.backend.path_exists(output_path):
return
- for entry in sorted(os.listdir(output_path)):
+ for entry in sorted(self.backend.listdir(output_path)):
path = os.path.join(output_path, entry)
- if os.path.islink(path):
+ if self.backend.islink(path):
continue
if entry.endswith(".snap") or entry.endswith(".manifest"):
- self._slave.addWaitingFile(path)
+ self.addWaitingFileFromBackend(path)
=== modified file 'lpbuildd/target/backend.py'
--- lpbuildd/target/backend.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/target/backend.py 2017-08-05 09:47:12 +0000
@@ -49,12 +49,14 @@
"""
raise NotImplementedError
- def run(self, args, env=None, input_text=None, **kwargs):
+ def run(self, args, env=None, input_text=None, get_output=False,
+ **kwargs):
"""Run a command in the target environment.
:param args: the command and arguments to run.
:param env: additional environment variables to set.
:param input_text: input text to pass on the command's stdin.
+ :param get_output: if True, return the output from the command.
:param kwargs: additional keyword arguments for `subprocess.Popen`.
"""
raise NotImplementedError
@@ -73,6 +75,57 @@
"""
raise NotImplementedError
+ def copy_out(self, source_path, target_path):
+ """Copy a file out of the target environment.
+
+ The target file will have the same permission mode as the source
+ file.
+
+ :param source_path: the path to the file that should be copied,
+ relative to the target environment's root.
+ :param target_path: the path where the file should be installed in
+ the host system.
+ """
+ raise NotImplementedError
+
+ def path_exists(self, path):
+ """Test whether a path exists in the target environment.
+
+ :param path: the path to the file to test, relative to the target
+ environment's root.
+ """
+ try:
+ self.run(["test", "-e", path])
+ return True
+ except subprocess.CalledProcessError:
+ return False
+
+ def islink(self, path):
+ """Test whether a file is a symbolic link in the target environment.
+
+ :param path: the path to the file to test, relative to the target
+ environment's root.
+ """
+ try:
+ self.run(["test", "-h", path])
+ return True
+ except subprocess.CalledProcessError:
+ return False
+
+ def listdir(self, path):
+ """List a directory in the target environment.
+
+ :param path: the path to the directory to list, relative to the
+ target environment's root.
+ """
+ paths = self.run(
+ ["find", path, "-mindepth", "1", "-maxdepth", "1",
+ "-printf", "%P\\0"],
+ get_output=True).rstrip(b"\0").split(b"\0")
+ # XXX cjwatson 2017-08-04: Use `os.fsdecode` instead once we're on
+ # Python 3.
+ return [path.decode("UTF-8") for path in paths]
+
def kill_processes(self):
"""Kill any processes left running in the target.
=== modified file 'lpbuildd/target/chroot.py'
--- lpbuildd/target/chroot.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/target/chroot.py 2017-08-05 09:47:12 +0000
@@ -52,7 +52,8 @@
for path in ("/etc/hosts", "/etc/hostname", "/etc/resolv.conf"):
self.copy_in(path, path)
- def run(self, args, env=None, input_text=None, **kwargs):
+ def run(self, args, env=None, input_text=None, get_output=False,
+ **kwargs):
"""See `Backend`."""
if env:
args = ["env"] + [
@@ -61,14 +62,17 @@
if self.arch is not None:
args = set_personality(args, self.arch, series=self.series)
cmd = ["sudo", "/usr/sbin/chroot", self.chroot_path] + args
- if input_text is None:
+ if input_text is None and not get_output:
subprocess.check_call(cmd, cwd=self.chroot_path, **kwargs)
else:
- proc = subprocess.Popen(
- cmd, stdin=subprocess.PIPE, universal_newlines=True, **kwargs)
- proc.communicate(input_text)
+ if get_output:
+ kwargs["stdout"] = subprocess.PIPE
+ proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, **kwargs)
+ output, _ = proc.communicate(input_text)
if proc.returncode:
raise subprocess.CalledProcessError(proc.returncode, cmd)
+ if get_output:
+ return output
def copy_in(self, source_path, target_path):
"""See `Backend`."""
@@ -82,6 +86,14 @@
["sudo", "install", "-o", "root", "-g", "root", "-m", "%o" % mode,
source_path, full_target_path])
+ def copy_out(self, source_path, target_path):
+ # We can just use a plain copy here, since the file ownership in the
+ # host system isn't important.
+ full_source_path = os.path.join(
+ self.chroot_path, source_path.lstrip("/"))
+ subprocess.check_call(
+ ["sudo", "cp", "-p", full_source_path, target_path])
+
def kill_processes(self):
"""See `Backend`."""
prefix = os.path.realpath(self.chroot_path)
=== modified file 'lpbuildd/target/override_sources_list.py'
--- lpbuildd/target/override_sources_list.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/target/override_sources_list.py 2017-08-05 09:47:12 +0000
@@ -6,6 +6,7 @@
__metaclass__ = type
import logging
+import os
import tempfile
from lpbuildd.target.operation import Operation
@@ -31,5 +32,6 @@
for archive in self.args.archives:
print(archive, file=sources_list)
sources_list.flush()
+ os.fchmod(sources_list.fileno(), 0o644)
self.backend.copy_in(sources_list.name, "/etc/apt/sources.list")
return 0
=== modified file 'lpbuildd/target/tests/test_chroot.py'
--- lpbuildd/target/tests/test_chroot.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/target/tests/test_chroot.py 2017-08-05 09:47:12 +0000
@@ -3,6 +3,7 @@
__metaclass__ = type
+import io
import os.path
import signal
from textwrap import dedent
@@ -97,6 +98,25 @@
expected_args,
[proc._args["args"] for proc in processes_fixture.procs])
+ def test_run_get_output(self):
+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
+ processes_fixture = self.useFixture(FakeProcesses())
+ processes_fixture.add(
+ lambda _: {"stdout": io.BytesIO(b"hello\n")}, name="sudo")
+ self.assertEqual(
+ "hello\n",
+ Chroot("1", "xenial", "amd64").run(
+ ["echo", "hello"], get_output=True))
+
+ expected_args = [
+ ["sudo", "/usr/sbin/chroot",
+ "/expected/home/build-1/chroot-autobuild",
+ "linux64", "echo", "hello"],
+ ]
+ self.assertEqual(
+ expected_args,
+ [proc._args["args"] for proc in processes_fixture.procs])
+
def test_copy_in(self):
self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
source_dir = self.useFixture(TempDir()).path
@@ -119,6 +139,77 @@
expected_args,
[proc._args["args"] for proc in processes_fixture.procs])
+ def test_copy_out(self):
+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
+ processes_fixture = self.useFixture(FakeProcesses())
+ processes_fixture.add(lambda _: {}, name="sudo")
+ Chroot("1", "xenial", "amd64").copy_out(
+ "/path/to/source", "/path/to/target")
+
+ expected_args = [
+ ["sudo", "cp", "-p",
+ "/expected/home/build-1/chroot-autobuild/path/to/source",
+ "/path/to/target"],
+ ]
+ self.assertEqual(
+ expected_args,
+ [proc._args["args"] for proc in processes_fixture.procs])
+
+ def test_path_exists(self):
+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
+ processes_fixture = self.useFixture(FakeProcesses())
+ test_proc_infos = iter([{}, {"returncode": 1}])
+ processes_fixture.add(lambda _: next(test_proc_infos), name="sudo")
+ self.assertTrue(Chroot("1", "xenial", "amd64").path_exists("/present"))
+ self.assertFalse(Chroot("1", "xenial", "amd64").path_exists("/absent"))
+
+ expected_args = [
+ ["sudo", "/usr/sbin/chroot",
+ "/expected/home/build-1/chroot-autobuild",
+ "linux64", "test", "-e", path]
+ for path in ("/present", "/absent")
+ ]
+ self.assertEqual(
+ expected_args,
+ [proc._args["args"] for proc in processes_fixture.procs])
+
+ def test_islink(self):
+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
+ processes_fixture = self.useFixture(FakeProcesses())
+ test_proc_infos = iter([{}, {"returncode": 1}])
+ processes_fixture.add(lambda _: next(test_proc_infos), name="sudo")
+ self.assertTrue(Chroot("1", "xenial", "amd64").islink("/link"))
+ self.assertFalse(Chroot("1", "xenial", "amd64").islink("/file"))
+
+ expected_args = [
+ ["sudo", "/usr/sbin/chroot",
+ "/expected/home/build-1/chroot-autobuild",
+ "linux64", "test", "-h", path]
+ for path in ("/link", "/file")
+ ]
+ self.assertEqual(
+ expected_args,
+ [proc._args["args"] for proc in processes_fixture.procs])
+
+ def test_listdir(self):
+ self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
+ processes_fixture = self.useFixture(FakeProcesses())
+ processes_fixture.add(
+ lambda _: {"stdout": io.BytesIO(b"foo\0bar\0baz\0")}, name="sudo")
+ self.assertEqual(
+ ["foo", "bar", "baz"],
+ Chroot("1", "xenial", "amd64").listdir("/path"))
+
+ expected_args = [
+ ["sudo", "/usr/sbin/chroot",
+ "/expected/home/build-1/chroot-autobuild",
+ "linux64", "find", "/path", "-mindepth", "1", "-maxdepth", "1",
+ "-printf", "%P\\0"],
+ ]
+ self.assertEqual(
+ expected_args,
+ [proc._args["args"] for proc in processes_fixture.procs])
+
def test_kill_processes(self):
self.useFixture(EnvironmentVariable("HOME", "/expected/home"))
fs_fixture = self.useFixture(FakeFilesystem())
=== modified file 'lpbuildd/target/tests/test_override_sources_list.py'
--- lpbuildd/target/tests/test_override_sources_list.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/target/tests/test_override_sources_list.py 2017-08-05 09:47:12 +0000
@@ -3,6 +3,7 @@
__metaclass__ = type
+import stat
from textwrap import dedent
from testtools import TestCase
@@ -20,9 +21,9 @@
]
override_sources_list = OverrideSourcesList(args=args)
self.assertEqual(0, override_sources_list.run())
- self.assertEqual({
- "/etc/apt/sources.list": dedent("""\
+ self.assertEqual(
+ (dedent("""\
deb http://archive.ubuntu.com/ubuntu xenial main
deb http://ppa.launchpad.net/launchpad/ppa/ubuntu xenial main
- """).encode("UTF-8"),
- }, override_sources_list.backend.copied_in)
+ """).encode("UTF-8"), stat.S_IFREG | 0o644),
+ override_sources_list.backend.backend_fs["/etc/apt/sources.list"])
=== modified file 'lpbuildd/tests/fakeslave.py'
--- lpbuildd/tests/fakeslave.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/tests/fakeslave.py 2017-08-05 09:47:12 +0000
@@ -10,6 +10,7 @@
import hashlib
import os
import shutil
+import stat
from lpbuildd.target.backend import Backend
@@ -117,8 +118,55 @@
)
for fake_method in fake_methods:
setattr(self, fake_method, FakeMethod())
- self.copied_in = {}
+ self.backend_fs = {}
+
+ def _add_inode(self, path, contents, full_mode):
+ path = os.path.normpath(path)
+ parent = os.path.dirname(path)
+ if parent != path and parent not in self.backend_fs:
+ self.add_dir(parent)
+ self.backend_fs[path] = (contents, full_mode)
+
+ def add_dir(self, path, mode=0o755):
+ self._add_inode(path, None, stat.S_IFDIR | mode)
+
+ def add_file(self, path, contents, mode=0o644):
+ self._add_inode(path, contents, stat.S_IFREG | mode)
+
+ def add_link(self, path, target):
+ self._add_inode(path, target, stat.S_IFLNK | 0o777)
def copy_in(self, source_path, target_path):
with open(source_path, "rb") as source:
- self.copied_in[target_path] = source.read()
+ self.add_file(
+ target_path, source.read(), os.fstat(source.fileno()).st_mode)
+
+ def _get_inode(self, path):
+ while True:
+ contents, mode = self.backend_fs[path]
+ if not stat.S_ISLNK(mode):
+ return contents, mode
+ path = os.path.normpath(
+ os.path.join(os.path.dirname(path), contents))
+
+ def copy_out(self, source_path, target_path):
+ contents, mode = self._get_inode(source_path)
+ with open(target_path, "wb") as target:
+ target.write(contents)
+ os.fchmod(target.fileno(), stat.S_IMODE(mode))
+
+ def path_exists(self, path):
+ try:
+ self._get_inode(path)
+ return True
+ except KeyError:
+ return False
+
+ def islink(self, path):
+ _, mode = self.backend_fs.get(path, (b"", 0))
+ return stat.S_ISLNK(mode)
+
+ def listdir(self, path):
+ return [
+ os.path.basename(p) for p in self.backend_fs
+ if os.path.dirname(p) == path]
=== modified file 'lpbuildd/tests/test_livefs.py'
--- lpbuildd/tests/test_livefs.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/tests/test_livefs.py 2017-08-05 09:47:12 +0000
@@ -4,9 +4,11 @@
__metaclass__ = type
import os
-import shutil
-import tempfile
+from fixtures import (
+ EnvironmentVariable,
+ TempDir,
+ )
from testtools import TestCase
from lpbuildd.livefs import (
@@ -35,19 +37,16 @@
"""Run LiveFilesystemBuildManager through its iteration steps."""
def setUp(self):
super(TestLiveFilesystemBuildManagerIteration, self).setUp()
- self.working_dir = tempfile.mkdtemp()
- self.addCleanup(lambda: shutil.rmtree(self.working_dir))
+ self.working_dir = self.useFixture(TempDir()).path
slave_dir = os.path.join(self.working_dir, "slave")
home_dir = os.path.join(self.working_dir, "home")
for dir in (slave_dir, home_dir):
os.mkdir(dir)
+ self.useFixture(EnvironmentVariable("HOME", home_dir))
self.slave = FakeSlave(slave_dir)
self.buildid = "123"
self.buildmanager = MockBuildManager(self.slave, self.buildid)
- self.buildmanager.home = home_dir
self.buildmanager._cachepath = self.slave._cachepath
- self.build_dir = os.path.join(
- home_dir, "build-%s" % self.buildid, "chroot-autobuild", "build")
def getState(self):
"""Retrieve build manager's state."""
@@ -62,7 +61,10 @@
"pocket": "release",
"arch_tag": "i386",
}
+ original_backend_name = self.buildmanager.backend_name
+ self.buildmanager.backend_name = "fake"
self.buildmanager.initiate({}, "chroot.tar.gz", extra_args)
+ self.buildmanager.backend_name = original_backend_name
# Skip states that are done in DebianBuildManager to the state
# directly before BUILD_LIVEFS.
@@ -90,10 +92,8 @@
with open(log_path, "w") as log:
log.write("I am a build log.")
- os.makedirs(self.build_dir)
- manifest_path = os.path.join(self.build_dir, "livecd.ubuntu.manifest")
- with open(manifest_path, "w") as manifest:
- manifest.write("I am a manifest file.")
+ self.buildmanager.backend.add_file(
+ "/build/livecd.ubuntu.manifest", b"I am a manifest file.")
# After building the package, reap processes.
self.buildmanager.iterate(0)
@@ -133,13 +133,10 @@
with open(log_path, "w") as log:
log.write("I am a build log.")
- os.makedirs(self.build_dir)
- target_path = os.path.join(
- self.build_dir, "livecd.ubuntu.kernel-generic")
- with open(target_path, "w") as target:
- target.write("I am a kernel.")
- link_path = os.path.join(self.build_dir, "livecd.ubuntu.kernel")
- os.symlink("livecd.ubuntu.kernel-generic", link_path)
+ self.buildmanager.backend.add_file(
+ "/build/livecd.ubuntu.kernel-generic", b"I am a kernel.")
+ self.buildmanager.backend.add_link(
+ "/build/livecd.ubuntu.kernel", "livefs.ubuntu.kernel-generic")
self.buildmanager.iterate(0)
self.assertThat(self.slave, HasWaitingFiles.byEquality({
=== modified file 'lpbuildd/tests/test_snap.py'
--- lpbuildd/tests/test_snap.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/tests/test_snap.py 2017-08-05 09:47:12 +0000
@@ -4,9 +4,11 @@
__metaclass__ = type
import os
-import shutil
-import tempfile
+from fixtures import (
+ EnvironmentVariable,
+ TempDir,
+ )
from testtools import TestCase
from lpbuildd.snap import (
@@ -35,19 +37,16 @@
"""Run SnapBuildManager through its iteration steps."""
def setUp(self):
super(TestSnapBuildManagerIteration, self).setUp()
- self.working_dir = tempfile.mkdtemp()
- self.addCleanup(lambda: shutil.rmtree(self.working_dir))
+ self.working_dir = self.useFixture(TempDir()).path
slave_dir = os.path.join(self.working_dir, "slave")
home_dir = os.path.join(self.working_dir, "home")
for dir in (slave_dir, home_dir):
os.mkdir(dir)
+ self.useFixture(EnvironmentVariable("HOME", home_dir))
self.slave = FakeSlave(slave_dir)
self.buildid = "123"
self.buildmanager = MockBuildManager(self.slave, self.buildid)
- self.buildmanager.home = home_dir
self.buildmanager._cachepath = self.slave._cachepath
- self.build_dir = os.path.join(
- home_dir, "build-%s" % self.buildid, "chroot-autobuild", "build")
def getState(self):
"""Retrieve build manager's state."""
@@ -63,7 +62,10 @@
"git_repository": "https://git.launchpad.dev/~example/+git/snap",
"git_path": "master",
}
+ original_backend_name = self.buildmanager.backend_name
+ self.buildmanager.backend_name = "fake"
self.buildmanager.initiate({}, "chroot.tar.gz", extra_args)
+ self.buildmanager.backend_name = original_backend_name
# Skip states that are done in DebianBuildManager to the state
# directly before BUILD_SNAP.
@@ -102,11 +104,8 @@
with open(log_path, "w") as log:
log.write("I am a build log.")
- output_dir = os.path.join(self.build_dir, "test-snap")
- os.makedirs(output_dir)
- snap_path = os.path.join(output_dir, "test-snap_0_all.snap")
- with open(snap_path, "w") as snap:
- snap.write("I am a snap package.")
+ self.buildmanager.backend.add_file(
+ "/build/test-snap/test-snap_0_all.snap", b"I am a snap package.")
# After building the package, reap processes.
self.buildmanager.iterate(0)
@@ -146,14 +145,10 @@
with open(log_path, "w") as log:
log.write("I am a build log.")
- output_dir = os.path.join(self.build_dir, "test-snap")
- os.makedirs(output_dir)
- snap_path = os.path.join(output_dir, "test-snap_0_all.snap")
- with open(snap_path, "w") as snap:
- snap.write("I am a snap package.")
- manifest_path = os.path.join(output_dir, "test-snap_0_all.manifest")
- with open(manifest_path, "w") as manifest:
- manifest.write("I am a manifest.")
+ self.buildmanager.backend.add_file(
+ "/build/test-snap/test-snap_0_all.snap", b"I am a snap package.")
+ self.buildmanager.backend.add_file(
+ "/build/test-snap/test-snap_0_all.manifest", b"I am a manifest.")
# After building the package, reap processes.
self.buildmanager.iterate(0)
=== modified file 'lpbuildd/tests/test_translationtemplatesbuildmanager.py'
--- lpbuildd/tests/test_translationtemplatesbuildmanager.py 2017-08-05 09:47:12 +0000
+++ lpbuildd/tests/test_translationtemplatesbuildmanager.py 2017-08-05 09:47:12 +0000
@@ -4,9 +4,11 @@
__metaclass__ = type
import os
-import shutil
-import tempfile
+from fixtures import (
+ EnvironmentVariable,
+ TempDir,
+ )
from testtools import TestCase
from lpbuildd.tests.fakeslave import FakeSlave
@@ -35,16 +37,15 @@
"""Run TranslationTemplatesBuildManager through its iteration steps."""
def setUp(self):
super(TestTranslationTemplatesBuildManagerIteration, self).setUp()
- self.working_dir = tempfile.mkdtemp()
- self.addCleanup(lambda: shutil.rmtree(self.working_dir))
+ self.working_dir = self.useFixture(TempDir()).path
slave_dir = os.path.join(self.working_dir, 'slave')
home_dir = os.path.join(self.working_dir, 'home')
for dir in (slave_dir, home_dir):
os.mkdir(dir)
+ self.useFixture(EnvironmentVariable("HOME", home_dir))
self.slave = FakeSlave(slave_dir)
self.buildid = '123'
self.buildmanager = MockBuildManager(self.slave, self.buildid)
- self.buildmanager.home = home_dir
self.chrootdir = os.path.join(
home_dir, 'build-%s' % self.buildid, 'chroot-autobuild')
@@ -57,8 +58,11 @@
url = 'lp:~my/branch'
# The build manager's iterate() kicks off the consecutive states
# after INIT.
+ original_backend_name = self.buildmanager.backend_name
+ self.buildmanager.backend_name = "fake"
self.buildmanager.initiate(
{}, 'chroot.tar.gz', {'series': 'xenial', 'branch_url': url})
+ self.buildmanager.backend_name = original_backend_name
# Skip states that are done in DebianBuildManager to the state
# directly before INSTALL.
@@ -94,12 +98,9 @@
self.assertFalse(self.slave.wasCalled('chrootFail'))
outfile_path = os.path.join(
- self.chrootdir, self.buildmanager.home[1:],
- self.buildmanager._resultname)
- os.makedirs(os.path.dirname(outfile_path))
-
- with open(outfile_path, 'w') as outfile:
- outfile.write("I am a template tarball. Seriously.")
+ self.buildmanager.home, self.buildmanager._resultname)
+ self.buildmanager.backend.add_file(
+ outfile_path, b"I am a template tarball. Seriously.")
# After generating templates, reap processes.
self.buildmanager.iterate(0)
@@ -166,7 +167,7 @@
self.buildmanager.initiate(
{}, 'chroot.tar.gz', {'series': 'xenial', 'branch_url': url})
- # Skip states to the INSTALL state.
+ # Skip states to the GENERATE state.
self.buildmanager._state = TranslationTemplatesBuildState.GENERATE
# The buildmanager fails and reaps processes.
=== modified file 'lpbuildd/translationtemplates.py'
--- lpbuildd/translationtemplates.py 2015-05-11 05:39:25 +0000
+++ lpbuildd/translationtemplates.py 2017-08-05 09:47:12 +0000
@@ -64,12 +64,9 @@
"""Gather the results of the build and add them to the file cache."""
# The file is inside the chroot, in the home directory of the buildd
# user. Should be safe to assume the home dirs are named identically.
- assert self.home.startswith('/'), "home directory must be absolute."
-
- path = os.path.join(
- self._chroot_path, self.home[1:], self._resultname)
- if os.access(path, os.F_OK):
- self._slave.addWaitingFile(path)
+ path = os.path.join(self.home, self._resultname)
+ if self.backend.path_exists(path):
+ self.addWaitingFileFromBackend(path)
def iterate_INSTALL(self, success):
"""Installation was done."""