Source code for saltfactories.utils.markers
"""
..
PYTEST_DONT_REWRITE
saltfactories.utils.markers
~~~~~~~~~~~~~~~~~~~~~~~~~~~
PyTest Markers related utilities
"""
import fnmatch
import logging
import pytest
log = logging.getLogger(__name__)
[docs]def check_required_loader_attributes(loader_instance, loader_attr, required_items):
"""
:type loader_instance: ~saltfactories.utils.functional.Loaders
:param loader_instance:
An instance of :py:class:`~saltfactories.utils.functional.Loaders`
:param str loader_attr:
The name of the minion attribute to check, such as 'modules' or 'states'
:param tuple required_items:
The items that must be part of the loader attribute for the decorated test
:return: The modules that are not available
:rtype: set
"""
required_salt_items = set(required_items)
available_items = list(getattr(loader_instance, loader_attr))
not_available_items = set()
name = "__not_available_{items}s__".format(items=loader_attr)
if not hasattr(loader_instance, name):
cached_not_available_items = set()
setattr(loader_instance, name, cached_not_available_items)
loader_instance._reload_all_funcs.append(cached_not_available_items.clear)
else:
cached_not_available_items = getattr(loader_instance, name)
for not_available_item in cached_not_available_items:
if not_available_item in required_salt_items:
not_available_items.add(not_available_item)
required_salt_items.remove(not_available_item)
for required_item_name in required_salt_items:
search_name = required_item_name
if "." not in search_name:
search_name += ".*"
if not fnmatch.filter(available_items, search_name):
not_available_items.add(required_item_name)
cached_not_available_items.add(required_item_name)
return not_available_items
[docs]def evaluate_markers(item):
"""
Fixtures injection based on markers or test skips based on CLI arguments
"""
# Two special markers, requires_salt_modules and requires_salt_states. These need access to a
# saltfactories.utils.functional.Loader instance
# They will use a session_markers_loader fixture to gain access to that
requires_salt_modules_marker = item.get_closest_marker("requires_salt_modules")
if requires_salt_modules_marker is not None:
if requires_salt_modules_marker.kwargs:
raise pytest.UsageError(
"The 'required_salt_modules' marker does not accept keyword arguments"
)
required_salt_modules = requires_salt_modules_marker.args
if not required_salt_modules:
raise pytest.UsageError(
"The 'required_salt_modules' marker needs at least one module name to be passed"
)
for arg in required_salt_modules:
if not isinstance(arg, str):
raise pytest.UsageError(
"The 'required_salt_modules' marker only accepts strings as arguments"
)
session_markers_loader = item._request.getfixturevalue("session_markers_loader")
required_salt_modules = set(required_salt_modules)
not_available_modules = check_required_loader_attributes(
session_markers_loader, "modules", required_salt_modules
)
if not_available_modules:
item._skipped_by_mark = True
if len(not_available_modules) == 1:
pytest.skip("Salt module '{}' is not available".format(*not_available_modules))
pytest.skip("Salt modules not available: {}".format(", ".join(not_available_modules)))
requires_salt_states_marker = item.get_closest_marker("requires_salt_states")
if requires_salt_states_marker is not None:
if requires_salt_states_marker.kwargs:
raise pytest.UsageError(
"The 'required_salt_states' marker does not accept keyword arguments"
)
required_salt_states = requires_salt_states_marker.args
if not required_salt_states:
raise pytest.UsageError(
"The 'required_salt_states' marker needs at least one state module name to be passed"
)
for arg in required_salt_states:
if not isinstance(arg, str):
raise pytest.UsageError(
"The 'required_salt_states' marker only accepts strings as arguments"
)
session_markers_loader = item._request.getfixturevalue("session_markers_loader")
required_salt_states = set(required_salt_states)
not_available_states = check_required_loader_attributes(
session_markers_loader, "states", required_salt_states
)
if not_available_states:
item._skipped_by_mark = True
if len(not_available_states) == 1:
pytest.skip("Salt state module '{}' is not available".format(*not_available_states))
pytest.skip(
"Salt state modules not available: {}".format(", ".join(not_available_states))
)