From 458e53d6768e665e4497a6c2674266952dcf7ef1 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Wed, 18 Sep 2024 17:35:18 -0400 Subject: [PATCH] exec-runnable-recipe resolver: add support for arguments This adds support for used defined arguments to be passed while running the executables that will generate the runnables recipe JSON content. It gives the opportunity for either calling the executables with a particular option that will output the runnables (instead of other action), or tweaking the type of runnables that will be generated. Signed-off-by: Cleber Rosa --- avocado/plugins/list.py | 8 +++++++ avocado/plugins/resolvers.py | 21 ++++++++++++++++++- avocado/plugins/run.py | 8 +++++++ .../source/guides/writer/chapters/recipes.rst | 15 +++++++++++++ .../resolvers/exec_runnables_recipe_kind.sh | 3 +++ selftests/check.py | 2 +- selftests/functional/resolver.py | 21 +++++++++++++++++++ 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100755 examples/nrunner/resolvers/exec_runnables_recipe_kind.sh 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):