diff --git a/test/integration/conftest.py b/test/integration/conftest.py index 559031ad..f9953bff 100644 --- a/test/integration/conftest.py +++ b/test/integration/conftest.py @@ -125,3 +125,62 @@ def container_image(request, cli, tmp_path): # pylint: disable=W0621 [runtime, 'rmi', '-f', image_name], bare=True, ) + + +@pytest.fixture +def container_image_devel(request, cli, tmp_path): # pylint: disable=W0621 + branch = request.getfixturevalue('branch') + + DOCKERFILE = f""" +FROM quay.io/centos/centos:stream9 +ARG WHEEL +COPY $WHEEL /$WHEEL + +# Need python 3.11 minimum for devel +RUN dnf install -y python3.11 python3.11-pip git +RUN alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 0 +RUN python3 -m pip install /$WHEEL git+https://github.com/ansible/ansible@{branch} + +RUN mkdir -p /runner/{{env,inventory,project,artifacts}} /home/runner/.ansible/tmp +RUN chmod -R 777 /runner /home/runner +WORKDIR /runner +ENV HOME=/home/runner +CMD ["ansible-runner", "run", "/runner"] +""" + + try: + containerized = request.getfixturevalue('containerized') + if not containerized: + yield None + return + except Exception: + # Test func doesn't use containerized + pass + + if (env_image_name := os.getenv('RUNNER_TEST_IMAGE_NAME')): + yield env_image_name + return + + cli( + ['pyproject-build', '-w', '-o', str(tmp_path)], + cwd=here.parent.parent, + bare=True, + ) + + wheel = next(tmp_path.glob('*.whl')) # pylint: disable=R1708 + + runtime = request.getfixturevalue('runtime') + dockerfile_path = tmp_path / 'Dockerfile' + dockerfile_path.write_text(DOCKERFILE) + random_string = ''.join(random.choice(ascii_lowercase) for i in range(10)) + image_name = f'ansible-runner-{random_string}-event-test' + + cli( + [runtime, 'build', '--build-arg', f'WHEEL={wheel.name}', '--rm=true', '-t', image_name, '-f', str(dockerfile_path), str(tmp_path)], + bare=True, + ) + yield image_name + cli( + [runtime, 'rmi', '-f', image_name], + bare=True, + ) diff --git a/test/integration/test_core_integration.py b/test/integration/test_core_integration.py new file mode 100644 index 00000000..ccc177d4 --- /dev/null +++ b/test/integration/test_core_integration.py @@ -0,0 +1,82 @@ +import sys +import pytest + +from ansible_runner.interface import run + + +TEST_BRANCHES = ( + 'devel', + 'stable-2.16', +) + + +@pytest.mark.test_all_runtimes +@pytest.mark.parametrize('branch', TEST_BRANCHES) +@pytest.mark.skipif(sys.platform == 'darwin', reason='does not work on macOS') +def test_adhoc(tmp_path, runtime, branch, container_image_devel): + # pvt_data_dir is mounted on the container, so it must contain the expected directories + project_dir = tmp_path / 'project' + project_dir.mkdir() + r = run(private_data_dir=str(tmp_path), + host_pattern='localhost', + module='shell', + module_args='pwd', + process_isolation_executable=runtime, + process_isolation=True, + container_image=container_image_devel, + ) + + assert r.status == 'successful' + assert r.rc == 0 + assert 'ok' in r.stats + assert 'localhost' in r.stats['ok'] + events = [x['event'] for x in r.events if x['event'] != 'verbose'] + assert len(events) == 4 + + +@pytest.mark.test_all_runtimes +@pytest.mark.parametrize('branch', TEST_BRANCHES) +@pytest.mark.skipif(sys.platform == 'darwin', reason='does not work on macOS') +def test_playbook(tmp_path, runtime, branch, container_image_devel): + PLAYBOOK = """ +- hosts: localhost + gather_facts: False + tasks: + - set_fact: + foo: bar +""" + + # pvt_data_dir is mounted on the container, so it must contain the expected directories + project_dir = tmp_path / 'project' + project_dir.mkdir() + inventory_dir = tmp_path / 'inventory' + inventory_dir.mkdir() + + hosts_file = inventory_dir / 'hosts' + hosts_file.write_text('localhost\n') + + playbook = project_dir / 'test.yml' + playbook.write_text(PLAYBOOK) + + r = run(private_data_dir=str(tmp_path), + playbook='test.yml', + process_isolation_executable=runtime, + process_isolation=True, + container_image=container_image_devel, + ) + + expected_events = [ + 'playbook_on_start', + 'playbook_on_play_start', + 'playbook_on_task_start', + 'runner_on_start', + 'runner_on_ok', + 'playbook_on_stats', + ] + + assert r.status == 'successful' + assert r.rc == 0 + assert 'ok' in r.stats + assert 'localhost' in r.stats['ok'] + events = [x['event'] for x in r.events if x['event'] != 'verbose'] + assert events == expected_events