-
Notifications
You must be signed in to change notification settings - Fork 340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce "exec-runnables-recipe" resolver #6032
Open
clebergnu
wants to merge
4
commits into
avocado-framework:master
Choose a base branch
from
clebergnu:resolver_exec
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
94982e7
selftests/.data/whiteboard.py: remove unused file
clebergnu 2920bc9
Resolvers: refactor common code that checks for executable files
clebergnu eb9d4e9
Introduce "exec-runnables-recipe" resolver
clebergnu a882899
exec-runnable-recipe resolver: add support for arguments
clebergnu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,10 +19,12 @@ | |
import json | ||
import os | ||
import re | ||
import shlex | ||
import subprocess | ||
|
||
from avocado.core.extension_manager import PluginPriority | ||
from avocado.core.nrunner.runnable import Runnable | ||
from avocado.core.plugin_interfaces import Resolver | ||
from avocado.core.plugin_interfaces import Init, Resolver | ||
from avocado.core.references import reference_split | ||
from avocado.core.resolver import ( | ||
ReferenceResolution, | ||
|
@@ -31,16 +33,12 @@ | |
get_file_assets, | ||
) | ||
from avocado.core.safeloader import find_avocado_tests, find_python_unittests | ||
from avocado.core.settings import settings | ||
|
||
|
||
class ExecTestResolver(Resolver): | ||
|
||
name = "exec-test" | ||
description = "Test resolver for executable files to be handled as tests" | ||
priority = PluginPriority.VERY_LOW | ||
|
||
def resolve(self, reference): | ||
|
||
class BaseExec: | ||
@staticmethod | ||
def check_exec(reference): | ||
criteria_check = check_file( | ||
reference, | ||
reference, | ||
|
@@ -52,6 +50,18 @@ def resolve(self, reference): | |
if criteria_check is not True: | ||
return criteria_check | ||
|
||
|
||
class ExecTestResolver(BaseExec, Resolver): | ||
|
||
name = "exec-test" | ||
description = "Test resolver for executable files to be handled as tests" | ||
priority = PluginPriority.VERY_LOW | ||
|
||
def resolve(self, reference): | ||
exec_criteria = self.check_exec(reference) | ||
if exec_criteria is not None: | ||
return exec_criteria | ||
|
||
runnable = Runnable("exec-test", reference, assets=get_file_assets(reference)) | ||
return ReferenceResolution( | ||
reference, ReferenceResolutionResult.SUCCESS, [runnable] | ||
|
@@ -121,24 +131,16 @@ def resolve(self, reference): | |
) | ||
|
||
|
||
class TapResolver(Resolver): | ||
class TapResolver(BaseExec, Resolver): | ||
|
||
name = "tap" | ||
description = "Test resolver for executable files to be handled as TAP tests" | ||
priority = PluginPriority.LAST_RESORT | ||
|
||
def resolve(self, reference): | ||
|
||
criteria_check = check_file( | ||
reference, | ||
reference, | ||
suffix=None, | ||
type_name="executable file", | ||
access_check=os.R_OK | os.X_OK, | ||
access_name="executable", | ||
) | ||
if criteria_check is not True: | ||
return criteria_check | ||
exec_criteria = self.check_exec(reference) | ||
if exec_criteria is not None: | ||
return exec_criteria | ||
|
||
runnable = Runnable("tap", reference, assets=get_file_assets(reference)) | ||
return ReferenceResolution( | ||
|
@@ -196,3 +198,102 @@ def resolve(self, reference): | |
return criteria_check | ||
|
||
return self._validate_and_load_runnables(reference) | ||
|
||
|
||
class ExecRunnablesRecipeInit(Init): | ||
name = "exec-runnables-recipe" | ||
description = 'Configuration for resolver plugin "exec-runnables-recipe" plugin' | ||
|
||
def initialize(self): | ||
help_msg = ( | ||
'Whether resolvers (such as "exec-runnables-recipe") should ' | ||
"execute files given as test references that have executable " | ||
"permissions. This is disabled by default due to security " | ||
"implications of running executables that may not be trusted." | ||
) | ||
settings.register_option( | ||
section="resolver", | ||
key="run_executables", | ||
key_type=bool, | ||
default=False, | ||
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" | ||
description = "Test resolver for executables that output JSON runnable recipes" | ||
priority = PluginPriority.LOW | ||
|
||
def resolve(self, reference): | ||
if not self.config.get("resolver.run_executables"): | ||
return ReferenceResolution( | ||
reference, | ||
ReferenceResolutionResult.NOTFOUND, | ||
info=( | ||
"Running executables is not enabled. Refer to " | ||
'"resolver.run_executables" configuration option' | ||
), | ||
) | ||
|
||
exec_criteria = self.check_exec(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( | ||
cmd, | ||
stdin=subprocess.DEVNULL, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
) | ||
except (FileNotFoundError, PermissionError) as exc: | ||
return ReferenceResolution( | ||
reference, | ||
ReferenceResolutionResult.NOTFOUND, | ||
info=(f'Failure while running running executable "{reference}": {exc}'), | ||
) | ||
|
||
content, _ = process.communicate() | ||
try: | ||
runnables = json.loads(content) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This whole part from 258 to 280 is duplication of |
||
except json.JSONDecodeError: | ||
return ReferenceResolution( | ||
reference, | ||
ReferenceResolutionResult.NOTFOUND, | ||
info=f'Content generated by running executable "{reference}" is not JSON', | ||
) | ||
|
||
if not ( | ||
isinstance(runnables, list) | ||
and all([isinstance(r, dict) for r in runnables]) | ||
): | ||
return ReferenceResolution( | ||
reference, | ||
ReferenceResolutionResult.NOTFOUND, | ||
info=f"Content generated by running executable {reference} does not look like a runnables recipe JSON content", | ||
) | ||
|
||
return ReferenceResolution( | ||
reference, | ||
ReferenceResolutionResult.SUCCESS, | ||
[Runnable.from_dict(r) for r in runnables], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/bin/sh | ||
echo '[{"kind": "exec-test","uri": "/bin/true","identifier": "true-test"},{"kind": "exec-test","uri": "/bin/false","identifier": "false-test"}]' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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\"}]" |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if this is the best solution, what would happen when there would be more than one
run-executables-resolver
, all of them should get the same arguments?What about have the arguments as part of the reference behind
:
. Like this: