ansible-runner/test/integration/test___main__.py
2021-03-03 11:36:53 +08:00

250 lines
6.9 KiB
Python

import os
import sys
import uuid
import json
import random
import string
import tempfile
import shutil
from pytest import raises
from unittest.mock import patch
from ansible_runner.__main__ import main
def random_string():
return ''.join(random.choice(string.ascii_uppercase + string.digits)
for _ in range(random.randint(3, 20)))
def random_json(keys=None):
data = dict()
if keys:
for key in keys:
data[key] = random_string()
else:
for _ in range(0, 5):
data[random_string()] = random_string()
return json.dumps(data)
def cmdline(command, *args):
cmdline = ['ansible-runner', command]
cmdline.extend(args)
sys.argv = cmdline
def test_main_bad_private_data_dir():
tmpfile = os.path.join('/tmp', str(uuid.uuid4().hex))
open(tmpfile, 'w').write(random_string())
cmdline('run', tmpfile, '-p', 'fake')
try:
with raises(OSError):
main()
finally:
os.remove(tmpfile)
def run_role(options, private_data_dir=None, expected_rc=0):
try:
private_data_dir = private_data_dir or tempfile.mkdtemp()
args = ['run', private_data_dir]
args.extend(options)
with patch('ansible_runner.interface.run') as mock_run:
with raises(SystemExit) as exc:
main()
assert exc.type == SystemExit
assert exc.value.code == expected_rc
finally:
shutil.rmtree(private_data_dir)
return mock_run
def test_cmdline_role_defaults():
"""Run a role directly with all command line defaults
"""
private_data_dir = tempfile.mkdtemp()
options = ['-r' , 'test']
playbook = [{'hosts': 'all', 'gather_facts': True, 'roles': [{'role': 'test'}]}]
run_options = {
'private_data_dir': private_data_dir,
'playbook': playbook
}
result = run_role(options, private_data_dir)
result.called_with_args([run_options])
def test_cmdline_role_skip_facts():
"""Run a role directly and set --role-skip-facts option
"""
private_data_dir = tempfile.mkdtemp()
options = ['-r' , 'test', '--role-skip-facts']
playbook = [{'hosts': 'all', 'gather_facts': False, 'roles': [{'role': 'test'}]}]
run_options = {
'private_data_dir': private_data_dir,
'playbook': playbook
}
result = run_role(options, private_data_dir)
result.called_with_args([run_options])
def test_cmdline_role_inventory():
"""Run a role directly and set --inventory option
"""
private_data_dir = tempfile.mkdtemp()
options = ['-r' , 'test', '--inventory hosts']
playbook = [{'hosts': 'all', 'gather_facts': False, 'roles': [{'role': 'test'}]}]
run_options = {
'private_data_dir': private_data_dir,
'playbook': playbook,
'inventory': 'hosts'
}
result = run_role(options, private_data_dir)
result.called_with_args([run_options])
def test_cmdline_role_vars():
"""Run a role directly and set --role-vars option
"""
private_data_dir = tempfile.mkdtemp()
options = ['-r' , 'test', '--role-vars "foo=bar"']
playbook = [{
'hosts': 'all',
'gather_facts': False,
'roles': [{
'role': 'test',
'vars': {'foo': 'bar'}
}]
}]
run_options = {
'private_data_dir': private_data_dir,
'playbook': playbook
}
result = run_role(options, private_data_dir)
result.called_with_args([run_options])
def test_cmdline_roles_path():
"""Run a role directly and set --roles-path option
"""
private_data_dir = tempfile.mkdtemp()
options = ['-r' , 'test', '--roles-path /tmp/roles']
playbook = [{'hosts': 'all', 'gather_facts': False, 'roles': [{'role': 'test'}]}]
run_options = {
'private_data_dir': private_data_dir,
'playbook': playbook,
'envvars': {'ANSIBLE_ROLES_PATH': '/tmp/roles'}
}
result = run_role(options, private_data_dir)
result.called_with_args([run_options])
def test_cmdline_role_with_playbook_option():
"""Test error is raised with invalid command line option '-p'
"""
cmdline('run', 'private_data_dir', '-r', 'fake', '-p', 'fake')
with raises(SystemExit) as exc:
main()
assert exc == 1
def test_cmdline_playbook(is_pre_ansible28):
try:
private_data_dir = tempfile.mkdtemp()
play = [{'hosts': 'all', 'tasks': [{'debug': {'msg': random_string()}}]}]
path = os.path.join(private_data_dir, 'project')
os.makedirs(path)
playbook = os.path.join(path, 'main.yaml')
with open(playbook, 'w') as f:
f.write(json.dumps(play))
path = os.path.join(private_data_dir, 'inventory')
os.makedirs(path)
inventory = os.path.join(path, 'hosts')
with open(inventory, 'w') as f:
if is_pre_ansible28:
f.write('[all]\nlocalhost ansible_connection=local ansible_python_interpreter="/usr/bin/env python"')
else:
f.write('[all]\nlocalhost ansible_connection=local')
cmdline('run', private_data_dir, '-p', playbook, '--inventory', inventory)
assert main() == 0
with open(playbook) as f:
assert json.loads(f.read()) == play
finally:
shutil.rmtree(private_data_dir)
def test_cmdline_playbook_hosts():
"""Test error is raised with trying to pass '--hosts' with '-p'
"""
cmdline('run', 'private_data_dir', '-p', 'fake', '--hosts', 'all')
with raises(SystemExit) as exc:
main()
assert exc == 1
def test_cmdline_includes_one_option():
"""Test error is raised if not '-p', '-m' or '-r'
"""
cmdline('run', 'private_data_dir')
with raises(SystemExit) as exc:
main()
assert exc == 1
def test_cmdline_cmdline_override(is_pre_ansible28):
try:
private_data_dir = tempfile.mkdtemp()
play = [{'hosts': 'all', 'tasks': [{'debug': {'msg': random_string()}}]}]
path = os.path.join(private_data_dir, 'project')
os.makedirs(path)
playbook = os.path.join(path, 'main.yaml')
with open(playbook, 'w') as f:
f.write(json.dumps(play))
path = os.path.join(private_data_dir, 'inventory')
os.makedirs(path)
inventory = os.path.join(path, 'hosts')
with open(inventory, 'w') as f:
if is_pre_ansible28:
f.write('[all]\nlocalhost ansible_connection=local ansible_python_interpreter="/usr/bin/env python"')
else:
f.write('[all]\nlocalhost ansible_connection=local')
# privateip: removed --hosts command line option from test beause it is
# not a supported combination of cli options
#cmdline('run', private_data_dir, '-p', playbook, '--hosts', 'all', '--cmdline', '-e foo=bar')
cmdline('run', private_data_dir, '-p', playbook, '--cmdline', '-e foo=bar')
assert main() == 0
finally:
shutil.rmtree(private_data_dir)