summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Schubert <ben.c.schubert@gmail.com>2018-11-08 11:07:12 +0000
committerBenjamin Schubert <ben.c.schubert@gmail.com>2018-11-08 11:07:12 +0000
commitf116b9b7e4c804c04816ca3078e5849d1f0bd856 (patch)
tree8c74ffd7e3d6cba52b895cd191248d1c91dab769
parent83d153506691b8f6bdd161f5c71154df755f8b2d (diff)
parentc51ba01b7dce07c713ba7d9fd5505a5b9d575c5b (diff)
downloadbuildstream-f116b9b7e4c804c04816ca3078e5849d1f0bd856.tar.gz
Merge branch 'bschubert/tests-no-chroot-linux' into 'master'
test behavior when there is no sandbox on Linux Closes #696 and #736 See merge request BuildStream/buildstream!921
-rw-r--r--buildstream/_platform/linux.py35
-rw-r--r--buildstream/_site.py43
-rw-r--r--buildstream/sandbox/_sandboxdummy.py3
-rwxr-xr-xconftest.py7
-rwxr-xr-xtests/sandboxes/missing-dependencies/elements/base.bst4
-rwxr-xr-xtests/sandboxes/missing-dependencies/files/base/bin/sh1
-rwxr-xr-xtests/sandboxes/missing-dependencies/project.conf4
-rw-r--r--tests/sandboxes/missing_dependencies.py86
8 files changed, 134 insertions, 49 deletions
diff --git a/buildstream/_platform/linux.py b/buildstream/_platform/linux.py
index 6e488472f..afdf81c79 100644
--- a/buildstream/_platform/linux.py
+++ b/buildstream/_platform/linux.py
@@ -18,9 +18,9 @@
# Tristan Maat <tristan.maat@codethink.co.uk>
import os
+import shutil
import subprocess
-from .. import _site
from .. import utils
from ..sandbox import SandboxDummy
@@ -37,12 +37,19 @@ class Linux(Platform):
self._gid = os.getegid()
self._have_fuse = os.path.exists("/dev/fuse")
- self._bwrap_exists = _site.check_bwrap_version(0, 0, 0)
- self._have_good_bwrap = _site.check_bwrap_version(0, 1, 2)
- self._local_sandbox_available = self._have_fuse and self._have_good_bwrap
+ bwrap_version = self._get_bwrap_version()
- self._die_with_parent_available = _site.check_bwrap_version(0, 1, 8)
+ if bwrap_version is None:
+ self._bwrap_exists = False
+ self._have_good_bwrap = False
+ self._die_with_parent_available = False
+ else:
+ self._bwrap_exists = True
+ self._have_good_bwrap = (0, 1, 2) <= bwrap_version
+ self._die_with_parent_available = (0, 1, 8) <= bwrap_version
+
+ self._local_sandbox_available = self._have_fuse and self._have_good_bwrap
if self._local_sandbox_available:
self._user_ns_available = self._check_user_ns_available()
@@ -112,3 +119,21 @@ class Linux(Platform):
output = ''
return output == 'root'
+
+ def _get_bwrap_version(self):
+ # Get the current bwrap version
+ #
+ # returns None if no bwrap was found
+ # otherwise returns a tuple of 3 int: major, minor, patch
+ bwrap_path = shutil.which('bwrap')
+
+ if not bwrap_path:
+ return None
+
+ cmd = [bwrap_path, "--version"]
+ try:
+ version = str(subprocess.check_output(cmd).split()[1], "utf-8")
+ except subprocess.CalledProcessError:
+ return None
+
+ return tuple(int(x) for x in version.split("."))
diff --git a/buildstream/_site.py b/buildstream/_site.py
index 30e1000d4..d64390b5d 100644
--- a/buildstream/_site.py
+++ b/buildstream/_site.py
@@ -18,8 +18,6 @@
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
import os
-import shutil
-import subprocess
#
# Private module declaring some info about where the buildstream
@@ -46,44 +44,3 @@ build_all_template = os.path.join(root, 'data', 'build-all.sh.in')
# Module building script template
build_module_template = os.path.join(root, 'data', 'build-module.sh.in')
-
-# Cached bwrap version
-_bwrap_major = None
-_bwrap_minor = None
-_bwrap_patch = None
-
-
-# check_bwrap_version()
-#
-# Checks the version of installed bwrap against the requested version
-#
-# Args:
-# major (int): The required major version
-# minor (int): The required minor version
-# patch (int): The required patch level
-#
-# Returns:
-# (bool): Whether installed bwrap meets the requirements
-#
-def check_bwrap_version(major, minor, patch):
- # pylint: disable=global-statement
-
- global _bwrap_major
- global _bwrap_minor
- global _bwrap_patch
-
- # Parse bwrap version and save into cache, if not already cached
- if _bwrap_major is None:
- bwrap_path = shutil.which('bwrap')
- if not bwrap_path:
- return False
- cmd = [bwrap_path, "--version"]
- try:
- version = str(subprocess.check_output(cmd).split()[1], "utf-8")
- except subprocess.CalledProcessError:
- # Failure trying to run bubblewrap
- return False
- _bwrap_major, _bwrap_minor, _bwrap_patch = map(int, version.split("."))
-
- # Check whether the installed version meets the requirements
- return (_bwrap_major, _bwrap_minor, _bwrap_patch) >= (major, minor, patch)
diff --git a/buildstream/sandbox/_sandboxdummy.py b/buildstream/sandbox/_sandboxdummy.py
index c0a86a0bb..0e3754c1b 100644
--- a/buildstream/sandbox/_sandboxdummy.py
+++ b/buildstream/sandbox/_sandboxdummy.py
@@ -42,4 +42,5 @@ class SandboxDummy(Sandbox):
"'{}'".format(command[0]),
reason='missing-command')
- raise SandboxError("This platform does not support local builds: {}".format(self._reason))
+ raise SandboxError("This platform does not support local builds: {}".format(self._reason),
+ reason="unavailable-local-sandbox")
diff --git a/conftest.py b/conftest.py
index 99a602db4..1f0259f0f 100755
--- a/conftest.py
+++ b/conftest.py
@@ -23,6 +23,8 @@ import shutil
import pytest
+from buildstream._platform.platform import Platform
+
def pytest_addoption(parser):
parser.addoption('--integration', action='store_true', default=False,
@@ -52,3 +54,8 @@ def integration_cache(request):
shutil.rmtree(os.path.join(cache_dir, 'artifacts'))
except FileNotFoundError:
pass
+
+
+@pytest.fixture(autouse=True)
+def clean_platform_cache():
+ Platform._instance = None
diff --git a/tests/sandboxes/missing-dependencies/elements/base.bst b/tests/sandboxes/missing-dependencies/elements/base.bst
new file mode 100755
index 000000000..dcd6a9d60
--- /dev/null
+++ b/tests/sandboxes/missing-dependencies/elements/base.bst
@@ -0,0 +1,4 @@
+kind: import
+sources:
+- kind: local
+ path: files/base/
diff --git a/tests/sandboxes/missing-dependencies/files/base/bin/sh b/tests/sandboxes/missing-dependencies/files/base/bin/sh
new file mode 100755
index 000000000..c102e04c1
--- /dev/null
+++ b/tests/sandboxes/missing-dependencies/files/base/bin/sh
@@ -0,0 +1 @@
+# This is the original bash
diff --git a/tests/sandboxes/missing-dependencies/project.conf b/tests/sandboxes/missing-dependencies/project.conf
new file mode 100755
index 000000000..080ab758f
--- /dev/null
+++ b/tests/sandboxes/missing-dependencies/project.conf
@@ -0,0 +1,4 @@
+# Project config for missing dependencies test
+name: test
+
+element-path: elements
diff --git a/tests/sandboxes/missing_dependencies.py b/tests/sandboxes/missing_dependencies.py
new file mode 100644
index 000000000..d77674c64
--- /dev/null
+++ b/tests/sandboxes/missing_dependencies.py
@@ -0,0 +1,86 @@
+import os
+import pytest
+from tests.testutils import cli
+from tests.testutils.site import IS_LINUX
+
+from buildstream import _yaml
+from buildstream._exceptions import ErrorDomain
+
+
+# Project directory
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "missing-dependencies",
+)
+
+
+@pytest.mark.skipif(not IS_LINUX, reason='Only available on Linux')
+@pytest.mark.datafiles(DATA_DIR)
+def test_missing_brwap_has_nice_error_message(cli, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element_path = os.path.join(project, 'elements', 'element.bst')
+
+ # Write out our test target
+ element = {
+ 'kind': 'script',
+ 'depends': [
+ {
+ 'filename': 'base.bst',
+ 'type': 'build',
+ },
+ ],
+ 'config': {
+ 'commands': [
+ 'false',
+ ],
+ },
+ }
+ _yaml.dump(element, element_path)
+
+ # Build without access to host tools, this should fail with a nice error
+ result = cli.run(
+ project=project, args=['build', 'element.bst'], env={'PATH': ''})
+ result.assert_task_error(ErrorDomain.SANDBOX, 'unavailable-local-sandbox')
+ assert "not found" in result.stderr
+
+
+@pytest.mark.skipif(not IS_LINUX, reason='Only available on Linux')
+@pytest.mark.datafiles(DATA_DIR)
+def test_old_brwap_has_nice_error_message(cli, datafiles, tmp_path):
+ bwrap = tmp_path.joinpath('bin/bwrap')
+ bwrap.parent.mkdir()
+ with bwrap.open('w') as fp:
+ fp.write('''
+ #!/bin/sh
+ echo bubblewrap 0.0.1
+ '''.strip())
+
+ bwrap.chmod(0o755)
+
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element_path = os.path.join(project, 'elements', 'element3.bst')
+
+ # Write out our test target
+ element = {
+ 'kind': 'script',
+ 'depends': [
+ {
+ 'filename': 'base.bst',
+ 'type': 'build',
+ },
+ ],
+ 'config': {
+ 'commands': [
+ 'false',
+ ],
+ },
+ }
+ _yaml.dump(element, element_path)
+
+ # Build without access to host tools, this should fail with a nice error
+ result = cli.run(
+ project=project,
+ args=['--debug', '--verbose', 'build', 'element3.bst'],
+ env={'PATH': str(tmp_path.joinpath('bin'))})
+ result.assert_task_error(ErrorDomain.SANDBOX, 'unavailable-local-sandbox')
+ assert "too old" in result.stderr