Remove the use of mock from validate-modules (#50098)

* Remove the use of mock from validate-modules

* Monkeypatch AnsibleModule.__init__ not AnsibleModule
pull/50106/head
Matt Martz 6 years ago committed by GitHub
parent ee29ba5d4f
commit 6025990fe9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,16 +21,9 @@ import sys
from contextlib import contextmanager from contextlib import contextmanager
import mock
from ansible.module_utils.six import reraise from ansible.module_utils.six import reraise
MODULE_CLASSES = [
'ansible.module_utils.basic.AnsibleModule',
]
class AnsibleModuleCallError(RuntimeError): class AnsibleModuleCallError(RuntimeError):
pass pass
@ -39,20 +32,39 @@ class AnsibleModuleImportError(ImportError):
pass pass
class _FakeAnsibleModuleInit:
def __init__(self):
self.args = tuple()
self.kwargs = {}
self.called = False
def __call__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.called = True
raise AnsibleModuleCallError('AnsibleModuleCallError')
def _fake_load_params():
pass
@contextmanager @contextmanager
def add_mocks(filename): def setup_env(filename):
# Used to clean up imports later # Used to clean up imports later
pre_sys_modules = list(sys.modules.keys()) pre_sys_modules = list(sys.modules.keys())
module_mock = mock.MagicMock() fake = _FakeAnsibleModuleInit()
for module_class in MODULE_CLASSES: module = __import__('ansible.module_utils.basic').module_utils.basic
p = mock.patch('%s.__init__' % module_class, new=module_mock).start() _original_init = module.AnsibleModule.__init__
p.side_effect = AnsibleModuleCallError('AnsibleModuleCallError') _original_load_params = module._load_params
mock.patch('ansible.module_utils.basic._load_params').start() setattr(module.AnsibleModule, '__init__', fake)
setattr(module, '_load_params', _fake_load_params)
yield module_mock yield fake
mock.patch.stopall() setattr(module.AnsibleModule, '__init__', _original_init)
setattr(module, '_load_params', _original_load_params)
# Clean up imports to prevent issues with mutable data being used in modules # Clean up imports to prevent issues with mutable data being used in modules
for k in list(sys.modules.keys()): for k in list(sys.modules.keys()):
@ -63,10 +75,13 @@ def add_mocks(filename):
def get_argument_spec(filename): def get_argument_spec(filename):
with add_mocks(filename) as module_mock: with setup_env(filename) as fake:
try: try:
# We use ``module`` here instead of ``__main__``
# which helps with some import issues in this tool
# where modules may import things that conflict
mod = imp.load_source('module', filename) mod = imp.load_source('module', filename)
if not module_mock.call_args: if not fake.called:
mod.main() mod.main()
except AnsibleModuleCallError: except AnsibleModuleCallError:
pass pass
@ -74,10 +89,9 @@ def get_argument_spec(filename):
reraise(AnsibleModuleImportError, AnsibleModuleImportError('%s' % e), sys.exc_info()[2]) reraise(AnsibleModuleImportError, AnsibleModuleImportError('%s' % e), sys.exc_info()[2])
try: try:
args, kwargs = module_mock.call_args
try: try:
return kwargs['argument_spec'], args, kwargs return fake.kwargs['argument_spec'], fake.args, fake.kwargs
except KeyError: except KeyError:
return args[0], args, kwargs return fake.args[0], fake.args, fake.kwargs
except TypeError: except TypeError:
return {}, (), {} return {}, (), {}

Loading…
Cancel
Save