Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:GA
salt.17876
do-not-make-ansiblegate-to-crash-on-python3-min...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File do-not-make-ansiblegate-to-crash-on-python3-minions.patch of Package salt.17876
From 235cca81be2f64ed3feb48ed42bfa3f9196bff39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= <psuarezhernandez@suse.com> Date: Fri, 28 Jun 2019 15:17:56 +0100 Subject: [PATCH] Do not make ansiblegate to crash on Python3 minions Fix pylint issues Move MockTimedProc implementation to tests.support.mock Add unit test for ansible caller --- salt/modules/ansiblegate.py | 14 +++++++++--- tests/support/mock.py | 31 +++++++++++++++++++++++++ tests/unit/modules/test_ansiblegate.py | 41 ++++++++++++++++++++++++++++++++++ tests/unit/modules/test_cmdmod.py | 35 ++--------------------------- 4 files changed, 85 insertions(+), 36 deletions(-) diff --git a/salt/modules/ansiblegate.py b/salt/modules/ansiblegate.py index 6b903c2b94..8e28fcafa3 100644 --- a/salt/modules/ansiblegate.py +++ b/salt/modules/ansiblegate.py @@ -147,6 +147,10 @@ class AnsibleModuleCaller(object): :param kwargs: keywords to the module :return: ''' + if six.PY3: + python_exec = 'python3' + else: + python_exec = 'python' module = self._resolver.load_module(module) if not hasattr(module, 'main'): @@ -162,9 +166,13 @@ class AnsibleModuleCaller(object): ["echo", "{0}".format(js_args)], stdout=subprocess.PIPE, timeout=self.timeout) proc_out.run() + if six.PY3: + proc_out_stdout = proc_out.stdout.decode() + else: + proc_out_stdout = proc_out.stdout proc_exc = salt.utils.timed_subprocess.TimedProc( - ['python', module.__file__], - stdin=proc_out.stdout, stdout=subprocess.PIPE, timeout=self.timeout) + [python_exec, module.__file__], + stdin=proc_out_stdout, stdout=subprocess.PIPE, timeout=self.timeout) proc_exc.run() try: @@ -263,7 +271,7 @@ def help(module=None, *args): description = doc.get('description') or '' del doc['description'] ret['Description'] = description - ret['Available sections on module "{}"'.format(module.__name__.replace('ansible.modules.', ''))] = doc.keys() + ret['Available sections on module "{}"'.format(module.__name__.replace('ansible.modules.', ''))] = [i for i in doc.keys()] else: for arg in args: info = doc.get(arg) diff --git a/tests/support/mock.py b/tests/support/mock.py index 805a60377c..67ecb4838a 100644 --- a/tests/support/mock.py +++ b/tests/support/mock.py @@ -461,6 +461,37 @@ class MockOpen(object): ret.extend(fh_.writelines_calls) return ret +class MockTimedProc(object): + ''' + Class used as a stand-in for salt.utils.timed_subprocess.TimedProc + ''' + class _Process(object): + ''' + Used to provide a dummy "process" attribute + ''' + def __init__(self, returncode=0, pid=12345): + self.returncode = returncode + self.pid = pid + + def __init__(self, stdout=None, stderr=None, returncode=0, pid=12345): + if stdout is not None and not isinstance(stdout, bytes): + raise TypeError('Must pass stdout to MockTimedProc as bytes') + if stderr is not None and not isinstance(stderr, bytes): + raise TypeError('Must pass stderr to MockTimedProc as bytes') + self._stdout = stdout + self._stderr = stderr + self.process = self._Process(returncode=returncode, pid=pid) + + def run(self): + pass + + @property + def stdout(self): + return self._stdout + + @property + def stderr(self): + return self._stderr # reimplement mock_open to support multiple filehandles mock_open = MockOpen diff --git a/tests/unit/modules/test_ansiblegate.py b/tests/unit/modules/test_ansiblegate.py index 5613a0e79b..b7b43efda4 100644 --- a/tests/unit/modules/test_ansiblegate.py +++ b/tests/unit/modules/test_ansiblegate.py @@ -29,11 +29,13 @@ from tests.support.unit import TestCase, skipIf from tests.support.mock import ( patch, MagicMock, + MockTimedProc, ) import salt.modules.ansiblegate as ansible import salt.utils.platform from salt.exceptions import LoaderError +from salt.ext import six @skipIf(NO_PYTEST, False) @@ -134,3 +136,42 @@ description: ''' with patch('salt.modules.ansiblegate.ansible', None): assert ansible.__virtual__() == 'ansible' + + def test_ansible_module_call(self): + ''' + Test Ansible module call from ansible gate module + + :return: + ''' + + class Module(object): + ''' + An ansible module mock. + ''' + __name__ = 'one.two.three' + __file__ = 'foofile' + + def main(): + pass + + ANSIBLE_MODULE_ARGS = '{"ANSIBLE_MODULE_ARGS": ["arg_1", {"kwarg1": "foobar"}]}' + + proc = MagicMock(side_effect=[ + MockTimedProc( + stdout=ANSIBLE_MODULE_ARGS.encode(), + stderr=None), + MockTimedProc(stdout='{"completed": true}'.encode(), stderr=None) + ]) + + with patch.object(ansible, '_resolver', self.resolver), \ + patch.object(ansible._resolver, 'load_module', MagicMock(return_value=Module())): + _ansible_module_caller = ansible.AnsibleModuleCaller(ansible._resolver) + with patch('salt.utils.timed_subprocess.TimedProc', proc): + ret = _ansible_module_caller.call("one.two.three", "arg_1", kwarg1="foobar") + if six.PY3: + proc.assert_any_call(['echo', '{"ANSIBLE_MODULE_ARGS": {"kwarg1": "foobar", "_raw_params": "arg_1"}}'], stdout=-1, timeout=1200) + proc.assert_any_call(['python3', 'foofile'], stdin=ANSIBLE_MODULE_ARGS, stdout=-1, timeout=1200) + else: + proc.assert_any_call(['echo', '{"ANSIBLE_MODULE_ARGS": {"_raw_params": "arg_1", "kwarg1": "foobar"}}'], stdout=-1, timeout=1200) + proc.assert_any_call(['python', 'foofile'], stdin=ANSIBLE_MODULE_ARGS, stdout=-1, timeout=1200) + assert ret == {"completed": True, "timeout": 1200} diff --git a/tests/unit/modules/test_cmdmod.py b/tests/unit/modules/test_cmdmod.py index 8170a56b4e..f8fba59294 100644 --- a/tests/unit/modules/test_cmdmod.py +++ b/tests/unit/modules/test_cmdmod.py @@ -26,6 +26,7 @@ from tests.support.helpers import TstSuiteLoggingHandler from tests.support.mock import ( mock_open, Mock, + MockTimedProc, MagicMock, patch ) @@ -36,39 +37,7 @@ MOCK_SHELL_FILE = '# List of acceptable shells\n' \ '/bin/bash\n' -class MockTimedProc(object): - ''' - Class used as a stand-in for salt.utils.timed_subprocess.TimedProc - ''' - class _Process(object): - ''' - Used to provide a dummy "process" attribute - ''' - def __init__(self, returncode=0, pid=12345): - self.returncode = returncode - self.pid = pid - - def __init__(self, stdout=None, stderr=None, returncode=0, pid=12345): - if stdout is not None and not isinstance(stdout, bytes): - raise TypeError('Must pass stdout to MockTimedProc as bytes') - if stderr is not None and not isinstance(stderr, bytes): - raise TypeError('Must pass stderr to MockTimedProc as bytes') - self._stdout = stdout - self._stderr = stderr - self.process = self._Process(returncode=returncode, pid=pid) - - def run(self): - pass - - @property - def stdout(self): - return self._stdout - - @property - def stderr(self): - return self._stderr - - +@skipIf(NO_MOCK, NO_MOCK_REASON) class CMDMODTestCase(TestCase, LoaderModuleMockMixin): ''' Unit tests for the salt.modules.cmdmod module -- 2.16.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor