Skip to content

Commit

Permalink
Merge remote-tracking branch 'clebergnu/runnable_job_suite_config_ide…
Browse files Browse the repository at this point in the history
…ntifier'

Signed-off-by: Cleber Rosa <[email protected]>
  • Loading branch information
clebergnu committed Jun 27, 2024
2 parents 47499b6 + 3a73b30 commit afc71b7
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 47 deletions.
56 changes: 30 additions & 26 deletions avocado/core/nrunner/runnable.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
#: Location used for schemas when packaged (as in RPMs)
SYSTEM_WIDE_SCHEMA_PATH = "/usr/share/avocado/schemas"

#: Configuration used by all runnables, no matter what its kind. The
#: configuration that a kind uses in addition to this is set in their
#: own class attribute "CONFIGURATION_USED"
CONFIGURATION_USED = ["runner.identifier_format"]


class RunnableRecipeInvalidError(Exception):
"""Signals that a runnable recipe is not well formed, contains
Expand Down Expand Up @@ -97,7 +102,7 @@ def __init__(self, kind, uri, *args, config=None, **kwargs):
#: attr:`avocado.core.nrunner.runner.BaseRunner.CONFIGURATION_USED`
self._config = {}
if config is None:
config = self.add_configuration_used(kind, {})
config = self.filter_runnable_config(kind, {})
self.config = config or {}
self.args = args
self.tags = kwargs.pop("tags", None)
Expand All @@ -108,7 +113,6 @@ def __init__(self, kind, uri, *args, config=None, **kwargs):
#: expressing assets that the test will require in order to run.
self.assets = kwargs.pop("assets", None)
self.kwargs = kwargs
self._identifier_format = config.get("runner.identifier_format", "{uri}")

def __repr__(self):
fmt = (
Expand Down Expand Up @@ -152,11 +156,10 @@ def identifier(self):
Since this is formatter, combined values can be used. Example:
"{uri}-{args}".
"""
fmt = self._identifier_format
fmt = self.config.get("runner.identifier_format", "{uri}")

# For the cases where there is no config (when calling the Runnable
# directly
if not fmt:
# Optimize for the most common scenario
if fmt == "{uri}":
return self.uri

# For args we can use the entire list of arguments or with a specific
Expand Down Expand Up @@ -193,10 +196,10 @@ def config(self, config):
configuration_used = Runnable.get_configuration_used_by_kind(self.kind)
if not set(configuration_used).issubset(set(config.keys())):
LOG.warning(
"The runnable config should have values essential for its runner. "
"In this case, it's missing some of the used configuration. In a "
"future avocado version this will raise a ValueError. Please "
"use avocado.core.nrunner.runnable.Runnable.add_configuration_used "
"The runnable config should have only values "
"essential for its runner. In the next version of "
"avocado, this will raise a Value Error. Please "
"use avocado.core.nrunner.runnable.Runnable.filter_runnable_config "
"or avocado.core.nrunner.runnable.Runnable.from_avocado_config"
)
self._config = config
Expand Down Expand Up @@ -297,7 +300,7 @@ def from_avocado_config(cls, kind, uri, *args, config=None, **kwargs):
"""Creates runnable with only essential config for runner of specific kind."""
if not config:
config = {}
config = cls.add_configuration_used(kind, config)
config = cls.filter_runnable_config(kind, config)
return cls(kind, uri, *args, config=config, **kwargs)

@classmethod
Expand All @@ -321,30 +324,31 @@ def get_configuration_used_by_kind(cls, kind):
return configuration_used

@classmethod
def add_configuration_used(cls, kind, config):
def filter_runnable_config(cls, kind, config):
"""
Adds essential configuration values for specific runner.
Returns only essential values for specific runner.
It will add missing configuration in the given config,
complementing it with values from config file and avocado default
configuration.
It will use configuration from argument completed by values from
config file and avocado default configuration.
:param kind: Kind of runner which should use the configuration.
:type kind: str
:param config: Configuration values for runner. If any used configuration
values are missing, the default ones and from config file
will be used.
:param config: Configuration values for runner. If some values will be
missing the default ones and from config file will be
used.
:type config: dict
:returns: Config dict, which has existing entries plus values
essential for runner based on
STANDALONE_EXECUTABLE_CONFIG_USED
:returns: Config dict, which has only values essential for runner
based on STANDALONE_EXECUTABLE_CONFIG_USED
:rtype: dict
"""
whole_config = settings.as_dict()
for config_item in cls.get_configuration_used_by_kind(kind):
if config_item not in config:
config[config_item] = whole_config.get(config_item)
return config
filtered_config = {}
config_items = cls.get_configuration_used_by_kind(kind) + CONFIGURATION_USED
for config_item in config_items:
filtered_config[config_item] = config.get(
config_item, whole_config.get(config_item)
)
return filtered_config

def read_dependencies(self, dependencies_dict):
"""
Expand Down
1 change: 1 addition & 0 deletions avocado/core/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def resolutions_to_runnables(resolutions, config):
if resolution.result != ReferenceResolutionResult.SUCCESS:
continue
for runnable in resolution.resolutions:
runnable.config = runnable.filter_runnable_config(runnable.kind, config)
result.append(runnable)
return result

Expand Down
17 changes: 0 additions & 17 deletions avocado/plugins/runner_nrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from avocado.core.dispatcher import SpawnerDispatcher
from avocado.core.exceptions import JobError, JobFailFast
from avocado.core.messages import MessageHandler
from avocado.core.nrunner.runnable import Runnable
from avocado.core.nrunner.runner import check_runnables_runner_requirements
from avocado.core.output import LOG_JOB
from avocado.core.plugin_interfaces import CLI, Init, SuiteRunner
Expand Down Expand Up @@ -212,18 +211,6 @@ def __init__(self):
super().__init__()
self.status_server_dir = None

@staticmethod
def _update_avocado_configuration_used_on_runnables(runnables, config):
"""Updates the config used on runnables with this suite's config values
:param runnables: the tasks whose runner requirements will be checked
:type runnables: list of :class:`Runnable`
:param config: A config dict to be used on the desired test suite.
:type config: dict
"""
for runnable in runnables:
runnable.config = Runnable.add_configuration_used(runnable.kind, config)

def _determine_status_server(self, test_suite, config_key):
if test_suite.config.get("run.status_server_auto"):
# no UNIX domain sockets on Windows
Expand Down Expand Up @@ -303,10 +290,6 @@ def run_suite(self, job, test_suite):
test_suite.tests
)

self._update_avocado_configuration_used_on_runnables(
test_suite.tests, test_suite.config
)

self._abort_if_missing_runners(missing_requirements)

job.result.tests_total = len(test_suite.tests)
Expand Down
2 changes: 1 addition & 1 deletion selftests/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"job-api-7": 1,
"nrunner-interface": 70,
"nrunner-requirement": 28,
"unit": 669,
"unit": 670,
"jobs": 11,
"functional-parallel": 307,
"functional-serial": 7,
Expand Down
22 changes: 19 additions & 3 deletions selftests/unit/nrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,38 @@ def test_identifier_args(self):
def test_runnable_command_args(self):
runnable = Runnable("noop", "uri", "arg1", "arg2")
actual_args = runnable.get_command_args()
exp_args = ["-k", "noop", "-u", "uri", "-a", "arg1", "-a", "arg2"]
exp_args = [
"-k",
"noop",
"-u",
"uri",
"-c",
'{"runner.identifier_format": "{uri}"}',
"-a",
"arg1",
"-a",
"arg2",
]
self.assertEqual(actual_args, exp_args)

def test_get_dict(self):
runnable = Runnable("noop", "_uri_", "arg1", "arg2")
self.assertEqual(
runnable.get_dict(),
{"kind": "noop", "uri": "_uri_", "args": ("arg1", "arg2"), "config": {}},
{
"kind": "noop",
"uri": "_uri_",
"args": ("arg1", "arg2"),
"config": {"runner.identifier_format": "{uri}"},
},
)

def test_get_json(self):
runnable = Runnable("noop", "_uri_", "arg1", "arg2")
expected = (
'{"kind": "noop", '
'"uri": "_uri_", '
'"config": {}, '
'"config": {"runner.identifier_format": "{uri}"}, '
'"args": ["arg1", "arg2"]}'
)
self.assertEqual(runnable.get_json(), expected)
Expand Down
11 changes: 11 additions & 0 deletions selftests/unit/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ def test_config_extend_automatic(self):
self.suite = TestSuite.from_config(config=suite_config, job_config=job_config)
self.assertEqual(self.suite.config.get("core.show"), ["none"])

def test_config_runnable(self):
config = {
"resolver.references": [
"examples/nrunner/recipes/runnable/noop.json",
],
"runner.identifier_format": "NOT FOO",
}
suite = TestSuite.from_config(config)
runnable = suite.tests[0]
self.assertEqual(runnable.config.get("runner.identifier_format"), "NOT FOO")

def tearDown(self):
self.tmpdir.cleanup()

Expand Down

0 comments on commit afc71b7

Please sign in to comment.