diff --git a/avocado/plugins/list.py b/avocado/plugins/list.py index ca6d6bca4d..2cf67e26d1 100644 --- a/avocado/plugins/list.py +++ b/avocado/plugins/list.py @@ -221,6 +221,14 @@ def configure(self, parser): allow_multiple=True, ) + settings.add_argparser_to_option( + namespace="resolver.exec_runnables_recipe.arguments", + metavar="ARGS", + parser=parser, + long_arg="--resolver-exec-arguments", + allow_multiple=True, + ) + help_msg = "Writes runnable recipe files to a directory." settings.register_option( section="list.recipes", diff --git a/avocado/plugins/resolvers.py b/avocado/plugins/resolvers.py index 1daa42055f..1ff1c3761d 100644 --- a/avocado/plugins/resolvers.py +++ b/avocado/plugins/resolvers.py @@ -19,6 +19,7 @@ import json import os import re +import shlex import subprocess from avocado.core.extension_manager import PluginPriority @@ -218,6 +219,19 @@ def initialize(self): help_msg=help_msg, ) + help_msg = ( + "Command line options (space separated) that will be added " + "to the executable when executing it as a producer of " + "runnables-recipe JSON content." + ) + settings.register_option( + section="resolver.exec_runnables_recipe", + key="arguments", + key_type=str, + default="", + help_msg=help_msg, + ) + class ExecRunnablesRecipeResolver(BaseExec, Resolver): name = "exec-runnables-recipe" @@ -239,9 +253,14 @@ def resolve(self, reference): if exec_criteria is not None: return exec_criteria + args = self.config.get("resolver.exec_runnables_recipe.arguments") + if args: + cmd = [reference] + shlex.split(args) + else: + cmd = reference try: process = subprocess.Popen( - reference, + cmd, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE, diff --git a/avocado/plugins/run.py b/avocado/plugins/run.py index 8ce7150607..85ff9aaf42 100644 --- a/avocado/plugins/run.py +++ b/avocado/plugins/run.py @@ -274,6 +274,14 @@ def configure(self, parser): allow_multiple=True, ) + settings.add_argparser_to_option( + namespace="resolver.exec_runnables_recipe.arguments", + metavar="ARGS", + parser=parser, + long_arg="--resolver-exec-arguments", + allow_multiple=True, + ) + parser_common_args.add_tag_filter_args(parser) def run(self, config): diff --git a/docs/source/guides/writer/chapters/recipes.rst b/docs/source/guides/writer/chapters/recipes.rst index f0fdc1814d..01855acf6a 100644 --- a/docs/source/guides/writer/chapters/recipes.rst +++ b/docs/source/guides/writer/chapters/recipes.rst @@ -104,3 +104,18 @@ run``. Example:: exec-test true-test exec-test false-test + +If the executable to be run needs arguments, you can pass it via the +``--resolver-exec-arguments`` or the underlying +``resolver.exec_runnable_recipe.arguments`` option. The following +script receives an optional parameter that can change the type of the +tests it generates: + +.. literalinclude:: ../../../../../examples/nrunner/resolvers/exec_runnables_recipe_kind.sh + +In order to have those tests resolved as ``tap`` tests, one can run:: + + $ avocado list --resolver-run-executables --resolver-exec-arguments tap examples/nrunner/resolvers/exec_runnables_recipe_kind.sh + + tap true-test + tap false-test diff --git a/examples/nrunner/resolvers/exec_runnables_recipe_kind.sh b/examples/nrunner/resolvers/exec_runnables_recipe_kind.sh new file mode 100755 index 0000000000..29cc83fc86 --- /dev/null +++ b/examples/nrunner/resolvers/exec_runnables_recipe_kind.sh @@ -0,0 +1,3 @@ +#!/bin/sh +kind=${1:-exec-test} +echo "[{\"kind\": \"$kind\",\"uri\": \"/bin/true\",\"identifier\": \"true-test\"},{\"kind\": \"$kind\",\"uri\": \"/bin/false\",\"identifier\": \"false-test\"}]" diff --git a/selftests/check.py b/selftests/check.py index 13e6c96c06..02fbdc4354 100755 --- a/selftests/check.py +++ b/selftests/check.py @@ -29,7 +29,7 @@ "nrunner-requirement": 28, "unit": 678, "jobs": 11, - "functional-parallel": 311, + "functional-parallel": 312, "functional-serial": 7, "optional-plugins": 0, "optional-plugins-golang": 2, diff --git a/selftests/functional/resolver.py b/selftests/functional/resolver.py index eb1f04afc0..d7c2145293 100644 --- a/selftests/functional/resolver.py +++ b/selftests/functional/resolver.py @@ -201,6 +201,27 @@ def test_exec_runnable_recipe_enabled(self): ) self.assertIn(b"exec-test: 2\n", result.stdout) + @skipUnlessPathExists("/bin/sh") + def test_exec_runnable_recipe_args(self): + resolver_path = os.path.join( + BASEDIR, + "examples", + "nrunner", + "resolvers", + "exec_runnables_recipe_kind.sh", + ) + cmd_line = f"{AVOCADO} -V list --resolver-run-executables --resolver-exec-arguments tap {resolver_path}" + result = process.run(cmd_line) + self.assertIn( + b"tap true-test /bin/true exec-runnables-recipe", + result.stdout, + ) + self.assertIn( + b"tap false-test /bin/false exec-runnables-recipe", + result.stdout, + ) + self.assertIn(b"tap: 2\n", result.stdout) + class ResolverFunctionalTmp(TestCaseTmpDir): def test_runnables_recipe(self):