diff --git a/tmt/checks/__init__.py b/tmt/checks/__init__.py index 37709cce75..809e23c385 100644 --- a/tmt/checks/__init__.py +++ b/tmt/checks/__init__.py @@ -180,6 +180,22 @@ def delegate( return cast(CheckPlugin[CheckT], find_plugin(raw_data['how'])) \ ._check_class.from_spec(raw_data, logger) + @classmethod + def essential_requires( + cls, + test: 'tmt.base.Test', + logger: tmt.log.Logger) -> list['tmt.base.DependencySimple']: + """ + Collect all essential requirements of the test check. + + Essential requirements of a check are necessary for the check to + perform its basic functionality. + + :returns: a list of requirements. + """ + + return [] + @classmethod def before_test( cls, diff --git a/tmt/checks/avc.py b/tmt/checks/avc.py index 964ef93039..eef656d97f 100644 --- a/tmt/checks/avc.py +++ b/tmt/checks/avc.py @@ -11,6 +11,7 @@ from tmt.utils import CommandOutput, Path, ShellScript, render_run_exception_streams if TYPE_CHECKING: + import tmt.base from tmt.steps.execute import TestInvocation #: The filename of the final check report file. @@ -285,6 +286,19 @@ class AvcDenials(CheckPlugin[Check]): _check_class = Check + @classmethod + def essential_requires( + cls, + test: 'tmt.base.Test', + logger: tmt.log.Logger) -> list['tmt.base.DependencySimple']: + # Avoid circular imports + import tmt.base + + return [ + tmt.base.DependencySimple('/usr/bin/sestatus'), + tmt.base.DependencySimple('/usr/sbin/ausearch') + ] + @classmethod def before_test( cls, diff --git a/tmt/checks/dmesg.py b/tmt/checks/dmesg.py index 8ac6c1af2c..e592004776 100644 --- a/tmt/checks/dmesg.py +++ b/tmt/checks/dmesg.py @@ -12,6 +12,7 @@ from tmt.utils import Path, render_run_exception_streams if TYPE_CHECKING: + import tmt.base from tmt.steps.execute import TestInvocation TEST_POST_DMESG_FILENAME = 'dmesg-{event}.txt' @@ -42,6 +43,16 @@ class DmesgCheck(CheckPlugin[Check]): _check_class = Check + @classmethod + def essential_requires( + cls, + test: 'tmt.base.Test', + logger: tmt.log.Logger) -> list['tmt.base.DependencySimple']: + # Avoid circular imports + import tmt.base + + return [tmt.base.DependencySimple('/usr/bin/dmesg')] + @classmethod def _fetch_dmesg( cls, diff --git a/tmt/steps/prepare/__init__.py b/tmt/steps/prepare/__init__.py index 3a1f4f1721..c895c925a3 100644 --- a/tmt/steps/prepare/__init__.py +++ b/tmt/steps/prepare/__init__.py @@ -261,6 +261,11 @@ def as_key(self) -> frozenset['tmt.base.DependencySimple']: test, self._logger) + for check in test.check: + collected_requires[guest].dependencies += check.plugin.essential_requires( + test, + self._logger) + # Now we have guests and all their requirements. There can be # duplicities, multiple tests requesting the same package, but also # some guests may share the set of packages to be installed on them.