Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions dbuild/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1286,14 +1286,15 @@ def run(cfg: Config, args: argparse.Namespace) -> int:
# Determine which backends to run
if backend_arg == "all":
backends = ["podman"]
if cfg.metadata.appjail and not _appjail_cit_applicable(cfg):
if cfg.metadata.appjail is None:
pass # appjail: false
elif not _appjail_cit_applicable(cfg):
log.info("appjail backend skipped: this image declares sidecars (appjail.depends_on); "
"the single-jail CIT can't run its stack")
elif cfg.metadata.appjail:
if AppJailBackend.available():
backends.append("appjail")
else:
log.warn("appjail configured but not installed — skipping appjail backend")
elif AppJailBackend.available():
backends.append("appjail")
else:
log.warn("appjail configured but not installed — skipping appjail backend")
else:
backends = [backend_arg]

Expand Down Expand Up @@ -1381,6 +1382,7 @@ def _appjail_cit_applicable(cfg) -> bool:
director bundle is what runs the whole stack on AppJail.
"""
aj = cfg.metadata.appjail
if not aj:
# {} is enabled (appjail: true, or no key); only None is appjail: false
if aj is None:
return False
return not (isinstance(aj, dict) and aj.get("depends_on"))
54 changes: 54 additions & 0 deletions tests/test_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,3 +687,57 @@ def test_diagnose_port_not_listening(self):

if __name__ == "__main__":
unittest.main()


class TestAppJailBackendSelection(unittest.TestCase):
"""`dbuild test` runs the appjail backend for every image that has AppJail
on, including the default (no appjail key) and `appjail: true`, which
parse to {}."""

def _backends(self, meta):
from dbuild.config import _parse_appjail
cfg = MagicMock()
cfg.metadata.appjail = _parse_appjail(meta)
cfg.test.puid = False
cfg.variants = [MagicMock(tag="latest", puid=None)]
args = MagicMock(variant=None, json_output=None, backend="all", puid=None)
seen = []

def fake_test_variant(cfg, variant, test, **kw):
seen.append(kw["force_backend"])
return 0

with patch("dbuild.ci.detect") as detect, \
patch.object(cit.AppJailBackend, "available", return_value=True), \
patch.object(cit, "_test_variant", side_effect=fake_test_variant):
detect.return_value.should_skip.return_value = False
self.assertEqual(cit.run(cfg, args), 0)
return seen

def test_no_key_is_on(self):
self.assertEqual(self._backends({}), ["podman", "appjail"])

def test_true_is_on(self):
self.assertEqual(self._backends({"appjail": True}), ["podman", "appjail"])

def test_bare_is_on(self):
self.assertEqual(self._backends({"appjail": None}), ["podman", "appjail"])

def test_false_is_off(self):
self.assertEqual(self._backends({"appjail": False}), ["podman"])

def test_custom_config_is_on(self):
meta = {"appjail": {"director": {"options": []}}}
self.assertEqual(self._backends(meta), ["podman", "appjail"])

def test_sidecars_skip_appjail(self):
meta = {"appjail": {"depends_on": ["postgres"]}}
self.assertEqual(self._backends(meta), ["podman"])

def test_applicable_for_default(self):
from dbuild.config import _parse_appjail
cfg = MagicMock()
cfg.metadata.appjail = _parse_appjail({})
self.assertTrue(cit._appjail_cit_applicable(cfg))
cfg.metadata.appjail = _parse_appjail({"appjail": False})
self.assertFalse(cit._appjail_cit_applicable(cfg))
Loading