Tests verifying functionality ansible runtime infrastructure
New tests verify callback order of precedence, white list handling and environment variable setting under various conditions. Closes-Bug: #1922726 Signed-off-by: Jiri Podivin <jpodivin@redhat.com> Change-Id: I20b0c9a4289c7c8885e5b1981c8bea81c1deab47
This commit is contained in:
parent
5558cb0d15
commit
1701904ca3
|
@ -19,12 +19,14 @@ try:
|
|||
except ImportError:
|
||||
import mock
|
||||
from unittest import TestCase
|
||||
import os
|
||||
|
||||
from ansible_runner import Runner
|
||||
from validations_libs import constants
|
||||
from validations_libs.ansible import Ansible
|
||||
from validations_libs.tests import fakes
|
||||
|
||||
|
||||
try:
|
||||
version = pkg_resources.get_distribution("ansible_runner").version
|
||||
backward_compat = (version < '1.4.0')
|
||||
|
@ -363,10 +365,10 @@ class TestAnsible(TestCase):
|
|||
return_value="/foo/inventory.yaml")
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch('validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake.py'})
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
@mock.patch('os.environ.copy', return_value={})
|
||||
@mock.patch('os.path.abspath', return_value='/tmp/foo/localhost')
|
||||
def test_run_specific_log_path(self, moch_path, mock_env, mock_env_var,
|
||||
def test_run_specific_log_path(self, mock_path, mock_env, mock_env_var,
|
||||
mock_config, mock_dump_artifact, mock_run,
|
||||
mock_mkdirs, mock_exists, mock_open):
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
|
@ -390,7 +392,7 @@ class TestAnsible(TestCase):
|
|||
if not backward_compat:
|
||||
opt.update({
|
||||
'envvars': {
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake.py',
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CONFIG': '/tmp/foo/artifacts/ansible.cfg',
|
||||
'VALIDATIONS_LOG_DIR': '/tmp/foo'},
|
||||
'project_dir': '/tmp',
|
||||
|
@ -479,3 +481,613 @@ class TestAnsible(TestCase):
|
|||
self.assertEqual((_playbook, _rc, _status),
|
||||
('existing.yaml', 0, 'successful'))
|
||||
mock_open.assert_called_with('/tmp/ansible.cfg', 'w')
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch(
|
||||
'ansible_runner.utils.dump_artifact',
|
||||
autospec=True,
|
||||
return_value="/foo/inventory.yaml")
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
@mock.patch('os.path.abspath', return_value='/tmp/foo/localhost')
|
||||
@mock.patch('os.environ.copy', return_value={})
|
||||
def test_run_no_log_path(self, mock_env, mock_path,
|
||||
mock_env_var, mock_config,
|
||||
mock_dump_artifact, mock_run,
|
||||
mock_exists, mock_open):
|
||||
"""
|
||||
Tests if leaving default (None) log_path appropriately sets
|
||||
'ANSIBLE_CONFIG' and 'fact_cache' envvars,
|
||||
using constants.constants.VALIDATION_ANSIBLE_ARTIFACT_PATH.
|
||||
Bulk of the mocks are only for purposes of convenience.
|
||||
|
||||
Assertions:
|
||||
Presence of key: value pairs.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp')
|
||||
|
||||
opt = {
|
||||
'artifact_dir': '/tmp',
|
||||
'extravars': {},
|
||||
'ident': '',
|
||||
'inventory': '/tmp/foo/localhost',
|
||||
'playbook': 'existing.yaml',
|
||||
'private_data_dir': '/tmp',
|
||||
'quiet': False,
|
||||
'rotate_artifacts': 256,
|
||||
'verbosity': 0}
|
||||
|
||||
if not backward_compat:
|
||||
opt.update({
|
||||
'envvars': {
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CONFIG': os.path.join(
|
||||
constants.VALIDATION_ANSIBLE_ARTIFACT_PATH,
|
||||
'ansible.cfg')},
|
||||
'project_dir': '/tmp',
|
||||
'fact_cache': constants.VALIDATION_ANSIBLE_ARTIFACT_PATH,
|
||||
'fact_cache_type': 'jsonfile'})
|
||||
|
||||
mock_config.assert_called_once_with(**opt)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch(
|
||||
'ansible_runner.utils.dump_artifact',
|
||||
autospec=True,
|
||||
return_value="/foo/inventory.yaml")
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
@mock.patch('os.path.abspath', return_value='/tmp/foo/localhost')
|
||||
@mock.patch('os.environ.copy', return_value={})
|
||||
def test_run_tags(self, mock_env, mock_path,
|
||||
mock_env_var, mock_config,
|
||||
mock_dump_artifact, mock_run,
|
||||
mock_exists, mock_open):
|
||||
"""
|
||||
Tests if specifying tags appropriately sets
|
||||
'tags' envvar, passed as dict entry to RunnerConfig.
|
||||
Bulk of the mocks are only for purposes of convenience.
|
||||
|
||||
Assertions:
|
||||
Presence of key: value pairs.
|
||||
"""
|
||||
tags = ','.join(['master', 'train', 'fake'])
|
||||
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
log_path='/tmp/foo',
|
||||
tags=tags)
|
||||
|
||||
opt = {
|
||||
'artifact_dir': '/tmp',
|
||||
'extravars': {},
|
||||
'ident': '',
|
||||
'inventory': '/tmp/foo/localhost',
|
||||
'playbook': 'existing.yaml',
|
||||
'private_data_dir': '/tmp',
|
||||
'quiet': False,
|
||||
'rotate_artifacts': 256,
|
||||
'verbosity': 0,
|
||||
'tags': tags}
|
||||
|
||||
if not backward_compat:
|
||||
opt.update({
|
||||
'envvars': {
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CONFIG': '/tmp/foo/artifacts/ansible.cfg',
|
||||
'VALIDATIONS_LOG_DIR': '/tmp/foo'},
|
||||
'project_dir': '/tmp',
|
||||
'fact_cache': '/tmp/foo/artifacts/',
|
||||
'fact_cache_type': 'jsonfile'})
|
||||
|
||||
mock_config.assert_called_once_with(**opt)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._encode_envvars',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks',
|
||||
'ANSIBLE_CONFIG': os.path.join(
|
||||
constants.VALIDATION_ANSIBLE_ARTIFACT_PATH,
|
||||
'ansible.cfg')})
|
||||
@mock.patch(
|
||||
'os.environ.copy',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
@mock.patch('os.path.abspath', return_value='/tmp/foo/localhost')
|
||||
def test_run_ansible_playbook_dir(self, mock_path, mock_env,
|
||||
mock_encode_envvars,
|
||||
mock_config, mock_run,
|
||||
mock_exists, mock_open):
|
||||
"""
|
||||
Tests if leaving default (None) log_path and setting playbook_dir
|
||||
appropriately sets 'project_dir' value in r_opts dict.
|
||||
Bulk of the mocks are only for purposes of convenience.
|
||||
|
||||
Assertions:
|
||||
Presence of key: value pairs.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
playbook_dir='/tmp/fake_playbooks')
|
||||
|
||||
opt = {
|
||||
'artifact_dir': '/tmp',
|
||||
'extravars': {},
|
||||
'ident': '',
|
||||
'inventory': '/tmp/foo/localhost',
|
||||
'playbook': 'existing.yaml',
|
||||
'private_data_dir': '/tmp',
|
||||
'quiet': False,
|
||||
'rotate_artifacts': 256,
|
||||
'verbosity': 0}
|
||||
|
||||
if not backward_compat:
|
||||
opt.update({
|
||||
'envvars': {
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CONFIG': os.path.join(
|
||||
constants.VALIDATION_ANSIBLE_ARTIFACT_PATH,
|
||||
'ansible.cfg'),
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks'
|
||||
},
|
||||
'project_dir': '/tmp/fake_playbooks',
|
||||
'fact_cache': constants.VALIDATION_ANSIBLE_ARTIFACT_PATH,
|
||||
'fact_cache_type': 'jsonfile'})
|
||||
|
||||
mock_config.assert_called_once_with(**opt)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'log_plays,mail,fake,validation_json,profile_tasks'
|
||||
})
|
||||
@mock.patch('os.environ.copy', return_value={})
|
||||
def test_run_callback_whitelist_extend(self, mock_env,
|
||||
mock_env_var, mock_config,
|
||||
mock_run, mock_exists,
|
||||
mock_open):
|
||||
"""Tests if Ansible._callbacks method appropriately constructs callback_whitelist,
|
||||
when provided explicit whitelist and output_callback.
|
||||
Bulk of the mocks are only for purposes of convenience.
|
||||
|
||||
Assertions:
|
||||
Presence of key: value pairs.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
ssh_user='root',
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
log_path='/tmp/foo',
|
||||
output_callback='fake',
|
||||
callback_whitelist='log_plays,mail')
|
||||
|
||||
args = {
|
||||
'output_callback': 'fake',
|
||||
'ssh_user': 'root',
|
||||
'workdir': '/tmp',
|
||||
'connection': 'smart',
|
||||
'gathering_policy': 'smart',
|
||||
'module_path': None,
|
||||
'key': None,
|
||||
'extra_env_variables': None,
|
||||
'ansible_timeout': 30,
|
||||
'callback_whitelist': 'log_plays,mail,fake,profile_tasks,vf_validation_json',
|
||||
'base_dir': '/usr/share/ansible',
|
||||
'python_interpreter': None}
|
||||
|
||||
#Specific form of Ansible.env_var neccessiates convoluted arg unpacking.
|
||||
mock_env_var.assert_called_once_with(*args.values(), validation_cfg_file=None)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks'
|
||||
})
|
||||
@mock.patch('os.environ.copy', return_value={})
|
||||
def test_run_callback_whitelist_none(self, mock_env,
|
||||
mock_env_var, mock_config,
|
||||
mock_run, mock_exists,
|
||||
mock_open):
|
||||
"""Tests if Ansible._callbacks method appropriately constructs callback_whitelist,
|
||||
when provided default (None) whitelist and specific output_callback.
|
||||
Bulk of the mocks are only for purposes of convenience.
|
||||
|
||||
Assertions:
|
||||
Presence of key: value pairs.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
ssh_user='root',
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
log_path='/tmp/foo',
|
||||
output_callback='fake')
|
||||
|
||||
args = {
|
||||
'output_callback': 'fake',
|
||||
'ssh_user': 'root',
|
||||
'workdir': '/tmp',
|
||||
'connection': 'smart',
|
||||
'gathering_policy': 'smart',
|
||||
'module_path': None,
|
||||
'key': None,
|
||||
'extra_env_variables': None,
|
||||
'ansible_timeout': 30,
|
||||
'callback_whitelist': 'fake,profile_tasks,vf_validation_json',
|
||||
'base_dir': '/usr/share/ansible',
|
||||
'python_interpreter': None}
|
||||
|
||||
#Specific form of Ansible.env_var neccessiates convoluted arg unpacking.
|
||||
mock_env_var.assert_called_once_with(*args.values(), validation_cfg_file=None)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'different_fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'different_fake,validation_json,profile_tasks'
|
||||
})
|
||||
@mock.patch(
|
||||
'os.environ.copy',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'different_fake'})
|
||||
def test_run_callback_precedence(self, mock_env,
|
||||
mock_env_var, mock_config,
|
||||
mock_run, mock_exists, mock_open):
|
||||
"""Tests if Ansible._callbacks method reaches for output_callback
|
||||
if and only if env dict doesn't contain 'ANSIBLE_STDOUT_CALLBACK' key.
|
||||
Bulk of the mocks are only for purposes of convenience.
|
||||
|
||||
Assertions:
|
||||
Presence of key: value pairs.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
ssh_user='root',
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
log_path='/tmp/foo',
|
||||
output_callback='fake')
|
||||
|
||||
args = {
|
||||
'output_callback': 'different_fake',
|
||||
'ssh_user': 'root',
|
||||
'workdir': '/tmp',
|
||||
'connection': 'smart',
|
||||
'gathering_policy': 'smart',
|
||||
'module_path': None,
|
||||
'key': None,
|
||||
'extra_env_variables': None,
|
||||
'ansible_timeout': 30,
|
||||
'callback_whitelist': 'different_fake,profile_tasks,vf_validation_json',
|
||||
'base_dir': '/usr/share/ansible',
|
||||
'python_interpreter': None}
|
||||
|
||||
#Specific form of Ansible.env_var neccessiates convoluted arg unpacking.
|
||||
mock_env_var.assert_called_once_with(*args.values(), validation_cfg_file=None)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks'
|
||||
})
|
||||
@mock.patch(
|
||||
'os.environ.copy',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
def test_run_ansible_artifact_path_set(self, mock_env,
|
||||
mock_env_var, mock_config,
|
||||
mock_run, mock_exists, mock_open):
|
||||
"""Tests if specified 'ansible_artifact_path' is passed in a valid
|
||||
and unchanged form to RunnerConfig as value of 'fact_cache' param.
|
||||
Additional assertion on number of calls is placed,
|
||||
to ensure that RunnerConfig is called only once.
|
||||
Otherwise followup assertions could fail.
|
||||
|
||||
Assertions:
|
||||
Validity of specified path in filesystem:
|
||||
os.lstat raises FileNotFoundError only if specified path is valid,
|
||||
but does not exist in current filesystem.
|
||||
|
||||
Passing of specified value (ansible_artifact_path) to RunnerConfig.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
log_path='/tmp/foo',
|
||||
output_callback='fake',
|
||||
ansible_artifact_path='/tmp/artifact/path')
|
||||
|
||||
mock_config.assert_called_once()
|
||||
|
||||
"""Is the path even valid in our filesystem? Index 1 stands for kwargs in py<=36.
|
||||
os.lstat raises FileNotFoundError only if specified path is valid,
|
||||
but does not exist in current filesystem.
|
||||
"""
|
||||
self.assertRaises(FileNotFoundError, os.lstat, mock_config.call_args[1]['fact_cache'])
|
||||
|
||||
self.assertTrue('/tmp/artifact/path' in mock_config.call_args[1]['fact_cache'])
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks'
|
||||
})
|
||||
@mock.patch(
|
||||
'os.environ.copy',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
def test_run_ansible_artifact_path_from_log_path(self, mock_env,
|
||||
mock_env_var, mock_config,
|
||||
mock_run, mock_exists, mock_open):
|
||||
"""Tests if specified 'log_path' is passed in a valid
|
||||
and unchanged form to RunnerConfig as value of 'fact_cache' param,
|
||||
in absence of specified 'ansible_artifact_path'.
|
||||
Additional assertion on number of calls is placed,
|
||||
to ensure that RunnerConfig is called only once.
|
||||
Otherwise followup assertions could fail.
|
||||
|
||||
Assertions:
|
||||
Validity of specified path in filesystem.:
|
||||
os.lstat raises FileNotFoundError only if specified path is valid,
|
||||
but does not exist in current filesystem.
|
||||
|
||||
Passing of specified value (log_path) to RunnerConfig.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
log_path='/tmp/foo',
|
||||
output_callback='fake')
|
||||
|
||||
mock_config.assert_called_once()
|
||||
"""Is the path even valid in our filesystem? Index 1 stands for kwargs in py<=36.
|
||||
os.lstat raises FileNotFoundError only if specified path is valid,
|
||||
but does not exist in current filesystem.
|
||||
"""
|
||||
self.assertRaises(FileNotFoundError, os.lstat, mock_config.call_args[1]['fact_cache'])
|
||||
|
||||
self.assertTrue('/tmp/foo' in mock_config.call_args[1]['fact_cache'])
|
||||
|
||||
@mock.patch.object(
|
||||
constants,
|
||||
'VALIDATION_ANSIBLE_ARTIFACT_PATH',
|
||||
new='foo/bar')
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._ansible_env_var',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks',
|
||||
})
|
||||
@mock.patch(
|
||||
'os.environ.copy',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
def test_run_ansible_artifact_path_from_constants(self, mock_env,
|
||||
mock_env_var, mock_config,
|
||||
mock_run, mock_exists,
|
||||
mock_open):
|
||||
"""Tests if 'constants.constants.VALIDATION_ANSIBLE_ARTIFACT_PATH' passed in a valid
|
||||
and unchanged form to RunnerConfig as value of 'fact_cache' param,
|
||||
in absence of specified 'ansible_artifact_path' or 'log_path'.
|
||||
Additional assertion on number of calls is placed,
|
||||
to ensure that RunnerConfig is called only once.
|
||||
Otherwise followup assertions could fail.
|
||||
|
||||
Assertions:
|
||||
Validity of specified path in filesystem.:
|
||||
os.lstat raises FileNotFoundError only if specified path is valid,
|
||||
but does not exist in current filesystem.
|
||||
|
||||
Passing of specified value (log_path) to RunnerConfig.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp')
|
||||
|
||||
mock_config.assert_called_once()
|
||||
"""Is the path even valid in our filesystem? Index 1 stands for kwargs in py<=36.
|
||||
os.lstat raises FileNotFoundError only if specified path is valid,
|
||||
but does not exist in current filesystem.
|
||||
"""
|
||||
self.assertRaises(FileNotFoundError, os.lstat, mock_config.call_args[1]['fact_cache'])
|
||||
|
||||
self.assertTrue(constants.VALIDATION_ANSIBLE_ARTIFACT_PATH in mock_config.call_args[1]['fact_cache'])
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._encode_envvars',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks',
|
||||
'ANSIBLE_CONFIG': os.path.join(
|
||||
constants.VALIDATION_ANSIBLE_ARTIFACT_PATH,
|
||||
'ansible.cfg')})
|
||||
@mock.patch(
|
||||
'os.environ.copy',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
def test_run_ansible_envvars(self, mock_env,
|
||||
mock_encode_envvars,
|
||||
mock_config, mock_run,
|
||||
mock_exists, mock_open):
|
||||
"""Tests if Ansible._ansible_env_var method,
|
||||
and following conditionals, correctly assemble the env dict.
|
||||
|
||||
Assertions:
|
||||
Dictinary passed to Ansible._encode_envvars contains key: value
|
||||
pairs representing proper superset of key: value pairs required.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp')
|
||||
|
||||
env = {
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_DISPLAY_FAILED_STDERR': True,
|
||||
'ANSIBLE_FORKS': 36,
|
||||
'ANSIBLE_TIMEOUT': 30,
|
||||
'ANSIBLE_GATHER_TIMEOUT': 45,
|
||||
'ANSIBLE_SSH_RETRIES': 3,
|
||||
'ANSIBLE_PIPELINING': True,
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,profile_tasks,vf_validation_json',
|
||||
'ANSIBLE_RETRY_FILES_ENABLED': False,
|
||||
'ANSIBLE_HOST_KEY_CHECKING': False,
|
||||
'ANSIBLE_TRANSPORT': 'smart',
|
||||
'ANSIBLE_CACHE_PLUGIN_TIMEOUT': 7200,
|
||||
'ANSIBLE_GATHERING': 'smart',
|
||||
'ANSIBLE_CONFIG': os.path.join(
|
||||
constants.VALIDATION_ANSIBLE_ARTIFACT_PATH,
|
||||
'ansible.cfg')}
|
||||
|
||||
#Test will work properly only if the method was called once.
|
||||
mock_encode_envvars.assert_called_once()
|
||||
|
||||
"""True if, and only if, every item (key:value pair) in the env dict
|
||||
is also present in the kwargs dict. Index 1 stands for kwargs in py<=36
|
||||
This test does not rely on order of items.
|
||||
"""
|
||||
self.assertGreaterEqual(
|
||||
mock_encode_envvars.call_args[1]['env'].items(),
|
||||
env.items())
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch.object(
|
||||
Runner,
|
||||
'run',
|
||||
return_value=fakes.fake_ansible_runner_run_return(rc=0))
|
||||
@mock.patch('ansible_runner.runner_config.RunnerConfig')
|
||||
@mock.patch(
|
||||
'validations_libs.ansible.Ansible._encode_envvars',
|
||||
return_value={
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,validation_json,profile_tasks',
|
||||
'ANSIBLE_CONFIG': '/tmp/foo/artifacts/ansible.cfg'})
|
||||
@mock.patch(
|
||||
'os.environ.copy',
|
||||
return_value={'ANSIBLE_STDOUT_CALLBACK': 'fake'})
|
||||
def test_run_ansible_envvars_logdir(self, mock_env,
|
||||
mock_encode_envvars,
|
||||
mock_config, mock_run,
|
||||
mock_exists, mock_open):
|
||||
"""Tests if Ansible._ansible_env_var method,
|
||||
and following conditionals, correctly assemble the env dict.
|
||||
While using the specified `log_path` value in appropriate places.
|
||||
|
||||
Assertions:
|
||||
Dictinary passed to Ansible._encode_envvars contains key: value
|
||||
pairs representing proper superset of key: value pairs required.
|
||||
"""
|
||||
_playbook, _rc, _status = self.run.run(
|
||||
playbook='existing.yaml',
|
||||
inventory='localhost,',
|
||||
workdir='/tmp',
|
||||
log_path='/tmp/foo')
|
||||
|
||||
env = {
|
||||
'ANSIBLE_STDOUT_CALLBACK': 'fake',
|
||||
'ANSIBLE_DISPLAY_FAILED_STDERR': True,
|
||||
'ANSIBLE_FORKS': 36,
|
||||
'ANSIBLE_TIMEOUT': 30,
|
||||
'ANSIBLE_GATHER_TIMEOUT': 45,
|
||||
'ANSIBLE_SSH_RETRIES': 3,
|
||||
'ANSIBLE_PIPELINING': True,
|
||||
'ANSIBLE_CALLBACK_WHITELIST': 'fake,profile_tasks,vf_validation_json',
|
||||
'ANSIBLE_RETRY_FILES_ENABLED': False,
|
||||
'ANSIBLE_HOST_KEY_CHECKING': False,
|
||||
'ANSIBLE_TRANSPORT': 'smart',
|
||||
'ANSIBLE_CACHE_PLUGIN_TIMEOUT': 7200,
|
||||
'ANSIBLE_GATHERING': 'smart',
|
||||
'ANSIBLE_CONFIG': '/tmp/foo/artifacts/ansible.cfg',
|
||||
'VALIDATIONS_LOG_DIR': '/tmp/foo'}
|
||||
|
||||
#Test will work properly only if the method was called once.
|
||||
mock_encode_envvars.assert_called_once()
|
||||
|
||||
"""True if, and only if, every item (key:value pair) in the env dict
|
||||
is also present in the kwargs dict. Index 1 stands for kwargs in py<=36
|
||||
This test does not rely on order of items.
|
||||
"""
|
||||
self.assertGreaterEqual(
|
||||
mock_encode_envvars.call_args[1]['env'].items(),
|
||||
env.items())
|
||||
|
|
Loading…
Reference in New Issue