mirror of https://github.com/ansible/ansible.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
3.2 KiB
Python
74 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.abc
|
|
import importlib.util
|
|
|
|
import ansible
|
|
import pathlib
|
|
import pytest
|
|
|
|
from ansible.module_utils._internal import _messages
|
|
from ansible.module_utils._internal import _deprecator
|
|
|
|
|
|
class FakePathLoader(importlib.abc.SourceLoader):
|
|
"""A test loader that can fake out the code/frame paths to simulate callers of various types without relying on actual files on disk."""
|
|
def get_filename(self, fullname):
|
|
if fullname.startswith('ansible.'):
|
|
basepath = pathlib.Path(ansible.__file__).parent.parent
|
|
else:
|
|
basepath = '/x/y'
|
|
|
|
return f'{basepath}/{fullname.replace(".", "/")}'
|
|
|
|
def get_data(self, path):
|
|
return b'''
|
|
from ansible.module_utils._internal import _deprecator
|
|
|
|
def do_stuff():
|
|
return _deprecator.get_caller_plugin_info()
|
|
'''
|
|
|
|
def exec_module(self, module):
|
|
return super().exec_module(module)
|
|
|
|
|
|
@pytest.mark.parametrize("python_fq_name,expected_resolved_name,expected_plugin_type", (
|
|
# legacy module callers
|
|
('ansible.legacy.blah', 'ansible.legacy.blah', 'module'),
|
|
# core callers
|
|
('ansible.modules.ping', 'ansible.builtin.ping', 'module'),
|
|
('ansible.plugins.filters.core', _deprecator.ANSIBLE_CORE_DEPRECATOR.resolved_name, _deprecator.ANSIBLE_CORE_DEPRECATOR.type),
|
|
('ansible.plugins.tests.core', _deprecator.ANSIBLE_CORE_DEPRECATOR.resolved_name, _deprecator.ANSIBLE_CORE_DEPRECATOR.type),
|
|
('ansible.nonplugin_something', _deprecator.ANSIBLE_CORE_DEPRECATOR.resolved_name, _deprecator.ANSIBLE_CORE_DEPRECATOR.type),
|
|
# collections plugin callers
|
|
('ansible_collections.foo.bar.plugins.modules.module_thing', 'foo.bar.module_thing', 'module'),
|
|
('ansible_collections.foo.bar.plugins.filter.somefilter', 'foo.bar', _deprecator._COLLECTION_ONLY_TYPE),
|
|
('ansible_collections.foo.bar.plugins.test.sometest', 'foo.bar', _deprecator._COLLECTION_ONLY_TYPE),
|
|
# indeterminate callers (e.g. collection module_utils- must specify since they might be calling on behalf of another
|
|
('ansible_collections.foo.bar.plugins.module_utils.something',
|
|
_deprecator.INDETERMINATE_DEPRECATOR.resolved_name, _deprecator.INDETERMINATE_DEPRECATOR.type),
|
|
# other callers
|
|
('something.else', None, None),
|
|
('ansible_collections.foo.bar.nonplugin_something', None, None),
|
|
))
|
|
def test_get_caller_plugin_info(python_fq_name: str, expected_resolved_name: str, expected_plugin_type: str):
|
|
"""Validates the expected `PluginInfo` values received from various types of core/non-core/collection callers."""
|
|
# invoke a standalone fake loader that generates a Python module with the specified FQ python name (converted to a corresponding __file__ entry) that
|
|
# pretends as if it called `get_caller_plugin_info()` and returns its result
|
|
loader = FakePathLoader()
|
|
spec = importlib.util.spec_from_loader(name=python_fq_name, loader=loader)
|
|
mod = importlib.util.module_from_spec(spec)
|
|
|
|
loader.exec_module(mod)
|
|
|
|
pi: _messages.PluginInfo = mod.do_stuff()
|
|
|
|
if not expected_resolved_name and not expected_plugin_type:
|
|
assert pi is None
|
|
return
|
|
|
|
assert pi is not None
|
|
assert pi.resolved_name == expected_resolved_name
|
|
assert pi.type == expected_plugin_type
|