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

280 lines
8.0 KiB
Python

# -*- coding: utf-8 -*-
import json
import os
import re
import pytest
import six
import sys
try:
from unittest.mock import MagicMock
except ImportError:
from unittest.mock import MagicMock
from ansible_runner import Runner
from ansible_runner.exceptions import AnsibleRunnerException
@pytest.mark.serial
def test_password_prompt(rc):
rc.command = [sys.executable, '-c' 'import time; print(input("Password: "))']
rc.expect_passwords[re.compile(r'Password:\s*?$', re.M)] = '1234'
status, exitcode = Runner(config=rc).run()
assert status == 'successful'
assert exitcode == 0
with open(os.path.join(rc.artifact_dir, 'stdout')) as f:
assert '1234' in f.read()
def test_run_command(rc):
rc.command = ['sleep', '1']
status, exitcode = Runner(config=rc).run()
assert status == 'successful'
assert exitcode == 0
with open(os.path.join(rc.artifact_dir, 'command')) as f:
data = json.load(f)
assert data.get('command') == ['sleep','1']
assert 'cwd' in data
assert isinstance(data.get('env'), dict)
def test_run_command_with_unicode(rc):
expected = '"utf-8-䉪ቒ칸ⱷ?噂폄蔆㪗輥"'
if six.PY2:
expected = expected.decode('utf-8')
rc.command = ['echo', '"utf-8-䉪ቒ칸ⱷ?噂폄蔆㪗輥"']
rc.envvars = {"䉪ቒ칸": "蔆㪗輥"}
rc.prepare_env()
status, exitcode = Runner(config=rc).run()
assert status == 'successful'
assert exitcode == 0
with open(os.path.join(rc.artifact_dir, 'command')) as f:
data = json.load(f)
assert data.get('command') == ['echo', expected]
assert 'cwd' in data
assert isinstance(data.get('env'), dict)
assert u"䉪ቒ칸" in data.get('env')
def test_run_command_finished_callback(rc):
finished_callback = MagicMock()
rc.command = ['sleep','1']
runner = Runner(config=rc, finished_callback=finished_callback)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
finished_callback.assert_called_with(runner)
def test_run_command_explosive_finished_callback(rc):
def boom(*args):
raise Exception('boom')
rc.command = ['sleep','1']
runner = Runner(config=rc, finished_callback=boom)
with pytest.raises(Exception):
runner.run()
def test_run_command_explosive_cancel_callback(rc):
def boom(*args):
raise Exception('boom')
rc.command = ['sleep','1']
runner = Runner(config=rc, cancel_callback=boom)
with pytest.raises(Exception):
runner.run()
def test_run_command_cancel_callback(rc):
def cancel(*args):
return True
rc.command = ['sleep','1']
runner = Runner(config=rc, cancel_callback=cancel)
status, exitcode = runner.run()
assert status == 'canceled'
assert exitcode == 254
def test_run_command_job_timeout(rc):
rc.command = ['sleep', '1']
rc.job_timeout = 0.0000001
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'timeout'
assert exitcode == 254
def test_run_command_idle_timeout(rc):
rc.command = ['sleep', '1']
rc.idle_timeout = 0.0000001
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'timeout'
assert exitcode == 254
def test_run_command_failed(rc):
rc.command = ['false']
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'failed'
assert exitcode == 1
def test_executable_not_found(rc):
rc.command = ['supercalifragilistic']
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'failed'
assert exitcode == 127
events = list(runner.events)
assert len(events) == 1
assert 'The command was not found or was not executable: supercalifragilistic' in events[0]['stdout'] # noqa
def test_run_command_long_running(rc):
rc.command = ['yes']
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'timeout'
assert exitcode == 254
def test_run_command_long_running_children(rc):
rc.command = ['bash', '-c', "(yes)"]
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'timeout'
assert exitcode == 254
def test_run_command_events_missing(rc):
rc.command = ['sleep','1']
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
assert list(runner.events) == []
def test_run_command_stdout_missing(rc):
rc.command = ['sleep','1']
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
os.unlink(os.path.join(runner.config.artifact_dir, 'stdout'))
with pytest.raises(AnsibleRunnerException):
list(runner.stdout)
def test_run_command_no_stats(rc):
rc.command = ['sleep','1']
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
assert runner.stats is None
def test_run_command_ansible(rc):
rc.module = "debug"
rc.host_pattern = "localhost"
rc.prepare()
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
assert list(runner.events) != []
assert runner.stats != {}
assert list(runner.host_events('localhost')) != []
stdout = runner.stdout
assert stdout.read() != ""
def test_run_command_ansible_event_handler(rc):
event_handler = MagicMock()
status_handler = MagicMock()
rc.module = "debug"
rc.host_pattern = "localhost"
rc.prepare()
runner = Runner(config=rc, event_handler=event_handler, status_handler=status_handler)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
event_handler.assert_called()
status_handler.assert_called()
def test_run_command_ansible_event_handler_failure(rc):
def event_handler(*args):
raise IOError()
rc.module = "debug"
rc.host_pattern = "localhost"
rc.prepare()
runner = Runner(config=rc, event_handler=event_handler)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
def test_run_command_ansible_rotate_artifacts(rc):
rc.module = "debug"
rc.host_pattern = "localhost"
rc.prepare()
rc.rotate_artifacts = 1
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
def test_get_fact_cache(rc):
assert os.path.basename(rc.fact_cache) == 'fact_cache'
rc.module = "setup"
rc.host_pattern = "localhost"
rc.prepare()
runner = Runner(config=rc)
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
print(rc.cwd)
assert os.path.exists(os.path.join(rc.artifact_dir, 'fact_cache'))
assert os.path.exists(os.path.join(rc.artifact_dir, 'fact_cache', 'localhost'))
data = runner.get_fact_cache('localhost')
assert data
def test_set_fact_cache(rc):
assert os.path.basename(rc.fact_cache) == 'fact_cache'
rc.module = "debug"
rc.module_args = "var=message"
rc.host_pattern = "localhost"
rc.prepare()
runner = Runner(config=rc)
runner.set_fact_cache('localhost', dict(message='hello there'))
status, exitcode = runner.run()
assert status == 'successful'
assert exitcode == 0
print(rc.cwd)
assert os.path.exists(os.path.join(rc.artifact_dir, 'fact_cache'))
assert os.path.exists(os.path.join(rc.artifact_dir, 'fact_cache', 'localhost'))
data = runner.get_fact_cache('localhost')
assert data['message'] == 'hello there'
def test_set_extra_vars(rc):
rc.module = "debug"
rc.module_args = "var=test_extra_vars"
rc.host_pattern = "localhost"
rc.extra_vars = dict(test_extra_vars='hello there')
rc.prepare()
runner = Runner(config=rc)
status, exitcode = runner.run()
with open(os.path.join(rc.artifact_dir, 'stdout')) as f:
assert 'hello there' in f.read()