def test_passed_on_selfcontained_role(testdir): smart_create(testdir.tmpdir, ''' ## local-role-base/role1/meta/main.yml galaxy_info: author: John Doe dependencies: [] ## local-role-base/role1/tasks/main.yml - file: path: "{{ playbook_dir }}/.role1.run" state: touch ## local-role-base/role1/tests/inventory 127.0.0.1 ansible_connection=local ## local-role-base/role1/tests/test_playbook.yml - hosts: 127.0.0.1 gather_facts: no roles: - role: role1 - hosts: 127.0.0.1 gather_facts: no tasks: - name: assert role1 run file: path: "{{ playbook_dir }}/.role1.run" state: file tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_passed_on_wait_for_success(testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: create .pid file file: path: "{{ playbook_dir }}/.pid" state: touch - name: task1 wait_for: path: "{{ playbook_dir }}/.pid" timeout: 5 tags: test - name: task2 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2)
def test_docker_pull_is_called_once_per_image_when_multiple_times(testdir, docker_client): docker_client.inspect_image.side_effect = \ docker.errors.NotFound('image not found', None, explanation='simulate missing docker image') smart_create(testdir.tmpdir, ''' ## inventory guesthostname1 goodplay_image=busybox:latest guesthostname2 goodplay_image=busybox:latest ## test_playbook.yml - hosts: guesthostname1:guesthostname2 gather_facts: no tasks: - name: task 1 raw: "ls -la /" changed_when: False tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1) docker_client.inspect_image.assert_called_once_with('busybox:latest') docker_client.pull.assert_called_once_with('busybox:latest')
def test_docker_pull_called_with_resolved_goodplay_platform(testdir, docker_client): docker_client.inspect_image.side_effect = \ docker.errors.NotFound('image not found', None, explanation='simulate missing docker image') smart_create(testdir.tmpdir, ''' ## .goodplay.yml platforms: - name: thename version: theversion image: busybox:latest ## inventory guesthostname goodplay_platform=thename:theversion ## test_playbook.yml - hosts: guesthostname gather_facts: no tasks: - name: task 1 raw: "ls -la /" changed_when: False tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1) docker_client.inspect_image.assert_called_once_with('busybox:latest') docker_client.pull.assert_called_once_with('busybox:latest')
def test_goodplay_info_is_logged_to_stdout_and_logging(testdir, caplog, capfd): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: tags: test ''') testdir.inline_run('-s') message = 'soft dependencies file not found at {0!s} ... nothing to install'.format( testdir.tmpdir.join('requirements.yml')) # capfd needs to be used here as logging module seems to use fd stdout, _ = capfd.readouterr() # assert message is exactly once in stdout (no double logging occurs) assert stdout.count(message) == 1 assert ('goodplay.ansible_support.playbook', logging.INFO, message) in caplog.record_tuples
def test_multiple_plays_multiple_blocks_single_test(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 tasks: - block: - name: task1 ping: - block: - name: task2 ping: - hosts: 127.0.0.1 tasks: - block: - name: task3 ping: - block: - name: task4 ping: tags: test ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 1 assert items[0].name == 'task4'
def test_wait_for_task_timeout_does_not_stop_test_run_with_multiple_hosts( testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local 127.0.0.2 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1:127.0.0.2 gather_facts: no tasks: - name: task1 wait_for: port: 143 timeout: 1 tags: test - name: task2 ping: tags: test - name: task3 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2, failed=1)
def test_skipped_outcome_takes_priority_over_passed(testdir): smart_create(testdir.tmpdir, ''' ## inventory host1 ansible_connection=local host2 ansible_connection=local ## test_playbook.yml - hosts: host1 gather_facts: no tasks: - name: avoid all test tasks skipped ping: tags: test - hosts: host1:host2 gather_facts: no tasks: - name: task2 ping: when: inventory_hostname != 'host2' tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1, skipped=1)
def test_goodplay_traceback_is_absent(testdir, capsys): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: tags: test - name: intentionally failed task ping: failed_when: True ## test_something.py def please_fail(): raise Exception() def test_something(): please_fail() ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1, failed=2) stdout, _ = capsys.readouterr() stacktrace_entry_separator_count = \ len([line for line in stdout.splitlines() if line.startswith('_ _ _ _ ')]) # assert only single stacktrace entry separator for failing Python test assert stacktrace_entry_separator_count == 1
def test_skipped_outcome_takes_priority_over_passed(testdir): smart_create( testdir.tmpdir, ''' ## inventory host1 ansible_connection=local host2 ansible_connection=local ## test_playbook.yml - hosts: host1 gather_facts: no tasks: - name: avoid all test tasks skipped ping: tags: test - hosts: host1:host2 gather_facts: no tasks: - name: task2 ping: when: inventory_hostname != 'host2' tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1, skipped=1)
def test_custom_module_runs_in_normal_mode_when_check_mode_not_supported(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## library/checkrunmode.py from ansible.module_utils.basic import AnsibleModule import os def main(): module = AnsibleModule( argument_spec = dict(), supports_check_mode=False ) module.exit_json(changed=False, run_in_check_mode=module.check_mode) if __name__ == '__main__': main() ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: assert custom module not run in check mode checkrunmode: register: result failed_when: "{{ result.run_in_check_mode }}" tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_hosts_can_resolve_google_com_domain(testdir): smart_create( testdir.tmpdir, ''' ## docker-compose.yml version: "2" services: guesthost: image: "busybox:latest" tty: True ## inventory guesthost ansible_user=root ## test_playbook.yml - hosts: guesthost gather_facts: no tasks: - name: assert google.com domain is reachable raw: ping -c 1 google.com changed_when: False tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_goodplay_info_is_logged_to_stdout_and_logging(testdir, caplog, capfd): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: tags: test ''') testdir.inline_run('-s') message = 'soft dependencies file not found at {0!s} ... nothing to install'.format( testdir.tmpdir.join('requirements.yml')) # capfd needs to be used here as logging module seems to use fd stdout, _ = capfd.readouterr() # assert message is exactly once in stdout (no double logging occurs) assert stdout.count(message) == 1 assert ('goodplay.ansible_support.playbook', logging.INFO, message) in caplog.record_tuples
def test_docker_build_error_results_in_fail_with_message(testdir): smart_create( testdir.tmpdir, ''' ## image/Dockerfile FROM "https://unknownregistry/busybox:latest" ## docker-compose.yml version: "2" services: guesthost: build: context: "./image" tty: True ## inventory guesthost ansible_user=root ## test_playbook.yml - hosts: guesthost gather_facts: no tasks: - name: task1 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(failed=1) assert "Failed: building service 'guesthost' failed with reason 'invalid reference format'" \ in str(result.getfailures()[0].longrepr)
def test_smart_create_multiple_archives_multiple_files(tmpdir): smart_create( tmpdir, ''' ## archive1.tar.gz #### file1 Hello World ## archive2.tar.gz #### file2 Content of file2 ''') # extract archive1.tar.gz archive1_path = tmpdir.join('archive1.tar.gz') extracted1_path = tmpdir.join('archive1.tar.gz.extracted') extracted1_path.ensure(dir=True) with tarfile.open(str(archive1_path), 'r:gz') as tar: tar.extractall(str(extracted1_path)) assert extracted1_path.join('file1').read() == 'Hello World' # extract archive2.tar.gz archive2_path = tmpdir.join('archive2.tar.gz') extracted2_path = tmpdir.join('archive2.tar.gz.extracted') extracted2_path.ensure(dir=True) with tarfile.open(str(archive2_path), 'r:gz') as tar: tar.extractall(str(extracted2_path)) assert extracted2_path.join('file2').read() == 'Content of file2'
def test_lineinfile_task_tagged_with_test_runs_in_check_mode(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - lineinfile: dest: "{{ playbook_dir }}/HELLO" create: yes line: "WORLD" state: present - name: intentionally failing test file: path: "{{ playbook_dir }}/HELLO" line: "WORLD" state: absent tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(failed=1) assert testdir.tmpdir.join('HELLO').check(file=True) assert testdir.tmpdir.join('HELLO').read() == 'WORLD\n'
def test_host_vars_directory_beside_inventory_file_is_incorporated(testdir): smart_create( testdir.tmpdir, ''' ## docker-compose.yml version: "2" services: guesthostname: image: "busybox:latest" tty: True ## inventory guesthostname ansible_user=root ## host_vars/guesthostname hello: world ## test_playbook.yml - hosts: guesthostname gather_facts: no tasks: - name: task 1 raw: 'echo -n {{ hello }}' register: echo_result failed_when: echo_result.stdout != 'world' changed_when: False tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_host_vars_directory_beside_inventory_file_is_incorporated(testdir): smart_create(testdir.tmpdir, ''' ## docker-compose.yml version: "2" services: guesthostname: image: "busybox:latest" tty: True ## inventory guesthostname ansible_user=root ## host_vars/guesthostname hello: world ## test_playbook.yml - hosts: guesthostname gather_facts: no tasks: - name: task 1 raw: 'echo -n {{ hello }}' register: echo_result failed_when: echo_result.stdout != 'world' changed_when: False tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_fail_on_non_unique_task_names_both_tagged_test(testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 tasks: - name: task1 ping: tags: test - name: task1 ping: tags: test ''') items, result = testdir.inline_genitems() result.assertoutcome(failed=1) message = "ValueError: Playbook '{0!s}' contains tests with non-unique name 'task1'".format( testdir.tmpdir.join('test_playbook.yml')) assert message in str(result.getfailures()[0].longrepr) assert len(items) == 0
def test_multiple_plays_multiple_blocks_single_test(testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 tasks: - block: - name: task1 ping: - block: - name: task2 ping: - hosts: 127.0.0.1 tasks: - block: - name: task3 ping: - block: - name: task4 ping: tags: test ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 1 assert items[0].name == 'task4'
def test_passed_multiple_on_previously_changed_task(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: changed_when: True tags: test - name: task2 ping: tags: test - name: task3 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2, failed=1)
def test_smart_create_multiple_archives_multiple_files(tmpdir): smart_create( tmpdir, """ ## archive1.tar.gz #### file1 Hello World ## archive2.tar.gz #### file2 Content of file2 """, ) # extract archive1.tar.gz archive1_path = tmpdir.join("archive1.tar.gz") extracted1_path = tmpdir.join("archive1.tar.gz.extracted") extracted1_path.ensure(dir=True) with tarfile.open(str(archive1_path), "r:gz") as tar: tar.extractall(str(extracted1_path)) assert extracted1_path.join("file1").read() == "Hello World" # extract archive2.tar.gz archive2_path = tmpdir.join("archive2.tar.gz") extracted2_path = tmpdir.join("archive2.tar.gz.extracted") extracted2_path.ensure(dir=True) with tarfile.open(str(archive2_path), "r:gz") as tar: tar.extractall(str(extracted2_path)) assert extracted2_path.join("file2").read() == "Content of file2"
def test_wait_for_task_timeout_does_not_stop_test_run_with_multiple_hosts(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local 127.0.0.2 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1:127.0.0.2 gather_facts: no tasks: - name: task1 wait_for: port: 143 timeout: 1 tags: test - name: task2 ping: tags: test - name: task3 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2, failed=1)
def test_goodplay_traceback_is_absent(testdir, capsys): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: tags: test - name: intentionally failed task ping: failed_when: True ## test_something.py def please_fail(): raise Exception() def test_something(): please_fail() ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1, failed=2) stdout, _ = capsys.readouterr() stacktrace_entry_separator_count = \ len([line for line in stdout.splitlines() if line.startswith('_ _ _ _ ')]) # assert only single stacktrace entry separator for failing Python test assert stacktrace_entry_separator_count == 1
def test_passed_on_wait_for_success(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: create .pid file file: path: "{{ playbook_dir }}/.pid" state: touch - name: task1 wait_for: path: "{{ playbook_dir }}/.pid" timeout: 5 tags: test - name: task2 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2)
def test_passed_multiple_on_previously_changed_task(testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: changed_when: True tags: test - name: task2 ping: tags: test - name: task3 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2, failed=1)
def test_smart_create_single_file_single_line(tmpdir): smart_create(tmpdir, ''' ## file1 Hello World ''') assert tmpdir.join('file1').check(file=True) assert tmpdir.join('file1').read() == 'Hello World'
def test_smart_create_single_file_empty(tmpdir): smart_create(tmpdir, ''' ## file1 ''') assert tmpdir.join('file1').check(file=True) assert tmpdir.join('file1').read() == ''
def test_config_paths_for_playbook_path_docker_compose_yml_only(tmpdir): playbook_path = tmpdir.join('test_playbook.yml') smart_create(tmpdir, ''' ## docker-compose.yml ''') expected = [['docker-compose.yml']] assert config_paths_for_playbook_path(playbook_path) == expected
def test_config_paths_for_playbook_path_docker_compose_override_yml_only(tmpdir): playbook_path = tmpdir.join('test_playbook.yml') smart_create(tmpdir, ''' ## docker-compose.override.yml ''') expected = [['docker-compose.override.yml']] assert config_paths_for_playbook_path(playbook_path) == expected
def test_become_user_on_task_without_become_does_not_execute_as_become_user( testdir): smart_create( testdir.tmpdir, ''' ## docker-compose.yml version: "2" services: host1: image: centos:centos6 tty: True ## inventory host1 ansible_user=root ## test_playbook.yml - hosts: host1 gather_facts: no tasks: - name: create system group myservice group: name: myservice system: yes state: present - name: create system user myservice user: name: myservice group: myservice shell: /sbin/nologin system: yes state: present - name: create myservice directory file: path: /opt/myservice owner: myservice group: myservice mode: 0700 state: directory - name: intentionally only specify become_user on this task file: path: /opt/myservice/somefile state: touch become_user: myservice - name: ensure somefile is owned by root user which is not the become_user file: path: /opt/myservice/somefile owner: root group: root state: file tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_become_with_become_user_on_play(testdir): smart_create( testdir.tmpdir, ''' ## docker-compose.yml version: "2" services: host1: image: centos:centos6 tty: True ## inventory host1 ansible_user=root ## test_playbook.yml - hosts: host1 gather_facts: no become_user: myservice tasks: - name: create system group myservice group: name: myservice system: yes state: present - name: create system user myservice user: name: myservice group: myservice shell: /sbin/nologin system: yes state: present - name: create myservice directory file: path: /opt/myservice owner: myservice group: myservice mode: 0700 state: directory - name: make some file operation as myservice user file: path: /opt/myservice/somefile state: touch become: yes - name: ensure somefile is owned by myservice user file: path: /opt/myservice/somefile owner: myservice group: myservice state: file tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_become_with_become_user_on_play(testdir): smart_create(testdir.tmpdir, ''' ## docker-compose.yml version: "2" services: host1: image: centos:centos6 tty: True ## inventory host1 ansible_user=root ## test_playbook.yml - hosts: host1 gather_facts: no become_user: myservice tasks: - name: create system group myservice group: name: myservice system: yes state: present - name: create system user myservice user: name: myservice group: myservice shell: /sbin/nologin system: yes state: present - name: create myservice directory file: path: /opt/myservice owner: myservice group: myservice mode: 0700 state: directory - name: make some file operation as myservice user file: path: /opt/myservice/somefile state: touch become: yes - name: ensure somefile is owned by myservice user file: path: /opt/myservice/somefile owner: myservice group: myservice state: file tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_smart_create_single_file_in_subdir(tmpdir): smart_create(tmpdir, ''' ## dir1/file1 Hello World ''') assert tmpdir.join('dir1').check(dir=True) assert tmpdir.join('dir1', 'file1').check(file=True) assert tmpdir.join('dir1', 'file1').read() == 'Hello\nWorld'
def test_passed_on_role_with_external_soft_dependent_role(testdir): smart_create(testdir.tmpdir, ''' ## external-role-base/role1.tar.gz #### role1/meta/main.yml galaxy_info: author: John Doe dependencies: [] #### role1/tasks/main.yml - file: path: "{{ playbook_dir }}/.role1.run" state: touch ## local-role-base/role2/meta/main.yml galaxy_info: author: John Doe dependencies: [] ## local-role-base/role2/tasks/main.yml - file: path: "{{ playbook_dir }}/.role2.run" state: touch ## local-role-base/role2/tests/inventory 127.0.0.1 ansible_connection=local ## local-role-base/role2/tests/requirements.yml - name: role1 src: external-role-base/role1.tar.gz ## local-role-base/role2/tests/test_playbook.yml - hosts: 127.0.0.1 gather_facts: no roles: - role: role1 - role: role2 - hosts: 127.0.0.1 gather_facts: no tasks: - name: assert role1 run file: path: "{{ playbook_dir }}/.role1.run" state: file tags: test - name: assert role2 run file: path: "{{ playbook_dir }}/.role2.run" state: file tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2)
def test_become_user_on_task_without_become_does_not_execute_as_become_user(testdir): smart_create(testdir.tmpdir, ''' ## docker-compose.yml version: "2" services: host1: image: centos:centos6 tty: True ## inventory host1 ansible_user=root ## test_playbook.yml - hosts: host1 gather_facts: no tasks: - name: create system group myservice group: name: myservice system: yes state: present - name: create system user myservice user: name: myservice group: myservice shell: /sbin/nologin system: yes state: present - name: create myservice directory file: path: /opt/myservice owner: myservice group: myservice mode: 0700 state: directory - name: intentionally only specify become_user on this task file: path: /opt/myservice/somefile state: touch become_user: myservice - name: ensure somefile is owned by root user which is not the become_user file: path: /opt/myservice/somefile owner: root group: root state: file tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_config_paths_for_playbook_path_single_level_only_override(tmpdir): playbook_path = tmpdir.join('test_playbook.yml') smart_create( tmpdir, ''' ## docker-compose.yml ## docker-compose.item1.override.yml ''') expected = [['docker-compose.yml', 'docker-compose.item1.override.yml']] assert config_paths_for_playbook_path(playbook_path) == expected
def test_smart_create_single_file_empty(tmpdir): smart_create( tmpdir, """ ## file1 """, ) assert tmpdir.join("file1").check(file=True) assert tmpdir.join("file1").read() == ""
def test_smart_create_single_file_single_line(tmpdir): smart_create( tmpdir, """ ## file1 Hello World """, ) assert tmpdir.join("file1").check(file=True) assert tmpdir.join("file1").read() == "Hello World"
def test_config_paths_for_playbook_path_single_level_only_override(tmpdir): playbook_path = tmpdir.join('test_playbook.yml') smart_create(tmpdir, ''' ## docker-compose.yml ## docker-compose.item1.override.yml ''') expected = [ ['docker-compose.yml', 'docker-compose.item1.override.yml'] ] assert config_paths_for_playbook_path(playbook_path) == expected
def test_nothing_collected_when_inventory_missing(testdir): smart_create(testdir.tmpdir, ''' ## test_playbook.yml - hosts: all tasks: - name: task1 ping: tags: test ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 0
def test_smart_create_single_file_in_subdir(tmpdir): smart_create( tmpdir, """ ## dir1/file1 Hello World """, ) assert tmpdir.join("dir1").check(dir=True) assert tmpdir.join("dir1", "file1").check(file=True) assert tmpdir.join("dir1", "file1").read() == "Hello\nWorld"
def test_config_paths_for_playbook_path_multiple_levels(tmpdir): playbook_path = tmpdir.join('test_playbook.yml') smart_create( tmpdir, ''' ## docker-compose.yml ## docker-compose.item1.item11.yml ## docker-compose.item2.item21.yml ''') expected = [['docker-compose.item1.item11.yml'], ['docker-compose.item2.item21.yml']] assert config_paths_for_playbook_path(playbook_path) == expected
def test_goodplay_cli_does_not_collect_python_tests(tmpdir): smart_create(tmpdir, ''' ## test_somepython.py def test_something_python_related(): pass ''') # pytest's exit code when no tests have been collected EXIT_NOTESTSCOLLECTED = 5 goodplay_returncode = subprocess.call( ['goodplay'], cwd=str(tmpdir)) assert goodplay_returncode == EXIT_NOTESTSCOLLECTED
def test_goodplay_cli_does_not_collect_python_tests(tmpdir): smart_create( tmpdir, ''' ## test_somepython.py def test_something_python_related(): pass ''') # pytest's exit code when no tests have been collected EXIT_NOTESTSCOLLECTED = 5 goodplay_returncode = subprocess.call(['goodplay'], cwd=str(tmpdir)) assert goodplay_returncode == EXIT_NOTESTSCOLLECTED
def test_config_paths_for_playbook_path_multiple_levels(tmpdir): playbook_path = tmpdir.join('test_playbook.yml') smart_create(tmpdir, ''' ## docker-compose.yml ## docker-compose.item1.item11.yml ## docker-compose.item2.item21.yml ''') expected = [ ['docker-compose.item1.item11.yml'], ['docker-compose.item2.item21.yml'] ] assert config_paths_for_playbook_path(playbook_path) == expected
def test_nothing_collected_when_inventory_missing(testdir): smart_create( testdir.tmpdir, ''' ## test_playbook.yml - hosts: all tasks: - name: task1 ping: tags: test ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 0
def test_role_with_goodplay_platform_wildcard(testdir, docker_client): smart_create(testdir.tmpdir, ''' ## local-role-base/role1/meta/main.yml galaxy_info: author: John Doe platforms: - name: EL versions: - 6 - 7 dependencies: [] ## local-role-base/role1/tasks/main.yml - ping: ## local-role-base/role1/tests/.goodplay.yml platforms: - name: EL version: 6 image: centos:centos6 - name: EL version: 7 image: centos:centos7 ## local-role-base/role1/tests/inventory default goodplay_platform=* ## local-role-base/role1/tests/test_playbook.yml - hosts: default gather_facts: no tasks: - name: host is reachable ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=2) assert docker_client.create_container.call_count == 2 _, _, kwargs = docker_client.create_container.mock_calls[0] assert kwargs['image'] == 'centos:centos6' _, _, kwargs = docker_client.create_container.mock_calls[1] assert kwargs['image'] == 'centos:centos7' assert docker_client.start.call_count == 2
def test_single_play_no_tests(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 tasks: - name: task1 ping: ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 0
def test_smart_create_multiple_files(tmpdir): smart_create( tmpdir, ''' ## file1 Hello World ## file2 Hello, John Doe ''') assert tmpdir.join('file1').check(file=True) assert tmpdir.join('file1').read() == 'Hello\nWorld' assert tmpdir.join('file2').check(file=True) assert tmpdir.join('file2').read() == 'Hello, John Doe'
def test_nodeid_with_environment(testdir): smart_create( testdir.tmpdir, ''' ## role1/meta/main.yml galaxy_info: author: John Doe platforms: - name: EL versions: - 6 - 7 dependencies: [] ## role1/tasks/main.yml - ping: ## role1/tests/docker-compose.EL.6.yml version: "2" services: default: image: centos:centos6 tty: True ## role1/tests/docker-compose.EL.7.yml version: "2" services: default: image: centos:centos7 tty: True ## role1/tests/inventory default ansible_user=root ## role1/tests/test_playbook.yml - hosts: default tasks: - name: host is reachable ping: tags: test ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 2 assert items[ 0].nodeid == 'role1/tests/test_playbook.yml::EL.6::host is reachable' assert items[ 1].nodeid == 'role1/tests/test_playbook.yml::EL.7::host is reachable'
def test_passed_on_non_changed_task(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)
def test_failed_on_unreachable_host_on_gather_facts(testdir): smart_create(testdir.tmpdir, ''' ## inventory unreachable.host.local ## test_playbook.yml - hosts: unreachable.host.local gather_facts: yes tasks: - name: task1 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(skipped=1, failed=1)
def test_nothing_collected_when_only_non_test_tags(testdir): smart_create(testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 tasks: - name: task1 ping: tags: other ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 0
def test_smart_create_single_archive_single_file(tmpdir): smart_create( tmpdir, ''' ## archive.tar.gz #### file1 Hello World ''') archive_path = tmpdir.join('archive.tar.gz') extracted_path = tmpdir.join('archive.tar.gz.extracted') extracted_path.ensure(dir=True) with tarfile.open(str(archive_path), 'r:gz') as tar: tar.extractall(str(extracted_path)) assert extracted_path.join('file1').read() == 'Hello World'
def test_single_play_no_tests(testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 tasks: - name: task1 ping: ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 0
def test_multiple_plays_multiple_blocks_multiple_tests(testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 tasks: - block: - name: task1 ping: tags: test - name: task2 ping: - block: - name: task3 ping: tags: test - name: task4 ping: tags: test - hosts: 127.0.0.1 tasks: - block: - name: task5 ping: tags: test - block: - name: task6 ping: tags: test - name: task7 ping: ''') items, result = testdir.inline_genitems() result.assertoutcome() assert len(items) == 5 assert [item.name for item in items ] == ['task1', 'task3', 'task4', 'task5', 'task6']
def test_passed_on_non_changed_task(testdir): smart_create( testdir.tmpdir, ''' ## inventory 127.0.0.1 ansible_connection=local ## test_playbook.yml - hosts: 127.0.0.1 gather_facts: no tasks: - name: task1 ping: tags: test ''') result = testdir.inline_run('-s') result.assertoutcome(passed=1)