Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions tests/common/devices/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import logging
import collections
import os
import signal
import threading
from contextlib import contextmanager
Expand Down Expand Up @@ -42,6 +43,11 @@ def ansible_tqm_has_signal_registration():
_signal_patch_lock = threading.RLock()
_signal_patch_ref_count = 0
_original_signal = None
# pytest-ansible resolves modules through mutable plugin-loader caches shared
# by threads in each Python process. Reset the process-local lock after fork so
# a child cannot inherit it while held by a vanished parent thread.
_ansible_module_resolution_lock = threading.RLock()
Comment thread
auspham marked this conversation as resolved.
os.register_at_fork(after_in_child=_ansible_module_resolution_lock._at_fork_reinit)


@contextmanager
Expand Down Expand Up @@ -158,21 +164,27 @@ def __init__(self, ansible_adhoc, hostname, *args, **kwargs):
self.hostname = hostname

def __getattr__(self, module_name):
if self.host.has_module(module_name):
with _ansible_module_resolution_lock:
has_module = self.host.has_module(module_name)
if has_module:
Comment thread
auspham marked this conversation as resolved.
def _run_wrapper(*module_args, **kwargs):
return self._run(module_name, *module_args, **kwargs)
return _run_wrapper
raise AttributeError(
"'%s' object has no attribute '%s'" % (self.__class__, module_name)
)

def _get_ansible_module(self, module_name):
with _ansible_module_resolution_lock:
Comment thread
auspham marked this conversation as resolved.
return getattr(self.host, module_name)

def _run(self, module_name, *module_args, **complex_args):

previous_frame = inspect.currentframe().f_back
filename, line_number, function_name, lines, index = inspect.getframeinfo(previous_frame)

verbose = complex_args.pop('verbose', True)
module = getattr(self.host, module_name)
module = self._get_ansible_module(module_name)
if verbose:
logger.debug(
"{}::{}#{}: [{}] AnsibleModule::{}, args={}, kwargs={}".format(
Expand Down
Loading