Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-2.0] Backport test fixes #871

Merged
Merged
Show file tree
Hide file tree
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
9 changes: 9 additions & 0 deletions .zuul.d/jobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,12 @@
- job:
name: ansible-runner-integration
parent: ansible-tox-py38


# =============================================================================

- job:
name: ansible-runner-tox-linters
parent: ansible-tox-linters
pre-run: .zuul.d/playbooks/ansible-runner-tox-linters/pre.yaml
nodeset: centos-8-stream
8 changes: 8 additions & 0 deletions .zuul.d/playbooks/ansible-runner-tox-linters/pre.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- hosts: all
tasks:
- name: Ensure python3.8 is present
become: true
package:
name: python38-devel
state: present
1 change: 1 addition & 0 deletions .zuul.d/project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- ansible-runner-build-container-image-stable-2.10
- ansible-runner-build-container-image-stable-2.11
- ansible-runner-integration
- ansible-runner-tox-linters
- ansible-tox-docs:
vars:
sphinx_build_dir: docs/build
Expand Down
8 changes: 8 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@
markers =
serial: tests that cannot be reliably ran with pytest multiprocessing
timeout: used with pytest-timeout
addopts =
-r a
--color yes
--showlocals
--verbose
--numprocesses auto
--durations 10
--durations-min 1
6 changes: 0 additions & 6 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@ packages =
data-files =
share/ansible-runner/utils = utils/*

[pep8]
# W503 - Line break occurred before a binary operator
ignore=W503
exclude=.tox,venv

[flake8]
# W503 - Line break occurred before a binary operator
ignore=W503
max-line-length=160
exclude=.tox,venv
6 changes: 3 additions & 3 deletions test/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@


@pytest.fixture(scope='function')
def rc(tmpdir):
rc = RunnerConfig(str(tmpdir))
def rc(tmp_path):
rc = RunnerConfig(str(tmp_path))
rc.suppress_ansible_output = True
rc.expect_passwords = {
pexpect.TIMEOUT: None,
pexpect.EOF: None
}
rc.cwd = str(tmpdir)
rc.cwd = str(tmp_path)
rc.env = {}
rc.job_timeout = 10
rc.idle_timeout = 0
Expand Down
242 changes: 81 additions & 161 deletions test/integration/test___main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@
import json
import random
import string
import tempfile
import shutil

from pytest import raises
from unittest.mock import patch
import pytest

from ansible_runner.__main__ import main
import ansible_runner.__main__


def random_string():
Expand Down Expand Up @@ -42,202 +39,125 @@ def test_main_bad_private_data_dir():
cmdline('run', tmpfile, '-p', 'fake')

try:
with raises(OSError):
main()
with pytest.raises(OSError):
ansible_runner.__main__.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'
}
def save_playbook(**kwargs):
os.link(kwargs['playbook'], os.path.join(kwargs['private_data_dir'], 'play.yml'))

result = run_role(options, private_data_dir)
result.called_with_args([run_options])
raise AttributeError("Raised intentionally")


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'}
}]
}]
@pytest.mark.parametrize(
('options', 'expected_playbook'),
(
(
['-r', 'test'],
[{'hosts': 'all', 'gather_facts': True, 'roles': [{'name': 'test'}]}],
),
(
['-r', 'test', '--role-skip-facts'],
[{'hosts': 'all', 'gather_facts': False, 'roles': [{'name': 'test'}]}],
),
(
['-r', 'test', '--role-vars', 'foo=bar'],
[{'hosts': 'all', 'gather_facts': True, 'roles': [{'name': 'test', 'vars': {'foo': 'bar'}}]}],
),
(
['-r', 'test', '--roles-path', '/tmp/roles'],
[{'hosts': 'all', 'gather_facts': True, 'roles': [{'name': 'test'}]}],
),
)
)
def test_cmdline_role(options, expected_playbook, tmp_path, mocker):
mocker.patch.object(ansible_runner.__main__, 'run', save_playbook)
spy = mocker.spy(ansible_runner.__main__, 'run')

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']
command = ['run', str(tmp_path)]
command.extend(options)

playbook = [{'hosts': 'all', 'gather_facts': False, 'roles': [{'role': 'test'}]}]
rc = ansible_runner.__main__.main(command)

run_options = {
'private_data_dir': private_data_dir,
'playbook': playbook,
'envvars': {'ANSIBLE_ROLES_PATH': '/tmp/roles'}
}
with open(tmp_path / 'play.yml') as f:
playbook = json.loads(f.read())

result = run_role(options, private_data_dir)
result.called_with_args([run_options])
assert rc == 1
assert playbook == expected_playbook
assert spy.call_args.kwargs.get('private_data_dir') == str(tmp_path)


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()
with pytest.raises(SystemExit) as exc:
ansible_runner.__main__.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)
def test_cmdline_playbook(is_pre_ansible28, tmp_path):
private_data_dir = tmp_path
play = [{'hosts': 'all', 'tasks': [{'debug': {'msg': random_string()}}]}]

playbook = os.path.join(path, 'main.yaml')
with open(playbook, 'w') as f:
f.write(json.dumps(play))
path = private_data_dir / 'project'
path.mkdir()

path = os.path.join(private_data_dir, 'inventory')
os.makedirs(path)
playbook = path / 'main.yaml'
with open(playbook, 'w') as f:
f.write(json.dumps(play))

inventory = os.path.join(path, 'hosts')
with open(inventory, 'w') as f:
f.write('[all]\nlocalhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"')
path = private_data_dir / 'inventory'
os.makedirs(path)

cmdline('run', private_data_dir, '-p', playbook, '--inventory', inventory)
inventory = path / 'hosts'
with open(inventory, 'w') as f:
f.write('[all]\nlocalhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"')

assert main() == 0
cmdline('run', str(private_data_dir), '-p', str(playbook), '--inventory', str(inventory))

with open(playbook) as f:
assert json.loads(f.read()) == play
assert ansible_runner.__main__.main() == 0

finally:
shutil.rmtree(private_data_dir)
with open(playbook) as f:
assert json.loads(f.read()) == play


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()
with pytest.raises(SystemExit) as exc:
ansible_runner.__main__.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()
with pytest.raises(SystemExit) as exc:
ansible_runner.__main__.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:
f.write('[all]\nlocalhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"')

# 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)
def test_cmdline_cmdline_override(is_pre_ansible28, tmp_path):
private_data_dir = tmp_path
play = [{'hosts': 'all', 'tasks': [{'debug': {'msg': random_string()}}]}]

path = private_data_dir / 'project'
path.mkdir()

playbook = path / 'main.yaml'
with open(playbook, 'w') as f:
f.write(json.dumps(play))
path = private_data_dir / 'inventory'
os.makedirs(path)

inventory = path / 'hosts'
with open(inventory, 'w') as f:
f.write('[all]\nlocalhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"')

cmdline('run', str(private_data_dir), '-p', str(playbook), '--cmdline', '-e foo=bar')
assert ansible_runner.__main__.main() == 0
Loading