summaryrefslogtreecommitdiff
path: root/test/integration/targets
diff options
context:
space:
mode:
authorLee Garrett <lgarrett@rocketjump.eu>2021-11-17 20:15:37 +0100
committerLee Garrett <lgarrett@rocketjump.eu>2021-11-17 20:15:37 +0100
commitb1739f3e93dadd7d8fa794644ceedc24bddc8388 (patch)
tree193d287510fd44d67857e2d6b6bfcbb2b495c60a /test/integration/targets
parent13e2c2e94d3559b85a7d813d98e9835b891b0a9f (diff)
downloaddebian-ansible-core-b1739f3e93dadd7d8fa794644ceedc24bddc8388.zip
New upstream version 2.12.0
Diffstat (limited to 'test/integration/targets')
-rw-r--r--test/integration/targets/adhoc/aliases1
-rw-r--r--test/integration/targets/ansiballz_python/aliases1
-rw-r--r--test/integration/targets/ansible-doc/aliases1
-rw-r--r--test/integration/targets/ansible-doc/fakemodule.output4
-rw-r--r--test/integration/targets/ansible-doc/randommodule-text.output105
-rwxr-xr-xtest/integration/targets/ansible-doc/runme.sh8
-rw-r--r--test/integration/targets/ansible-galaxy-collection-scm/aliases3
-rw-r--r--test/integration/targets/ansible-galaxy-collection/aliases1
-rw-r--r--test/integration/targets/ansible-galaxy-collection/tasks/install.yml4
-rw-r--r--test/integration/targets/ansible-galaxy-collection/tasks/upgrade.yml6
-rw-r--r--test/integration/targets/ansible-galaxy-role/aliases2
-rw-r--r--test/integration/targets/ansible-galaxy/aliases3
-rw-r--r--test/integration/targets/ansible-inventory/aliases1
-rw-r--r--test/integration/targets/ansible-inventory/files/invalid_sample.yml7
-rw-r--r--test/integration/targets/ansible-inventory/files/valid_sample.yml7
-rw-r--r--test/integration/targets/ansible-inventory/tasks/main.yml114
-rw-r--r--test/integration/targets/ansible-pull/aliases (renamed from test/integration/targets/vault/aliases)2
-rw-r--r--test/integration/targets/ansible-pull/cleanup.yml (renamed from test/integration/targets/pull/cleanup.yml)0
-rw-r--r--test/integration/targets/ansible-pull/pull-integration-test/ansible.cfg (renamed from test/integration/targets/pull/pull-integration-test/ansible.cfg)0
-rw-r--r--test/integration/targets/ansible-pull/pull-integration-test/inventory (renamed from test/integration/targets/pull/pull-integration-test/inventory)0
-rw-r--r--test/integration/targets/ansible-pull/pull-integration-test/local.yml (renamed from test/integration/targets/pull/pull-integration-test/local.yml)0
-rw-r--r--test/integration/targets/ansible-pull/pull-integration-test/multi_play_1.yml (renamed from test/integration/targets/pull/pull-integration-test/multi_play_1.yml)0
-rw-r--r--test/integration/targets/ansible-pull/pull-integration-test/multi_play_2.yml (renamed from test/integration/targets/pull/pull-integration-test/multi_play_2.yml)0
-rwxr-xr-xtest/integration/targets/ansible-pull/runme.sh (renamed from test/integration/targets/pull/runme.sh)0
-rw-r--r--test/integration/targets/ansible-pull/setup.yml (renamed from test/integration/targets/pull/setup.yml)0
-rw-r--r--test/integration/targets/ansible-runner/aliases3
-rw-r--r--test/integration/targets/ansible-test-cloud-acme/aliases3
-rw-r--r--test/integration/targets/ansible-test-cloud-acme/tasks/main.yml7
-rw-r--r--test/integration/targets/ansible-test-cloud-cs/aliases3
-rw-r--r--test/integration/targets/ansible-test-cloud-cs/tasks/main.yml8
-rw-r--r--test/integration/targets/ansible-test-cloud-foreman/aliases3
-rw-r--r--test/integration/targets/ansible-test-cloud-foreman/tasks/main.yml6
-rw-r--r--test/integration/targets/ansible-test-cloud-galaxy/aliases4
-rw-r--r--test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml25
-rw-r--r--test/integration/targets/ansible-test-cloud-httptester-windows/aliases4
-rw-r--r--test/integration/targets/ansible-test-cloud-httptester-windows/tasks/main.yml15
-rw-r--r--test/integration/targets/ansible-test-cloud-httptester/aliases3
-rw-r--r--test/integration/targets/ansible-test-cloud-httptester/tasks/main.yml15
-rw-r--r--test/integration/targets/ansible-test-cloud-nios/aliases3
-rw-r--r--test/integration/targets/ansible-test-cloud-nios/tasks/main.yml10
-rw-r--r--test/integration/targets/ansible-test-cloud-openshift/aliases4
-rw-r--r--test/integration/targets/ansible-test-cloud-openshift/tasks/main.yml6
-rw-r--r--test/integration/targets/ansible-test-cloud-vcenter/aliases3
-rw-r--r--test/integration/targets/ansible-test-cloud-vcenter/tasks/main.yml6
-rw-r--r--test/integration/targets/ansible-test-docker/aliases1
-rwxr-xr-xtest/integration/targets/ansible-test-docker/collection-tests/docker.sh2
-rw-r--r--test/integration/targets/ansible-test/aliases2
-rw-r--r--test/integration/targets/ansible-test/ansible_collections/ns/col_constraints/tests/integration/targets/constraints/aliases1
-rwxr-xr-xtest/integration/targets/ansible-test/collection-tests/coverage.sh4
-rwxr-xr-xtest/integration/targets/ansible-test/collection-tests/venv.sh4
-rw-r--r--test/integration/targets/ansible-vault/aliases (renamed from test/integration/targets/pull/aliases)2
-rw-r--r--test/integration/targets/ansible-vault/empty-password (renamed from test/integration/targets/vault/empty-password)0
-rw-r--r--test/integration/targets/ansible-vault/encrypted-vault-password (renamed from test/integration/targets/vault/encrypted-vault-password)0
-rw-r--r--test/integration/targets/ansible-vault/encrypted_file_encrypted_var_password (renamed from test/integration/targets/vault/encrypted_file_encrypted_var_password)0
-rw-r--r--test/integration/targets/ansible-vault/example1_password (renamed from test/integration/targets/vault/example1_password)0
-rw-r--r--test/integration/targets/ansible-vault/example2_password (renamed from test/integration/targets/vault/example2_password)0
-rw-r--r--test/integration/targets/ansible-vault/example3_password (renamed from test/integration/targets/vault/example3_password)0
-rwxr-xr-xtest/integration/targets/ansible-vault/faux-editor.py (renamed from test/integration/targets/vault/faux-editor.py)2
-rw-r--r--test/integration/targets/ansible-vault/files/test_assemble/nonsecret.txt (renamed from test/integration/targets/vault/files/test_assemble/nonsecret.txt)0
-rw-r--r--test/integration/targets/ansible-vault/files/test_assemble/secret.vault (renamed from test/integration/targets/vault/files/test_assemble/secret.vault)0
-rw-r--r--test/integration/targets/ansible-vault/format_1_1_AES256.yml (renamed from test/integration/targets/vault/format_1_1_AES256.yml)0
-rw-r--r--test/integration/targets/ansible-vault/format_1_2_AES256.yml (renamed from test/integration/targets/vault/format_1_2_AES256.yml)0
-rw-r--r--test/integration/targets/ansible-vault/host_vars/myhost.yml (renamed from test/integration/targets/vault/host_vars/myhost.yml)0
-rw-r--r--test/integration/targets/ansible-vault/host_vars/testhost.yml (renamed from test/integration/targets/vault/host_vars/testhost.yml)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/README.md (renamed from test/integration/targets/vault/invalid_format/README.md)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/broken-group-vars-tasks.yml (renamed from test/integration/targets/vault/invalid_format/broken-group-vars-tasks.yml)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/broken-host-vars-tasks.yml (renamed from test/integration/targets/vault/invalid_format/broken-host-vars-tasks.yml)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/group_vars/broken-group-vars.yml (renamed from test/integration/targets/vault/invalid_format/group_vars/broken-group-vars.yml)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/host_vars/broken-host-vars.example.com/vars (renamed from test/integration/targets/vault/invalid_format/host_vars/broken-host-vars.example.com/vars)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/inventory (renamed from test/integration/targets/vault/invalid_format/inventory)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/original-broken-host-vars (renamed from test/integration/targets/vault/invalid_format/original-broken-host-vars)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/original-group-vars.yml (renamed from test/integration/targets/vault/invalid_format/original-group-vars.yml)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/some-vars (renamed from test/integration/targets/vault/invalid_format/some-vars)0
-rw-r--r--test/integration/targets/ansible-vault/invalid_format/vault-secret (renamed from test/integration/targets/vault/invalid_format/vault-secret)0
-rw-r--r--test/integration/targets/ansible-vault/inventory.toml (renamed from test/integration/targets/vault/inventory.toml)0
-rwxr-xr-xtest/integration/targets/ansible-vault/password-script.py (renamed from test/integration/targets/vault/password-script.py)2
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault/tasks/main.yml (renamed from test/integration/targets/vault/roles/test_vault/tasks/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault/vars/main.yml (renamed from test/integration/targets/vault/roles/test_vault/vars/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault_embedded/tasks/main.yml (renamed from test/integration/targets/vault/roles/test_vault_embedded/tasks/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault_embedded/vars/main.yml (renamed from test/integration/targets/vault/roles/test_vault_embedded/vars/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/tasks/main.yml (renamed from test/integration/targets/vault/roles/test_vault_embedded_ids/tasks/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/vars/main.yml (renamed from test/integration/targets/vault/roles/test_vault_embedded_ids/vars/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/README.md (renamed from test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/README.md)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/tasks/main.yml (renamed from test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/tasks/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/vars/main.yml (renamed from test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/vars/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vaulted_template/tasks/main.yml (renamed from test/integration/targets/vault/roles/test_vaulted_template/tasks/main.yml)0
-rw-r--r--test/integration/targets/ansible-vault/roles/test_vaulted_template/templates/vaulted_template.j2 (renamed from test/integration/targets/vault/roles/test_vaulted_template/templates/vaulted_template.j2)0
-rwxr-xr-xtest/integration/targets/ansible-vault/runme.sh (renamed from test/integration/targets/vault/runme.sh)0
-rw-r--r--test/integration/targets/ansible-vault/single_vault_as_string.yml (renamed from test/integration/targets/vault/single_vault_as_string.yml)2
-rwxr-xr-xtest/integration/targets/ansible-vault/test-vault-client.py (renamed from test/integration/targets/vault/test-vault-client.py)0
-rw-r--r--test/integration/targets/ansible-vault/test_dangling_temp.yml (renamed from test/integration/targets/vault/test_dangling_temp.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_utf8_value_in_filename.yml (renamed from test/integration/targets/vault/test_utf8_value_in_filename.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vault.yml (renamed from test/integration/targets/vault/test_vault.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vault_embedded.yml (renamed from test/integration/targets/vault/test_vault_embedded.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vault_embedded_ids.yml (renamed from test/integration/targets/vault/test_vault_embedded_ids.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vault_file_encrypted_embedded.yml (renamed from test/integration/targets/vault/test_vault_file_encrypted_embedded.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vaulted_inventory.yml (renamed from test/integration/targets/vault/test_vaulted_inventory.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vaulted_inventory_toml.yml (renamed from test/integration/targets/vault/test_vaulted_inventory_toml.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vaulted_template.yml (renamed from test/integration/targets/vault/test_vaulted_template.yml)0
-rw-r--r--test/integration/targets/ansible-vault/test_vaulted_utf8_value.yml (renamed from test/integration/targets/vault/test_vaulted_utf8_value.yml)0
-rw-r--r--test/integration/targets/ansible-vault/vault-café.yml (renamed from test/integration/targets/vault/vault-café.yml)0
-rw-r--r--test/integration/targets/ansible-vault/vault-password (renamed from test/integration/targets/vault/vault-password)0
-rw-r--r--test/integration/targets/ansible-vault/vault-password-ansible (renamed from test/integration/targets/vault/vault-password-ansible)0
-rw-r--r--test/integration/targets/ansible-vault/vault-password-wrong (renamed from test/integration/targets/vault/vault-password-wrong)0
-rw-r--r--test/integration/targets/ansible-vault/vault-secret.txt (renamed from test/integration/targets/vault/vault-secret.txt)0
-rw-r--r--test/integration/targets/ansible-vault/vaulted.inventory (renamed from test/integration/targets/vault/vaulted.inventory)0
-rw-r--r--test/integration/targets/ansible/aliases2
-rwxr-xr-xtest/integration/targets/ansible/module_common_regex_regression.sh15
-rwxr-xr-xtest/integration/targets/ansible/runme.sh4
-rw-r--r--test/integration/targets/any_errors_fatal/18602.yml21
-rw-r--r--test/integration/targets/any_errors_fatal/aliases1
-rw-r--r--test/integration/targets/any_errors_fatal/on_includes.yml2
-rw-r--r--test/integration/targets/apt/tasks/downgrade.yml77
-rw-r--r--test/integration/targets/apt/tasks/repo.yml25
-rw-r--r--test/integration/targets/args/aliases1
-rw-r--r--test/integration/targets/argspec/aliases1
-rw-r--r--test/integration/targets/assert/aliases2
-rw-r--r--test/integration/targets/async/tasks/main.yml29
-rw-r--r--test/integration/targets/async_extra_data/aliases1
-rw-r--r--test/integration/targets/become/aliases1
-rw-r--r--test/integration/targets/become/tasks/main.yml6
-rw-r--r--test/integration/targets/become_su/aliases2
-rw-r--r--test/integration/targets/become_unprivileged/aliases2
-rw-r--r--test/integration/targets/binary/aliases1
-rw-r--r--test/integration/targets/binary_modules_posix/aliases1
-rw-r--r--test/integration/targets/blocks/aliases1
-rw-r--r--test/integration/targets/blocks/main.yml8
-rw-r--r--test/integration/targets/blocks/nested_fail.yml4
-rw-r--r--test/integration/targets/blocks/nested_nested_fail.yml4
-rw-r--r--test/integration/targets/builtin_vars_prompt/aliases1
-rw-r--r--test/integration/targets/callback_default/aliases1
-rwxr-xr-xtest/integration/targets/callback_default/runme.sh7
-rw-r--r--test/integration/targets/callback_default/test_async.yml14
-rw-r--r--test/integration/targets/changed_when/aliases1
-rw-r--r--test/integration/targets/changed_when/tasks/main.yml12
-rw-r--r--test/integration/targets/check_mode/aliases1
-rw-r--r--test/integration/targets/cli/aliases1
-rw-r--r--test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyCSMUOptional.cs19
-rw-r--r--test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyPSMUOptional.psm116
-rw-r--r--test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_uses_optional.ps133
-rwxr-xr-xtest/integration/targets/collections/runme.sh6
-rwxr-xr-xtest/integration/targets/collections/test_task_resolved_plugin.sh48
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/action_plugins/legacy_action.py14
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/callback_plugins/display_resolved_action.py37
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/meta/runtime.yml7
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/action/collection_action.py14
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/modules/collection_module.py29
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/fqcn.yml14
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/library/legacy_module.py29
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/unqualified.yml8
-rw-r--r--test/integration/targets/collections/test_task_resolved_plugin/unqualified_and_collections_kw.yml14
-rw-r--r--test/integration/targets/collections/windows.yml6
-rw-r--r--test/integration/targets/collections_plugin_namespace/aliases1
-rw-r--r--test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/PSRel4.psm112
-rw-r--r--test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/win_relative_optional.ps117
-rw-r--r--test/integration/targets/collections_relative_imports/windows.yml9
-rw-r--r--test/integration/targets/collections_runtime_pythonpath/aliases3
-rwxr-xr-xtest/integration/targets/collections_runtime_pythonpath/runme.sh6
-rw-r--r--test/integration/targets/command_nonexisting/aliases3
-rw-r--r--test/integration/targets/command_shell/tasks/main.yml4
-rw-r--r--test/integration/targets/common_network/aliases1
-rw-r--r--test/integration/targets/conditionals/aliases1
-rw-r--r--test/integration/targets/conditionals/play.yml150
-rwxr-xr-xtest/integration/targets/conditionals/runme.sh12
-rw-r--r--test/integration/targets/conditionals/test_no_warnings.yml18
-rw-r--r--test/integration/targets/conditionals/test_warnings.yml14
-rw-r--r--test/integration/targets/conditionals/vars/main.yml7
-rw-r--r--test/integration/targets/config/aliases1
-rw-r--r--test/integration/targets/config/files/types.env11
-rw-r--r--test/integration/targets/config/files/types.ini13
-rw-r--r--test/integration/targets/config/files/types.vars15
-rw-r--r--test/integration/targets/config/files/types_dump.txt8
-rw-r--r--test/integration/targets/config/lookup_plugins/types.py82
-rwxr-xr-xtest/integration/targets/config/runme.sh16
-rw-r--r--test/integration/targets/config/type_munging.cfg8
-rw-r--r--test/integration/targets/config/types.yml25
-rw-r--r--test/integration/targets/connection_delegation/aliases1
-rwxr-xr-xtest/integration/targets/connection_delegation/runme.sh2
-rw-r--r--test/integration/targets/connection_paramiko_ssh/aliases1
-rw-r--r--test/integration/targets/connection_ssh/aliases1
-rwxr-xr-xtest/integration/targets/connection_ssh/runme.sh3
-rw-r--r--test/integration/targets/connection_ssh/test_ssh_defaults.cfg5
-rw-r--r--test/integration/targets/connection_ssh/verify_config.yml21
-rw-r--r--test/integration/targets/controller/aliases2
-rw-r--r--test/integration/targets/controller/tasks/main.yml9
-rw-r--r--test/integration/targets/copy/tasks/main.yml3
-rw-r--r--test/integration/targets/copy/tasks/tests.yml8
-rw-r--r--test/integration/targets/cron/tasks/main.yml20
-rw-r--r--test/integration/targets/dataloader/aliases1
-rw-r--r--test/integration/targets/debug/aliases1
-rw-r--r--test/integration/targets/delegate_to/aliases2
-rw-r--r--test/integration/targets/dict_transformations/aliases1
-rw-r--r--test/integration/targets/dnf/tasks/cacheonly.yml15
-rw-r--r--test/integration/targets/dnf/tasks/dnf.yml22
-rw-r--r--test/integration/targets/dnf/tasks/main.yml11
-rw-r--r--test/integration/targets/dnf/vars/Fedora-34.yml2
-rw-r--r--test/integration/targets/dpkg_selections/tasks/main.yaml2
-rw-r--r--test/integration/targets/egg-info/aliases1
-rw-r--r--test/integration/targets/embedded_module/aliases1
-rw-r--r--test/integration/targets/environment/aliases1
-rw-r--r--test/integration/targets/error_from_connection/aliases1
-rw-r--r--test/integration/targets/facts_d/aliases1
-rw-r--r--test/integration/targets/facts_linux_network/aliases1
-rw-r--r--test/integration/targets/failed_when/aliases1
-rw-r--r--test/integration/targets/failed_when/tasks/main.yml12
-rw-r--r--test/integration/targets/fetch/aliases1
-rw-r--r--test/integration/targets/fetch/cleanup.yml16
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/defaults/main.yml1
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/handlers/main.yml8
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/tasks/fail_on_missing.yml53
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml41
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/tasks/main.yml146
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/tasks/normal.yml38
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/tasks/setup.yml45
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/tasks/symlink.yml13
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/vars/Darwin.yml3
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/vars/default.yml1
-rwxr-xr-xtest/integration/targets/fetch/runme.sh26
-rw-r--r--test/integration/targets/fetch/setup_unreadable_test.yml40
-rw-r--r--test/integration/targets/fetch/test_unreadable_with_stat.yml36
-rw-r--r--test/integration/targets/file/handlers/main.yml1
-rw-r--r--test/integration/targets/file/tasks/directory_as_dest.yml2
-rw-r--r--test/integration/targets/file/tasks/main.yml5
-rw-r--r--test/integration/targets/file/tasks/selinux_tests.yml2
-rw-r--r--test/integration/targets/file/tasks/state_link.yml4
-rw-r--r--test/integration/targets/filter_core/aliases2
-rw-r--r--test/integration/targets/filter_core/tasks/main.yml49
-rw-r--r--test/integration/targets/filter_encryption/aliases1
-rw-r--r--test/integration/targets/filter_encryption/base.yml37
-rwxr-xr-xtest/integration/targets/filter_encryption/runme.sh5
-rw-r--r--test/integration/targets/filter_mathstuff/aliases2
-rw-r--r--test/integration/targets/filter_mathstuff/host_vars/localhost.yml1
-rwxr-xr-xtest/integration/targets/filter_mathstuff/runme.sh17
-rw-r--r--test/integration/targets/filter_mathstuff/runme.yml4
-rw-r--r--test/integration/targets/filter_mathstuff/tasks/main.yml36
-rw-r--r--test/integration/targets/filter_mathstuff/vars/defined_later.yml3
-rw-r--r--test/integration/targets/filter_mathstuff/vars/main.yml1
-rw-r--r--test/integration/targets/filter_urls/aliases2
-rw-r--r--test/integration/targets/filter_urlsplit/aliases2
-rw-r--r--test/integration/targets/find/tasks/main.yml116
-rw-r--r--test/integration/targets/gathering/aliases1
-rw-r--r--test/integration/targets/gathering_facts/aliases1
-rw-r--r--test/integration/targets/gathering_facts/collections/ansible_collections/cisco/ios/plugins/modules/ios_facts.py38
-rw-r--r--test/integration/targets/gathering_facts/inventory2
-rwxr-xr-xtest/integration/targets/gathering_facts/runme.sh2
-rw-r--r--test/integration/targets/gathering_facts/test_gathering_facts.yml28
-rw-r--r--test/integration/targets/gathering_facts/test_module_defaults.yml51
-rw-r--r--test/integration/targets/gathering_facts/test_prevent_injection.yml2
-rw-r--r--test/integration/targets/get_url/tasks/main.yml29
-rw-r--r--test/integration/targets/git/tasks/archive.yml1
-rw-r--r--test/integration/targets/git/tasks/main.yml1
-rw-r--r--test/integration/targets/git/tasks/missing_hostkey.yml13
-rw-r--r--test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml78
-rw-r--r--test/integration/targets/git/tasks/submodules.yml26
-rw-r--r--test/integration/targets/groupby_filter/aliases1
-rw-r--r--test/integration/targets/handler_race/aliases3
-rw-r--r--test/integration/targets/handlers/58841.yml9
-rw-r--r--test/integration/targets/handlers/aliases3
-rw-r--r--test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml11
-rw-r--r--test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml5
-rw-r--r--test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml5
-rw-r--r--test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml5
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml2
-rwxr-xr-xtest/integration/targets/handlers/runme.sh26
-rw-r--r--test/integration/targets/handlers/test_handlers_include.yml2
-rw-r--r--test/integration/targets/hardware_facts/aliases1
-rw-r--r--test/integration/targets/hash/aliases1
-rw-r--r--test/integration/targets/hosts_field/aliases1
-rw-r--r--test/integration/targets/ignore_errors/aliases1
-rw-r--r--test/integration/targets/ignore_unreachable/aliases1
-rw-r--r--test/integration/targets/import_tasks/aliases2
-rw-r--r--test/integration/targets/incidental_cloud_init_data_facts/aliases1
-rw-r--r--test/integration/targets/incidental_deploy_helper/aliases1
-rw-r--r--test/integration/targets/incidental_inventory_aws_ec2/aliases1
-rwxr-xr-xtest/integration/targets/incidental_inventory_aws_ec2/runme.sh4
-rw-r--r--test/integration/targets/incidental_inventory_docker_swarm/aliases3
-rw-r--r--test/integration/targets/incidental_inventory_foreman/aliases1
-rw-r--r--test/integration/targets/incidental_inventory_foreman/inspect_cache.yml4
-rwxr-xr-xtest/integration/targets/incidental_inventory_foreman/runme.sh4
-rw-r--r--test/integration/targets/incidental_ios_file/tasks/cli.yaml2
-rw-r--r--test/integration/targets/incidental_ios_file/tasks/main.yaml2
-rw-r--r--test/integration/targets/incidental_mongodb_parameter/aliases1
-rw-r--r--test/integration/targets/incidental_setup_docker/vars/RedHat-8.yml1
-rw-r--r--test/integration/targets/incidental_vyos_config/tasks/cli.yaml8
-rw-r--r--test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml4
-rw-r--r--test/integration/targets/incidental_vyos_config/tasks/main.yaml4
-rw-r--r--test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml2
-rw-r--r--test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml2
-rw-r--r--test/integration/targets/incidental_win_data_deduplication/tasks/main.yml2
-rw-r--r--test/integration/targets/incidental_win_data_deduplication/tasks/pre_test.yml2
-rw-r--r--test/integration/targets/incidental_win_security_policy/aliases2
-rw-r--r--test/integration/targets/incidental_win_security_policy/library/test_win_security_policy.ps153
-rw-r--r--test/integration/targets/incidental_win_security_policy/tasks/main.yml41
-rw-r--r--test/integration/targets/incidental_win_security_policy/tasks/tests.yml186
-rw-r--r--test/integration/targets/include_import/aliases2
-rw-r--r--test/integration/targets/include_import/include_role_omit/playbook.yml12
-rw-r--r--test/integration/targets/include_import/include_role_omit/roles/foo/tasks/main.yml2
-rw-r--r--test/integration/targets/include_import/playbook/test_templated_filenames.yml47
-rw-r--r--test/integration/targets/include_import/playbook/validate_templated_playbook.yml5
-rw-r--r--test/integration/targets/include_import/playbook/validate_templated_tasks.yml1
-rw-r--r--test/integration/targets/include_import/roles/role1/tasks/templated.yml1
-rwxr-xr-xtest/integration/targets/include_import/runme.sh9
-rw-r--r--test/integration/targets/include_import/undefined_var/playbook.yml3
-rw-r--r--test/integration/targets/include_vars-ad-hoc/aliases1
-rw-r--r--test/integration/targets/include_vars/tasks/main.yml53
-rw-r--r--test/integration/targets/include_vars/vars/no_auto_unsafe.yml1
-rw-r--r--test/integration/targets/include_vars/vars2/hashes/hash1.yml5
-rw-r--r--test/integration/targets/include_vars/vars2/hashes/hash2.yml5
-rw-r--r--test/integration/targets/include_when_parent_is_dynamic/aliases2
-rw-r--r--test/integration/targets/include_when_parent_is_static/aliases2
-rw-r--r--test/integration/targets/includes/aliases1
-rw-r--r--test/integration/targets/includes/include_on_playbook_should_fail.yml1
-rw-r--r--test/integration/targets/includes/roles/test_includes/tasks/branch_toplevel.yml10
-rw-r--r--test/integration/targets/includes/roles/test_includes/tasks/main.yml24
-rwxr-xr-xtest/integration/targets/includes/runme.sh6
-rw-r--r--test/integration/targets/includes/test_includes.yml8
-rw-r--r--test/integration/targets/includes_race/aliases2
-rw-r--r--test/integration/targets/infra/aliases1
-rwxr-xr-xtest/integration/targets/infra/runme.sh4
-rw-r--r--test/integration/targets/interpreter_discovery_python/aliases1
-rw-r--r--test/integration/targets/interpreter_discovery_python/tasks/main.yml4
-rw-r--r--test/integration/targets/interpreter_discovery_python_delegate_facts/aliases1
-rw-r--r--test/integration/targets/inventory/aliases1
-rw-r--r--test/integration/targets/inventory_advanced_host_list/aliases (renamed from test/integration/targets/module_utils_respawn/aliases)0
-rwxr-xr-xtest/integration/targets/inventory_advanced_host_list/runme.sh36
-rw-r--r--test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml9
-rw-r--r--test/integration/targets/inventory_cache/aliases1
-rw-r--r--test/integration/targets/inventory_constructed/keyed_group_default_value.yml5
-rw-r--r--test/integration/targets/inventory_constructed/keyed_group_list_default_value.yml5
-rw-r--r--test/integration/targets/inventory_constructed/keyed_group_str_default_value.yml5
-rw-r--r--test/integration/targets/inventory_constructed/keyed_group_trailing_separator.yml5
-rwxr-xr-xtest/integration/targets/inventory_constructed/runme.sh29
-rw-r--r--test/integration/targets/inventory_constructed/tag_inventory.yml12
-rw-r--r--test/integration/targets/inventory_yaml/aliases1
-rw-r--r--test/integration/targets/jinja2_native_types/aliases1
-rw-r--r--test/integration/targets/jinja_plugins/aliases2
-rw-r--r--test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter.py11
-rw-r--r--test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/good_collection_filter.py13
-rw-r--r--test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/bad_collection_test.py11
-rw-r--r--test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/good_collection_test.py13
-rw-r--r--test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py11
-rw-r--r--test/integration/targets/jinja_plugins/filter_plugins/good_filter.py13
-rw-r--r--test/integration/targets/jinja_plugins/playbook.yml10
-rw-r--r--test/integration/targets/jinja_plugins/tasks/main.yml22
-rw-r--r--test/integration/targets/jinja_plugins/test_plugins/bad_test.py11
-rw-r--r--test/integration/targets/jinja_plugins/test_plugins/good_test.py13
-rw-r--r--test/integration/targets/json_cleanup/aliases1
-rw-r--r--test/integration/targets/limit_inventory/aliases1
-rw-r--r--test/integration/targets/lineinfile/meta/main.yml1
-rw-r--r--test/integration/targets/lineinfile/tasks/main.yml279
-rw-r--r--test/integration/targets/lineinfile/tasks/test_string01.yml26
-rw-r--r--test/integration/targets/lineinfile/tasks/test_string02.yml28
-rw-r--r--test/integration/targets/lookup_config/aliases2
-rw-r--r--test/integration/targets/lookup_config/tasks/main.yml17
-rw-r--r--test/integration/targets/lookup_csvfile/aliases1
-rw-r--r--test/integration/targets/lookup_csvfile/tasks/main.yml30
-rw-r--r--test/integration/targets/lookup_dict/aliases2
-rw-r--r--test/integration/targets/lookup_env/aliases2
-rw-r--r--test/integration/targets/lookup_file/aliases2
-rw-r--r--test/integration/targets/lookup_first_found/aliases2
-rw-r--r--test/integration/targets/lookup_first_found/tasks/main.yml21
-rw-r--r--test/integration/targets/lookup_indexed_items/aliases2
-rw-r--r--test/integration/targets/lookup_indexed_items/tasks/main.yml16
-rw-r--r--test/integration/targets/lookup_ini/aliases1
-rw-r--r--test/integration/targets/lookup_ini/lookup_case_check.properties2
-rw-r--r--test/integration/targets/lookup_ini/mysql.ini8
-rwxr-xr-xtest/integration/targets/lookup_ini/runme.sh3
-rw-r--r--test/integration/targets/lookup_ini/test_allow_no_value.yml23
-rw-r--r--test/integration/targets/lookup_ini/test_case_sensitive.yml31
-rw-r--r--test/integration/targets/lookup_ini/test_errors.yml32
-rw-r--r--test/integration/targets/lookup_ini/test_ini.yml4
-rw-r--r--test/integration/targets/lookup_ini/test_lookup_properties.yml12
-rw-r--r--test/integration/targets/lookup_inventory_hostnames/aliases1
-rw-r--r--test/integration/targets/lookup_items/aliases2
-rw-r--r--test/integration/targets/lookup_lines/aliases2
-rw-r--r--test/integration/targets/lookup_list/aliases2
-rw-r--r--test/integration/targets/lookup_nested/aliases2
-rw-r--r--test/integration/targets/lookup_password/aliases2
-rw-r--r--test/integration/targets/lookup_pipe/aliases2
-rw-r--r--test/integration/targets/lookup_random_choice/aliases2
-rw-r--r--test/integration/targets/lookup_sequence/aliases2
-rw-r--r--test/integration/targets/lookup_sequence/tasks/main.yml135
-rw-r--r--test/integration/targets/lookup_subelements/aliases2
-rw-r--r--test/integration/targets/lookup_template/aliases2
-rw-r--r--test/integration/targets/lookup_template/tasks/main.yml8
-rw-r--r--test/integration/targets/lookup_template/templates/hello_comment.txt2
-rw-r--r--test/integration/targets/lookup_together/aliases2
-rw-r--r--test/integration/targets/lookup_together/tasks/main.yml15
-rw-r--r--test/integration/targets/lookup_unvault/aliases1
-rw-r--r--test/integration/targets/lookup_url/aliases2
-rw-r--r--test/integration/targets/lookup_varnames/aliases1
-rw-r--r--test/integration/targets/lookup_vars/aliases2
-rw-r--r--test/integration/targets/lookup_vars/tasks/main.yml40
-rw-r--r--test/integration/targets/loop_control/aliases1
-rw-r--r--test/integration/targets/loops/aliases2
-rw-r--r--test/integration/targets/meta_tasks/aliases1
-rwxr-xr-xtest/integration/targets/meta_tasks/runme.sh15
-rw-r--r--test/integration/targets/meta_tasks/test_end_batch.yml13
-rw-r--r--test/integration/targets/meta_tasks/test_end_play_serial_one.yml13
-rw-r--r--test/integration/targets/missing_required_lib/aliases1
-rw-r--r--test/integration/targets/module_defaults/action_plugins/debug.py80
-rw-r--r--test/integration/targets/module_defaults/aliases1
-rw-r--r--test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/meta/runtime.yml30
-rw-r--r--test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/metadata.py45
-rw-r--r--test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ping.py83
-rw-r--r--test/integration/targets/module_defaults/library/legacy_ping.py83
-rwxr-xr-xtest/integration/targets/module_defaults/runme.sh4
-rw-r--r--test/integration/targets/module_defaults/tasks/main.yml2
-rw-r--r--test/integration/targets/module_defaults/templates/test_metadata_warning.yml.j28
-rw-r--r--test/integration/targets/module_defaults/test_action_group_metadata.yml123
-rw-r--r--test/integration/targets/module_defaults/test_action_groups.yml132
-rw-r--r--test/integration/targets/module_defaults/test_defaults.yml52
-rw-r--r--test/integration/targets/module_no_log/aliases2
-rw-r--r--test/integration/targets/module_precedence/aliases1
-rw-r--r--test/integration/targets/module_tracebacks/aliases2
-rw-r--r--test/integration/targets/module_utils/aliases1
-rw-r--r--test/integration/targets/module_utils/module_utils_basic_setcwd.yml8
-rw-r--r--test/integration/targets/module_utils/module_utils_test.yml4
-rw-r--r--test/integration/targets/module_utils/module_utils_test_no_log.yml3
-rw-r--r--test/integration/targets/module_utils/module_utils_vvvvv.yml3
-rw-r--r--test/integration/targets/module_utils_common.respawn/aliases1
-rw-r--r--test/integration/targets/module_utils_common.respawn/library/respawnme.py (renamed from test/integration/targets/module_utils_respawn/library/respawnme.py)0
-rw-r--r--test/integration/targets/module_utils_common.respawn/tasks/main.yml (renamed from test/integration/targets/module_utils_respawn/tasks/main.yml)0
-rw-r--r--test/integration/targets/module_utils_distro/aliases2
-rw-r--r--test/integration/targets/module_utils_distro/meta/main.yml2
-rwxr-xr-xtest/integration/targets/module_utils_distro/runme.sh24
-rw-r--r--test/integration/targets/module_utils_facts.system.selinux/aliases (renamed from test/integration/targets/module_utils_selinux/aliases)1
-rw-r--r--test/integration/targets/module_utils_facts.system.selinux/tasks/main.yml (renamed from test/integration/targets/module_utils_selinux/tasks/main.yml)0
-rw-r--r--test/integration/targets/module_utils_facts.system.selinux/tasks/selinux.yml (renamed from test/integration/targets/module_utils_selinux/tasks/selinux.yml)0
-rw-r--r--test/integration/targets/no_log/aliases1
-rw-r--r--test/integration/targets/noexec/aliases1
-rw-r--r--test/integration/targets/old_style_cache_plugins/aliases4
-rw-r--r--test/integration/targets/old_style_cache_plugins/cleanup.yml41
-rw-r--r--test/integration/targets/old_style_cache_plugins/inspect_cache.yml36
-rw-r--r--test/integration/targets/old_style_cache_plugins/plugins/cache/configurable_redis.py147
-rw-r--r--test/integration/targets/old_style_cache_plugins/plugins/cache/legacy_redis.py (renamed from test/integration/targets/old_style_cache_plugins/plugins/cache/redis.py)0
-rwxr-xr-xtest/integration/targets/old_style_cache_plugins/runme.sh91
-rw-r--r--test/integration/targets/old_style_cache_plugins/setup_redis_cache.yml51
-rw-r--r--test/integration/targets/old_style_cache_plugins/test_fact_gathering.yml16
-rw-r--r--test/integration/targets/old_style_cache_plugins/test_inventory_cache.yml45
-rw-r--r--test/integration/targets/old_style_modules_posix/aliases1
-rw-r--r--test/integration/targets/omit/aliases1
-rw-r--r--test/integration/targets/order/aliases1
-rw-r--r--test/integration/targets/package/tasks/main.yml104
-rw-r--r--test/integration/targets/parsing/aliases1
-rw-r--r--test/integration/targets/path_lookups/aliases1
-rw-r--r--test/integration/targets/path_lookups/play.yml10
-rw-r--r--test/integration/targets/path_with_comma_in_inventory/aliases1
-rw-r--r--test/integration/targets/pause/aliases2
-rw-r--r--test/integration/targets/pip/tasks/pip.yml55
-rw-r--r--test/integration/targets/pkg_resources/aliases1
-rw-r--r--test/integration/targets/play_iterator/aliases1
-rw-r--r--test/integration/targets/playbook/aliases1
-rw-r--r--test/integration/targets/playbook/empty.yml1
-rw-r--r--test/integration/targets/playbook/empty_hosts.yml4
-rw-r--r--test/integration/targets/playbook/malformed_post_tasks.yml2
-rw-r--r--test/integration/targets/playbook/malformed_pre_tasks.yml2
-rw-r--r--test/integration/targets/playbook/malformed_roles.yml2
-rw-r--r--test/integration/targets/playbook/malformed_tasks.yml2
-rw-r--r--test/integration/targets/playbook/malformed_vars_prompt.yml3
-rw-r--r--test/integration/targets/playbook/old_style_role.yml3
-rw-r--r--test/integration/targets/playbook/remote_user_and_user.yml6
-rw-r--r--test/integration/targets/playbook/roles_null.yml3
-rwxr-xr-xtest/integration/targets/playbook/runme.sh83
-rw-r--r--test/integration/targets/playbook/some_vars.yml2
-rw-r--r--test/integration/targets/playbook/user.yml23
-rw-r--r--test/integration/targets/playbook/vars_files_null.yml3
-rw-r--r--test/integration/targets/playbook/vars_files_string.yml6
-rw-r--r--test/integration/targets/playbook/vars_prompt_null.yml3
-rw-r--r--test/integration/targets/plugin_config_for_inventory/aliases1
-rw-r--r--test/integration/targets/plugin_filtering/aliases1
-rw-r--r--test/integration/targets/plugin_loader/aliases1
-rw-r--r--test/integration/targets/plugin_namespace/aliases1
-rw-r--r--test/integration/targets/prepare_http_tests/tasks/kerberos.yml4
-rw-r--r--test/integration/targets/rel_plugin_loading/aliases1
-rw-r--r--test/integration/targets/remote_tmp/aliases2
-rw-r--r--test/integration/targets/remote_tmp/playbook.yml14
-rwxr-xr-xtest/integration/targets/remote_tmp/runme.sh2
-rw-r--r--test/integration/targets/retry_task_name_in_callback/aliases1
-rw-r--r--test/integration/targets/roles/aliases1
-rw-r--r--test/integration/targets/roles/no_dupes.yml10
-rwxr-xr-xtest/integration/targets/roles/runme.sh3
-rw-r--r--test/integration/targets/roles_arg_spec/aliases1
-rw-r--r--test/integration/targets/roles_var_inheritance/aliases2
-rw-r--r--test/integration/targets/roles_var_inheritance/play.yml4
-rw-r--r--test/integration/targets/roles_var_inheritance/roles/A/meta/main.yml4
-rw-r--r--test/integration/targets/roles_var_inheritance/roles/B/meta/main.yml4
-rw-r--r--test/integration/targets/roles_var_inheritance/roles/child_nested_dep/vars/main.yml1
-rw-r--r--test/integration/targets/roles_var_inheritance/roles/common_dep/meta/main.yml4
-rw-r--r--test/integration/targets/roles_var_inheritance/roles/common_dep/vars/main.yml1
-rw-r--r--test/integration/targets/roles_var_inheritance/roles/nested_dep/meta/main.yml3
-rw-r--r--test/integration/targets/roles_var_inheritance/roles/nested_dep/tasks/main.yml5
-rwxr-xr-xtest/integration/targets/roles_var_inheritance/runme.sh9
-rw-r--r--test/integration/targets/rpm_key/tasks/main.yaml2
-rw-r--r--test/integration/targets/run_modules/aliases1
-rw-r--r--test/integration/targets/set_fact/aliases2
-rwxr-xr-xtest/integration/targets/set_fact/runme.sh3
-rw-r--r--test/integration/targets/set_fact/set_fact_auto_unsafe.yml10
-rw-r--r--test/integration/targets/set_stats/aliases2
-rwxr-xr-xtest/integration/targets/set_stats/runme.sh13
-rw-r--r--test/integration/targets/set_stats/test_aggregate.yml13
-rw-r--r--test/integration/targets/set_stats/test_simple.yml79
-rw-r--r--test/integration/targets/setup_cron/defaults/main.yml2
-rw-r--r--test/integration/targets/setup_cron/meta/main.yml2
-rw-r--r--test/integration/targets/setup_cron/tasks/main.yml12
-rw-r--r--test/integration/targets/setup_paramiko/install-FreeBSD-11-python-2.yml3
-rw-r--r--test/integration/targets/setup_paramiko/install-FreeBSD-11-python-3.yml12
-rw-r--r--test/integration/targets/setup_paramiko/install-FreeBSD-11.4-python-3.yml3
-rw-r--r--test/integration/targets/setup_paramiko/install-FreeBSD-12-python-2.yml3
-rw-r--r--test/integration/targets/setup_paramiko/install-FreeBSD-12-python-3.yml3
-rw-r--r--test/integration/targets/setup_paramiko/install-FreeBSD-12.2-python-3.yml3
-rw-r--r--test/integration/targets/setup_paramiko/install-FreeBSD-python-3.yml6
-rw-r--r--test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-2.yml4
-rw-r--r--test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-3.yml4
-rw-r--r--test/integration/targets/setup_paramiko/uninstall-FreeBSD-11.4-python-3.yml4
-rw-r--r--test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-2.yml4
-rw-r--r--test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-3.yml4
-rw-r--r--test/integration/targets/setup_paramiko/uninstall-FreeBSD-12.2-python-3.yml4
-rw-r--r--test/integration/targets/setup_paramiko/uninstall-FreeBSD-python-3.yml4
-rw-r--r--test/integration/targets/setup_remote_tmp_dir/defaults/main.yml2
-rw-r--r--test/integration/targets/setup_remote_tmp_dir/handlers/main.yml2
-rw-r--r--test/integration/targets/setup_remote_tmp_dir/tasks/default.yml1
-rw-r--r--test/integration/targets/setup_rpm_repo/files/create-repo.py71
-rw-r--r--test/integration/targets/special_vars/aliases1
-rw-r--r--test/integration/targets/special_vars_hosts/aliases2
-rw-r--r--test/integration/targets/special_vars_hosts/inventory3
-rw-r--r--test/integration/targets/special_vars_hosts/playbook.yml53
-rwxr-xr-xtest/integration/targets/special_vars_hosts/runme.sh7
-rw-r--r--test/integration/targets/split/aliases2
-rw-r--r--test/integration/targets/split/tasks/main.yml30
-rw-r--r--test/integration/targets/subversion/roles/subversion/defaults/main.yml5
-rw-r--r--test/integration/targets/subversion/roles/subversion/tasks/setup.yml18
-rwxr-xr-xtest/integration/targets/subversion/runme.sh15
-rw-r--r--test/integration/targets/subversion/runme.yml2
-rw-r--r--test/integration/targets/tags/aliases2
-rw-r--r--test/integration/targets/task_ordering/aliases1
-rw-r--r--test/integration/targets/task_ordering/tasks/main.yml2
-rw-r--r--test/integration/targets/tasks/aliases1
-rw-r--r--test/integration/targets/tempfile/aliases1
-rw-r--r--test/integration/targets/tempfile/meta/main.yml2
-rw-r--r--test/integration/targets/tempfile/tasks/main.yml63
-rw-r--r--test/integration/targets/template/aliases2
-rw-r--r--test/integration/targets/template/files/custom_comment_string.expected2
-rwxr-xr-xtest/integration/targets/template/runme.sh4
-rw-r--r--test/integration/targets/template/tasks/main.yml22
-rw-r--r--test/integration/targets/template/templates/custom_comment_string.j23
-rw-r--r--test/integration/targets/template_jinja2_latest/aliases2
-rw-r--r--test/integration/targets/template_jinja2_non_native/aliases1
-rw-r--r--test/integration/targets/templating_lookups/aliases2
-rw-r--r--test/integration/targets/templating_settings/aliases1
-rw-r--r--test/integration/targets/test_core/aliases1
-rw-r--r--test/integration/targets/test_files/aliases1
-rw-r--r--test/integration/targets/test_mathstuff/aliases1
-rw-r--r--test/integration/targets/throttle/aliases1
-rw-r--r--test/integration/targets/unarchive/tasks/test_download.yml66
-rw-r--r--test/integration/targets/unarchive/tasks/test_include.yml3
-rw-r--r--test/integration/targets/unarchive/tasks/test_owner_group.yml2
-rw-r--r--test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml2
-rw-r--r--test/integration/targets/unarchive/tasks/test_unprivileged_user.yml4
-rw-r--r--test/integration/targets/undefined/aliases1
-rw-r--r--test/integration/targets/undefined/tasks/main.yml3
-rw-r--r--test/integration/targets/unicode/aliases1
-rw-r--r--test/integration/targets/unsafe_writes/aliases2
-rw-r--r--test/integration/targets/unsafe_writes/basic.yml21
-rwxr-xr-xtest/integration/targets/unsafe_writes/runme.sh6
-rw-r--r--test/integration/targets/until/aliases1
-rw-r--r--test/integration/targets/unvault/aliases1
-rw-r--r--test/integration/targets/uri/meta/main.yml1
-rw-r--r--test/integration/targets/uri/tasks/main.yml54
-rw-r--r--test/integration/targets/user/tasks/main.yml2
-rw-r--r--test/integration/targets/user/tasks/test_umask.yml57
-rw-r--r--test/integration/targets/var_blending/aliases1
-rw-r--r--test/integration/targets/var_precedence/aliases1
-rw-r--r--test/integration/targets/var_reserved/aliases1
-rw-r--r--test/integration/targets/var_templating/aliases1
-rwxr-xr-xtest/integration/targets/vault/runme_change_pip_installed.sh27
-rw-r--r--test/integration/targets/want_json_modules_posix/aliases1
-rw-r--r--test/integration/targets/yaml_parsing/aliases1
-rw-r--r--test/integration/targets/yum/filter_plugins/filter_list_of_tuples_by_first_param.py25
-rw-r--r--test/integration/targets/yum/tasks/cacheonly.yml16
-rw-r--r--test/integration/targets/yum/tasks/main.yml13
-rw-r--r--test/integration/targets/yum/tasks/multiarch.yml154
-rw-r--r--test/integration/targets/yum/tasks/repo.yml24
-rw-r--r--test/integration/targets/yum/tasks/yum.yml15
-rw-r--r--test/integration/targets/yum/vars/main.yml1
-rw-r--r--test/integration/targets/yum_repository/tasks/main.yml24
586 files changed, 5664 insertions, 1213 deletions
diff --git a/test/integration/targets/adhoc/aliases b/test/integration/targets/adhoc/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/adhoc/aliases
+++ b/test/integration/targets/adhoc/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/ansiballz_python/aliases b/test/integration/targets/ansiballz_python/aliases
index f8e28c7e..e2c8fd39 100644
--- a/test/integration/targets/ansiballz_python/aliases
+++ b/test/integration/targets/ansiballz_python/aliases
@@ -1,2 +1,3 @@
shippable/posix/group1
skip/aix
+context/target
diff --git a/test/integration/targets/ansible-doc/aliases b/test/integration/targets/ansible-doc/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/ansible-doc/aliases
+++ b/test/integration/targets/ansible-doc/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/ansible-doc/fakemodule.output b/test/integration/targets/ansible-doc/fakemodule.output
index 01070fd5..5548ad5e 100644
--- a/test/integration/targets/ansible-doc/fakemodule.output
+++ b/test/integration/targets/ansible-doc/fakemodule.output
@@ -2,6 +2,8 @@
this is a fake module
+ADDED IN: version 1.0.0 of testns.testcol
+
OPTIONS (= is mandatory):
- _notreal
@@ -12,5 +14,3 @@ OPTIONS (= is mandatory):
AUTHOR: me
SHORT_DESCIPTION: fake module
-
-VERSION_ADDED_COLLECTION: testns.testcol
diff --git a/test/integration/targets/ansible-doc/randommodule-text.output b/test/integration/targets/ansible-doc/randommodule-text.output
new file mode 100644
index 00000000..24327a59
--- /dev/null
+++ b/test/integration/targets/ansible-doc/randommodule-text.output
@@ -0,0 +1,105 @@
+> TESTNS.TESTCOL.RANDOMMODULE (./collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py)
+
+ A random module.
+
+ADDED IN: version 1.0.0 of testns.testcol
+
+DEPRECATED:
+
+ Reason: Test deprecation
+ Will be removed in: Ansible 3.0.0
+ Alternatives: Use some other module
+
+
+OPTIONS (= is mandatory):
+
+- sub
+ Suboptions.
+ [Default: (null)]
+ set_via:
+ env:
+ - deprecated:
+ alternative: none
+ removed_in: 2.0.0
+ version: 2.0.0
+ why: Test deprecation
+ name: TEST_ENV
+
+ type: dict
+
+ OPTIONS:
+
+ - subtest2
+ Another suboption.
+ [Default: (null)]
+ type: float
+ added in: version 1.1.0
+
+
+
+ SUBOPTIONS:
+
+ - subtest
+ A suboption.
+ [Default: (null)]
+ type: int
+ added in: version 1.1.0 of testns.testcol
+
+
+- test
+ Some text.
+ [Default: (null)]
+ type: str
+ added in: version 1.2.0 of testns.testcol
+
+
+- testcol2option
+ An option taken from testcol2
+ [Default: (null)]
+ type: str
+ added in: version 1.0.0 of testns.testcol2
+
+
+- testcol2option2
+ Another option taken from testcol2
+ [Default: (null)]
+ type: str
+
+
+AUTHOR: Ansible Core Team
+
+EXAMPLES:
+
+
+
+
+RETURN VALUES:
+- a_first
+ A first result.
+
+ returned: success
+ type: str
+
+- m_middle
+ This should be in the middle.
+ Has some more data
+
+ returned: success and 1st of month
+ type: dict
+
+ CONTAINS:
+
+ - suboption
+ A suboption.
+ (Choices: ARF, BARN, c_without_capital_first_letter)
+ type: str
+ added in: version 1.4.0 of testns.testcol
+
+
+- z_last
+ A last result.
+
+ returned: success
+ type: str
+ added in: version 1.3.0 of testns.testcol
+
diff --git a/test/integration/targets/ansible-doc/runme.sh b/test/integration/targets/ansible-doc/runme.sh
index 4f40d7c3..549a341b 100755
--- a/test/integration/targets/ansible-doc/runme.sh
+++ b/test/integration/targets/ansible-doc/runme.sh
@@ -19,6 +19,11 @@ current_out="$(ansible-doc --playbook-dir ./ testns.testcol.fakemodule | sed '1
expected_out="$(sed '1 s/\(^> TESTNS\.TESTCOL\.FAKEMODULE\).*(.*)$/\1/' fakemodule.output)"
test "$current_out" == "$expected_out"
+# we use sed to strip the module path from the first line
+current_out="$(ansible-doc --playbook-dir ./ testns.testcol.randommodule | sed '1 s/\(^> TESTNS\.TESTCOL\.RANDOMMODULE\).*(.*)$/\1/')"
+expected_out="$(sed '1 s/\(^> TESTNS\.TESTCOL\.RANDOMMODULE\).*(.*)$/\1/' randommodule-text.output)"
+test "$current_out" == "$expected_out"
+
# ensure we do work with valid collection name for list
ansible-doc --list testns.testcol --playbook-dir ./ 2>&1 | grep -v "Invalid collection pattern"
@@ -94,3 +99,6 @@ test "$current_out" == "$expected_out"
current_out="$(ansible-doc --json --playbook-dir ./ -t vars testns.testcol.noop_vars_plugin | sed 's/ *$//' | sed 's/ *"filename": "[^"]*",$//')"
expected_out="$(sed 's/ *"filename": "[^"]*",$//' noop_vars_plugin.output)"
test "$current_out" == "$expected_out"
+
+# just ensure it runs
+ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --playbook-dir /dev/null
diff --git a/test/integration/targets/ansible-galaxy-collection-scm/aliases b/test/integration/targets/ansible-galaxy-collection-scm/aliases
index 9c34b360..498fedd5 100644
--- a/test/integration/targets/ansible-galaxy-collection-scm/aliases
+++ b/test/integration/targets/ansible-galaxy-collection-scm/aliases
@@ -1,3 +1,2 @@
shippable/posix/group4
-skip/aix
-skip/python2.6 # ansible-galaxy uses tarfile with features not available until 2.7
+context/controller
diff --git a/test/integration/targets/ansible-galaxy-collection/aliases b/test/integration/targets/ansible-galaxy-collection/aliases
index e501bce5..6c57208a 100644
--- a/test/integration/targets/ansible-galaxy-collection/aliases
+++ b/test/integration/targets/ansible-galaxy-collection/aliases
@@ -1,3 +1,4 @@
shippable/galaxy/group1
shippable/galaxy/smoketest
cloud/galaxy
+context/controller
diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/install.yml b/test/integration/targets/ansible-galaxy-collection/tasks/install.yml
index 7d66be2f..ad10bff8 100644
--- a/test/integration/targets/ansible-galaxy-collection/tasks/install.yml
+++ b/test/integration/targets/ansible-galaxy-collection/tasks/install.yml
@@ -214,7 +214,7 @@
state: absent
- assert:
- that: expected_error in error
+ that: error == expected_error
vars:
reset_color: '\x1b\[0m'
color: '\x1b\[[0-9];[0-9]{2}m'
@@ -260,7 +260,7 @@
- debug: msg="Expected - {{ expected_error }}"
- assert:
- that: expected_error in error
+ that: error == expected_error
always:
- name: clean up collection skeleton and artifact
file:
diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/upgrade.yml b/test/integration/targets/ansible-galaxy-collection/tasks/upgrade.yml
index b49f1eec..893ea803 100644
--- a/test/integration/targets/ansible-galaxy-collection/tasks/upgrade.yml
+++ b/test/integration/targets/ansible-galaxy-collection/tasks/upgrade.yml
@@ -124,9 +124,9 @@
that:
- '"parent_dep.parent_collection:1.1.0 was installed successfully" in result.stdout_lines'
- (metadata.results[0].content | b64decode | from_json).collection_info.version == '1.1.0'
- - "\"Skipping 'child_dep.child_collection:0.9.9' as it is already installed\" in result.stdout_lines"
+ - "\"'child_dep.child_collection:0.9.9' is already installed, skipping.\" in result.stdout_lines"
- (metadata.results[1].content | b64decode | from_json).collection_info.version == '0.9.9'
- - "\"Skipping 'child_dep.child_dep2:1.2.2' as it is already installed\" in result.stdout_lines"
+ - "\"'child_dep.child_dep2:1.2.2' is already installed, skipping.\" in result.stdout_lines"
- (metadata.results[2].content | b64decode | from_json).collection_info.version == '1.2.2'
##### Updating collections with --upgrade
@@ -187,7 +187,7 @@
register: result
- assert:
- that: "\"Skipping 'namespace1.name1:1.1.0-beta.1' as it is already installed\" in result.stdout"
+ that: "\"'namespace1.name1:1.1.0-beta.1' is already installed, skipping.\" in result.stdout"
# With deps
diff --git a/test/integration/targets/ansible-galaxy-role/aliases b/test/integration/targets/ansible-galaxy-role/aliases
index 62548acd..498fedd5 100644
--- a/test/integration/targets/ansible-galaxy-role/aliases
+++ b/test/integration/targets/ansible-galaxy-role/aliases
@@ -1,2 +1,2 @@
shippable/posix/group4
-skip/python2.6 # build uses tarfile with features not available until 2.7
+context/controller
diff --git a/test/integration/targets/ansible-galaxy/aliases b/test/integration/targets/ansible-galaxy/aliases
index 48ed7d60..275bdbfd 100644
--- a/test/integration/targets/ansible-galaxy/aliases
+++ b/test/integration/targets/ansible-galaxy/aliases
@@ -1,4 +1,3 @@
destructive
shippable/posix/group4
-skip/python2.6 # build uses tarfile with features not available until 2.7
-skip/aix
+context/controller
diff --git a/test/integration/targets/ansible-inventory/aliases b/test/integration/targets/ansible-inventory/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/ansible-inventory/aliases
+++ b/test/integration/targets/ansible-inventory/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/ansible-inventory/files/invalid_sample.yml b/test/integration/targets/ansible-inventory/files/invalid_sample.yml
new file mode 100644
index 00000000..f7bbe0cf
--- /dev/null
+++ b/test/integration/targets/ansible-inventory/files/invalid_sample.yml
@@ -0,0 +1,7 @@
+all:
+ children:
+ somegroup:
+ hosts:
+ something:
+ 7.2: bar
+ ungrouped: {}
diff --git a/test/integration/targets/ansible-inventory/files/valid_sample.yml b/test/integration/targets/ansible-inventory/files/valid_sample.yml
new file mode 100644
index 00000000..477f82f2
--- /dev/null
+++ b/test/integration/targets/ansible-inventory/files/valid_sample.yml
@@ -0,0 +1,7 @@
+all:
+ children:
+ somegroup:
+ hosts:
+ something:
+ foo: bar
+ ungrouped: {} \ No newline at end of file
diff --git a/test/integration/targets/ansible-inventory/tasks/main.yml b/test/integration/targets/ansible-inventory/tasks/main.yml
index 0ab09c07..685cad88 100644
--- a/test/integration/targets/ansible-inventory/tasks/main.yml
+++ b/test/integration/targets/ansible-inventory/tasks/main.yml
@@ -1,3 +1,111 @@
+- name: "No command supplied"
+ command: ansible-inventory
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - result is failed
+ - '"ERROR! No action selected, at least one of --host, --graph or --list needs to be specified." in result.stderr'
+
+- name: "test option: --list --export"
+ command: ansible-inventory --list --export
+ register: result
+
+- assert:
+ that:
+ - result is succeeded
+
+- name: "test option: --list --yaml --export"
+ command: ansible-inventory --list --yaml --export
+ register: result
+
+- assert:
+ that:
+ - result is succeeded
+
+- name: "test option: --list --output"
+ command: ansible-inventory --list --output junk.txt
+ register: result
+
+- name: stat output file
+ stat:
+ path: junk.txt
+ register: st
+
+- assert:
+ that:
+ - result is succeeded
+ - st.stat.exists
+
+- name: "test option: --graph"
+ command: ansible-inventory --graph
+ register: result
+
+- assert:
+ that:
+ - result is succeeded
+
+- name: "test option: --graph --vars"
+ command: ansible-inventory --graph --vars
+ register: result
+
+- assert:
+ that:
+ - result is succeeded
+
+- name: "test option: --graph with bad pattern"
+ command: ansible-inventory --graph invalid
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - result is failed
+ - '"ERROR! Pattern must be valid group name when using --graph" in result.stderr'
+
+- name: "test option: --host localhost"
+ command: ansible-inventory --host localhost
+ register: result
+
+- assert:
+ that:
+ - result is succeeded
+
+- name: "test option: --host with invalid host"
+ command: ansible-inventory --host invalid
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - result is failed
+ - '"ERROR! Could not match supplied host pattern, ignoring: invalid" in result.stderr'
+
+- name: Install toml package
+ pip:
+ name:
+ - toml
+ state: present
+
+- name: "test option: --toml with valid group name"
+ command: ansible-inventory --list --toml -i {{ role_path }}/files/valid_sample.yml
+ register: result
+
+- assert:
+ that:
+ - result is succeeded
+
+- name: "test option: --toml with invalid group name"
+ command: ansible-inventory --list --toml -i {{ role_path }}/files/invalid_sample.yml
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - result is failed
+ - '"ERROR! The source inventory contains a non-string key" in result.stderr'
+
- name: "test json output with unicode characters"
command: ansible-inventory --list -i {{ role_path }}/files/unicode.yml
register: result
@@ -47,12 +155,6 @@
state: absent
- block:
- - name: Install toml package
- pip:
- name:
- - toml
- state: present
-
- name: "test toml output with unicode characters"
command: ansible-inventory --list --toml -i {{ role_path }}/files/unicode.yml
register: result
diff --git a/test/integration/targets/vault/aliases b/test/integration/targets/ansible-pull/aliases
index 757c9966..8278ec8b 100644
--- a/test/integration/targets/vault/aliases
+++ b/test/integration/targets/ansible-pull/aliases
@@ -1,2 +1,2 @@
shippable/posix/group3
-skip/aix
+context/controller
diff --git a/test/integration/targets/pull/cleanup.yml b/test/integration/targets/ansible-pull/cleanup.yml
index 68686964..68686964 100644
--- a/test/integration/targets/pull/cleanup.yml
+++ b/test/integration/targets/ansible-pull/cleanup.yml
diff --git a/test/integration/targets/pull/pull-integration-test/ansible.cfg b/test/integration/targets/ansible-pull/pull-integration-test/ansible.cfg
index f8fc6cdb..f8fc6cdb 100644
--- a/test/integration/targets/pull/pull-integration-test/ansible.cfg
+++ b/test/integration/targets/ansible-pull/pull-integration-test/ansible.cfg
diff --git a/test/integration/targets/pull/pull-integration-test/inventory b/test/integration/targets/ansible-pull/pull-integration-test/inventory
index 72644cef..72644cef 100644
--- a/test/integration/targets/pull/pull-integration-test/inventory
+++ b/test/integration/targets/ansible-pull/pull-integration-test/inventory
diff --git a/test/integration/targets/pull/pull-integration-test/local.yml b/test/integration/targets/ansible-pull/pull-integration-test/local.yml
index d358ee86..d358ee86 100644
--- a/test/integration/targets/pull/pull-integration-test/local.yml
+++ b/test/integration/targets/ansible-pull/pull-integration-test/local.yml
diff --git a/test/integration/targets/pull/pull-integration-test/multi_play_1.yml b/test/integration/targets/ansible-pull/pull-integration-test/multi_play_1.yml
index 0ec0da6b..0ec0da6b 100644
--- a/test/integration/targets/pull/pull-integration-test/multi_play_1.yml
+++ b/test/integration/targets/ansible-pull/pull-integration-test/multi_play_1.yml
diff --git a/test/integration/targets/pull/pull-integration-test/multi_play_2.yml b/test/integration/targets/ansible-pull/pull-integration-test/multi_play_2.yml
index 1fe5a584..1fe5a584 100644
--- a/test/integration/targets/pull/pull-integration-test/multi_play_2.yml
+++ b/test/integration/targets/ansible-pull/pull-integration-test/multi_play_2.yml
diff --git a/test/integration/targets/pull/runme.sh b/test/integration/targets/ansible-pull/runme.sh
index 347971a4..347971a4 100755
--- a/test/integration/targets/pull/runme.sh
+++ b/test/integration/targets/ansible-pull/runme.sh
diff --git a/test/integration/targets/pull/setup.yml b/test/integration/targets/ansible-pull/setup.yml
index ebd5a1c0..ebd5a1c0 100644
--- a/test/integration/targets/pull/setup.yml
+++ b/test/integration/targets/ansible-pull/setup.yml
diff --git a/test/integration/targets/ansible-runner/aliases b/test/integration/targets/ansible-runner/aliases
index 42d2022b..17ae2d5e 100644
--- a/test/integration/targets/ansible-runner/aliases
+++ b/test/integration/targets/ansible-runner/aliases
@@ -1,6 +1,5 @@
shippable/posix/group3
-skip/python2 # ansible-runner is for controller and deprecated python2 support
-skip/aix
+context/controller
skip/osx
skip/macos
skip/freebsd
diff --git a/test/integration/targets/ansible-test-cloud-acme/aliases b/test/integration/targets/ansible-test-cloud-acme/aliases
new file mode 100644
index 00000000..db3ab680
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-acme/aliases
@@ -0,0 +1,3 @@
+cloud/acme
+shippable/generic/group1
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-acme/tasks/main.yml b/test/integration/targets/ansible-test-cloud-acme/tasks/main.yml
new file mode 100644
index 00000000..42ebc284
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-acme/tasks/main.yml
@@ -0,0 +1,7 @@
+- name: Verify endpoints respond
+ uri:
+ url: "{{ item }}"
+ validate_certs: no
+ with_items:
+ - http://{{ acme_host }}:5000/
+ - https://{{ acme_host }}:14000/dir
diff --git a/test/integration/targets/ansible-test-cloud-cs/aliases b/test/integration/targets/ansible-test-cloud-cs/aliases
new file mode 100644
index 00000000..cf43ff1e
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-cs/aliases
@@ -0,0 +1,3 @@
+cloud/cs
+shippable/generic/group1
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-cs/tasks/main.yml b/test/integration/targets/ansible-test-cloud-cs/tasks/main.yml
new file mode 100644
index 00000000..3b219c7e
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-cs/tasks/main.yml
@@ -0,0 +1,8 @@
+- name: Verify endpoints respond
+ uri:
+ url: "{{ item }}"
+ validate_certs: no
+ register: this
+ failed_when: "this.status != 401" # authentication is required, but not provided (requests must be signed)
+ with_items:
+ - "{{ ansible_env.CLOUDSTACK_ENDPOINT }}"
diff --git a/test/integration/targets/ansible-test-cloud-foreman/aliases b/test/integration/targets/ansible-test-cloud-foreman/aliases
new file mode 100644
index 00000000..a4bdcea6
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-foreman/aliases
@@ -0,0 +1,3 @@
+cloud/foreman
+shippable/generic/group1
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-foreman/tasks/main.yml b/test/integration/targets/ansible-test-cloud-foreman/tasks/main.yml
new file mode 100644
index 00000000..4170d83e
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-foreman/tasks/main.yml
@@ -0,0 +1,6 @@
+- name: Verify endpoints respond
+ uri:
+ url: "{{ item }}"
+ validate_certs: no
+ with_items:
+ - http://{{ ansible_env.FOREMAN_HOST }}:{{ ansible_env.FOREMAN_PORT }}/ping
diff --git a/test/integration/targets/ansible-test-cloud-galaxy/aliases b/test/integration/targets/ansible-test-cloud-galaxy/aliases
new file mode 100644
index 00000000..6c57208a
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-galaxy/aliases
@@ -0,0 +1,4 @@
+shippable/galaxy/group1
+shippable/galaxy/smoketest
+cloud/galaxy
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml b/test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml
new file mode 100644
index 00000000..8ae15ea5
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml
@@ -0,0 +1,25 @@
+# The pulp container has a long start up time.
+# The first task to interact with pulp needs to wait until it responds appropriately.
+- name: Wait for Pulp API
+ uri:
+ url: '{{ pulp_api }}/pulp/api/v3/distributions/ansible/ansible/'
+ user: '{{ pulp_user }}'
+ password: '{{ pulp_password }}'
+ force_basic_auth: true
+ register: this
+ until: this is successful
+ delay: 1
+ retries: 60
+
+- name: Verify Galaxy NG server
+ uri:
+ url: "{{ galaxy_ng_server }}"
+ user: '{{ pulp_user }}'
+ password: '{{ pulp_password }}'
+ force_basic_auth: true
+
+- name: Verify Pulp server
+ uri:
+ url: "{{ pulp_server }}"
+ status_code:
+ - 404 # endpoint responds without authentication
diff --git a/test/integration/targets/ansible-test-cloud-httptester-windows/aliases b/test/integration/targets/ansible-test-cloud-httptester-windows/aliases
new file mode 100644
index 00000000..f45a1623
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-httptester-windows/aliases
@@ -0,0 +1,4 @@
+cloud/httptester
+windows
+shippable/windows/group1
+context/target
diff --git a/test/integration/targets/ansible-test-cloud-httptester-windows/tasks/main.yml b/test/integration/targets/ansible-test-cloud-httptester-windows/tasks/main.yml
new file mode 100644
index 00000000..a78b28ca
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-httptester-windows/tasks/main.yml
@@ -0,0 +1,15 @@
+- name: Verify HTTPTESTER environment variable
+ assert:
+ that:
+ - "lookup('env', 'HTTPTESTER') == '1'"
+
+- name: Verify endpoints respond
+ ansible.windows.win_uri:
+ url: "{{ item }}"
+ validate_certs: no
+ with_items:
+ - http://ansible.http.tests/
+ - https://ansible.http.tests/
+ - https://sni1.ansible.http.tests/
+ - https://fail.ansible.http.tests/
+ - https://self-signed.ansible.http.tests/
diff --git a/test/integration/targets/ansible-test-cloud-httptester/aliases b/test/integration/targets/ansible-test-cloud-httptester/aliases
new file mode 100644
index 00000000..eb5f7080
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-httptester/aliases
@@ -0,0 +1,3 @@
+needs/httptester # using legacy alias for testing purposes
+shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-httptester/tasks/main.yml b/test/integration/targets/ansible-test-cloud-httptester/tasks/main.yml
new file mode 100644
index 00000000..16b632f3
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-httptester/tasks/main.yml
@@ -0,0 +1,15 @@
+- name: Verify HTTPTESTER environment variable
+ assert:
+ that:
+ - "lookup('env', 'HTTPTESTER') == '1'"
+
+- name: Verify endpoints respond
+ uri:
+ url: "{{ item }}"
+ validate_certs: no
+ with_items:
+ - http://ansible.http.tests/
+ - https://ansible.http.tests/
+ - https://sni1.ansible.http.tests/
+ - https://fail.ansible.http.tests/
+ - https://self-signed.ansible.http.tests/
diff --git a/test/integration/targets/ansible-test-cloud-nios/aliases b/test/integration/targets/ansible-test-cloud-nios/aliases
new file mode 100644
index 00000000..136344a9
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-nios/aliases
@@ -0,0 +1,3 @@
+cloud/nios
+shippable/generic/group1
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-nios/tasks/main.yml b/test/integration/targets/ansible-test-cloud-nios/tasks/main.yml
new file mode 100644
index 00000000..b4d447d7
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-nios/tasks/main.yml
@@ -0,0 +1,10 @@
+- name: Verify endpoints respond
+ uri:
+ url: "{{ item }}"
+ url_username: "{{ nios_provider.username }}"
+ url_password: "{{ nios_provider.password }}"
+ validate_certs: no
+ register: this
+ failed_when: "this.status != 404" # authentication succeeded, but the requested path was not found
+ with_items:
+ - https://{{ nios_provider.host }}/
diff --git a/test/integration/targets/ansible-test-cloud-openshift/aliases b/test/integration/targets/ansible-test-cloud-openshift/aliases
new file mode 100644
index 00000000..6e32db7b
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-openshift/aliases
@@ -0,0 +1,4 @@
+cloud/openshift
+shippable/generic/group1
+disabled # disabled due to requirements conflict: botocore 1.20.6 has requirement urllib3<1.27,>=1.25.4, but you have urllib3 1.24.3.
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-openshift/tasks/main.yml b/test/integration/targets/ansible-test-cloud-openshift/tasks/main.yml
new file mode 100644
index 00000000..c3b51904
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-openshift/tasks/main.yml
@@ -0,0 +1,6 @@
+- name: Verify endpoints respond
+ uri:
+ url: "{{ item }}"
+ validate_certs: no
+ with_items:
+ - https://openshift-origin:8443/
diff --git a/test/integration/targets/ansible-test-cloud-vcenter/aliases b/test/integration/targets/ansible-test-cloud-vcenter/aliases
new file mode 100644
index 00000000..0cd8ad20
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-vcenter/aliases
@@ -0,0 +1,3 @@
+cloud/vcenter
+shippable/generic/group1
+context/controller
diff --git a/test/integration/targets/ansible-test-cloud-vcenter/tasks/main.yml b/test/integration/targets/ansible-test-cloud-vcenter/tasks/main.yml
new file mode 100644
index 00000000..49e5c16a
--- /dev/null
+++ b/test/integration/targets/ansible-test-cloud-vcenter/tasks/main.yml
@@ -0,0 +1,6 @@
+- name: Verify endpoints respond
+ uri:
+ url: "{{ item }}"
+ validate_certs: no
+ with_items:
+ - http://{{ vcenter_hostname }}:5000/ # control endpoint for the simulator
diff --git a/test/integration/targets/ansible-test-docker/aliases b/test/integration/targets/ansible-test-docker/aliases
index d1284cf7..a862ab8b 100644
--- a/test/integration/targets/ansible-test-docker/aliases
+++ b/test/integration/targets/ansible-test-docker/aliases
@@ -1 +1,2 @@
shippable/generic/group1 # Runs in the default test container so access to tools like pwsh
+context/controller
diff --git a/test/integration/targets/ansible-test-docker/collection-tests/docker.sh b/test/integration/targets/ansible-test-docker/collection-tests/docker.sh
index e0e34290..69372245 100755
--- a/test/integration/targets/ansible-test-docker/collection-tests/docker.sh
+++ b/test/integration/targets/ansible-test-docker/collection-tests/docker.sh
@@ -7,7 +7,7 @@ cd "${WORK_DIR}/ansible_collections/ns/col"
# common args for all tests
# because we are running in shippable/generic/ we are already in the default docker container
-common=(--python "${ANSIBLE_TEST_PYTHON_VERSION}" --color --truncate 0 "${@}")
+common=(--python "${ANSIBLE_TEST_PYTHON_VERSION}" --venv --venv-system-site-packages --color --truncate 0 "${@}")
# prime the venv to work around issue with PyYAML detection in ansible-test
ansible-test sanity "${common[@]}" --test ignores
diff --git a/test/integration/targets/ansible-test/aliases b/test/integration/targets/ansible-test/aliases
index f8e28c7e..13e01f0c 100644
--- a/test/integration/targets/ansible-test/aliases
+++ b/test/integration/targets/ansible-test/aliases
@@ -1,2 +1,2 @@
shippable/posix/group1
-skip/aix
+context/controller
diff --git a/test/integration/targets/ansible-test/ansible_collections/ns/col_constraints/tests/integration/targets/constraints/aliases b/test/integration/targets/ansible-test/ansible_collections/ns/col_constraints/tests/integration/targets/constraints/aliases
new file mode 100644
index 00000000..1af1cf90
--- /dev/null
+++ b/test/integration/targets/ansible-test/ansible_collections/ns/col_constraints/tests/integration/targets/constraints/aliases
@@ -0,0 +1 @@
+context/controller
diff --git a/test/integration/targets/ansible-test/collection-tests/coverage.sh b/test/integration/targets/ansible-test/collection-tests/coverage.sh
index 033a9836..221ae66a 100755
--- a/test/integration/targets/ansible-test/collection-tests/coverage.sh
+++ b/test/integration/targets/ansible-test/collection-tests/coverage.sh
@@ -7,8 +7,8 @@ cd "${WORK_DIR}/ansible_collections/ns/col"
# rename the sanity ignore file to match the current ansible version and update import ignores with the python version
ansible_version="$(python -c 'import ansible.release; print(".".join(ansible.release.__version__.split(".")[:2]))')"
-if [ "${ANSIBLE_TEST_PYTHON_VERSION}" == "2.6" ]; then
- # Non-module/module_utils plugins are not checked on this remote-only Python versions
+if [[ "${ANSIBLE_TEST_PYTHON_VERSION}" =~ ^2\. ]] || [[ "${ANSIBLE_TEST_PYTHON_VERSION}" =~ ^3\.[567] ]]; then
+ # Non-module/module_utils plugins are not checked on these remote-only Python versions
sed "s/ import$/ import-${ANSIBLE_TEST_PYTHON_VERSION}/;" < "tests/sanity/ignore.txt" | grep -v 'plugins/[^m].* import' > "tests/sanity/ignore-${ansible_version}.txt"
else
sed "s/ import$/ import-${ANSIBLE_TEST_PYTHON_VERSION}/;" < "tests/sanity/ignore.txt" > "tests/sanity/ignore-${ansible_version}.txt"
diff --git a/test/integration/targets/ansible-test/collection-tests/venv.sh b/test/integration/targets/ansible-test/collection-tests/venv.sh
index ba0d2628..42dbfde4 100755
--- a/test/integration/targets/ansible-test/collection-tests/venv.sh
+++ b/test/integration/targets/ansible-test/collection-tests/venv.sh
@@ -7,8 +7,8 @@ cd "${WORK_DIR}/ansible_collections/ns/col"
# rename the sanity ignore file to match the current ansible version and update import ignores with the python version
ansible_version="$(python -c 'import ansible.release; print(".".join(ansible.release.__version__.split(".")[:2]))')"
-if [ "${ANSIBLE_TEST_PYTHON_VERSION}" == "2.6" ]; then
- # Non-module/module_utils plugins are not checked on this remote-only Python versions
+if [[ "${ANSIBLE_TEST_PYTHON_VERSION}" =~ ^2\. ]] || [[ "${ANSIBLE_TEST_PYTHON_VERSION}" =~ ^3\.[567] ]]; then
+ # Non-module/module_utils plugins are not checked on these remote-only Python versions
sed "s/ import$/ import-${ANSIBLE_TEST_PYTHON_VERSION}/;" < "tests/sanity/ignore.txt" | grep -v 'plugins/[^m].* import' > "tests/sanity/ignore-${ansible_version}.txt"
else
sed "s/ import$/ import-${ANSIBLE_TEST_PYTHON_VERSION}/;" < "tests/sanity/ignore.txt" > "tests/sanity/ignore-${ansible_version}.txt"
diff --git a/test/integration/targets/pull/aliases b/test/integration/targets/ansible-vault/aliases
index 757c9966..8278ec8b 100644
--- a/test/integration/targets/pull/aliases
+++ b/test/integration/targets/ansible-vault/aliases
@@ -1,2 +1,2 @@
shippable/posix/group3
-skip/aix
+context/controller
diff --git a/test/integration/targets/vault/empty-password b/test/integration/targets/ansible-vault/empty-password
index e69de29b..e69de29b 100644
--- a/test/integration/targets/vault/empty-password
+++ b/test/integration/targets/ansible-vault/empty-password
diff --git a/test/integration/targets/vault/encrypted-vault-password b/test/integration/targets/ansible-vault/encrypted-vault-password
index 7aa4e4be..7aa4e4be 100644
--- a/test/integration/targets/vault/encrypted-vault-password
+++ b/test/integration/targets/ansible-vault/encrypted-vault-password
diff --git a/test/integration/targets/vault/encrypted_file_encrypted_var_password b/test/integration/targets/ansible-vault/encrypted_file_encrypted_var_password
index 57bc06e3..57bc06e3 100644
--- a/test/integration/targets/vault/encrypted_file_encrypted_var_password
+++ b/test/integration/targets/ansible-vault/encrypted_file_encrypted_var_password
diff --git a/test/integration/targets/vault/example1_password b/test/integration/targets/ansible-vault/example1_password
index e723c8f9..e723c8f9 100644
--- a/test/integration/targets/vault/example1_password
+++ b/test/integration/targets/ansible-vault/example1_password
diff --git a/test/integration/targets/vault/example2_password b/test/integration/targets/ansible-vault/example2_password
index 7b010f87..7b010f87 100644
--- a/test/integration/targets/vault/example2_password
+++ b/test/integration/targets/ansible-vault/example2_password
diff --git a/test/integration/targets/vault/example3_password b/test/integration/targets/ansible-vault/example3_password
index f5bc5a8c..f5bc5a8c 100644
--- a/test/integration/targets/vault/example3_password
+++ b/test/integration/targets/ansible-vault/example3_password
diff --git a/test/integration/targets/vault/faux-editor.py b/test/integration/targets/ansible-vault/faux-editor.py
index 68f62590..b67c7475 100755
--- a/test/integration/targets/vault/faux-editor.py
+++ b/test/integration/targets/ansible-vault/faux-editor.py
@@ -14,7 +14,7 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
# ansible-vault is a script that encrypts/decrypts YAML files. See
-# https://docs.ansible.com/playbooks_vault.html for more details.
+# https://docs.ansible.com/ansible/latest/user_guide/vault.html for more details.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
diff --git a/test/integration/targets/vault/files/test_assemble/nonsecret.txt b/test/integration/targets/ansible-vault/files/test_assemble/nonsecret.txt
index 320b6b4c..320b6b4c 100644
--- a/test/integration/targets/vault/files/test_assemble/nonsecret.txt
+++ b/test/integration/targets/ansible-vault/files/test_assemble/nonsecret.txt
diff --git a/test/integration/targets/vault/files/test_assemble/secret.vault b/test/integration/targets/ansible-vault/files/test_assemble/secret.vault
index fd278564..fd278564 100644
--- a/test/integration/targets/vault/files/test_assemble/secret.vault
+++ b/test/integration/targets/ansible-vault/files/test_assemble/secret.vault
diff --git a/test/integration/targets/vault/format_1_1_AES256.yml b/test/integration/targets/ansible-vault/format_1_1_AES256.yml
index 5616605e..5616605e 100644
--- a/test/integration/targets/vault/format_1_1_AES256.yml
+++ b/test/integration/targets/ansible-vault/format_1_1_AES256.yml
diff --git a/test/integration/targets/vault/format_1_2_AES256.yml b/test/integration/targets/ansible-vault/format_1_2_AES256.yml
index 1e3795fb..1e3795fb 100644
--- a/test/integration/targets/vault/format_1_2_AES256.yml
+++ b/test/integration/targets/ansible-vault/format_1_2_AES256.yml
diff --git a/test/integration/targets/vault/host_vars/myhost.yml b/test/integration/targets/ansible-vault/host_vars/myhost.yml
index 1434ec15..1434ec15 100644
--- a/test/integration/targets/vault/host_vars/myhost.yml
+++ b/test/integration/targets/ansible-vault/host_vars/myhost.yml
diff --git a/test/integration/targets/vault/host_vars/testhost.yml b/test/integration/targets/ansible-vault/host_vars/testhost.yml
index b3e569ad..b3e569ad 100644
--- a/test/integration/targets/vault/host_vars/testhost.yml
+++ b/test/integration/targets/ansible-vault/host_vars/testhost.yml
diff --git a/test/integration/targets/vault/invalid_format/README.md b/test/integration/targets/ansible-vault/invalid_format/README.md
index cbbc07a9..cbbc07a9 100644
--- a/test/integration/targets/vault/invalid_format/README.md
+++ b/test/integration/targets/ansible-vault/invalid_format/README.md
diff --git a/test/integration/targets/vault/invalid_format/broken-group-vars-tasks.yml b/test/integration/targets/ansible-vault/invalid_format/broken-group-vars-tasks.yml
index 71dbacc0..71dbacc0 100644
--- a/test/integration/targets/vault/invalid_format/broken-group-vars-tasks.yml
+++ b/test/integration/targets/ansible-vault/invalid_format/broken-group-vars-tasks.yml
diff --git a/test/integration/targets/vault/invalid_format/broken-host-vars-tasks.yml b/test/integration/targets/ansible-vault/invalid_format/broken-host-vars-tasks.yml
index 9afbd58e..9afbd58e 100644
--- a/test/integration/targets/vault/invalid_format/broken-host-vars-tasks.yml
+++ b/test/integration/targets/ansible-vault/invalid_format/broken-host-vars-tasks.yml
diff --git a/test/integration/targets/vault/invalid_format/group_vars/broken-group-vars.yml b/test/integration/targets/ansible-vault/invalid_format/group_vars/broken-group-vars.yml
index 5f477431..5f477431 100644
--- a/test/integration/targets/vault/invalid_format/group_vars/broken-group-vars.yml
+++ b/test/integration/targets/ansible-vault/invalid_format/group_vars/broken-group-vars.yml
diff --git a/test/integration/targets/vault/invalid_format/host_vars/broken-host-vars.example.com/vars b/test/integration/targets/ansible-vault/invalid_format/host_vars/broken-host-vars.example.com/vars
index 2d309eb5..2d309eb5 100644
--- a/test/integration/targets/vault/invalid_format/host_vars/broken-host-vars.example.com/vars
+++ b/test/integration/targets/ansible-vault/invalid_format/host_vars/broken-host-vars.example.com/vars
diff --git a/test/integration/targets/vault/invalid_format/inventory b/test/integration/targets/ansible-vault/invalid_format/inventory
index e6e259a4..e6e259a4 100644
--- a/test/integration/targets/vault/invalid_format/inventory
+++ b/test/integration/targets/ansible-vault/invalid_format/inventory
diff --git a/test/integration/targets/vault/invalid_format/original-broken-host-vars b/test/integration/targets/ansible-vault/invalid_format/original-broken-host-vars
index 6be696b5..6be696b5 100644
--- a/test/integration/targets/vault/invalid_format/original-broken-host-vars
+++ b/test/integration/targets/ansible-vault/invalid_format/original-broken-host-vars
diff --git a/test/integration/targets/vault/invalid_format/original-group-vars.yml b/test/integration/targets/ansible-vault/invalid_format/original-group-vars.yml
index 817557be..817557be 100644
--- a/test/integration/targets/vault/invalid_format/original-group-vars.yml
+++ b/test/integration/targets/ansible-vault/invalid_format/original-group-vars.yml
diff --git a/test/integration/targets/vault/invalid_format/some-vars b/test/integration/targets/ansible-vault/invalid_format/some-vars
index e841a262..e841a262 100644
--- a/test/integration/targets/vault/invalid_format/some-vars
+++ b/test/integration/targets/ansible-vault/invalid_format/some-vars
diff --git a/test/integration/targets/vault/invalid_format/vault-secret b/test/integration/targets/ansible-vault/invalid_format/vault-secret
index 4406e35c..4406e35c 100644
--- a/test/integration/targets/vault/invalid_format/vault-secret
+++ b/test/integration/targets/ansible-vault/invalid_format/vault-secret
diff --git a/test/integration/targets/vault/inventory.toml b/test/integration/targets/ansible-vault/inventory.toml
index d97ed398..d97ed398 100644
--- a/test/integration/targets/vault/inventory.toml
+++ b/test/integration/targets/ansible-vault/inventory.toml
diff --git a/test/integration/targets/vault/password-script.py b/test/integration/targets/ansible-vault/password-script.py
index c47fdfb9..1b7f02be 100755
--- a/test/integration/targets/vault/password-script.py
+++ b/test/integration/targets/ansible-vault/password-script.py
@@ -14,7 +14,7 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
# ansible-vault is a script that encrypts/decrypts YAML files. See
-# https://docs.ansible.com/playbooks_vault.html for more details.
+# https://docs.ansible.com/ansible/latest/user_guide/vault.html for more details.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
diff --git a/test/integration/targets/vault/roles/test_vault/tasks/main.yml b/test/integration/targets/ansible-vault/roles/test_vault/tasks/main.yml
index 4e5551d9..4e5551d9 100644
--- a/test/integration/targets/vault/roles/test_vault/tasks/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault/tasks/main.yml
diff --git a/test/integration/targets/vault/roles/test_vault/vars/main.yml b/test/integration/targets/ansible-vault/roles/test_vault/vars/main.yml
index cfac107a..cfac107a 100644
--- a/test/integration/targets/vault/roles/test_vault/vars/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault/vars/main.yml
diff --git a/test/integration/targets/vault/roles/test_vault_embedded/tasks/main.yml b/test/integration/targets/ansible-vault/roles/test_vault_embedded/tasks/main.yml
index eba93896..eba93896 100644
--- a/test/integration/targets/vault/roles/test_vault_embedded/tasks/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault_embedded/tasks/main.yml
diff --git a/test/integration/targets/vault/roles/test_vault_embedded/vars/main.yml b/test/integration/targets/ansible-vault/roles/test_vault_embedded/vars/main.yml
index 54e6004f..54e6004f 100644
--- a/test/integration/targets/vault/roles/test_vault_embedded/vars/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault_embedded/vars/main.yml
diff --git a/test/integration/targets/vault/roles/test_vault_embedded_ids/tasks/main.yml b/test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/tasks/main.yml
index 9aeaf240..9aeaf240 100644
--- a/test/integration/targets/vault/roles/test_vault_embedded_ids/tasks/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/tasks/main.yml
diff --git a/test/integration/targets/vault/roles/test_vault_embedded_ids/vars/main.yml b/test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/vars/main.yml
index 9c8fa4b2..9c8fa4b2 100644
--- a/test/integration/targets/vault/roles/test_vault_embedded_ids/vars/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/vars/main.yml
diff --git a/test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/README.md b/test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/README.md
index 4a75cece..4a75cece 100644
--- a/test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/README.md
+++ b/test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/README.md
diff --git a/test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/tasks/main.yml b/test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/tasks/main.yml
index e09004a1..e09004a1 100644
--- a/test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/tasks/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/tasks/main.yml
diff --git a/test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/vars/main.yml b/test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/vars/main.yml
index 89cc4a0f..89cc4a0f 100644
--- a/test/integration/targets/vault/roles/test_vault_file_encrypted_embedded/vars/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/vars/main.yml
diff --git a/test/integration/targets/vault/roles/test_vaulted_template/tasks/main.yml b/test/integration/targets/ansible-vault/roles/test_vaulted_template/tasks/main.yml
index b4af5efc..b4af5efc 100644
--- a/test/integration/targets/vault/roles/test_vaulted_template/tasks/main.yml
+++ b/test/integration/targets/ansible-vault/roles/test_vaulted_template/tasks/main.yml
diff --git a/test/integration/targets/vault/roles/test_vaulted_template/templates/vaulted_template.j2 b/test/integration/targets/ansible-vault/roles/test_vaulted_template/templates/vaulted_template.j2
index af9c3eb1..af9c3eb1 100644
--- a/test/integration/targets/vault/roles/test_vaulted_template/templates/vaulted_template.j2
+++ b/test/integration/targets/ansible-vault/roles/test_vaulted_template/templates/vaulted_template.j2
diff --git a/test/integration/targets/vault/runme.sh b/test/integration/targets/ansible-vault/runme.sh
index e3b21d7f..e3b21d7f 100755
--- a/test/integration/targets/vault/runme.sh
+++ b/test/integration/targets/ansible-vault/runme.sh
diff --git a/test/integration/targets/vault/single_vault_as_string.yml b/test/integration/targets/ansible-vault/single_vault_as_string.yml
index 1eb17d04..ca147b0b 100644
--- a/test/integration/targets/vault/single_vault_as_string.yml
+++ b/test/integration/targets/ansible-vault/single_vault_as_string.yml
@@ -27,7 +27,7 @@
- vaulted_value|forceescape == 'foo bar'
- vaulted_value|first == 'f'
- "'%s'|format(vaulted_value) == 'foo bar'"
- - vaulted_value|indent(indentfirst=True) == ' foo bar'
+ - vaulted_value|indent(first=True) == ' foo bar'
- vaulted_value.split() == ['foo', 'bar']
- vaulted_value|join('-') == 'f-o-o- -b-a-r'
- vaulted_value|last == 'r'
diff --git a/test/integration/targets/vault/test-vault-client.py b/test/integration/targets/ansible-vault/test-vault-client.py
index ee461887..ee461887 100755
--- a/test/integration/targets/vault/test-vault-client.py
+++ b/test/integration/targets/ansible-vault/test-vault-client.py
diff --git a/test/integration/targets/vault/test_dangling_temp.yml b/test/integration/targets/ansible-vault/test_dangling_temp.yml
index 71a9d73a..71a9d73a 100644
--- a/test/integration/targets/vault/test_dangling_temp.yml
+++ b/test/integration/targets/ansible-vault/test_dangling_temp.yml
diff --git a/test/integration/targets/vault/test_utf8_value_in_filename.yml b/test/integration/targets/ansible-vault/test_utf8_value_in_filename.yml
index 9bd394dc..9bd394dc 100644
--- a/test/integration/targets/vault/test_utf8_value_in_filename.yml
+++ b/test/integration/targets/ansible-vault/test_utf8_value_in_filename.yml
diff --git a/test/integration/targets/vault/test_vault.yml b/test/integration/targets/ansible-vault/test_vault.yml
index 7f8ed115..7f8ed115 100644
--- a/test/integration/targets/vault/test_vault.yml
+++ b/test/integration/targets/ansible-vault/test_vault.yml
diff --git a/test/integration/targets/vault/test_vault_embedded.yml b/test/integration/targets/ansible-vault/test_vault_embedded.yml
index ee9739f8..ee9739f8 100644
--- a/test/integration/targets/vault/test_vault_embedded.yml
+++ b/test/integration/targets/ansible-vault/test_vault_embedded.yml
diff --git a/test/integration/targets/vault/test_vault_embedded_ids.yml b/test/integration/targets/ansible-vault/test_vault_embedded_ids.yml
index 23ebbb96..23ebbb96 100644
--- a/test/integration/targets/vault/test_vault_embedded_ids.yml
+++ b/test/integration/targets/ansible-vault/test_vault_embedded_ids.yml
diff --git a/test/integration/targets/vault/test_vault_file_encrypted_embedded.yml b/test/integration/targets/ansible-vault/test_vault_file_encrypted_embedded.yml
index 685d20ef..685d20ef 100644
--- a/test/integration/targets/vault/test_vault_file_encrypted_embedded.yml
+++ b/test/integration/targets/ansible-vault/test_vault_file_encrypted_embedded.yml
diff --git a/test/integration/targets/vault/test_vaulted_inventory.yml b/test/integration/targets/ansible-vault/test_vaulted_inventory.yml
index 06b6582b..06b6582b 100644
--- a/test/integration/targets/vault/test_vaulted_inventory.yml
+++ b/test/integration/targets/ansible-vault/test_vaulted_inventory.yml
diff --git a/test/integration/targets/vault/test_vaulted_inventory_toml.yml b/test/integration/targets/ansible-vault/test_vaulted_inventory_toml.yml
index f6e2c5d6..f6e2c5d6 100644
--- a/test/integration/targets/vault/test_vaulted_inventory_toml.yml
+++ b/test/integration/targets/ansible-vault/test_vaulted_inventory_toml.yml
diff --git a/test/integration/targets/vault/test_vaulted_template.yml b/test/integration/targets/ansible-vault/test_vaulted_template.yml
index b495211d..b495211d 100644
--- a/test/integration/targets/vault/test_vaulted_template.yml
+++ b/test/integration/targets/ansible-vault/test_vaulted_template.yml
diff --git a/test/integration/targets/vault/test_vaulted_utf8_value.yml b/test/integration/targets/ansible-vault/test_vaulted_utf8_value.yml
index 63b602b1..63b602b1 100644
--- a/test/integration/targets/vault/test_vaulted_utf8_value.yml
+++ b/test/integration/targets/ansible-vault/test_vaulted_utf8_value.yml
diff --git a/test/integration/targets/vault/vault-café.yml b/test/integration/targets/ansible-vault/vault-café.yml
index 0d179aec..0d179aec 100644
--- a/test/integration/targets/vault/vault-café.yml
+++ b/test/integration/targets/ansible-vault/vault-café.yml
diff --git a/test/integration/targets/vault/vault-password b/test/integration/targets/ansible-vault/vault-password
index 96973929..96973929 100644
--- a/test/integration/targets/vault/vault-password
+++ b/test/integration/targets/ansible-vault/vault-password
diff --git a/test/integration/targets/vault/vault-password-ansible b/test/integration/targets/ansible-vault/vault-password-ansible
index 90d40550..90d40550 100644
--- a/test/integration/targets/vault/vault-password-ansible
+++ b/test/integration/targets/ansible-vault/vault-password-ansible
diff --git a/test/integration/targets/vault/vault-password-wrong b/test/integration/targets/ansible-vault/vault-password-wrong
index 50e2efad..50e2efad 100644
--- a/test/integration/targets/vault/vault-password-wrong
+++ b/test/integration/targets/ansible-vault/vault-password-wrong
diff --git a/test/integration/targets/vault/vault-secret.txt b/test/integration/targets/ansible-vault/vault-secret.txt
index b6bc9bfb..b6bc9bfb 100644
--- a/test/integration/targets/vault/vault-secret.txt
+++ b/test/integration/targets/ansible-vault/vault-secret.txt
diff --git a/test/integration/targets/vault/vaulted.inventory b/test/integration/targets/ansible-vault/vaulted.inventory
index 1ed258b6..1ed258b6 100644
--- a/test/integration/targets/vault/vaulted.inventory
+++ b/test/integration/targets/ansible-vault/vaulted.inventory
diff --git a/test/integration/targets/ansible/aliases b/test/integration/targets/ansible/aliases
index f71c8117..498fedd5 100644
--- a/test/integration/targets/ansible/aliases
+++ b/test/integration/targets/ansible/aliases
@@ -1,2 +1,2 @@
shippable/posix/group4
-skip/aix
+context/controller
diff --git a/test/integration/targets/ansible/module_common_regex_regression.sh b/test/integration/targets/ansible/module_common_regex_regression.sh
new file mode 100755
index 00000000..4869f4f0
--- /dev/null
+++ b/test/integration/targets/ansible/module_common_regex_regression.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+# #74270 -- ensure we escape directory names before passing to re.compile()
+# particularly in module_common.
+
+set -eux
+
+lib_path=$(python -c 'import os, ansible; print(os.path.dirname(os.path.dirname(ansible.__file__)))')
+bad_dir="${OUTPUT_DIR}/ansi[ble"
+
+mkdir "${bad_dir}"
+cp -a "${lib_path}" "${bad_dir}"
+
+PYTHONPATH="${bad_dir}/lib" ansible -m ping localhost -i ../../inventory "$@"
+rm -rf "${bad_dir}"
diff --git a/test/integration/targets/ansible/runme.sh b/test/integration/targets/ansible/runme.sh
index fc79e33e..e9e72a9f 100755
--- a/test/integration/targets/ansible/runme.sh
+++ b/test/integration/targets/ansible/runme.sh
@@ -80,3 +80,7 @@ if ansible-playbook -i ../../inventory --extra-vars ./vars.yml playbook.yml; the
fi
ansible-playbook -i ../../inventory --extra-vars @./vars.yml playbook.yml
+
+# #74270 -- ensure we escape directory names before passing to re.compile()
+# particularly in module_common.
+bash module_common_regex_regression.sh
diff --git a/test/integration/targets/any_errors_fatal/18602.yml b/test/integration/targets/any_errors_fatal/18602.yml
deleted file mode 100644
index 66bcb88b..00000000
--- a/test/integration/targets/any_errors_fatal/18602.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
- - hosts: localhost
- any_errors_fatal: true
- tasks:
- - block:
- - debug: msg='i execute normally'
- - name: EXPECTED FAILURE primary block command
- command: /bin/false
- - debug: msg='i never execute, cause ERROR!'
- rescue:
- - name: rescue block debug
- debug: msg='I caught an error'
- - name: EXPECTED FAILURE rescue block command
- command: /bin/false
- - debug: msg='I also never execute :-('
- always:
- - name: A debug task in the always block
- debug: msg="this always executes"
-
- - set_fact:
- always_ran: true
diff --git a/test/integration/targets/any_errors_fatal/aliases b/test/integration/targets/any_errors_fatal/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/any_errors_fatal/aliases
+++ b/test/integration/targets/any_errors_fatal/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/any_errors_fatal/on_includes.yml b/test/integration/targets/any_errors_fatal/on_includes.yml
index 981d9f46..cbc51cb2 100644
--- a/test/integration/targets/any_errors_fatal/on_includes.yml
+++ b/test/integration/targets/any_errors_fatal/on_includes.yml
@@ -4,4 +4,4 @@
hosts: testhost,testhost2
any_errors_fatal: True
tasks:
- - include: test_fatal.yml
+ - import_tasks: test_fatal.yml
diff --git a/test/integration/targets/apt/tasks/downgrade.yml b/test/integration/targets/apt/tasks/downgrade.yml
new file mode 100644
index 00000000..896b644d
--- /dev/null
+++ b/test/integration/targets/apt/tasks/downgrade.yml
@@ -0,0 +1,77 @@
+- block:
+ - name: Disable ubuntu repos so system packages are not upgraded and do not change testing env
+ command: mv /etc/apt/sources.list /etc/apt/sources.list.backup
+
+ - name: install latest foo
+ apt:
+ name: foo
+ state: latest
+ allow_unauthenticated: yes
+
+ - name: check foo version
+ shell: dpkg -s foo | grep Version | awk '{print $2}'
+ register: apt_downgrade_foo_version
+
+ - name: ensure the correct version of foo has been installed
+ assert:
+ that:
+ - "'1.0.1' in apt_downgrade_foo_version.stdout"
+
+ - name: try to downgrade foo
+ apt:
+ name: foo=1.0.0
+ state: present
+ allow_unauthenticated: yes
+ ignore_errors: yes
+ register: apt_downgrade_foo_fail
+
+ - name: verify failure of downgrading without allow downgrade flag
+ assert:
+ that:
+ - apt_downgrade_foo_fail is failed
+
+ - name: try to downgrade foo with flag
+ apt:
+ name: foo=1.0.0
+ state: present
+ allow_downgrade: yes
+ allow_unauthenticated: yes
+ register: apt_downgrade_foo_succeed
+
+ - name: verify success of downgrading with allow downgrade flag
+ assert:
+ that:
+ - apt_downgrade_foo_succeed is success
+
+ - name: check foo version
+ shell: dpkg -s foo | grep Version | awk '{print $2}'
+ register: apt_downgrade_foo_version
+
+ - name: check that version downgraded correctly
+ assert:
+ that:
+ - "'1.0.0' in apt_downgrade_foo_version.stdout"
+ - "{{ apt_downgrade_foo_version.changed }}"
+
+ - name: downgrade foo with flag again
+ apt:
+ name: foo=1.0.0
+ state: present
+ allow_downgrade: yes
+ allow_unauthenticated: yes
+ register: apt_downgrade_second_downgrade
+
+ - name: check that nothing has changed (idempotent)
+ assert:
+ that:
+ - "apt_downgrade_second_downgrade.changed == false"
+
+ always:
+ - name: Clean up
+ apt:
+ pkg: foo,foobar
+ state: absent
+ autoclean: yes
+
+ - name: Restore ubuntu repos
+ command: mv /etc/apt/sources.list.backup /etc/apt/sources.list
diff --git a/test/integration/targets/apt/tasks/repo.yml b/test/integration/targets/apt/tasks/repo.yml
index e1863f38..8269452a 100644
--- a/test/integration/targets/apt/tasks/repo.yml
+++ b/test/integration/targets/apt/tasks/repo.yml
@@ -210,6 +210,8 @@
- name: Restore ubuntu repos
command: mv /etc/apt/sources.list.backup /etc/apt/sources.list
+- name: Downgrades
+ import_tasks: "downgrade.yml"
- name: Upgrades
block:
@@ -263,3 +265,26 @@
state: absent
when:
- aptitude_status.stdout.find('ii') == -1
+
+- block:
+ - name: Install the foo package with diff=yes
+ apt:
+ name: foo
+ allow_unauthenticated: yes
+ diff: yes
+ register: apt_result
+
+ - debug:
+ var: apt_result
+
+ - name: Check the content of diff.prepared
+ assert:
+ that:
+ - apt_result is success
+ - "'The following NEW packages will be installed:\n foo' in apt_result.diff.prepared"
+ always:
+ - name: Clean up
+ apt:
+ name: foo
+ state: absent
+ allow_unauthenticated: yes
diff --git a/test/integration/targets/args/aliases b/test/integration/targets/args/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/args/aliases
+++ b/test/integration/targets/args/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/argspec/aliases b/test/integration/targets/argspec/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/argspec/aliases
+++ b/test/integration/targets/argspec/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/assert/aliases b/test/integration/targets/assert/aliases
index 757c9966..10179323 100644
--- a/test/integration/targets/assert/aliases
+++ b/test/integration/targets/assert/aliases
@@ -1,2 +1,2 @@
shippable/posix/group3
-skip/aix
+context/controller # this is a controller-only action, the module is just for documentation
diff --git a/test/integration/targets/async/tasks/main.yml b/test/integration/targets/async/tasks/main.yml
index c8c12f6d..05c789e6 100644
--- a/test/integration/targets/async/tasks/main.yml
+++ b/test/integration/targets/async/tasks/main.yml
@@ -244,26 +244,6 @@
path: '{{ custom_async_tmp }}'
state: absent
- - name: run async task with custom dir - deprecated format
- command: sleep 1
- register: async_custom_dir_dep
- async: 5
- poll: 1
- environment:
- ANSIBLE_ASYNC_DIR: '{{ custom_async_tmp }}'
-
- - name: check if the async temp dir is created - deprecated format
- stat:
- path: '{{ custom_async_tmp }}'
- register: async_custom_dir_dep_result
-
- - name: assert run async task with custom dir - deprecated format
- assert:
- that:
- - async_custom_dir_dep is successful
- - async_custom_dir_dep is finished
- - async_custom_dir_dep_result.stat.exists
-
- name: remove custom async dir after deprecation test
file:
path: '{{ custom_async_tmp }}'
@@ -290,13 +270,6 @@
vars:
ansible_async_dir: '{{ custom_async_tmp }}'
- - name: get async status with custom dir - deprecated format
- async_status:
- jid: '{{ async_fandf_custom_dir.ansible_job_id }}'
- register: async_fandf_custom_dir_dep_result
- environment:
- ANSIBLE_ASYNC_DIR: '{{ custom_async_tmp }}'
-
- name: assert run fire and forget async task with custom dir
assert:
that:
@@ -304,7 +277,6 @@
- async_fandf_custom_dir_fail is failed
- async_fandf_custom_dir_fail.msg == "could not find job"
- async_fandf_custom_dir_result is successful
- - async_fandf_custom_dir_dep_result is successful
always:
- name: remove custom tmp dir after test
@@ -320,6 +292,7 @@
- name: run async poll callback test playbook
command: ansible-playbook {{ role_path }}/callback_test.yml
+ delegate_to: localhost
register: callback_output
- assert:
diff --git a/test/integration/targets/async_extra_data/aliases b/test/integration/targets/async_extra_data/aliases
index 70a7b7a9..7bd941e6 100644
--- a/test/integration/targets/async_extra_data/aliases
+++ b/test/integration/targets/async_extra_data/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/target
diff --git a/test/integration/targets/become/aliases b/test/integration/targets/become/aliases
index 3a07aab3..ad691e7d 100644
--- a/test/integration/targets/become/aliases
+++ b/test/integration/targets/become/aliases
@@ -1,3 +1,4 @@
destructive
shippable/posix/group1
skip/aix
+context/target
diff --git a/test/integration/targets/become/tasks/main.yml b/test/integration/targets/become/tasks/main.yml
index 3feb5cc7..b4c7b601 100644
--- a/test/integration/targets/become/tasks/main.yml
+++ b/test/integration/targets/become/tasks/main.yml
@@ -1,5 +1,5 @@
- include_vars: default.yml
-- include: default.yml
-- include: sudo.yml
-- include: su.yml
+- import_tasks: default.yml
+- import_tasks: sudo.yml
+- import_tasks: su.yml
diff --git a/test/integration/targets/become_su/aliases b/test/integration/targets/become_su/aliases
index 3a07aab3..f3e45b5e 100644
--- a/test/integration/targets/become_su/aliases
+++ b/test/integration/targets/become_su/aliases
@@ -1,3 +1,3 @@
destructive
shippable/posix/group1
-skip/aix
+context/controller
diff --git a/test/integration/targets/become_unprivileged/aliases b/test/integration/targets/become_unprivileged/aliases
index c96617f6..c97d2f98 100644
--- a/test/integration/targets/become_unprivileged/aliases
+++ b/test/integration/targets/become_unprivileged/aliases
@@ -1,5 +1,5 @@
destructive
shippable/posix/group1
-skip/aix
needs/ssh
needs/root
+context/controller
diff --git a/test/integration/targets/binary/aliases b/test/integration/targets/binary/aliases
index 765b70da..6452e6d4 100644
--- a/test/integration/targets/binary/aliases
+++ b/test/integration/targets/binary/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/target
diff --git a/test/integration/targets/binary_modules_posix/aliases b/test/integration/targets/binary_modules_posix/aliases
index 2c6e4a07..2cfe7ea8 100644
--- a/test/integration/targets/binary_modules_posix/aliases
+++ b/test/integration/targets/binary_modules_posix/aliases
@@ -1,2 +1,3 @@
shippable/posix/group3
needs/target/binary_modules
+context/target
diff --git a/test/integration/targets/blocks/aliases b/test/integration/targets/blocks/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/blocks/aliases
+++ b/test/integration/targets/blocks/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/blocks/main.yml b/test/integration/targets/blocks/main.yml
index 012d5ab2..efe358a3 100644
--- a/test/integration/targets/blocks/main.yml
+++ b/test/integration/targets/blocks/main.yml
@@ -96,8 +96,8 @@
tasks:
- block:
- name: include fail.yml in tasks
- include: fail.yml
- args:
+ import_tasks: fail.yml
+ vars:
msg: "failed from tasks"
- name: tasks flag should not be set after failure
set_fact:
@@ -106,8 +106,8 @@
- set_fact:
rescue_run_after_include_fail: true
- name: include fail.yml in rescue
- include: fail.yml
- args:
+ import_tasks: fail.yml
+ vars:
msg: "failed from rescue"
- name: flag should not be set after failure in rescue
set_fact:
diff --git a/test/integration/targets/blocks/nested_fail.yml b/test/integration/targets/blocks/nested_fail.yml
index 31ae870e..12e33cb4 100644
--- a/test/integration/targets/blocks/nested_fail.yml
+++ b/test/integration/targets/blocks/nested_fail.yml
@@ -1,3 +1,3 @@
-- include: fail.yml
- args:
+- import_tasks: fail.yml
+ vars:
msg: "nested {{msg}}"
diff --git a/test/integration/targets/blocks/nested_nested_fail.yml b/test/integration/targets/blocks/nested_nested_fail.yml
index e9a050fb..f63fa5ce 100644
--- a/test/integration/targets/blocks/nested_nested_fail.yml
+++ b/test/integration/targets/blocks/nested_nested_fail.yml
@@ -1,3 +1,3 @@
-- include: nested_fail.yml
- args:
+- import_tasks: nested_fail.yml
+ vars:
msg: "nested {{msg}}"
diff --git a/test/integration/targets/builtin_vars_prompt/aliases b/test/integration/targets/builtin_vars_prompt/aliases
index 4317d112..4b94ea15 100644
--- a/test/integration/targets/builtin_vars_prompt/aliases
+++ b/test/integration/targets/builtin_vars_prompt/aliases
@@ -1,3 +1,4 @@
setup/always/setup_passlib
setup/always/setup_pexpect
shippable/posix/group4
+context/controller
diff --git a/test/integration/targets/callback_default/aliases b/test/integration/targets/callback_default/aliases
index f8e28c7e..a6dafcf8 100644
--- a/test/integration/targets/callback_default/aliases
+++ b/test/integration/targets/callback_default/aliases
@@ -1,2 +1 @@
shippable/posix/group1
-skip/aix
diff --git a/test/integration/targets/callback_default/runme.sh b/test/integration/targets/callback_default/runme.sh
index b5c98ef7..f9b60b6b 100755
--- a/test/integration/targets/callback_default/runme.sh
+++ b/test/integration/targets/callback_default/runme.sh
@@ -125,6 +125,13 @@ export ANSIBLE_CHECK_MODE_MARKERS=0
run_test default
+# Check for async output
+# NOTE: regex to match 1 or more digits works for both BSD and GNU grep
+ansible-playbook -i inventory test_async.yml 2>&1 | tee async_test.out
+grep "ASYNC OK .* jid=[0-9]\{1,\}" async_test.out
+grep "ASYNC FAILED .* jid=[0-9]\{1,\}" async_test.out
+rm -f async_test.out
+
# Hide skipped
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=0
diff --git a/test/integration/targets/callback_default/test_async.yml b/test/integration/targets/callback_default/test_async.yml
new file mode 100644
index 00000000..57294a4c
--- /dev/null
+++ b/test/integration/targets/callback_default/test_async.yml
@@ -0,0 +1,14 @@
+---
+- hosts: testhost
+ gather_facts: no
+ tasks:
+ - name: test success async output
+ command: sleep 1
+ async: 10
+ poll: 1
+
+ - name: test failure async output
+ command: sleep 10
+ async: 1
+ poll: 1
+ ignore_errors: yes
diff --git a/test/integration/targets/changed_when/aliases b/test/integration/targets/changed_when/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/changed_when/aliases
+++ b/test/integration/targets/changed_when/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/changed_when/tasks/main.yml b/test/integration/targets/changed_when/tasks/main.yml
index 7b997189..4f0a8747 100644
--- a/test/integration/targets/changed_when/tasks/main.yml
+++ b/test/integration/targets/changed_when/tasks/main.yml
@@ -59,3 +59,15 @@
assert:
that:
- groupby is not changed
+
+- name: invalid conditional
+ command: echo foo
+ changed_when: boomboomboom
+ register: invalid_conditional
+ ignore_errors: true
+
+- assert:
+ that:
+ - invalid_conditional is failed
+ - invalid_conditional.stdout is defined
+ - invalid_conditional.changed_when_result is contains('boomboomboom')
diff --git a/test/integration/targets/check_mode/aliases b/test/integration/targets/check_mode/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/check_mode/aliases
+++ b/test/integration/targets/check_mode/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/cli/aliases b/test/integration/targets/cli/aliases
index a8816e11..c73d4253 100644
--- a/test/integration/targets/cli/aliases
+++ b/test/integration/targets/cli/aliases
@@ -3,3 +3,4 @@ needs/root
needs/ssh
needs/target/setup_pexpect
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyCSMUOptional.cs b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyCSMUOptional.cs
new file mode 100644
index 00000000..0a3e758c
--- /dev/null
+++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyCSMUOptional.cs
@@ -0,0 +1,19 @@
+using System;
+
+using ansible_collections.testns.testcoll.plugins.module_utils.AnotherCSMU;
+using ansible_collections.testns.testcoll.plugins.module_utils.subpkg.subcs;
+
+//TypeAccelerator -Name MyCSMU -TypeName CustomThing
+
+namespace ansible_collections.testns.testcoll.plugins.module_utils.MyCSMU
+{
+ public class CustomThing
+ {
+ public static string HelloWorld()
+ {
+ string res1 = AnotherThing.CallMe();
+ string res2 = NestedUtil.HelloWorld();
+ return String.Format("Hello from user_mu collection-hosted MyCSMUOptional, also {0} and {1}", res1, res2);
+ }
+ }
+}
diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyPSMUOptional.psm1 b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyPSMUOptional.psm1
new file mode 100644
index 00000000..1e361598
--- /dev/null
+++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyPSMUOptional.psm1
@@ -0,0 +1,16 @@
+#AnsibleRequires -CSharpUtil Ansible.Invalid -Optional
+#AnsibleRequires -Powershell Ansible.ModuleUtils.Invalid -Optional
+#AnsibleRequires -CSharpUtil ansible_collections.testns.testcoll.plugins.module_utils.invalid -Optional
+#AnsibleRequires -CSharpUtil ansible_collections.testns.testcoll.plugins.module_utils.invalid.invalid -Optional
+#AnsibleRequires -Powershell ansible_collections.testns.testcoll.plugins.module_utils.invalid -Optional
+#AnsibleRequires -Powershell ansible_collections.testns.testcoll.plugins.module_utils.invalid.invalid -Optional
+
+Function Invoke-FromUserPSMU {
+ <#
+ .SYNOPSIS
+ Test function
+ #>
+ return "from optional user_mu"
+}
+
+Export-ModuleMember -Function Invoke-FromUserPSMU
diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_uses_optional.ps1 b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_uses_optional.ps1
new file mode 100644
index 00000000..c44dcfea
--- /dev/null
+++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_uses_optional.ps1
@@ -0,0 +1,33 @@
+#!powershell
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Test builtin C# still works with -Optional
+#AnsibleRequires -CSharpUtil Ansible.Basic -Optional
+
+# Test no failure when importing an invalid builtin C# and pwsh util with -Optional
+#AnsibleRequires -CSharpUtil Ansible.Invalid -Optional
+#AnsibleRequires -PowerShell Ansible.ModuleUtils.Invalid -Optional
+
+# Test valid module_util still works with -Optional
+#AnsibleRequires -CSharpUtil ansible_collections.testns.testcoll.plugins.module_utils.MyCSMUOptional -Optional
+#AnsibleRequires -Powershell ansible_collections.testns.testcoll.plugins.module_utils.MyPSMUOptional -Optional
+
+# Test no failure when importing an invalid collection C# and pwsh util with -Optional
+#AnsibleRequires -CSharpUtil ansible_collections.testns.testcoll.plugins.module_utils.invalid -Optional
+#AnsibleRequires -CSharpUtil ansible_collections.testns.testcoll.plugins.module_utils.invalid.invalid -Optional
+#AnsibleRequires -Powershell ansible_collections.testns.testcoll.plugins.module_utils.invalid -Optional
+#AnsibleRequires -Powershell ansible_collections.testns.testcoll.plugins.module_utils.invalid.invalid -Optional
+
+$spec = @{
+ options = @{
+ data = @{ type = "str"; default = "called $(Invoke-FromUserPSMU)" }
+ }
+ supports_check_mode = $true
+}
+$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
+
+$module.Result.data = $module.Params.data
+$module.Result.csharp = [MyCSMU]::HelloWorld()
+
+$module.ExitJson()
diff --git a/test/integration/targets/collections/runme.sh b/test/integration/targets/collections/runme.sh
index 1e9584ff..5a5261bb 100755
--- a/test/integration/targets/collections/runme.sh
+++ b/test/integration/targets/collections/runme.sh
@@ -8,10 +8,6 @@ export ANSIBLE_GATHER_SUBSET=minimal
export ANSIBLE_HOST_PATTERN_MISMATCH=error
unset ANSIBLE_COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH
-# FUTURE: just use INVENTORY_PATH as-is once ansible-test sets the right dir
-ipath=../../$(basename "${INVENTORY_PATH:-../../inventory}")
-export INVENTORY_PATH="$ipath"
-
# ensure we can call collection module
ansible localhost -m testns.testcoll.testmodule
@@ -137,3 +133,5 @@ if [[ "$(grep -wc "dynamic_host_a" "$CACHEFILE")" -ne "0" ]]; then
fi
./vars_plugin_tests.sh
+
+./test_task_resolved_plugin.sh
diff --git a/test/integration/targets/collections/test_task_resolved_plugin.sh b/test/integration/targets/collections/test_task_resolved_plugin.sh
new file mode 100755
index 00000000..444b4f11
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+set -eux
+
+export ANSIBLE_CALLBACKS_ENABLED=display_resolved_action
+
+ansible-playbook test_task_resolved_plugin/unqualified.yml "$@" | tee out.txt
+action_resolution=(
+ "legacy_action == legacy_action"
+ "legacy_module == legacy_module"
+ "debug == ansible.builtin.debug"
+ "ping == ansible.builtin.ping"
+)
+for result in "${action_resolution[@]}"; do
+ grep -q out.txt -e "$result"
+done
+
+ansible-playbook test_task_resolved_plugin/unqualified_and_collections_kw.yml "$@" | tee out.txt
+action_resolution=(
+ "legacy_action == legacy_action"
+ "legacy_module == legacy_module"
+ "debug == ansible.builtin.debug"
+ "ping == ansible.builtin.ping"
+ "collection_action == test_ns.test_coll.collection_action"
+ "collection_module == test_ns.test_coll.collection_module"
+ "formerly_action == test_ns.test_coll.collection_action"
+ "formerly_module == test_ns.test_coll.collection_module"
+)
+for result in "${action_resolution[@]}"; do
+ grep -q out.txt -e "$result"
+done
+
+ansible-playbook test_task_resolved_plugin/fqcn.yml "$@" | tee out.txt
+action_resolution=(
+ "ansible.legacy.legacy_action == legacy_action"
+ "ansible.legacy.legacy_module == legacy_module"
+ "ansible.legacy.debug == ansible.builtin.debug"
+ "ansible.legacy.ping == ansible.builtin.ping"
+ "ansible.builtin.debug == ansible.builtin.debug"
+ "ansible.builtin.ping == ansible.builtin.ping"
+ "test_ns.test_coll.collection_action == test_ns.test_coll.collection_action"
+ "test_ns.test_coll.collection_module == test_ns.test_coll.collection_module"
+ "test_ns.test_coll.formerly_action == test_ns.test_coll.collection_action"
+ "test_ns.test_coll.formerly_module == test_ns.test_coll.collection_module"
+)
+for result in "${action_resolution[@]}"; do
+ grep -q out.txt -e "$result"
+done
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/action_plugins/legacy_action.py b/test/integration/targets/collections/test_task_resolved_plugin/action_plugins/legacy_action.py
new file mode 100644
index 00000000..fa4d514b
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/action_plugins/legacy_action.py
@@ -0,0 +1,14 @@
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible.plugins.action import ActionBase
+
+
+class ActionModule(ActionBase):
+ TRANSFERS_FILES = False
+ _VALID_ARGS = frozenset()
+
+ def run(self, tmp=None, task_vars=None):
+ return {'changed': False}
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/callback_plugins/display_resolved_action.py b/test/integration/targets/collections/test_task_resolved_plugin/callback_plugins/display_resolved_action.py
new file mode 100644
index 00000000..23cce104
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/callback_plugins/display_resolved_action.py
@@ -0,0 +1,37 @@
+# (c) 2020 Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+ name: display_resolved_action
+ type: aggregate
+ short_description: Displays the requested and resolved actions at the end of a playbook.
+ description:
+ - Displays the requested and resolved actions in the format "requested == resolved".
+ requirements:
+ - Enable in configuration.
+'''
+
+from ansible import constants as C
+from ansible.plugins.callback import CallbackBase
+
+
+class CallbackModule(CallbackBase):
+
+ CALLBACK_VERSION = 2.0
+ CALLBACK_TYPE = 'aggregate'
+ CALLBACK_NAME = 'display_resolved_action'
+ CALLBACK_NEEDS_ENABLED = True
+
+ def __init__(self, *args, **kwargs):
+ super(CallbackModule, self).__init__(*args, **kwargs)
+ self.requested_to_resolved = {}
+
+ def v2_playbook_on_task_start(self, task, is_conditional):
+ self.requested_to_resolved[task.action] = task.resolved_action
+
+ def v2_playbook_on_stats(self, stats):
+ for requested, resolved in self.requested_to_resolved.items():
+ self._display.display("%s == %s" % (requested, resolved), screen_only=True)
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/meta/runtime.yml b/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/meta/runtime.yml
new file mode 100644
index 00000000..8c27dba0
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/meta/runtime.yml
@@ -0,0 +1,7 @@
+plugin_routing:
+ modules:
+ formerly_module:
+ redirect: test_ns.test_coll.collection_module
+ action:
+ formerly_action:
+ redirect: test_ns.test_coll.collection_action
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/action/collection_action.py b/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/action/collection_action.py
new file mode 100644
index 00000000..fa4d514b
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/action/collection_action.py
@@ -0,0 +1,14 @@
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible.plugins.action import ActionBase
+
+
+class ActionModule(ActionBase):
+ TRANSFERS_FILES = False
+ _VALID_ARGS = frozenset()
+
+ def run(self, tmp=None, task_vars=None):
+ return {'changed': False}
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/modules/collection_module.py b/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/modules/collection_module.py
new file mode 100644
index 00000000..8f312263
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/modules/collection_module.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: collection_module
+short_description: A module to test a task's resolved action name.
+description: A module to test a task's resolved action name.
+options: {}
+author: Ansible Core Team
+notes:
+ - Supports C(check_mode).
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(supports_check_mode=True, argument_spec={})
+ module.exit_json(changed=False)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/fqcn.yml b/test/integration/targets/collections/test_task_resolved_plugin/fqcn.yml
new file mode 100644
index 00000000..ab9e9259
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/fqcn.yml
@@ -0,0 +1,14 @@
+---
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - ansible.legacy.legacy_action:
+ - ansible.legacy.legacy_module:
+ - ansible.legacy.debug:
+ - ansible.legacy.ping:
+ - ansible.builtin.debug:
+ - ansible.builtin.ping:
+ - test_ns.test_coll.collection_action:
+ - test_ns.test_coll.collection_module:
+ - test_ns.test_coll.formerly_action:
+ - test_ns.test_coll.formerly_module:
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/library/legacy_module.py b/test/integration/targets/collections/test_task_resolved_plugin/library/legacy_module.py
new file mode 100644
index 00000000..4fd75871
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/library/legacy_module.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: legacy_module
+short_description: A module to test a task's resolved action name.
+description: A module to test a task's resolved action name.
+options: {}
+author: Ansible Core Team
+notes:
+ - Supports C(check_mode).
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(supports_check_mode=True, argument_spec={})
+ module.exit_json(changed=False)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/unqualified.yml b/test/integration/targets/collections/test_task_resolved_plugin/unqualified.yml
new file mode 100644
index 00000000..076b8cc7
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/unqualified.yml
@@ -0,0 +1,8 @@
+---
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - legacy_action:
+ - legacy_module:
+ - debug:
+ - ping:
diff --git a/test/integration/targets/collections/test_task_resolved_plugin/unqualified_and_collections_kw.yml b/test/integration/targets/collections/test_task_resolved_plugin/unqualified_and_collections_kw.yml
new file mode 100644
index 00000000..5af4eda9
--- /dev/null
+++ b/test/integration/targets/collections/test_task_resolved_plugin/unqualified_and_collections_kw.yml
@@ -0,0 +1,14 @@
+---
+- hosts: localhost
+ gather_facts: no
+ collections:
+ - test_ns.test_coll
+ tasks:
+ - legacy_action:
+ - legacy_module:
+ - debug:
+ - ping:
+ - collection_action:
+ - collection_module:
+ - formerly_action:
+ - formerly_module:
diff --git a/test/integration/targets/collections/windows.yml b/test/integration/targets/collections/windows.yml
index 4bdfb0ed..cf98ca1e 100644
--- a/test/integration/targets/collections/windows.yml
+++ b/test/integration/targets/collections/windows.yml
@@ -12,6 +12,9 @@
- testns.testcoll.win_uses_coll_csmu:
register: uses_coll_csmu
+ - testns.testcoll.win_uses_optional:
+ register: uses_coll_optional
+
- assert:
that:
- selfcontained_out.source == 'user'
@@ -26,3 +29,6 @@
- "'Hello from subpkg.subcs' in uses_coll_csmu.ping"
- uses_coll_csmu.subpkg == 'Hello from subpkg.subcs'
- uses_coll_csmu.type_accelerator == uses_coll_csmu.ping
+ # win_uses_optional
+ - uses_coll_optional.data == "called from optional user_mu"
+ - uses_coll_optional.csharp == "Hello from user_mu collection-hosted MyCSMUOptional, also Hello from nested user-collection-hosted AnotherCSMU and Hello from subpkg.subcs"
diff --git a/test/integration/targets/collections_plugin_namespace/aliases b/test/integration/targets/collections_plugin_namespace/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/collections_plugin_namespace/aliases
+++ b/test/integration/targets/collections_plugin_namespace/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/PSRel4.psm1 b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/PSRel4.psm1
new file mode 100644
index 00000000..bcb5ec19
--- /dev/null
+++ b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/PSRel4.psm1
@@ -0,0 +1,12 @@
+#AnsibleRequires -CSharpUtil .sub_pkg.CSRel5 -Optional
+#AnsibleRequires -PowerShell .sub_pkg.PSRelInvalid -Optional
+
+Function Invoke-FromPSRel4 {
+ <#
+ .SYNOPSIS
+ Test function
+ #>
+ return "Invoke-FromPSRel4"
+}
+
+Export-ModuleMember -Function Invoke-FromPSRel4
diff --git a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/win_relative_optional.ps1 b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/win_relative_optional.ps1
new file mode 100644
index 00000000..9086ca42
--- /dev/null
+++ b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/win_relative_optional.ps1
@@ -0,0 +1,17 @@
+#!powershell
+
+#AnsibleRequires -CSharpUtil Ansible.Basic -Optional
+#AnsibleRequires -PowerShell ..module_utils.PSRel4 -optional
+
+# These do not exist
+#AnsibleRequires -CSharpUtil ..invalid_package.name -Optional
+#AnsibleRequires -CSharpUtil ..module_utils.InvalidName -optional
+#AnsibleRequires -PowerShell ..invalid_package.pwsh_name -optional
+#AnsibleRequires -PowerShell ..module_utils.InvalidPwshName -Optional
+
+
+$module = [Ansible.Basic.AnsibleModule]::Create($args, @{})
+
+$module.Result.data = Invoke-FromPSRel4
+
+$module.ExitJson()
diff --git a/test/integration/targets/collections_relative_imports/windows.yml b/test/integration/targets/collections_relative_imports/windows.yml
index aa6badfa..3a3c5488 100644
--- a/test/integration/targets/collections_relative_imports/windows.yml
+++ b/test/integration/targets/collections_relative_imports/windows.yml
@@ -9,3 +9,12 @@
assert:
that:
- win_relative.data == 'CSRel4.Invoke() -> Invoke-FromPSRel3 -> Invoke-FromPSRel2 -> Invoke-FromPSRel1'
+
+ - name: test out relative imports on Windows modules with optional import
+ my_ns.my_col.win_relative_optional:
+ register: win_relative_optional
+
+ - name: assert relative imports on Windows modules with optional import
+ assert:
+ that:
+ - win_relative_optional.data == 'Invoke-FromPSRel4'
diff --git a/test/integration/targets/collections_runtime_pythonpath/aliases b/test/integration/targets/collections_runtime_pythonpath/aliases
index 0a772ad7..498fedd5 100644
--- a/test/integration/targets/collections_runtime_pythonpath/aliases
+++ b/test/integration/targets/collections_runtime_pythonpath/aliases
@@ -1,3 +1,2 @@
shippable/posix/group4
-skip/python2.6
-skip/aix
+context/controller
diff --git a/test/integration/targets/collections_runtime_pythonpath/runme.sh b/test/integration/targets/collections_runtime_pythonpath/runme.sh
index 654104a1..38c6c64f 100755
--- a/test/integration/targets/collections_runtime_pythonpath/runme.sh
+++ b/test/integration/targets/collections_runtime_pythonpath/runme.sh
@@ -25,19 +25,19 @@ ansible \
=== Test that the module \
gets picked up if installed \
into site-packages ===
-python -m pip.__main__ install pep517
+python -m pip install pep517
( # Build a binary Python dist (a wheel) using PEP517:
cp -r ansible-collection-python-dist-boo "${OUTPUT_DIR}/"
cd "${OUTPUT_DIR}/ansible-collection-python-dist-boo"
python -m pep517.build --binary --out-dir dist .
)
# Install a pre-built dist with pip:
-python -m pip.__main__ install \
+python -m pip install \
--no-index \
-f "${OUTPUT_DIR}/ansible-collection-python-dist-boo/dist/" \
--only-binary=ansible-collections.python.dist \
ansible-collections.python.dist
-python -m pip.__main__ show ansible-collections.python.dist
+python -m pip show ansible-collections.python.dist
ansible \
-m python.dist.boo \
-a 'name=Frodo' \
diff --git a/test/integration/targets/command_nonexisting/aliases b/test/integration/targets/command_nonexisting/aliases
index e2dcf795..90ea9e12 100644
--- a/test/integration/targets/command_nonexisting/aliases
+++ b/test/integration/targets/command_nonexisting/aliases
@@ -1 +1,2 @@
-shippable/posix/group2 \ No newline at end of file
+shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/command_shell/tasks/main.yml b/test/integration/targets/command_shell/tasks/main.yml
index 653b0059..aad63c0d 100644
--- a/test/integration/targets/command_shell/tasks/main.yml
+++ b/test/integration/targets/command_shell/tasks/main.yml
@@ -504,11 +504,11 @@
when: ansible_facts.python_version is version('3', '>=')
- name: run command with strip
- command: '{{ ansible_playbook_python}} -c "import sys; msg=''hello \n \r''; print(msg); {{ print_error_command }}"'
+ command: '{{ ansible_python_interpreter }} -c "import sys; msg=''hello \n \r''; print(msg); {{ print_error_command }}"'
register: command_strip
- name: run command without strip
- command: '{{ ansible_playbook_python}} -c "import sys; msg=''hello \n \r''; print(msg); {{ print_error_command }}"'
+ command: '{{ ansible_python_interpreter }} -c "import sys; msg=''hello \n \r''; print(msg); {{ print_error_command }}"'
args:
strip_empty_ends: no
register: command_no_strip
diff --git a/test/integration/targets/common_network/aliases b/test/integration/targets/common_network/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/common_network/aliases
+++ b/test/integration/targets/common_network/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/conditionals/aliases b/test/integration/targets/conditionals/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/conditionals/aliases
+++ b/test/integration/targets/conditionals/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/conditionals/play.yml b/test/integration/targets/conditionals/play.yml
index c6bb3815..455818c9 100644
--- a/test/integration/targets/conditionals/play.yml
+++ b/test/integration/targets/conditionals/play.yml
@@ -6,10 +6,6 @@
vars_files:
- vars/main.yml
tasks:
- - name: set conditional bare vars status
- set_fact:
- bare: "{{lookup('config', 'CONDITIONAL_BARE_VARS')|bool}}"
-
- name: test conditional '=='
shell: echo 'testing'
when: 1 == 1
@@ -164,6 +160,136 @@
- "result.stdout == 'testing'"
- "result.rc == 0"
+ - name: not test bare conditional
+ shell: echo 'testing'
+ when: not test_bare
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
+ - name: empty string is false
+ shell: echo 'testing'
+ when: string_lit_empty
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
+ - name: not empty string is true
+ shell: echo 'testing'
+ when: not string_lit_empty
+ register: result
+
+ - name: assert ran
+ assert:
+ that:
+ - result is not skipped
+
+ - name: literal 0 is false
+ shell: echo 'testing'
+ when: int_lit_0
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
+ - name: not literal 0 is true
+ shell: echo 'testing'
+ when: not int_lit_0
+ register: result
+
+ - name: assert ran
+ assert:
+ that:
+ - result is not skipped
+
+ - name: literal 1 is true
+ shell: echo 'testing'
+ when: int_lit_1
+ register: result
+
+ - name: assert ran
+ assert:
+ that:
+ - result is not skipped
+
+ - name: not literal 1 is false
+ shell: echo 'testing'
+ when: not int_lit_1
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
+ - name: null is false
+ shell: echo 'testing'
+ when: lit_null
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
+ - name: literal string "true" is true
+ shell: echo 'testing'
+ when: string_lit_true
+ register: result
+
+ - name: assert ran
+ assert:
+ that:
+ - result is not skipped
+
+ - name: not literal string "true" is false
+ shell: echo 'testing'
+ when: not string_lit_true
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
+ - name: literal string "false" is true (nonempty string)
+ shell: echo 'testing'
+ when: string_lit_false
+ register: result
+
+ - name: assert ran
+ assert:
+ that:
+ - result is not skipped
+
+ - name: not literal string "false" is false
+ shell: echo 'testing'
+ when: not string_lit_false
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
+ - name: not literal string "true" is false
+ shell: echo 'testing'
+ when: not string_lit_true
+ register: result
+
+ - name: assert did not run
+ assert:
+ that:
+ - result is skipped
+
- name: test conditional using a variable
shell: echo 'testing'
when: test_bare_var == 123
@@ -195,23 +321,13 @@
- debug: var={{item}}
loop:
- - bare
- result
- test_bare_nested_bad
- - name: assert that the bad nested conditional is skipped since 'bare' since 'string' template is resolved to 'false'
+ - name: assert that the bad nested conditional ran (it is a non-empty string, so truthy)
assert:
that:
- - result is skipped
-
- when: bare|bool
-
- - name: assert that the bad nested conditional did run since non bare 'string' is untemplated but 'trueish'
- assert:
- that:
- - result is skipped
- when: not bare|bool
- - result is changed
+ - result is not skipped
- name: test bad conditional based on nested variables with bool filter
shell: echo 'testing'
@@ -223,6 +339,7 @@
that:
- result is skipped
+
#-----------------------------------------------------------------------
# proper booleanification tests (issue #8629)
@@ -382,7 +499,6 @@
- name: Deal with multivar equality
tags: ['leveldiff']
- when: not bare|bool
vars:
toplevel_hash:
hash_var_one: justastring
diff --git a/test/integration/targets/conditionals/runme.sh b/test/integration/targets/conditionals/runme.sh
index 934443a5..4858fbf2 100755
--- a/test/integration/targets/conditionals/runme.sh
+++ b/test/integration/targets/conditionals/runme.sh
@@ -2,14 +2,4 @@
set -eux
-ANSIBLE_CONDITIONAL_BARE_VARS=1 ansible-playbook -i ../../inventory play.yml "$@"
-ANSIBLE_CONDITIONAL_BARE_VARS=0 ansible-playbook -i ../../inventory play.yml "$@"
-
-export ANSIBLE_CONDITIONAL_BARE_VARS=1
-export ANSIBLE_DEPRECATION_WARNINGS=True
-
-# No warnings for conditionals that are already type bool
-test "$(ansible-playbook -i ../../inventory test_no_warnings.yml "$@" 2>&1 | grep -c '\[DEPRECATION WARNING\]')" = 0
-
-# Warn for bare vars of other types since they may be interpreted differently when CONDITIONAL_BARE_VARS defaults to False
-test "$(ansible-playbook -i ../../inventory test_warnings.yml "$@" 2>&1 | grep -c '\[DEPRECATION WARNING\]')" = 2
+ansible-playbook -i ../../inventory play.yml "$@"
diff --git a/test/integration/targets/conditionals/test_no_warnings.yml b/test/integration/targets/conditionals/test_no_warnings.yml
deleted file mode 100644
index 93280447..00000000
--- a/test/integration/targets/conditionals/test_no_warnings.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-- hosts: testhost
- gather_facts: false
- vars:
- boolean_var: false
- nested:
- bool_var: false
- tasks:
- - name: Run tasks with previous warnings requesting the bool filter on type boolean vars
- block:
- - debug:
- when: boolean_var
- - debug:
- when: nested.bool_var
- - debug:
- when: double_interpolated
- vars:
- double_interpolated: "{{ other }}"
- other: false
diff --git a/test/integration/targets/conditionals/test_warnings.yml b/test/integration/targets/conditionals/test_warnings.yml
deleted file mode 100644
index 4186cd01..00000000
--- a/test/integration/targets/conditionals/test_warnings.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-- hosts: testhost
- gather_facts: false
- vars:
- str_boolean_var: 'false'
- tasks:
- - name: Run tasks with warnings for conditionals that will change in behavior depending on CONDITIONAL_BARE_VARS
- block:
- - debug:
- when: str_boolean_var
- - debug:
- when: double_interpolated
- vars:
- double_interpolated: other
- other: false
diff --git a/test/integration/targets/conditionals/vars/main.yml b/test/integration/targets/conditionals/vars/main.yml
index d6221478..2af6cee2 100644
--- a/test/integration/targets/conditionals/vars/main.yml
+++ b/test/integration/targets/conditionals/vars/main.yml
@@ -20,3 +20,10 @@ test_bare: true
test_bare_var: 123
test_bare_nested_good: "test_bare_var == 123"
test_bare_nested_bad: "{{test_bare_var}} == 321"
+
+string_lit_true: "true"
+string_lit_false: "false"
+string_lit_empty: ""
+lit_null: null
+int_lit_0: 0
+int_lit_1: 1
diff --git a/test/integration/targets/config/aliases b/test/integration/targets/config/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/config/aliases
+++ b/test/integration/targets/config/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/config/files/types.env b/test/integration/targets/config/files/types.env
new file mode 100644
index 00000000..b5fc43ee
--- /dev/null
+++ b/test/integration/targets/config/files/types.env
@@ -0,0 +1,11 @@
+# valid(list): does nothihng, just for testing values
+ANSIBLE_TYPES_VALID=
+
+# mustunquote(list): does nothihng, just for testing values
+ANSIBLE_TYPES_MUSTUNQUOTE=
+
+# notvalid(list): does nothihng, just for testing values
+ANSIBLE_TYPES_NOTVALID=
+
+# totallynotvalid(list): does nothihng, just for testing values
+ANSIBLE_TYPES_TOTALLYNOTVALID=
diff --git a/test/integration/targets/config/files/types.ini b/test/integration/targets/config/files/types.ini
new file mode 100644
index 00000000..c04b6d5a
--- /dev/null
+++ b/test/integration/targets/config/files/types.ini
@@ -0,0 +1,13 @@
+[list_values]
+# (list) does nothihng, just for testing values
+mustunquote=
+
+# (list) does nothihng, just for testing values
+notvalid=
+
+# (list) does nothihng, just for testing values
+totallynotvalid=
+
+# (list) does nothihng, just for testing values
+valid=
+
diff --git a/test/integration/targets/config/files/types.vars b/test/integration/targets/config/files/types.vars
new file mode 100644
index 00000000..d1427fc8
--- /dev/null
+++ b/test/integration/targets/config/files/types.vars
@@ -0,0 +1,15 @@
+# valid(list): does nothihng, just for testing values
+ansible_types_valid: ''
+
+
+# mustunquote(list): does nothihng, just for testing values
+ansible_types_mustunquote: ''
+
+
+# notvalid(list): does nothihng, just for testing values
+ansible_types_notvalid: ''
+
+
+# totallynotvalid(list): does nothihng, just for testing values
+ansible_types_totallynotvalid: ''
+
diff --git a/test/integration/targets/config/files/types_dump.txt b/test/integration/targets/config/files/types_dump.txt
new file mode 100644
index 00000000..2139f4d1
--- /dev/null
+++ b/test/integration/targets/config/files/types_dump.txt
@@ -0,0 +1,8 @@
+
+types:
+_____
+_terms(default) = None
+mustunquote(default) = None
+notvalid(default) = None
+totallynotvalid(default) = None
+valid(default) = None
diff --git a/test/integration/targets/config/lookup_plugins/types.py b/test/integration/targets/config/lookup_plugins/types.py
new file mode 100644
index 00000000..d3092296
--- /dev/null
+++ b/test/integration/targets/config/lookup_plugins/types.py
@@ -0,0 +1,82 @@
+# (c) 2021 Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+ name: types
+ author: Ansible Core Team
+ version_added: histerical
+ short_description: returns what you gave it
+ description:
+ - this is mostly a noop
+ options:
+ _terms:
+ description: stuff to pass through
+ valid:
+ description: does nothihng, just for testing values
+ type: list
+ ini:
+ - section: list_values
+ key: valid
+ env:
+ - name: ANSIBLE_TYPES_VALID
+ vars:
+ - name: ansible_types_valid
+ mustunquote:
+ description: does nothihng, just for testing values
+ type: list
+ ini:
+ - section: list_values
+ key: mustunquote
+ env:
+ - name: ANSIBLE_TYPES_MUSTUNQUOTE
+ vars:
+ - name: ansible_types_mustunquote
+ notvalid:
+ description: does nothihng, just for testing values
+ type: list
+ ini:
+ - section: list_values
+ key: notvalid
+ env:
+ - name: ANSIBLE_TYPES_NOTVALID
+ vars:
+ - name: ansible_types_notvalid
+ totallynotvalid:
+ description: does nothihng, just for testing values
+ type: list
+ ini:
+ - section: list_values
+ key: totallynotvalid
+ env:
+ - name: ANSIBLE_TYPES_TOTALLYNOTVALID
+ vars:
+ - name: ansible_types_totallynotvalid
+"""
+
+EXAMPLES = """
+- name: like some other plugins, this is mostly useless
+ debug: msg={{ q('types', [1,2,3])}}
+"""
+
+RETURN = """
+ _list:
+ description: basically the same as you fed in
+ type: list
+ elements: raw
+"""
+
+from ansible.plugins.lookup import LookupBase
+
+
+class LookupModule(LookupBase):
+
+ def run(self, terms, variables=None, **kwargs):
+
+ self.set_options(var_options=variables, direct=kwargs)
+
+ return terms
diff --git a/test/integration/targets/config/runme.sh b/test/integration/targets/config/runme.sh
index bbff6acc..76df44c4 100755
--- a/test/integration/targets/config/runme.sh
+++ b/test/integration/targets/config/runme.sh
@@ -21,3 +21,19 @@ ANSIBLE_CONFIG=inline_comment_ansible.cfg ansible-config dump --only-changed | g
# test the config option validation
ansible-playbook validation.yml "$@"
+
+# test types from config (just lists for now)
+ANSIBLE_CONFIG=type_munging.cfg ansible-playbook types.yml "$@"
+
+cleanup() {
+ rm -f files/*.new.*
+}
+
+trap 'cleanup' EXIT
+
+# check a-c init per format
+for format in "vars" "ini" "env"
+do
+ ANSIBLE_LOOKUP_PLUGINS=./ ansible-config init types -t lookup -f "${format}" > "files/types.new.${format}"
+ diff -u "files/types.${format}" "files/types.new.${format}"
+done
diff --git a/test/integration/targets/config/type_munging.cfg b/test/integration/targets/config/type_munging.cfg
new file mode 100644
index 00000000..d6aeaab6
--- /dev/null
+++ b/test/integration/targets/config/type_munging.cfg
@@ -0,0 +1,8 @@
+[defaults]
+nothing = here
+
+[list_values]
+valid = 1, 2, 3
+mustunquote = '1', '2', '3'
+notvalid = [1, 2, 3]
+totallynotvalid = ['1', '2', '3']
diff --git a/test/integration/targets/config/types.yml b/test/integration/targets/config/types.yml
new file mode 100644
index 00000000..650a96f6
--- /dev/null
+++ b/test/integration/targets/config/types.yml
@@ -0,0 +1,25 @@
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: ensures we got the list we expected
+ block:
+ - name: initialize plugin
+ debug: msg={{ lookup('types', 'starting test') }}
+
+ - set_fact:
+ valid: '{{ lookup("config", "valid", plugin_type="lookup", plugin_name="types") }}'
+ mustunquote: '{{ lookup("config", "mustunquote", plugin_type="lookup", plugin_name="types") }}'
+ notvalid: '{{ lookup("config", "notvalid", plugin_type="lookup", plugin_name="types") }}'
+ totallynotvalid: '{{ lookup("config", "totallynotvalid", plugin_type="lookup", plugin_name="types") }}'
+
+ - assert:
+ that:
+ - 'valid|type_debug == "list"'
+ - 'mustunquote|type_debug == "list"'
+ - 'notvalid|type_debug == "list"'
+ - 'totallynotvalid|type_debug == "list"'
+ - valid[0]|int == 1
+ - mustunquote[0]|int == 1
+ - "notvalid[0] == '[1'"
+ # using 'and true' to avoid quote hell
+ - totallynotvalid[0] == "['1'" and True
diff --git a/test/integration/targets/connection_delegation/aliases b/test/integration/targets/connection_delegation/aliases
index 87caabdf..44e49e4f 100644
--- a/test/integration/targets/connection_delegation/aliases
+++ b/test/integration/targets/connection_delegation/aliases
@@ -1,4 +1,5 @@
shippable/posix/group1
+context/controller
skip/freebsd # No sshpass
skip/osx # No sshpass
skip/macos # No sshpass
diff --git a/test/integration/targets/connection_delegation/runme.sh b/test/integration/targets/connection_delegation/runme.sh
index eb26f7c5..4d507243 100755
--- a/test/integration/targets/connection_delegation/runme.sh
+++ b/test/integration/targets/connection_delegation/runme.sh
@@ -3,7 +3,7 @@
set -ux
echo "Checking if sshpass is present"
-which sshpass 2>&1 || exit 0
+command -v sshpass 2>&1 || exit 0
echo "sshpass is present, continuing with test"
sshpass -p my_password ansible-playbook -i inventory.ini test.yml -k "$@"
diff --git a/test/integration/targets/connection_paramiko_ssh/aliases b/test/integration/targets/connection_paramiko_ssh/aliases
index ad44392e..fd5b08a4 100644
--- a/test/integration/targets/connection_paramiko_ssh/aliases
+++ b/test/integration/targets/connection_paramiko_ssh/aliases
@@ -2,4 +2,3 @@ needs/ssh
shippable/posix/group3
needs/target/setup_paramiko
destructive # potentially installs/uninstalls OS packages via setup_paramiko
-skip/aix
diff --git a/test/integration/targets/connection_ssh/aliases b/test/integration/targets/connection_ssh/aliases
index 1d822b45..50fb8eb8 100644
--- a/test/integration/targets/connection_ssh/aliases
+++ b/test/integration/targets/connection_ssh/aliases
@@ -1,3 +1,2 @@
needs/ssh
shippable/posix/group1
-skip/aix
diff --git a/test/integration/targets/connection_ssh/runme.sh b/test/integration/targets/connection_ssh/runme.sh
index 7e5953ed..cbadf1d5 100755
--- a/test/integration/targets/connection_ssh/runme.sh
+++ b/test/integration/targets/connection_ssh/runme.sh
@@ -68,3 +68,6 @@ ANSIBLE_SSH_TRANSFER_METHOD=piped ./posix.sh "$@"
# test config defaults override
ansible-playbook check_ssh_defaults.yml "$@" -i test_connection.inventory
+
+# ensure we can load from ini cfg
+ANSIBLE_CONFIG=./test_ssh_defaults.cfg ansible-playbook verify_config.yml "$@"
diff --git a/test/integration/targets/connection_ssh/test_ssh_defaults.cfg b/test/integration/targets/connection_ssh/test_ssh_defaults.cfg
new file mode 100644
index 00000000..362f9460
--- /dev/null
+++ b/test/integration/targets/connection_ssh/test_ssh_defaults.cfg
@@ -0,0 +1,5 @@
+[ssh_connection]
+ssh_common_args=fromconfig
+ssh_extra_args=fromconfig
+scp_extra_args=fromconfig
+sftp_extra_args=fromconfig
diff --git a/test/integration/targets/connection_ssh/verify_config.yml b/test/integration/targets/connection_ssh/verify_config.yml
new file mode 100644
index 00000000..0bf79586
--- /dev/null
+++ b/test/integration/targets/connection_ssh/verify_config.yml
@@ -0,0 +1,21 @@
+- hosts: localhost
+ gather_facts: false
+ vars:
+ ssh_configs:
+ - ssh_common_args
+ - ssh_extra_args
+ - sftp_extra_args
+ - scp_extra_args
+ tasks:
+ - debug:
+ msg: '{{item ~ ": " ~ lookup("config", item, plugin_type="connection", plugin_name="ssh")}}'
+ verbosity: 3
+ loop: '{{ssh_configs}}'
+ tags: [ configfile ]
+
+ - name: check config from file
+ assert:
+ that:
+ - 'lookup("config", item, plugin_type="connection", plugin_name="ssh") == "fromconfig"'
+ loop: '{{ssh_configs}}'
+ tags: [ configfile ]
diff --git a/test/integration/targets/controller/aliases b/test/integration/targets/controller/aliases
new file mode 100644
index 00000000..0ac86c92
--- /dev/null
+++ b/test/integration/targets/controller/aliases
@@ -0,0 +1,2 @@
+context/controller
+shippable/posix/group1
diff --git a/test/integration/targets/controller/tasks/main.yml b/test/integration/targets/controller/tasks/main.yml
new file mode 100644
index 00000000..354a593e
--- /dev/null
+++ b/test/integration/targets/controller/tasks/main.yml
@@ -0,0 +1,9 @@
+- name: Verify testhost is control host
+ stat:
+ path: "{{ output_dir }}"
+- name: Get control host details
+ setup:
+ register: control_host
+- name: Show control host details
+ debug:
+ msg: "{{ control_host.ansible_facts.ansible_distribution }} {{ control_host.ansible_facts.ansible_distribution_version }}"
diff --git a/test/integration/targets/copy/tasks/main.yml b/test/integration/targets/copy/tasks/main.yml
index e02c0232..bef182b8 100644
--- a/test/integration/targets/copy/tasks/main.yml
+++ b/test/integration/targets/copy/tasks/main.yml
@@ -27,6 +27,7 @@
chdir: '{{role_path}}/files/subdir/subdir1'
warn: no
with_dict: "{{ symlinks }}"
+ delegate_to: localhost
- name: Create remote unprivileged remote user
user:
@@ -78,6 +79,7 @@
when: ansible_os_family == 'RedHat' and ansible_selinux.get('mode') == 'enforcing'
- import_tasks: no_log.yml
+ delegate_to: localhost
- import_tasks: check_mode.yml
@@ -113,6 +115,7 @@
name: '{{ remote_unprivileged_user }}'
state: absent
remove: yes
+ force: yes
- name: Remove sudoers.d file
file:
diff --git a/test/integration/targets/copy/tasks/tests.yml b/test/integration/targets/copy/tasks/tests.yml
index be955317..fa4254c7 100644
--- a/test/integration/targets/copy/tasks/tests.yml
+++ b/test/integration/targets/copy/tasks/tests.yml
@@ -1489,13 +1489,13 @@
# src is a file, dest is a non-existent directory (2 levels of directories):
# using remote_src
# checks that dest is created
-- include: dest_in_non_existent_directories_remote_src.yml
+- include_tasks: file=dest_in_non_existent_directories_remote_src.yml
with_items:
- { src: 'foo.txt', dest: 'new_sub_dir1/sub_dir2/', check: 'new_sub_dir1/sub_dir2/foo.txt' }
# src is a file, dest is file in a non-existent directory: checks that a failure occurs
# using remote_src
-- include: src_file_dest_file_in_non_existent_dir_remote_src.yml
+- include_tasks: file=src_file_dest_file_in_non_existent_dir_remote_src.yml
with_items:
- 'new_sub_dir1/sub_dir2/foo.txt'
- 'new_sub_dir1/foo.txt'
@@ -1504,7 +1504,7 @@
# src is a file, dest is a non-existent directory (2 levels of directories):
# checks that dest is created
-- include: dest_in_non_existent_directories.yml
+- include_tasks: file=dest_in_non_existent_directories.yml
with_items:
- { src: 'foo.txt', dest: 'new_sub_dir1/sub_dir2/', check: 'new_sub_dir1/sub_dir2/foo.txt' }
- { src: 'subdir', dest: 'new_sub_dir1/sub_dir2/', check: 'new_sub_dir1/sub_dir2/subdir/bar.txt' }
@@ -1513,7 +1513,7 @@
- { src: 'subdir/', dest: 'new_sub_dir1/sub_dir2', check: 'new_sub_dir1/sub_dir2/bar.txt' }
# src is a file, dest is file in a non-existent directory: checks that a failure occurs
-- include: src_file_dest_file_in_non_existent_dir.yml
+- include_tasks: file=src_file_dest_file_in_non_existent_dir.yml
with_items:
- 'new_sub_dir1/sub_dir2/foo.txt'
- 'new_sub_dir1/foo.txt'
diff --git a/test/integration/targets/cron/tasks/main.yml b/test/integration/targets/cron/tasks/main.yml
index 899ec549..32e345d3 100644
--- a/test/integration/targets/cron/tasks/main.yml
+++ b/test/integration/targets/cron/tasks/main.yml
@@ -110,8 +110,9 @@
- assert:
that: remove_task_idempotence is not changed
-- name: Check that removing a cron task with cron_file and without specifying an user is allowed (#58493)
+- name: Check that removing a cron task with cron_file and without specifying a user is allowed (#58493)
cron:
+ name: test cron task
cron_file: unexistent_cron_file
state: absent
register: remove_cron_file
@@ -214,7 +215,24 @@
- assert:
that: not cron_file_stats.stat.exists
+- name: System cron tab can not be managed
+ when: ansible_distribution != 'Alpine'
+ block:
+ - name: Add cron job
+ cron:
+ cron_file: "{{ system_crontab }}"
+ user: root
+ name: "integration test cron"
+ job: 'ls'
+ ignore_errors: yes
+ register: result
+
+ - assert:
+ that: "result.msg == 'Will not manage /etc/crontab via cron_file, see documentation.'"
+
+# TODO: restrict other root crontab locations
- name: System cron tab does not get removed
+ when: ansible_distribution == 'Alpine'
block:
- name: Add cron job
cron:
diff --git a/test/integration/targets/dataloader/aliases b/test/integration/targets/dataloader/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/dataloader/aliases
+++ b/test/integration/targets/dataloader/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/debug/aliases b/test/integration/targets/debug/aliases
index a6dafcf8..97c468e5 100644
--- a/test/integration/targets/debug/aliases
+++ b/test/integration/targets/debug/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller # this is a controller-only action, the module is just for documentation
diff --git a/test/integration/targets/delegate_to/aliases b/test/integration/targets/delegate_to/aliases
index b8e973da..d6bb651c 100644
--- a/test/integration/targets/delegate_to/aliases
+++ b/test/integration/targets/delegate_to/aliases
@@ -1,4 +1,4 @@
shippable/posix/group3
needs/ssh
needs/root # only on macOS and FreeBSD to configure network interfaces
-skip/aix
+context/controller
diff --git a/test/integration/targets/dict_transformations/aliases b/test/integration/targets/dict_transformations/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/dict_transformations/aliases
+++ b/test/integration/targets/dict_transformations/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/dnf/tasks/cacheonly.yml b/test/integration/targets/dnf/tasks/cacheonly.yml
new file mode 100644
index 00000000..a5c84a37
--- /dev/null
+++ b/test/integration/targets/dnf/tasks/cacheonly.yml
@@ -0,0 +1,15 @@
+---
+- name: Test cacheonly (clean before testing)
+ command: dnf clean all
+
+- name: Try installing from cache where it has been cleaned
+ dnf:
+ name: sos
+ state: latest
+ cacheonly: true
+ register: dnf_result
+
+- name: Verify dnf has not changed
+ assert:
+ that:
+ - "not dnf_result is changed"
diff --git a/test/integration/targets/dnf/tasks/dnf.yml b/test/integration/targets/dnf/tasks/dnf.yml
index 7e6a8d8f..bf1ea848 100644
--- a/test/integration/targets/dnf/tasks/dnf.yml
+++ b/test/integration/targets/dnf/tasks/dnf.yml
@@ -700,7 +700,7 @@
content: |
[main]
exclude=lsof*
- dest: '{{ output_dir }}/test-dnf.conf'
+ dest: '{{ remote_tmp_dir }}/test-dnf.conf'
register: test_dnf_copy
- block:
@@ -728,7 +728,7 @@
always:
- name: remove exclude lsof conf file
file:
- path: '{{ output_dir }}/test-dnf.conf'
+ path: '{{ remote_tmp_dir }}/test-dnf.conf'
state: absent
# end test case where disable_excludes is supported
@@ -816,3 +816,21 @@
that:
- nonexisting is success
- nonexisting.msg == 'Nothing to do'
+
+# running on RHEL which is --remote where .mo language files are present
+# for dnf as opposed to in --docker
+- when: ansible_distribution == 'RedHat'
+ block:
+ - dnf:
+ name: langpacks-ja
+ state: present
+
+ - dnf:
+ name: nginx-mod*
+ state: absent
+ environment:
+ LANG: ja_JP.UTF-8
+ always:
+ - dnf:
+ name: langpacks-ja
+ state: absent
diff --git a/test/integration/targets/dnf/tasks/main.yml b/test/integration/targets/dnf/tasks/main.yml
index 51ab7d20..d66a0653 100644
--- a/test/integration/targets/dnf/tasks/main.yml
+++ b/test/integration/targets/dnf/tasks/main.yml
@@ -63,6 +63,15 @@
# TODO: Construct our own instance where 'nobest' applies, so we can stop using
# a third-party repo to test this behavior.
+#
+# This fails due to conflicts on Fedora 34, but we can nuke this entirely once
+# #74224 lands, because it covers nobest cases.
- include_tasks: nobest.yml
- when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('24', '>=')) or
+ when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('24', '>=') and
+ ansible_distribution_major_version is version('34', '!=')) or
+ (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version is version('8', '>='))
+
+
+- include_tasks: cacheonly.yml
+ when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('23', '>=')) or
(ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version is version('8', '>='))
diff --git a/test/integration/targets/dnf/vars/Fedora-34.yml b/test/integration/targets/dnf/vars/Fedora-34.yml
new file mode 100644
index 00000000..859059f1
--- /dev/null
+++ b/test/integration/targets/dnf/vars/Fedora-34.yml
@@ -0,0 +1,2 @@
+astream_name: '@httpd:2.4/common'
+astream_name_no_stream: '@httpd/common'
diff --git a/test/integration/targets/dpkg_selections/tasks/main.yaml b/test/integration/targets/dpkg_selections/tasks/main.yaml
index 6abd1dec..abf9fa1b 100644
--- a/test/integration/targets/dpkg_selections/tasks/main.yaml
+++ b/test/integration/targets/dpkg_selections/tasks/main.yaml
@@ -1,3 +1,3 @@
---
- - include: 'dpkg_selections.yaml'
+ - include_tasks: file='dpkg_selections.yaml'
when: ansible_distribution in ('Ubuntu', 'Debian')
diff --git a/test/integration/targets/egg-info/aliases b/test/integration/targets/egg-info/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/egg-info/aliases
+++ b/test/integration/targets/egg-info/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/embedded_module/aliases b/test/integration/targets/embedded_module/aliases
index 765b70da..6452e6d4 100644
--- a/test/integration/targets/embedded_module/aliases
+++ b/test/integration/targets/embedded_module/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/target
diff --git a/test/integration/targets/environment/aliases b/test/integration/targets/environment/aliases
index b5983214..a3ada117 100644
--- a/test/integration/targets/environment/aliases
+++ b/test/integration/targets/environment/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/target
diff --git a/test/integration/targets/error_from_connection/aliases b/test/integration/targets/error_from_connection/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/error_from_connection/aliases
+++ b/test/integration/targets/error_from_connection/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/facts_d/aliases b/test/integration/targets/facts_d/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/facts_d/aliases
+++ b/test/integration/targets/facts_d/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/facts_linux_network/aliases b/test/integration/targets/facts_linux_network/aliases
index 21a4e907..703c532e 100644
--- a/test/integration/targets/facts_linux_network/aliases
+++ b/test/integration/targets/facts_linux_network/aliases
@@ -3,3 +3,4 @@ shippable/posix/group2
skip/freebsd
skip/osx
skip/macos
+context/controller
diff --git a/test/integration/targets/failed_when/aliases b/test/integration/targets/failed_when/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/failed_when/aliases
+++ b/test/integration/targets/failed_when/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/failed_when/tasks/main.yml b/test/integration/targets/failed_when/tasks/main.yml
index 3f8ae545..1b10bef1 100644
--- a/test/integration/targets/failed_when/tasks/main.yml
+++ b/test/integration/targets/failed_when/tasks/main.yml
@@ -66,3 +66,15 @@
that:
- "'failed' in result and not result.failed"
- "'failed_when_result' in result and not result.failed_when_result"
+
+- name: invalid conditional
+ command: echo foo
+ failed_when: boomboomboom
+ register: invalid_conditional
+ ignore_errors: true
+
+- assert:
+ that:
+ - invalid_conditional is failed
+ - invalid_conditional.stdout is defined
+ - invalid_conditional.failed_when_result is contains('boomboomboom')
diff --git a/test/integration/targets/fetch/aliases b/test/integration/targets/fetch/aliases
index fb5d6faa..ff56593d 100644
--- a/test/integration/targets/fetch/aliases
+++ b/test/integration/targets/fetch/aliases
@@ -1,2 +1,3 @@
shippable/posix/group2
needs/target/setup_remote_tmp_dir
+needs/ssh
diff --git a/test/integration/targets/fetch/cleanup.yml b/test/integration/targets/fetch/cleanup.yml
new file mode 100644
index 00000000..792b603c
--- /dev/null
+++ b/test/integration/targets/fetch/cleanup.yml
@@ -0,0 +1,16 @@
+- name: Cleanup user account
+ hosts: testhost
+
+ tasks:
+ - name: remove test user
+ user:
+ name: fetcher
+ state: absent
+ remove: yes
+ force: yes
+
+ - name: delete temporary directory
+ file:
+ path: "{{ remote_tmp_dir }}"
+ state: absent
+ no_log: yes
diff --git a/test/integration/targets/fetch/roles/fetch_tests/defaults/main.yml b/test/integration/targets/fetch/roles/fetch_tests/defaults/main.yml
new file mode 100644
index 00000000..f0b9cfc4
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/defaults/main.yml
@@ -0,0 +1 @@
+skip_cleanup: no
diff --git a/test/integration/targets/fetch/roles/fetch_tests/handlers/main.yml b/test/integration/targets/fetch/roles/fetch_tests/handlers/main.yml
new file mode 100644
index 00000000..c6c296af
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/handlers/main.yml
@@ -0,0 +1,8 @@
+- name: remove test user
+ user:
+ name: fetcher
+ state: absent
+ remove: yes
+ force: yes
+ become: yes
+ when: not skip_cleanup | bool
diff --git a/test/integration/targets/fetch/roles/fetch_tests/tasks/fail_on_missing.yml b/test/integration/targets/fetch/roles/fetch_tests/tasks/fail_on_missing.yml
new file mode 100644
index 00000000..d918aaeb
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/tasks/fail_on_missing.yml
@@ -0,0 +1,53 @@
+- name: Attempt to fetch a non-existent file - do not fail on missing
+ fetch:
+ src: "{{ remote_tmp_dir }}/doesnotexist"
+ dest: "{{ output_dir }}/fetched"
+ fail_on_missing: no
+ register: fetch_missing_nofail
+
+- name: Attempt to fetch a non-existent file - fail on missing
+ fetch:
+ src: "{{ remote_tmp_dir }}/doesnotexist"
+ dest: "{{ output_dir }}/fetched"
+ fail_on_missing: yes
+ register: fetch_missing
+ ignore_errors: yes
+
+- name: Attempt to fetch a non-existent file - fail on missing implicit
+ fetch:
+ src: "{{ remote_tmp_dir }}/doesnotexist"
+ dest: "{{ output_dir }}/fetched"
+ register: fetch_missing_implicit
+ ignore_errors: yes
+
+- name: Attempt to fetch a directory - should not fail but return a message
+ fetch:
+ src: "{{ remote_tmp_dir }}"
+ dest: "{{ output_dir }}/somedir"
+ fail_on_missing: no
+ register: fetch_dir
+
+- name: Attempt to fetch a directory - should fail
+ fetch:
+ src: "{{ remote_tmp_dir }}"
+ dest: "{{ output_dir }}/somedir"
+ fail_on_missing: yes
+ register: failed_fetch_dir
+ ignore_errors: yes
+
+- name: Check fetch missing with failure with implicit fail
+ assert:
+ that:
+ - fetch_missing_nofail.msg is search('ignored')
+ - fetch_missing_nofail is not changed
+ - fetch_missing is failed
+ - fetch_missing is not changed
+ - fetch_missing.msg is search ('remote file does not exist')
+ - fetch_missing_implicit is failed
+ - fetch_missing_implicit is not changed
+ - fetch_missing_implicit.msg is search ('remote file does not exist')
+ - fetch_dir is not changed
+ - fetch_dir.msg is search('is a directory')
+ - failed_fetch_dir is failed
+ - failed_fetch_dir is not changed
+ - failed_fetch_dir.msg is search('is a directory')
diff --git a/test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml b/test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml
new file mode 100644
index 00000000..8a6b5b7b
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml
@@ -0,0 +1,41 @@
+- name: Fetch with no parameters
+ fetch:
+ register: fetch_no_params
+ ignore_errors: yes
+
+- name: Fetch with incorrect source type
+ fetch:
+ src: [1, 2]
+ dest: "{{ output_dir }}/fetched"
+ register: fetch_incorrect_src
+ ignore_errors: yes
+
+- name: Try to fetch a file inside an inaccessible directory
+ fetch:
+ src: "{{ remote_tmp_dir }}/noaccess/file1"
+ dest: "{{ output_dir }}"
+ register: failed_fetch_no_access
+ become: yes
+ become_user: fetcher
+ become_method: su
+ ignore_errors: yes
+
+- name: Dest is an existing directory name without trailing slash and flat=yes, should fail
+ fetch:
+ src: "{{ remote_tmp_dir }}/orig"
+ dest: "{{ output_dir }}"
+ flat: yes
+ register: failed_fetch_dest_dir
+ ignore_errors: true
+
+- name: Ensure fetch failed
+ assert:
+ that:
+ - fetch_no_params is failed
+ - fetch_no_params.msg is search('src and dest are required')
+ - fetch_incorrect_src is failed
+ - fetch_incorrect_src.msg is search('Invalid type supplied for source')
+ - failed_fetch_no_access is failed
+ - failed_fetch_no_access.msg is search('file is not readable')
+ - failed_fetch_dest_dir is failed
+ - failed_fetch_dest_dir.msg is search('dest is an existing directory')
diff --git a/test/integration/targets/fetch/roles/fetch_tests/tasks/main.yml b/test/integration/targets/fetch/roles/fetch_tests/tasks/main.yml
index 267ae0f0..eefe95c8 100644
--- a/test/integration/targets/fetch/roles/fetch_tests/tasks/main.yml
+++ b/test/integration/targets/fetch/roles/fetch_tests/tasks/main.yml
@@ -1,141 +1,5 @@
-# test code for the pip module
-# (c) 2014, Michael DeHaan <michael.dehaan@gmail.com>
-
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
-- name: create a file that we can use to fetch
- copy: content="test" dest={{ remote_tmp_dir }}/orig
-
-- name: fetch the test file
- fetch: src={{ remote_tmp_dir }}/orig dest={{ output_dir }}/fetched
- register: fetched
-
-- debug: var=fetched
-
-- name: Assert that we fetched correctly
- assert:
- that:
- - 'fetched["changed"] == True'
- - 'fetched["checksum"] == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"'
- - 'fetched["remote_checksum"] == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"'
- - 'lookup("file", output_dir + "/fetched/" + inventory_hostname + remote_tmp_dir + "/orig") == "test"'
-
-# TODO: check the become and non-become forms of fetch because in one form we'll do
-# the get method of the connection plugin and in the become case we'll use the
-# fetch module.
-
-- name: fetch a second time to show idempotence
- fetch: src={{ remote_tmp_dir }}/orig dest={{ output_dir }}/fetched
- register: fetched
-
-- name: Assert that the file was not fetched the second time
- assert:
- that:
- - 'fetched["changed"] == False'
- - 'fetched["checksum"] == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"'
-
-- name: attempt to fetch a non-existent file - do not fail on missing
- fetch: src={{ remote_tmp_dir }}/doesnotexist dest={{ output_dir }}/fetched fail_on_missing=False
- register: fetch_missing_nofail
-
-- name: check fetch missing no fail result
- assert:
- that:
- - "fetch_missing_nofail.msg"
- - "fetch_missing_nofail is not changed"
-
-- name: attempt to fetch a non-existent file - fail on missing
- fetch: src={{ remote_tmp_dir }}/doesnotexist dest={{ output_dir }}/fetched fail_on_missing=yes
- register: fetch_missing
- ignore_errors: true
-
-- name: check fetch missing with failure
- assert:
- that:
- - "fetch_missing is failed"
- - "fetch_missing.msg"
- - "fetch_missing is not changed"
-
-- name: attempt to fetch a non-existent file - fail on missing implicit
- fetch: src={{ remote_tmp_dir }}/doesnotexist dest={{ output_dir }}/fetched
- register: fetch_missing_implicit
- ignore_errors: true
-
-- name: check fetch missing with failure with implicit fail
- assert:
- that:
- - "fetch_missing_implicit is failed"
- - "fetch_missing_implicit.msg"
- - "fetch_missing_implicit is not changed"
-
-- name: attempt to fetch a directory - should not fail but return a message
- fetch: src={{ remote_tmp_dir }} dest={{ output_dir }}/somedir fail_on_missing=False
- register: fetch_dir
-
-- name: check fetch directory result
- assert:
- that:
- - "fetch_dir is not changed"
- - "fetch_dir.msg"
-
-- name: attempt to fetch a directory - should fail
- fetch: src={{ remote_tmp_dir }} dest={{ output_dir }}/somedir fail_on_missing=True
- register: failed_fetch_dir
- ignore_errors: true
-
-- name: check fetch directory result
- assert:
- that:
- - "failed_fetch_dir is failed"
- - "fetch_dir.msg"
-
-- name: create symlink to a file that we can fetch
- file:
- path: "{{ remote_tmp_dir }}/link"
- src: "{{ remote_tmp_dir }}/orig"
- state: "link"
-
-- name: fetch the file via a symlink
- fetch: src={{ remote_tmp_dir }}/link dest={{ output_dir }}/fetched-link
- register: fetched
-
-- debug: var=fetched
-
-- name: Assert that we fetched correctly
- assert:
- that:
- - 'fetched["changed"] == True'
- - 'fetched["checksum"] == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"'
- - 'fetched["remote_checksum"] == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"'
- - 'lookup("file", output_dir + "/fetched-link/" + inventory_hostname + remote_tmp_dir + "/link") == "test"'
-
-# TODO: check the become and non-become forms of fetch because in one form we'll do
-# the get method of the connection plugin and in the become case we'll use the
-# fetch module.
-
-- name: dest is an existing directory name without trailing slash and flat=yes, should fail
- fetch:
- src: "{{ remote_tmp_dir }}/orig"
- dest: "{{ output_dir }}"
- flat: yes
- register: failed_fetch_dest_dir
- ignore_errors: true
-
-- name: check that it indeed failed
- assert:
- that:
- - "failed_fetch_dest_dir is failed"
- - "failed_fetch_dest_dir.msg"
+- import_tasks: setup.yml
+- import_tasks: normal.yml
+- import_tasks: symlink.yml
+- import_tasks: fail_on_missing.yml
+- import_tasks: failures.yml
diff --git a/test/integration/targets/fetch/roles/fetch_tests/tasks/normal.yml b/test/integration/targets/fetch/roles/fetch_tests/tasks/normal.yml
new file mode 100644
index 00000000..6f3ab620
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/tasks/normal.yml
@@ -0,0 +1,38 @@
+- name: Fetch the test file
+ fetch: src={{ remote_tmp_dir }}/orig dest={{ output_dir }}/fetched
+ register: fetched
+
+- name: Fetch a second time to show no changes
+ fetch: src={{ remote_tmp_dir }}/orig dest={{ output_dir }}/fetched
+ register: fetched_again
+
+- name: Fetch the test file in check mode
+ fetch:
+ src: "{{ remote_tmp_dir }}/orig"
+ dest: "{{ output_dir }}/fetched"
+ check_mode: yes
+ register: fetch_check_mode
+
+- name: Fetch with dest ending in path sep
+ fetch:
+ src: "{{ remote_tmp_dir }}/orig"
+ dest: "{{ output_dir }}/"
+ flat: yes
+
+- name: Fetch with dest with relative path
+ fetch:
+ src: "{{ remote_tmp_dir }}/orig"
+ dest: "{{ output_dir[1:] }}"
+ flat: yes
+
+- name: Assert that we fetched correctly
+ assert:
+ that:
+ - fetched is changed
+ - fetched.checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
+ - fetched_again is not changed
+ - fetched_again.checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
+ - fetched.remote_checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
+ - lookup("file", output_dir + "/fetched/" + inventory_hostname + remote_tmp_dir + "/orig") == "test"
+ - fetch_check_mode is skipped
+ - fetch_check_mode.msg is search('not \(yet\) supported')
diff --git a/test/integration/targets/fetch/roles/fetch_tests/tasks/setup.yml b/test/integration/targets/fetch/roles/fetch_tests/tasks/setup.yml
new file mode 100644
index 00000000..89b94c46
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/tasks/setup.yml
@@ -0,0 +1,45 @@
+- name: Include system specific variables
+ include_vars: "{{ lookup('first_found', params) }}"
+ vars:
+ params:
+ files:
+ - "{{ ansible_facts.system }}.yml"
+ - default.yml
+ paths:
+ - "{{ role_path }}/vars"
+
+- name: Work-around for locked users on Alpine
+ # see https://github.com/ansible/ansible/issues/68676
+ set_fact:
+ password: '*'
+ when: ansible_distribution == 'Alpine'
+
+- name: Create test user
+ user:
+ name: fetcher
+ create_home: yes
+ groups: "{{ _fetch_additional_groups | default(omit) }}"
+ append: "{{ True if _fetch_additional_groups else False }}"
+ password: "{{ password | default(omit) }}"
+ become: yes
+ notify:
+ - remove test user
+
+- name: Create a file that we can use to fetch
+ copy:
+ content: "test"
+ dest: "{{ remote_tmp_dir }}/orig"
+
+- name: Create symlink to a file that we can fetch
+ file:
+ path: "{{ remote_tmp_dir }}/link"
+ src: "{{ remote_tmp_dir }}/orig"
+ state: "link"
+
+- name: Create an inaccessible directory
+ file:
+ path: "{{ remote_tmp_dir }}/noaccess"
+ state: directory
+ mode: '0600'
+ owner: root
+ become: yes
diff --git a/test/integration/targets/fetch/roles/fetch_tests/tasks/symlink.yml b/test/integration/targets/fetch/roles/fetch_tests/tasks/symlink.yml
new file mode 100644
index 00000000..41d7b35a
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/tasks/symlink.yml
@@ -0,0 +1,13 @@
+- name: Fetch the file via a symlink
+ fetch:
+ src: "{{ remote_tmp_dir }}/link"
+ dest: "{{ output_dir }}/fetched-link"
+ register: fetched_symlink
+
+- name: Assert that we fetched correctly
+ assert:
+ that:
+ - fetched_symlink is changed
+ - fetched_symlink.checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
+ - fetched_symlink.remote_checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
+ - 'lookup("file", output_dir + "/fetched-link/" + inventory_hostname + remote_tmp_dir + "/link") == "test"'
diff --git a/test/integration/targets/fetch/roles/fetch_tests/vars/Darwin.yml b/test/integration/targets/fetch/roles/fetch_tests/vars/Darwin.yml
new file mode 100644
index 00000000..0654b711
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/vars/Darwin.yml
@@ -0,0 +1,3 @@
+# macOS requires users to be in an additional group for ssh access
+
+_fetch_additional_groups: com.apple.access_ssh
diff --git a/test/integration/targets/fetch/roles/fetch_tests/vars/default.yml b/test/integration/targets/fetch/roles/fetch_tests/vars/default.yml
new file mode 100644
index 00000000..69d7958d
--- /dev/null
+++ b/test/integration/targets/fetch/roles/fetch_tests/vars/default.yml
@@ -0,0 +1 @@
+_fetch_additional_groups: []
diff --git a/test/integration/targets/fetch/runme.sh b/test/integration/targets/fetch/runme.sh
index 7e909dde..a508a0a6 100755
--- a/test/integration/targets/fetch/runme.sh
+++ b/test/integration/targets/fetch/runme.sh
@@ -2,11 +2,33 @@
set -eux
+function cleanup {
+ ansible-playbook -i "${INVENTORY_PATH}" cleanup.yml -e "output_dir=${OUTPUT_DIR}" -b "$@"
+ unset ANSIBLE_CACHE_PLUGIN
+ unset ANSIBLE_CACHE_PLUGIN_CONNECTION
+}
+
+trap 'cleanup "$@"' EXIT
+
# setup required roles
ln -s ../../setup_remote_tmp_dir roles/setup_remote_tmp_dir
# run old type role tests
-ansible-playbook -i ../../inventory run_fetch_tests.yml -e "output_dir=${OUTPUT_DIR}" -v "$@"
+ansible-playbook -i ../../inventory run_fetch_tests.yml -e "output_dir=${OUTPUT_DIR}" "$@"
+
+# run same test with become
+ansible-playbook -i ../../inventory run_fetch_tests.yml -e "output_dir=${OUTPUT_DIR}" -b "$@"
# run tests to avoid path injection from slurp when fetch uses become
-ansible-playbook -i ../../inventory injection/avoid_slurp_return.yml -e "output_dir=${OUTPUT_DIR}" -v "$@"
+ansible-playbook -i ../../inventory injection/avoid_slurp_return.yml -e "output_dir=${OUTPUT_DIR}" "$@"
+
+## Test unreadable file with stat. Requires running without become and as a user other than root.
+#
+# Change the known_hosts file to avoid changing the test environment
+export ANSIBLE_CACHE_PLUGIN=jsonfile
+export ANSIBLE_CACHE_PLUGIN_CONNECTION="${OUTPUT_DIR}/cache"
+# Create a non-root user account and configure SSH acccess for that account
+ansible-playbook -i "${INVENTORY_PATH}" setup_unreadable_test.yml -e "output_dir=${OUTPUT_DIR}" "$@"
+
+# Run the tests as the unprivileged user without become to test the use of the stat module from the fetch module
+ansible-playbook -i "${INVENTORY_PATH}" test_unreadable_with_stat.yml -e ansible_user=fetcher -e ansible_become=no -e "output_dir=${OUTPUT_DIR}" "$@"
diff --git a/test/integration/targets/fetch/setup_unreadable_test.yml b/test/integration/targets/fetch/setup_unreadable_test.yml
new file mode 100644
index 00000000..f4cc8c1e
--- /dev/null
+++ b/test/integration/targets/fetch/setup_unreadable_test.yml
@@ -0,0 +1,40 @@
+- name: Create a user account and configure ssh access
+ hosts: testhost
+ gather_facts: no
+
+ tasks:
+ - import_role:
+ name: fetch_tests
+ tasks_from: setup.yml
+ vars:
+ # Keep the remote temp dir and cache the remote_tmp_dir fact. The directory itself
+ # and the fact that contains the path are needed in a separate ansible-playbook run.
+ setup_remote_tmp_dir_skip_cleanup: yes
+ setup_remote_tmp_dir_cache_path: yes
+ skip_cleanup: yes
+
+ # This prevents ssh access. It is fixed in some container images but not all.
+ # https://github.com/ansible/distro-test-containers/pull/70
+ - name: Remove /run/nologin
+ file:
+ path: /run/nologin
+ state: absent
+
+ # Setup ssh access for the unprivileged user.
+ - name: Get home directory for temporary user
+ command: echo ~fetcher
+ register: fetcher_home
+
+ - name: Create .ssh dir
+ file:
+ path: "{{ fetcher_home.stdout }}/.ssh"
+ state: directory
+ owner: fetcher
+ mode: '0700'
+
+ - name: Configure authorized_keys
+ copy:
+ src: "~root/.ssh/authorized_keys"
+ dest: "{{ fetcher_home.stdout }}/.ssh/authorized_keys"
+ owner: fetcher
+ mode: '0600'
diff --git a/test/integration/targets/fetch/test_unreadable_with_stat.yml b/test/integration/targets/fetch/test_unreadable_with_stat.yml
new file mode 100644
index 00000000..c8a0145c
--- /dev/null
+++ b/test/integration/targets/fetch/test_unreadable_with_stat.yml
@@ -0,0 +1,36 @@
+# This playbook needs to be run as a non-root user without become. Under
+# those circumstances, the fetch module uses stat and not slurp.
+
+- name: Test unreadable file using stat
+ hosts: testhost
+ gather_facts: no
+
+ tasks:
+ - name: Check connectivity
+ command: whoami
+ register: whoami
+
+ - name: Verify user
+ assert:
+ that:
+ - whoami.stdout == 'fetcher'
+
+ - name: Try to fetch a file inside an inaccessible directory
+ fetch:
+ src: "{{ remote_tmp_dir }}/noaccess/file1"
+ dest: "{{ output_dir }}"
+ register: failed_fetch_no_access
+ ignore_errors: yes
+
+ - name: Try to fetch a file inside an inaccessible directory without fail_on_missing
+ fetch:
+ src: "{{ remote_tmp_dir }}/noaccess/file1"
+ dest: "{{ output_dir }}"
+ fail_on_missing: no
+ register: failed_fetch_no_access_fail_on_missing
+
+ - assert:
+ that:
+ - failed_fetch_no_access is failed
+ - failed_fetch_no_access.msg is search('Permission denied')
+ - failed_fetch_no_access_fail_on_missing.msg is search(', ignored')
diff --git a/test/integration/targets/file/handlers/main.yml b/test/integration/targets/file/handlers/main.yml
index b5040f6e..553f69ce 100644
--- a/test/integration/targets/file/handlers/main.yml
+++ b/test/integration/targets/file/handlers/main.yml
@@ -3,6 +3,7 @@
name: "{{ item }}"
state: absent
remove: yes
+ force: yes
loop:
- test1
- test_uid
diff --git a/test/integration/targets/file/tasks/directory_as_dest.yml b/test/integration/targets/file/tasks/directory_as_dest.yml
index 9b6ddb5d..85451e43 100644
--- a/test/integration/targets/file/tasks/directory_as_dest.yml
+++ b/test/integration/targets/file/tasks/directory_as_dest.yml
@@ -1,6 +1,6 @@
# File module tests for overwriting directories
- name: Initialize the test output dir
- include: initialize.yml
+ import_tasks: initialize.yml
# We need to make this more consistent:
# https://github.com/ansible/proposals/issues/111
diff --git a/test/integration/targets/file/tasks/main.yml b/test/integration/targets/file/tasks/main.yml
index 565afa02..c96beba3 100644
--- a/test/integration/targets/file/tasks/main.yml
+++ b/test/integration/targets/file/tasks/main.yml
@@ -91,7 +91,10 @@
- "file2_result.state == 'absent'"
- name: verify we can touch a file
- file: path={{output_dir}}/baz.txt state=touch
+ file:
+ path: "{{output_dir}}/baz.txt"
+ state: touch
+ mode: '0644'
register: file3_result
- name: verify that the file was marked as changed
diff --git a/test/integration/targets/file/tasks/selinux_tests.yml b/test/integration/targets/file/tasks/selinux_tests.yml
index 6a95c442..8efe8195 100644
--- a/test/integration/targets/file/tasks/selinux_tests.yml
+++ b/test/integration/targets/file/tasks/selinux_tests.yml
@@ -17,7 +17,7 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: Initialize the test output dir
- include: initialize.yml
+ import_tasks: initialize.yml
- name: touch a file for testing
file: path={{output_dir}}/foo-se.txt state=touch
diff --git a/test/integration/targets/file/tasks/state_link.yml b/test/integration/targets/file/tasks/state_link.yml
index d84bb310..851b213e 100644
--- a/test/integration/targets/file/tasks/state_link.yml
+++ b/test/integration/targets/file/tasks/state_link.yml
@@ -1,7 +1,7 @@
# file module tests for dealing with symlinks (state=link)
- name: Initialize the test output dir
- include: initialize.yml
+ import_tasks: initialize.yml
#
# Basic absolute symlink to a file
@@ -181,6 +181,8 @@
user:
name: '{{ remote_unprivileged_user }}'
state: absent
+ force: yes
+ remove: yes
- name: Delete unprivileged user home and tempdir
file:
diff --git a/test/integration/targets/filter_core/aliases b/test/integration/targets/filter_core/aliases
index 1603f435..765b70da 100644
--- a/test/integration/targets/filter_core/aliases
+++ b/test/integration/targets/filter_core/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
-skip/aix
diff --git a/test/integration/targets/filter_core/tasks/main.yml b/test/integration/targets/filter_core/tasks/main.yml
index 8ab9d446..5a5d813f 100644
--- a/test/integration/targets/filter_core/tasks/main.yml
+++ b/test/integration/targets/filter_core/tasks/main.yml
@@ -283,6 +283,7 @@
multi_line: "{{ 'hello\nworld' | regex_search('^world', multiline=true) }}"
named_groups: "{{ 'goodbye' | regex_search('(?P<first>good)(?P<second>bye)', '\\g<second>', '\\g<first>') }}"
numbered_groups: "{{ 'goodbye' | regex_search('(good)(bye)', '\\2', '\\1') }}"
+ no_match_is_none_inline: "{{ 'hello' | regex_search('world') == none }}"
- name: regex_search unknown argument (failure expected)
set_fact:
@@ -299,6 +300,7 @@
- multi_line == 'world'
- named_groups == ['bye', 'good']
- numbered_groups == ['bye', 'good']
+ - no_match_is_none_inline
- failure is failed
- name: Verify to_bool
@@ -378,6 +380,18 @@
- "2|from_yaml == 2"
- "'---\nbananas: yellow\n---\napples: red'|from_yaml_all|list == [{'bananas': 'yellow'}, {'apples': 'red'}]"
- "2|from_yaml_all == 2"
+ - "unsafe_fruit|from_yaml == {'bananas': 'yellow', 'apples': 'red'}"
+ - "unsafe_fruit_all|from_yaml_all|list == [{'bananas': 'yellow'}, {'apples': 'red'}]"
+ vars:
+ unsafe_fruit: !unsafe |
+ ---
+ bananas: yellow
+ apples: red
+ unsafe_fruit_all: !unsafe |
+ ---
+ bananas: yellow
+ ---
+ apples: red
- name: Verify random raises on non-iterable input (failure expected)
set_fact:
@@ -435,7 +449,7 @@
- name: Verify password_hash
assert:
that:
- - "'what in the WORLD is up?'|password_hash|length == 106"
+ - "'what in the WORLD is up?'|password_hash|length == 120 or 'what in the WORLD is up?'|password_hash|length == 106"
# This throws a vastly different error on py2 vs py3, so we just check
# that it's a failure, not a substring of the exception.
- password_hash_1 is failed
@@ -480,6 +494,39 @@
- mandatory_2 is failed
- "mandatory_2.msg == 'You did not give me a variable. I am a sad wolf.'"
+- name: Verify undef throws if resolved
+ set_fact:
+ foo: '{{ fail_foo }}'
+ vars:
+ fail_foo: '{{ undef("Expected failure") }}'
+ ignore_errors: yes
+ register: fail_1
+
+- name: Setup fail_foo for overriding in test
+ block:
+ - name: Verify undef not executed if overridden
+ set_fact:
+ foo: '{{ fail_foo }}'
+ vars:
+ fail_foo: 'overridden value'
+ register: fail_2
+ vars:
+ fail_foo: '{{ undef(hint="Expected failure") }}'
+
+- name: Verify undef is inspectable
+ debug:
+ var: fail_foo
+ vars:
+ fail_foo: '{{ undef("Expected failure") }}'
+ register: fail_3
+
+- name: Verify undef
+ assert:
+ that:
+ - fail_1 is failed
+ - not (fail_2 is failed)
+ - not (fail_3 is failed)
+
- name: Verify comment
assert:
that:
diff --git a/test/integration/targets/filter_encryption/aliases b/test/integration/targets/filter_encryption/aliases
new file mode 100644
index 00000000..765b70da
--- /dev/null
+++ b/test/integration/targets/filter_encryption/aliases
@@ -0,0 +1 @@
+shippable/posix/group2
diff --git a/test/integration/targets/filter_encryption/base.yml b/test/integration/targets/filter_encryption/base.yml
new file mode 100644
index 00000000..8bf25f77
--- /dev/null
+++ b/test/integration/targets/filter_encryption/base.yml
@@ -0,0 +1,37 @@
+- hosts: localhost
+ gather_facts: true
+ vars:
+ data: secret
+ dvault: '{{ "secret"|vault("test")}}'
+ password: test
+ s_32: '{{(2**31-1)}}'
+ s_64: '{{(2**63-1)}}'
+ vaultedstring_32: "$ANSIBLE_VAULT;1.2;AES256;filter_default\n33360a30386436633031333665316161303732656333373131373935623033393964633637346464\n6234613765313539306138373564366363306533356464613334320a666339363037303764636538\n3131633564326637303237313463613864626231\n"
+ vaultedstring_64: "$ANSIBLE_VAULT;1.2;AES256;filter_default\n33370a34333734353636633035656232613935353432656132646533346233326431346232616261\n6133383034376566366261316365633931356133633337396363370a376664386236313834326561\n6338373864623763613165366636633031303739\n"
+ vault: !vault |
+ $ANSIBLE_VAULT;1.1;AES256
+ 33323332333033383335333533383338333333303339333733323339333833303334333133313339
+ 33373339333133323331333833373335333933323338333633343338333133343334333733383334
+ 33333335333433383337333133303339333433353332333333363339333733363335333233303330
+ 3337333733353331333633313335333733373334333733320a373938666533366165653830313163
+ 62386564343438653437333564383664646538653364343138303831613039313232636437336530
+ 3438376662373764650a633366646563386335623161646262366137393635633464333265613938
+ 6661
+ # allow testing against 32b/64b limited archs, normally you can set higher values for random (2**256)
+ is_64: '{{ "64" in ansible_facts["architecture"] }}'
+ salt: '{{ is_64|bool|ternary(s_64, s_32)|random(seed=inventory_hostname)}}'
+ vaultedstring: '{{ is_64|bool|ternary(vaultedstring_64, vaultedstring_32) }}'
+
+ tasks:
+ - name: check vaulting
+ assert:
+ that:
+ - data|vault(password, salt=salt) == vaultedstring
+ - "data|vault(password, salt=salt)|type_debug != 'AnsibleVaultEncryptedUnicode'"
+ - "data|vault(password, salt=salt, wrap_object=True)|type_debug == 'AnsibleVaultEncryptedUnicode'"
+
+ - name: check unvaulting
+ assert:
+ that:
+ - vaultedstring|unvault(password) == data
+ - vault|unvault(password) == data
diff --git a/test/integration/targets/filter_encryption/runme.sh b/test/integration/targets/filter_encryption/runme.sh
new file mode 100755
index 00000000..41b30b1d
--- /dev/null
+++ b/test/integration/targets/filter_encryption/runme.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ANSIBLE_GATHER_SUBSET='min' ansible-playbook base.yml "$@"
diff --git a/test/integration/targets/filter_mathstuff/aliases b/test/integration/targets/filter_mathstuff/aliases
index 1603f435..765b70da 100644
--- a/test/integration/targets/filter_mathstuff/aliases
+++ b/test/integration/targets/filter_mathstuff/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
-skip/aix
diff --git a/test/integration/targets/filter_mathstuff/host_vars/localhost.yml b/test/integration/targets/filter_mathstuff/host_vars/localhost.yml
new file mode 100644
index 00000000..1f5a9e03
--- /dev/null
+++ b/test/integration/targets/filter_mathstuff/host_vars/localhost.yml
@@ -0,0 +1 @@
+foo: test
diff --git a/test/integration/targets/filter_mathstuff/runme.sh b/test/integration/targets/filter_mathstuff/runme.sh
new file mode 100755
index 00000000..36503003
--- /dev/null
+++ b/test/integration/targets/filter_mathstuff/runme.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -eux
+
+export ANSIBLE_ROLES_PATH=../
+
+ansible-playbook runme.yml "$@"
+
+source virtualenv.sh
+
+# Install Jinja < 2.10 since we want to test the fallback to Ansible's custom
+# unique filter. Jinja < 2.10 does not have do_unique so we will trigger the
+# fallback.
+pip install 'jinja2 < 2.10'
+
+# Run the playbook again in the venv with Jinja < 2.10
+ansible-playbook runme.yml "$@"
diff --git a/test/integration/targets/filter_mathstuff/runme.yml b/test/integration/targets/filter_mathstuff/runme.yml
new file mode 100644
index 00000000..a1eaef7a
--- /dev/null
+++ b/test/integration/targets/filter_mathstuff/runme.yml
@@ -0,0 +1,4 @@
+- hosts: localhost
+ gather_facts: false
+ roles:
+ - { role: filter_mathstuff }
diff --git a/test/integration/targets/filter_mathstuff/tasks/main.yml b/test/integration/targets/filter_mathstuff/tasks/main.yml
index 2a708be1..019f00e4 100644
--- a/test/integration/targets/filter_mathstuff/tasks/main.yml
+++ b/test/integration/targets/filter_mathstuff/tasks/main.yml
@@ -1,6 +1,6 @@
-- name: Verify unique's fallback's exception throwing for case_sensitive=True
+- name: Verify unique's fallback's exception throwing for case_sensitive=False
set_fact:
- unique_fallback_exc1: '{{ [{"foo": "bar", "moo": "cow"}]|unique(case_sensitive=True) }}'
+ unique_fallback_exc1: '{{ [{"foo": "bar", "moo": "cow"}]|unique(case_sensitive=False) }}'
ignore_errors: true
tags: unique
register: unique_fallback_exc1_res
@@ -67,6 +67,11 @@
- '[1,2,3]|intersect([3,2,1]) == [1,2,3]'
- '(1,2,3)|intersect((4,5,6))|list == []'
- '(1,2,3)|intersect((3,4,5,6))|list == [3]'
+ - '["a","A","b"]|intersect(["B","c","C"]) == []'
+ - '["a","A","b"]|intersect(["b","B","c","C"]) == ["b"]'
+ - '["a","A","b"]|intersect(["b","A","a"]) == ["a","A","b"]'
+ - '("a","A","b")|intersect(("B","c","C"))|list == []'
+ - '("a","A","b")|intersect(("b","B","c","C"))|list == ["b"]'
- name: Verify difference
tags: difference
@@ -77,6 +82,11 @@
- '[1,2,3]|difference([3,2,1]) == []'
- '(1,2,3)|difference((4,5,6))|list == [1,2,3]'
- '(1,2,3)|difference((3,4,5,6))|list == [1,2]'
+ - '["a","A","b"]|difference(["B","c","C"]) == ["a","A","b"]'
+ - '["a","A","b"]|difference(["b","B","c","C"]) == ["a","A"]'
+ - '["a","A","b"]|difference(["b","A","a"]) == []'
+ - '("a","A","b")|difference(("B","c","C"))|list|sort(case_sensitive=True) == ["A","a","b"]'
+ - '("a","A","b")|difference(("b","B","c","C"))|list|sort(case_sensitive=True) == ["A","a"]'
- name: Verify symmetric_difference
tags: symmetric_difference
@@ -87,6 +97,11 @@
- '[1,2,3]|symmetric_difference([3,2,1]) == []'
- '(1,2,3)|symmetric_difference((4,5,6))|list == [1,2,3,4,5,6]'
- '(1,2,3)|symmetric_difference((3,4,5,6))|list == [1,2,4,5,6]'
+ - '["a","A","b"]|symmetric_difference(["B","c","C"]) == ["a","A","b","B","c","C"]'
+ - '["a","A","b"]|symmetric_difference(["b","B","c","C"]) == ["a","A","B","c","C"]'
+ - '["a","A","b"]|symmetric_difference(["b","A","a"]) == []'
+ - '("a","A","b")|symmetric_difference(("B","c","C"))|list|sort(case_sensitive=True) == ["A","B","C","a","b","c"]'
+ - '("a","A","b")|symmetric_difference(("b","B","c","C"))|list|sort(case_sensitive=True) == ["A","B","C","a","c"]'
- name: Verify union
tags: union
@@ -97,6 +112,11 @@
- '[1,2,3]|union([3,2,1]) == [1,2,3]'
- '(1,2,3)|union((4,5,6))|list == [1,2,3,4,5,6]'
- '(1,2,3)|union((3,4,5,6))|list == [1,2,3,4,5,6]'
+ - '["a","A","b"]|union(["B","c","C"]) == ["a","A","b","B","c","C"]'
+ - '["a","A","b"]|union(["b","B","c","C"]) == ["a","A","b","B","c","C"]'
+ - '["a","A","b"]|union(["b","A","a"]) == ["a","A","b"]'
+ - '("a","A","b")|union(("B","c","C"))|list|sort(case_sensitive=True) == ["A","B","C","a","b","c"]'
+ - '("a","A","b")|union(("b","B","c","C"))|list|sort(case_sensitive=True) == ["A","B","C","a","b","c"]'
- name: Verify min
tags: min
@@ -281,6 +301,18 @@
- rekey_on_member_exc5_res is failed
- '"is not unique, cannot correctly turn into dict" in rekey_on_member_exc5_res.msg'
+- name: test undefined positional args for rekey_on_member are properly handled
+ vars:
+ all_vars: "{{ hostvars[inventory_hostname] }}"
+ test_var: "{{ all_vars.foo }}"
+ block:
+ - include_vars:
+ file: defined_later.yml
+ - assert:
+ that: "test_var == 'test'"
+ - assert:
+ that: "rekeyed == {'value': {'test': 'value'}}"
+
# TODO: For some reason, the coverage tool isn't accounting for the last test
# so add another "last test" to fake it...
- assert:
diff --git a/test/integration/targets/filter_mathstuff/vars/defined_later.yml b/test/integration/targets/filter_mathstuff/vars/defined_later.yml
new file mode 100644
index 00000000..dfb2421b
--- /dev/null
+++ b/test/integration/targets/filter_mathstuff/vars/defined_later.yml
@@ -0,0 +1,3 @@
+do_rekey:
+ - test: value
+rekeyed: "{{ do_rekey | rekey_on_member(defined_later) }}"
diff --git a/test/integration/targets/filter_mathstuff/vars/main.yml b/test/integration/targets/filter_mathstuff/vars/main.yml
new file mode 100644
index 00000000..bb61e12e
--- /dev/null
+++ b/test/integration/targets/filter_mathstuff/vars/main.yml
@@ -0,0 +1 @@
+defined_later: "{{ test_var }}"
diff --git a/test/integration/targets/filter_urls/aliases b/test/integration/targets/filter_urls/aliases
index 1603f435..765b70da 100644
--- a/test/integration/targets/filter_urls/aliases
+++ b/test/integration/targets/filter_urls/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
-skip/aix
diff --git a/test/integration/targets/filter_urlsplit/aliases b/test/integration/targets/filter_urlsplit/aliases
index 1603f435..765b70da 100644
--- a/test/integration/targets/filter_urlsplit/aliases
+++ b/test/integration/targets/filter_urlsplit/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
-skip/aix
diff --git a/test/integration/targets/find/tasks/main.yml b/test/integration/targets/find/tasks/main.yml
index 91d92471..366ef312 100644
--- a/test/integration/targets/find/tasks/main.yml
+++ b/test/integration/targets/find/tasks/main.yml
@@ -207,7 +207,8 @@
- assert:
that:
- failed_path.files == []
- - failed_path.msg.startswith("Skipped '{{mypath}}' path due to this access issue")
+ - 'failed_path.msg == "Not all paths examined, check warnings for details"'
+ - mypath in failed_path.skipped_paths
- name: test number of examined directories/files
block:
@@ -272,3 +273,116 @@
assert:
that:
- '"{{ output_dir_test }}/e/f/g/h/8.ogg" not in find_test3_list'
+
+- name: create our age/size testing sub-directory
+ file:
+ path: "{{ output_dir_test }}/astest"
+ state: directory
+
+- name: create test file with old timestamps
+ file:
+ path: "{{ output_dir_test }}/astest/old.txt"
+ state: touch
+ modification_time: "202001011200.0"
+
+- name: create test file with current timestamps
+ file:
+ path: "{{ output_dir_test }}/astest/new.txt"
+ state: touch
+
+- name: create hidden test file with current timestamps
+ file:
+ path: "{{ output_dir_test }}/astest/.hidden.txt"
+ state: touch
+
+- name: find files older than 1 week
+ find:
+ path: "{{ output_dir_test }}/astest"
+ age: 1w
+ hidden: true
+ register: result
+
+- set_fact:
+ astest_list: >-
+ [ {% for f in result.files %}
+ {{ f.path }}
+ {% if not loop.last %},{% endif %}
+ {% endfor %}
+ ]
+
+- name: assert we only find the old file
+ assert:
+ that:
+ - result.matched == 1
+ - '"{{ output_dir_test }}/astest/old.txt" in astest_list'
+
+- name: find files newer than 1 week
+ find:
+ path: "{{ output_dir_test }}/astest"
+ age: -1w
+ register: result
+
+- set_fact:
+ astest_list: >-
+ [ {% for f in result.files %}
+ {{ f.path }}
+ {% if not loop.last %},{% endif %}
+ {% endfor %}
+ ]
+
+- name: assert we only find the current file
+ assert:
+ that:
+ - result.matched == 1
+ - '"{{ output_dir_test }}/astest/new.txt" in astest_list'
+
+- name: add some content to the new file
+ shell: "echo hello world > {{ output_dir_test }}/astest/new.txt"
+
+- name: find files with MORE than 5 bytes, also get checksums
+ find:
+ path: "{{ output_dir_test }}/astest"
+ size: 5
+ hidden: true
+ get_checksum: true
+ register: result
+
+- set_fact:
+ astest_list: >-
+ [ {% for f in result.files %}
+ {{ f.path }}
+ {% if not loop.last %},{% endif %}
+ {% endfor %}
+ ]
+
+- name: assert we only find the hello world file
+ assert:
+ that:
+ - result.matched == 1
+ - '"{{ output_dir_test }}/astest/new.txt" in astest_list'
+ - '"checksum" in result.files[0]'
+
+- name: find ANY item with LESS than 5 bytes, also get checksums
+ find:
+ path: "{{ output_dir_test }}/astest"
+ size: -5
+ hidden: true
+ get_checksum: true
+ file_type: any
+ register: result
+
+- set_fact:
+ astest_list: >-
+ [ {% for f in result.files %}
+ {{ f.path }}
+ {% if not loop.last %},{% endif %}
+ {% endfor %}
+ ]
+
+- name: assert we do not find the hello world file and a checksum is present
+ assert:
+ that:
+ - result.matched == 2
+ - '"{{ output_dir_test }}/astest/old.txt" in astest_list'
+ - '"{{ output_dir_test }}/astest/.hidden.txt" in astest_list'
+ - '"checksum" in result.files[0]'
diff --git a/test/integration/targets/gathering/aliases b/test/integration/targets/gathering/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/gathering/aliases
+++ b/test/integration/targets/gathering/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/gathering_facts/aliases b/test/integration/targets/gathering_facts/aliases
index 0ee704e1..027aba88 100644
--- a/test/integration/targets/gathering_facts/aliases
+++ b/test/integration/targets/gathering_facts/aliases
@@ -1,2 +1,3 @@
shippable/posix/group3
needs/root
+context/controller
diff --git a/test/integration/targets/gathering_facts/collections/ansible_collections/cisco/ios/plugins/modules/ios_facts.py b/test/integration/targets/gathering_facts/collections/ansible_collections/cisco/ios/plugins/modules/ios_facts.py
new file mode 100644
index 00000000..b79f7941
--- /dev/null
+++ b/test/integration/targets/gathering_facts/collections/ansible_collections/cisco/ios/plugins/modules/ios_facts.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+DOCUMENTATION = """
+---
+module: ios_facts
+short_description: supporting network facts module
+description:
+ - supporting network facts module for gather_facts + module_defaults tests
+options:
+ gather_subset:
+ description:
+ - When supplied, this argument restricts the facts collected
+ to a given subset.
+ - Possible values for this argument include
+ C(all), C(hardware), C(config), and C(interfaces).
+ - Specify a list of values to include a larger subset.
+ - Use a value with an initial C(!) to collect all facts except that subset.
+ required: false
+ default: '!config'
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ """main entry point for module execution
+ """
+ argument_spec = dict(
+ gather_subset=dict(default='!config')
+ )
+ module = AnsibleModule(argument_spec=argument_spec,
+ supports_check_mode=True)
+
+ module.exit_json(ansible_facts={'gather_subset': module.params['gather_subset'], '_ansible_facts_gathered': True})
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/gathering_facts/inventory b/test/integration/targets/gathering_facts/inventory
index e15ae780..6352a7d7 100644
--- a/test/integration/targets/gathering_facts/inventory
+++ b/test/integration/targets/gathering_facts/inventory
@@ -1,2 +1,2 @@
[local]
-facthost[0:25] ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"
+facthost[0:26] ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"
diff --git a/test/integration/targets/gathering_facts/runme.sh b/test/integration/targets/gathering_facts/runme.sh
index ebb82ab4..c1df560c 100755
--- a/test/integration/targets/gathering_facts/runme.sh
+++ b/test/integration/targets/gathering_facts/runme.sh
@@ -23,3 +23,5 @@ ansible-playbook verify_subset.yml "$@"
# ensure we can set defaults for the action plugin and facts module
ansible-playbook test_module_defaults.yml "$@" --tags default_fact_module
ANSIBLE_FACTS_MODULES='ansible.legacy.setup' ansible-playbook test_module_defaults.yml "$@" --tags custom_fact_module
+
+ansible-playbook test_module_defaults.yml "$@" --tags networking
diff --git a/test/integration/targets/gathering_facts/test_gathering_facts.yml b/test/integration/targets/gathering_facts/test_gathering_facts.yml
index 0939cba7..9174675d 100644
--- a/test/integration/targets/gathering_facts/test_gathering_facts.yml
+++ b/test/integration/targets/gathering_facts/test_gathering_facts.yml
@@ -140,6 +140,34 @@
- 'ansible_virtualization_role|default("UNDEF_VIRT") != "UNDEF_VIRT"'
- 'ansible_env|default("UNDEF_ENV") != "UNDEF_ENV"'
+- hosts: facthost25
+ tags: [ 'fact_min' ]
+ gather_facts: no
+ tasks:
+ - setup:
+ filter:
+ - "date_time"
+
+ - name: Test that retrieving all facts filtered to date_time even w/o using ansible_ prefix
+ assert:
+ that:
+ - 'ansible_facts["date_time"]|default("UNDEF_MOUNT") != "UNDEF_MOUNT"'
+ - 'ansible_date_time|default("UNDEF_MOUNT") != "UNDEF_MOUNT"'
+
+- hosts: facthost26
+ tags: [ 'fact_min' ]
+ gather_facts: no
+ tasks:
+ - setup:
+ filter:
+ - "ansible_date_time"
+
+ - name: Test that retrieving all facts filtered to date_time even using ansible_ prefix
+ assert:
+ that:
+ - 'ansible_facts["date_time"]|default("UNDEF_MOUNT") != "UNDEF_MOUNT"'
+ - 'ansible_date_time|default("UNDEF_MOUNT") != "UNDEF_MOUNT"'
+
- hosts: facthost13
tags: [ 'fact_min' ]
connection: local
diff --git a/test/integration/targets/gathering_facts/test_module_defaults.yml b/test/integration/targets/gathering_facts/test_module_defaults.yml
index 5b0f9dd8..038b8ecf 100644
--- a/test/integration/targets/gathering_facts/test_module_defaults.yml
+++ b/test/integration/targets/gathering_facts/test_module_defaults.yml
@@ -77,3 +77,54 @@
- assert:
that:
- "gather_subset == ['min']"
+
+- hosts: localhost
+ gather_facts: no
+ tags:
+ - networking
+ tasks:
+ - name: test that task args aren't used for fqcn network facts
+ gather_facts:
+ gather_subset: min
+ vars:
+ ansible_network_os: 'cisco.ios.ios'
+ register: result
+
+ - assert:
+ that:
+ - "ansible_facts.gather_subset == '!config'"
+
+ - name: test that module_defaults are used for fqcn network facts
+ gather_facts:
+ vars:
+ ansible_network_os: 'cisco.ios.ios'
+ module_defaults:
+ 'cisco.ios.ios_facts': {'gather_subset': 'min'}
+ register: result
+
+ - assert:
+ that:
+ - "ansible_facts.gather_subset == 'min'"
+
+ - name: test that task args aren't used for legacy network facts
+ gather_facts:
+ gather_subset: min
+ vars:
+ ansible_network_os: 'ios'
+ register: result
+
+ - assert:
+ that:
+ - "ansible_facts.gather_subset == '!config'"
+
+ - name: test that module_defaults are used for legacy network facts
+ gather_facts:
+ vars:
+ ansible_network_os: 'ios'
+ module_defaults:
+ 'ios_facts': {'gather_subset': 'min'}
+ register: result
+
+ - assert:
+ that:
+ - "ansible_facts.gather_subset == 'min'"
diff --git a/test/integration/targets/gathering_facts/test_prevent_injection.yml b/test/integration/targets/gathering_facts/test_prevent_injection.yml
index f304fe88..064b7a90 100644
--- a/test/integration/targets/gathering_facts/test_prevent_injection.yml
+++ b/test/integration/targets/gathering_facts/test_prevent_injection.yml
@@ -5,7 +5,7 @@
- name: gather 'bad' facts
action: bogus_facts
- - name: ensure that the 'bad' facts didn't polute what they are not supposed to
+ - name: ensure that the 'bad' facts didn't pollute what they are not supposed to
assert:
that:
- "'touch' not in discovered_interpreter_python|default('')"
diff --git a/test/integration/targets/get_url/tasks/main.yml b/test/integration/targets/get_url/tasks/main.yml
index 32da1d51..b5a9c7e5 100644
--- a/test/integration/targets/get_url/tasks/main.yml
+++ b/test/integration/targets/get_url/tasks/main.yml
@@ -579,6 +579,35 @@
- '(result.content | b64decode) == "ansible.http.tests:SUCCESS"'
when: has_httptester
+- name: test unredirected_headers
+ get_url:
+ url: 'https://{{ httpbin_host }}/redirect-to?status_code=301&url=/basic-auth/user/passwd'
+ username: user
+ password: passwd
+ force_basic_auth: true
+ unredirected_headers:
+ - authorization
+ dest: "{{ remote_tmp_dir }}/doesnt_matter"
+ ignore_errors: true
+ register: unredirected_headers
+
+- name: test unredirected_headers
+ get_url:
+ url: 'https://{{ httpbin_host }}/redirect-to?status_code=301&url=/basic-auth/user/passwd'
+ username: user
+ password: passwd
+ force_basic_auth: true
+ dest: "{{ remote_tmp_dir }}/doesnt_matter"
+ register: redirected_headers
+
+- name: ensure unredirected_headers caused auth to fail
+ assert:
+ that:
+ - unredirected_headers is failed
+ - unredirected_headers.status_code == 401
+ - redirected_headers is successful
+ - redirected_headers.status_code == 200
+
- name: Test use_gssapi=True
include_tasks:
file: use_gssapi.yml
diff --git a/test/integration/targets/git/tasks/archive.yml b/test/integration/targets/git/tasks/archive.yml
index 574559ef..18b9dff3 100644
--- a/test/integration/targets/git/tasks/archive.yml
+++ b/test/integration/targets/git/tasks/archive.yml
@@ -119,6 +119,7 @@
unarchive:
src: '{{ checkout_dir }}/test_role.{{ item }}'
dest: '{{ checkout_dir }}/{{ git_archive_prefix }}.{{ item }}'
+ remote_src: yes
with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
- name: ARCHIVE | Check if prefix directory exists in what's extracted
diff --git a/test/integration/targets/git/tasks/main.yml b/test/integration/targets/git/tasks/main.yml
index c5aeacbe..ed06eab5 100644
--- a/test/integration/targets/git/tasks/main.yml
+++ b/test/integration/targets/git/tasks/main.yml
@@ -21,6 +21,7 @@
- import_tasks: formats.yml
- import_tasks: missing_hostkey.yml
+- import_tasks: missing_hostkey_acceptnew.yml
- import_tasks: no-destination.yml
- import_tasks: specific-revision.yml
- import_tasks: submodules.yml
diff --git a/test/integration/targets/git/tasks/missing_hostkey.yml b/test/integration/targets/git/tasks/missing_hostkey.yml
index 02d5be35..6e4d53c3 100644
--- a/test/integration/targets/git/tasks/missing_hostkey.yml
+++ b/test/integration/targets/git/tasks/missing_hostkey.yml
@@ -46,3 +46,16 @@
that:
- git_result is changed
when: github_ssh_private_key is defined
+
+- name: MISSING-HOSTEKY | Remove github.com hostkey from known_hosts
+ lineinfile:
+ dest: '{{ output_dir }}/known_hosts'
+ regexp: "github.com"
+ state: absent
+ when: github_ssh_private_key is defined
+
+- name: MISSING-HOSTKEY | clear checkout_dir
+ file:
+ state: absent
+ path: '{{ checkout_dir }}'
+ when: github_ssh_private_key is defined
diff --git a/test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml b/test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml
new file mode 100644
index 00000000..fb8bb063
--- /dev/null
+++ b/test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml
@@ -0,0 +1,78 @@
+- name: MISSING-HOSTKEY | check accept_newhostkey support
+ shell: ssh -o StrictHostKeyChecking=accept-new -V
+ register: ssh_supports_accept_newhostkey
+ ignore_errors: true
+
+- block:
+ - name: MISSING-HOSTKEY | accept_newhostkey when ssh does not support the option
+ git:
+ repo: '{{ repo_format2 }}'
+ dest: '{{ checkout_dir }}'
+ accept_newhostkey: true
+ ssh_opts: '-o UserKnownHostsFile={{ output_dir }}/known_hosts'
+ register: git_result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - git_result is failed
+ - git_result.warnings is search("does not support")
+
+ when: ssh_supports_accept_newhostkey.rc != 0
+
+- name: MISSING-HOSTKEY | checkout ssh://git@github.com repo without accept_newhostkey (expected fail)
+ git:
+ repo: '{{ repo_format2 }}'
+ dest: '{{ checkout_dir }}'
+ ssh_opts: '-o UserKnownHostsFile={{ output_dir }}/known_hosts'
+ register: git_result
+ ignore_errors: true
+
+- assert:
+ that:
+ - git_result is failed
+
+- block:
+ - name: MISSING-HOSTKEY | checkout git@github.com repo with accept_newhostkey (expected pass)
+ git:
+ repo: '{{ repo_format2 }}'
+ dest: '{{ checkout_dir }}'
+ accept_newhostkey: true
+ key_file: '{{ github_ssh_private_key }}'
+ ssh_opts: '-o UserKnownHostsFile={{ output_dir }}/known_hosts'
+ register: git_result
+
+ - assert:
+ that:
+ - git_result is changed
+
+ - name: MISSING-HOSTKEY | clear checkout_dir
+ file:
+ state: absent
+ path: '{{ checkout_dir }}'
+
+ - name: MISSING-HOSTKEY | checkout ssh://git@github.com repo with accept_newhostkey (expected pass)
+ git:
+ repo: '{{ repo_format3 }}'
+ dest: '{{ checkout_dir }}'
+ version: 'master'
+ accept_newhostkey: false # should already have been accepted
+ key_file: '{{ github_ssh_private_key }}'
+ ssh_opts: '-o UserKnownHostsFile={{ output_dir }}/known_hosts'
+ register: git_result
+
+ - assert:
+ that:
+ - git_result is changed
+
+ - name: MISSING-HOSTEKY | Remove github.com hostkey from known_hosts
+ lineinfile:
+ dest: '{{ output_dir }}/known_hosts'
+ regexp: "github.com"
+ state: absent
+
+ - name: MISSING-HOSTKEY | clear checkout_dir
+ file:
+ state: absent
+ path: '{{ checkout_dir }}'
+ when: github_ssh_private_key is defined and ssh_supports_accept_newhostkey.rc == 0
diff --git a/test/integration/targets/git/tasks/submodules.yml b/test/integration/targets/git/tasks/submodules.yml
index 647d1e23..0b311e79 100644
--- a/test/integration/targets/git/tasks/submodules.yml
+++ b/test/integration/targets/git/tasks/submodules.yml
@@ -122,3 +122,29 @@
- name: SUBMODULES | Enusre submodule2 is at the appropriate commit
assert:
that: '{{ submodule2.stdout_lines | length }} == 4'
+
+- name: SUBMODULES | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+
+- name: SUBMODULES | Clone main submodule repository
+ git:
+ repo: "{{ repo_submodules }}"
+ dest: "{{ checkout_dir }}/test.gitdir"
+ version: 45c6c07ef10fd9e453d90207e63da1ce5bd3ae1e
+ recursive: yes
+
+- name: SUBMODULES | Test that cloning submodule with .git in directory name works
+ git:
+ repo: "{{ repo_submodule1 }}"
+ dest: "{{ checkout_dir }}/test.gitdir/submodule1"
+
+- name: SUBMODULES | List submodule1
+ command: 'ls -1a {{ checkout_dir }}/test.gitdir/submodule1'
+ register: submodule1
+
+- name: SUBMODULES | Ensure submodule1 is at the appropriate commit
+ assert:
+ that: '{{ submodule1.stdout_lines | length }} == 4'
diff --git a/test/integration/targets/groupby_filter/aliases b/test/integration/targets/groupby_filter/aliases
index 31094c31..58201272 100644
--- a/test/integration/targets/groupby_filter/aliases
+++ b/test/integration/targets/groupby_filter/aliases
@@ -1,2 +1,3 @@
shippable/posix/group2
needs/file/test/lib/ansible_test/_data/requirements/constraints.txt
+context/controller
diff --git a/test/integration/targets/handler_race/aliases b/test/integration/targets/handler_race/aliases
index 68d6d978..1d28bdb2 100644
--- a/test/integration/targets/handler_race/aliases
+++ b/test/integration/targets/handler_race/aliases
@@ -1,3 +1,2 @@
shippable/posix/group5
-handler_race
-skip/aix
+context/controller
diff --git a/test/integration/targets/handlers/58841.yml b/test/integration/targets/handlers/58841.yml
new file mode 100644
index 00000000..eea5c2f3
--- /dev/null
+++ b/test/integration/targets/handlers/58841.yml
@@ -0,0 +1,9 @@
+---
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - include_role:
+ name: import_template_handler_names
+ tags:
+ - lazy_evaluation
+ - evaluation_time
diff --git a/test/integration/targets/handlers/aliases b/test/integration/targets/handlers/aliases
index 30bb677a..1d28bdb2 100644
--- a/test/integration/targets/handlers/aliases
+++ b/test/integration/targets/handlers/aliases
@@ -1,3 +1,2 @@
shippable/posix/group5
-handlers
-skip/aix
+context/controller
diff --git a/test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml b/test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml
new file mode 100644
index 00000000..3bc285e5
--- /dev/null
+++ b/test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml
@@ -0,0 +1,11 @@
+- import_role:
+ name: template_handler_names
+ tasks_from: lazy_evaluation
+ tags:
+ - lazy_evaluation
+
+- import_role:
+ name: template_handler_names
+ tasks_from: evaluation_time
+ tags:
+ - evaluation_time
diff --git a/test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml b/test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml
new file mode 100644
index 00000000..bf8ca851
--- /dev/null
+++ b/test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml
@@ -0,0 +1,5 @@
+- name: handler name with {{ test_var }}
+ debug: msg='handler with var ran'
+
+- name: handler name
+ debug: msg='handler ran'
diff --git a/test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml b/test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml
new file mode 100644
index 00000000..c0706fc5
--- /dev/null
+++ b/test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml
@@ -0,0 +1,5 @@
+- debug: msg='notify handler with variable in name'
+ notify: handler name with myvar
+ changed_when: True
+ tags:
+ - evaluation_time
diff --git a/test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml b/test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml
new file mode 100644
index 00000000..e82dca06
--- /dev/null
+++ b/test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml
@@ -0,0 +1,5 @@
+- debug: msg='notify handler'
+ notify: handler name
+ changed_when: True
+ tags:
+ - lazy_evaluation
diff --git a/test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml
index abe01be4..6c3b73c6 100644
--- a/test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml
+++ b/test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml
@@ -1 +1 @@
-- include: handlers.yml
+- import_tasks: handlers.yml
diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh
index cefa926b..7c403b4e 100755
--- a/test/integration/targets/handlers/runme.sh
+++ b/test/integration/targets/handlers/runme.sh
@@ -15,7 +15,7 @@ ansible-playbook from_handlers.yml -i inventory.handlers -v "$@" --tags scenario
ansible-playbook test_listening_handlers.yml -i inventory.handlers -v "$@"
[ "$(ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario2 -l A \
-| grep -E -o 'RUNNING HANDLER \[test_handlers : .*?]')" = "RUNNING HANDLER [test_handlers : test handler]" ]
+| grep -E -o 'RUNNING HANDLER \[test_handlers : .*]')" = "RUNNING HANDLER [test_handlers : test handler]" ]
# Test forcing handlers using the linear and free strategy
for strategy in linear free; do
@@ -55,13 +55,13 @@ for strategy in linear free; do
done
[ "$(ansible-playbook test_handlers_include.yml -i ../../inventory -v "$@" --tags playbook_include_handlers \
-| grep -E -o 'RUNNING HANDLER \[.*?]')" = "RUNNING HANDLER [test handler]" ]
+| grep -E -o 'RUNNING HANDLER \[.*]')" = "RUNNING HANDLER [test handler]" ]
[ "$(ansible-playbook test_handlers_include.yml -i ../../inventory -v "$@" --tags role_include_handlers \
-| grep -E -o 'RUNNING HANDLER \[test_handlers_include : .*?]')" = "RUNNING HANDLER [test_handlers_include : test handler]" ]
+| grep -E -o 'RUNNING HANDLER \[test_handlers_include : .*]')" = "RUNNING HANDLER [test_handlers_include : test handler]" ]
[ "$(ansible-playbook test_handlers_include_role.yml -i ../../inventory -v "$@" \
-| grep -E -o 'RUNNING HANDLER \[test_handlers_include_role : .*?]')" = "RUNNING HANDLER [test_handlers_include_role : test handler]" ]
+| grep -E -o 'RUNNING HANDLER \[test_handlers_include_role : .*]')" = "RUNNING HANDLER [test_handlers_include_role : test handler]" ]
# Notify handler listen
ansible-playbook test_handlers_listen.yml -i inventory.handlers -v "$@"
@@ -96,3 +96,21 @@ result="$(ansible-playbook test_handlers_template_run_once.yml -i inventory.hand
set -e
grep -q "handler A" <<< "$result"
grep -q "handler B" <<< "$result"
+
+# Test an undefined variable in another handler name isn't a failure
+ansible-playbook 58841.yml "$@" --tags lazy_evaluation 2>&1 | tee out.txt ; cat out.txt
+grep out.txt -e "\[WARNING\]: Handler 'handler name with {{ test_var }}' is unusable"
+[ "$(grep out.txt -ce 'handler ran')" = "1" ]
+[ "$(grep out.txt -ce 'handler with var ran')" = "0" ]
+
+# Test templating a handler name with a defined variable
+ansible-playbook 58841.yml "$@" --tags evaluation_time -e test_var=myvar | tee out.txt ; cat out.txt
+[ "$(grep out.txt -ce 'handler ran')" = "0" ]
+[ "$(grep out.txt -ce 'handler with var ran')" = "1" ]
+
+# Test the handler is not found when the variable is undefined
+ansible-playbook 58841.yml "$@" --tags evaluation_time 2>&1 | tee out.txt ; cat out.txt
+grep out.txt -e "ERROR! The requested handler 'handler name with myvar' was not found"
+grep out.txt -e "\[WARNING\]: Handler 'handler name with {{ test_var }}' is unusable"
+[ "$(grep out.txt -ce 'handler ran')" = "0" ]
+[ "$(grep out.txt -ce 'handler with var ran')" = "0" ]
diff --git a/test/integration/targets/handlers/test_handlers_include.yml b/test/integration/targets/handlers/test_handlers_include.yml
index 5514fc10..158266d2 100644
--- a/test/integration/targets/handlers/test_handlers_include.yml
+++ b/test/integration/targets/handlers/test_handlers_include.yml
@@ -6,7 +6,7 @@
notify: test handler
tags: ['playbook_include_handlers']
handlers:
- - include: handlers.yml
+ - import_tasks: handlers.yml
- name: verify that role can include handler
hosts: testhost
diff --git a/test/integration/targets/hardware_facts/aliases b/test/integration/targets/hardware_facts/aliases
index e00c22c3..3933d2e5 100644
--- a/test/integration/targets/hardware_facts/aliases
+++ b/test/integration/targets/hardware_facts/aliases
@@ -1,3 +1,4 @@
destructive
needs/privileged
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/hash/aliases b/test/integration/targets/hash/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/hash/aliases
+++ b/test/integration/targets/hash/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/hosts_field/aliases b/test/integration/targets/hosts_field/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/hosts_field/aliases
+++ b/test/integration/targets/hosts_field/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/ignore_errors/aliases b/test/integration/targets/ignore_errors/aliases
index 3005e4b2..498fedd5 100644
--- a/test/integration/targets/ignore_errors/aliases
+++ b/test/integration/targets/ignore_errors/aliases
@@ -1 +1,2 @@
shippable/posix/group4
+context/controller
diff --git a/test/integration/targets/ignore_unreachable/aliases b/test/integration/targets/ignore_unreachable/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/ignore_unreachable/aliases
+++ b/test/integration/targets/ignore_unreachable/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/import_tasks/aliases b/test/integration/targets/import_tasks/aliases
index fff62d9f..a1b27a83 100644
--- a/test/integration/targets/import_tasks/aliases
+++ b/test/integration/targets/import_tasks/aliases
@@ -1,2 +1,2 @@
shippable/posix/group5
-skip/aix
+context/controller # this is a controller-only action, the module is just for documentation
diff --git a/test/integration/targets/incidental_cloud_init_data_facts/aliases b/test/integration/targets/incidental_cloud_init_data_facts/aliases
index 85f7fe0f..544fcacd 100644
--- a/test/integration/targets/incidental_cloud_init_data_facts/aliases
+++ b/test/integration/targets/incidental_cloud_init_data_facts/aliases
@@ -4,3 +4,4 @@ skip/aix
skip/osx
skip/macos
skip/freebsd
+context/target
diff --git a/test/integration/targets/incidental_deploy_helper/aliases b/test/integration/targets/incidental_deploy_helper/aliases
index 31c6a8b4..3b88c806 100644
--- a/test/integration/targets/incidental_deploy_helper/aliases
+++ b/test/integration/targets/incidental_deploy_helper/aliases
@@ -1 +1,2 @@
shippable/posix/incidental
+context/target
diff --git a/test/integration/targets/incidental_inventory_aws_ec2/aliases b/test/integration/targets/incidental_inventory_aws_ec2/aliases
index 29f60feb..41a05d3c 100644
--- a/test/integration/targets/incidental_inventory_aws_ec2/aliases
+++ b/test/integration/targets/incidental_inventory_aws_ec2/aliases
@@ -1,2 +1,3 @@
cloud/aws
shippable/aws/incidental
+context/controller
diff --git a/test/integration/targets/incidental_inventory_aws_ec2/runme.sh b/test/integration/targets/incidental_inventory_aws_ec2/runme.sh
index 916f7e8f..339be5dd 100755
--- a/test/integration/targets/incidental_inventory_aws_ec2/runme.sh
+++ b/test/integration/targets/incidental_inventory_aws_ec2/runme.sh
@@ -2,6 +2,10 @@
set -eux
+source virtualenv.sh
+
+python -m pip install boto3 boto
+
# ensure test config is empty
ansible-playbook playbooks/empty_inventory_config.yml "$@"
diff --git a/test/integration/targets/incidental_inventory_docker_swarm/aliases b/test/integration/targets/incidental_inventory_docker_swarm/aliases
index c3a38c06..74d3befe 100644
--- a/test/integration/targets/incidental_inventory_docker_swarm/aliases
+++ b/test/integration/targets/incidental_inventory_docker_swarm/aliases
@@ -1,6 +1,5 @@
shippable/posix/incidental
-skip/aix
-skip/power/centos
+context/controller
skip/osx
skip/macos
skip/freebsd
diff --git a/test/integration/targets/incidental_inventory_foreman/aliases b/test/integration/targets/incidental_inventory_foreman/aliases
index c28a056e..7eaacbbc 100644
--- a/test/integration/targets/incidental_inventory_foreman/aliases
+++ b/test/integration/targets/incidental_inventory_foreman/aliases
@@ -1,3 +1,4 @@
shippable/cloud/incidental
cloud/foreman
destructive
+context/controller
diff --git a/test/integration/targets/incidental_inventory_foreman/inspect_cache.yml b/test/integration/targets/incidental_inventory_foreman/inspect_cache.yml
index c91f4c38..b9e32f7d 100644
--- a/test/integration/targets/incidental_inventory_foreman/inspect_cache.yml
+++ b/test/integration/targets/incidental_inventory_foreman/inspect_cache.yml
@@ -6,6 +6,10 @@
foreman_stub_api_path: /api/v2
cached_hosts_key: "http://{{ foreman_stub_host }}:{{ foreman_stub_port }}{{ foreman_stub_api_path }}/hosts"
tasks:
+ - name: make sure jmespath is installed
+ pip:
+ name: jmespath
+
- name: verify a cache file was created
find:
path:
diff --git a/test/integration/targets/incidental_inventory_foreman/runme.sh b/test/integration/targets/incidental_inventory_foreman/runme.sh
index ba94a936..d81fa02f 100755
--- a/test/integration/targets/incidental_inventory_foreman/runme.sh
+++ b/test/integration/targets/incidental_inventory_foreman/runme.sh
@@ -43,8 +43,8 @@ password: secure
validate_certs: False
FOREMAN_YAML
-ansible-playbook test_foreman_inventory.yml --connection=local "$@"
-ansible-playbook inspect_cache.yml --connection=local "$@"
+ansible-playbook test_foreman_inventory.yml --connection=local -e 'ansible_python_interpreter={{ ansible_playbook_python }}' "$@"
+ansible-playbook inspect_cache.yml --connection=local -e 'ansible_python_interpreter={{ ansible_playbook_python }}' "$@"
# remove inventory cache
rm -r ./foreman_cache
diff --git a/test/integration/targets/incidental_ios_file/tasks/cli.yaml b/test/integration/targets/incidental_ios_file/tasks/cli.yaml
index d4f663b3..3eb57691 100644
--- a/test/integration/targets/incidental_ios_file/tasks/cli.yaml
+++ b/test/integration/targets/incidental_ios_file/tasks/cli.yaml
@@ -10,7 +10,7 @@
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=ansible.netcommon.network_cli)
- include: "{{ test_case_to_run }}"
+ include_tasks: "{{ test_case_to_run }}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
diff --git a/test/integration/targets/incidental_ios_file/tasks/main.yaml b/test/integration/targets/incidental_ios_file/tasks/main.yaml
index 415c99d8..24ad94ae 100644
--- a/test/integration/targets/incidental_ios_file/tasks/main.yaml
+++ b/test/integration/targets/incidental_ios_file/tasks/main.yaml
@@ -1,2 +1,2 @@
---
-- { include: cli.yaml, tags: ['cli'] }
+- { import_tasks: cli.yaml, tags: ['cli'] }
diff --git a/test/integration/targets/incidental_mongodb_parameter/aliases b/test/integration/targets/incidental_mongodb_parameter/aliases
index dc285483..72ed62eb 100644
--- a/test/integration/targets/incidental_mongodb_parameter/aliases
+++ b/test/integration/targets/incidental_mongodb_parameter/aliases
@@ -6,3 +6,4 @@ skip/macos
skip/freebsd
skip/rhel
needs/root
+context/target
diff --git a/test/integration/targets/incidental_setup_docker/vars/RedHat-8.yml b/test/integration/targets/incidental_setup_docker/vars/RedHat-8.yml
index ff6dcf7b..82343898 100644
--- a/test/integration/targets/incidental_setup_docker/vars/RedHat-8.yml
+++ b/test/integration/targets/incidental_setup_docker/vars/RedHat-8.yml
@@ -3,6 +3,7 @@ docker_prereq_packages:
- device-mapper-persistent-data
- lvm2
- libseccomp
+ - iptables
docker_packages:
- docker-ce-19.03.13
diff --git a/test/integration/targets/incidental_vyos_config/tasks/cli.yaml b/test/integration/targets/incidental_vyos_config/tasks/cli.yaml
index 22a71d96..d601bb70 100644
--- a/test/integration/targets/incidental_vyos_config/tasks/cli.yaml
+++ b/test/integration/targets/incidental_vyos_config/tasks/cli.yaml
@@ -10,13 +10,17 @@
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test case (connection=ansible.netcommon.network_cli)
- include: "{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli"
+ include_tasks: "file={{ test_case_to_run }}"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
- name: run test case (connection=local)
- include: "{{ test_case_to_run }} ansible_connection=local"
+ include_tasks: "file={{ test_case_to_run }}"
+ vars:
+ ansible_connection: local
with_first_found: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
diff --git a/test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml b/test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml
index 8ed28748..7e673560 100644
--- a/test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml
+++ b/test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml
@@ -10,7 +10,9 @@
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test case (connection=ansible.netcommon.network_cli)
- include: "{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli"
+ include_tasks: "file={{ test_case_to_run }}"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
diff --git a/test/integration/targets/incidental_vyos_config/tasks/main.yaml b/test/integration/targets/incidental_vyos_config/tasks/main.yaml
index 13977a44..0d4e8fdd 100644
--- a/test/integration/targets/incidental_vyos_config/tasks/main.yaml
+++ b/test/integration/targets/incidental_vyos_config/tasks/main.yaml
@@ -1,3 +1,3 @@
---
-- {include: cli.yaml, tags: ['cli']}
-- {include: cli_config.yaml, tags: ['cli_config']}
+- {import_tasks: cli.yaml, tags: ['cli']}
+- {import_tasks: cli_config.yaml, tags: ['cli_config']}
diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml
index 83496e0e..c6923f3e 100644
--- a/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml
+++ b/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml
@@ -11,7 +11,7 @@
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: Run test case (connection=ansible.netcommon.network_cli)
- include: "{{ test_case_to_run }}"
+ include_tasks: "{{ test_case_to_run }}"
vars:
ansible_connection: ansible.netcommon.network_cli
with_items: "{{ test_items }}"
diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml
index d4cf26fc..a6d418bb 100644
--- a/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml
+++ b/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml
@@ -1,2 +1,2 @@
---
-- {include: cli.yaml, tags: ['cli']}
+- {import_tasks: cli.yaml, tags: ['cli']}
diff --git a/test/integration/targets/incidental_win_data_deduplication/tasks/main.yml b/test/integration/targets/incidental_win_data_deduplication/tasks/main.yml
index ae6be90e..83c7197c 100644
--- a/test/integration/targets/incidental_win_data_deduplication/tasks/main.yml
+++ b/test/integration/targets/incidental_win_data_deduplication/tasks/main.yml
@@ -1,2 +1,2 @@
---
-- include: pre_test.yml
+- import_tasks: pre_test.yml
diff --git a/test/integration/targets/incidental_win_data_deduplication/tasks/pre_test.yml b/test/integration/targets/incidental_win_data_deduplication/tasks/pre_test.yml
index f72955e4..0d1c3d50 100644
--- a/test/integration/targets/incidental_win_data_deduplication/tasks/pre_test.yml
+++ b/test/integration/targets/incidental_win_data_deduplication/tasks/pre_test.yml
@@ -34,7 +34,7 @@
- name: Run tests
block:
- - include: tests.yml
+ - import_tasks: tests.yml
always:
- name: Detach disk
win_command: diskpart.exe /s {{ remote_tmp_dir }}\partition_deletion_script.txt
diff --git a/test/integration/targets/incidental_win_security_policy/aliases b/test/integration/targets/incidental_win_security_policy/aliases
deleted file mode 100644
index a5fc90dc..00000000
--- a/test/integration/targets/incidental_win_security_policy/aliases
+++ /dev/null
@@ -1,2 +0,0 @@
-shippable/windows/incidental
-windows
diff --git a/test/integration/targets/incidental_win_security_policy/library/test_win_security_policy.ps1 b/test/integration/targets/incidental_win_security_policy/library/test_win_security_policy.ps1
deleted file mode 100644
index 5c83c1b5..00000000
--- a/test/integration/targets/incidental_win_security_policy/library/test_win_security_policy.ps1
+++ /dev/null
@@ -1,53 +0,0 @@
-#!powershell
-
-# WANT_JSON
-# POWERSHELL_COMMON
-
-# basic script to get the lsit of users in a particular right
-# this is quite complex to put as a simple script so this is
-# just a simple module
-
-$ErrorActionPreference = 'Stop'
-
-$params = Parse-Args $args -supports_check_mode $false
-$section = Get-AnsibleParam -obj $params -name "section" -type "str" -failifempty $true
-$key = Get-AnsibleParam -obj $params -name "key" -type "str" -failifempty $true
-
-$result = @{
- changed = $false
-}
-
-Function ConvertFrom-Ini($file_path) {
- $ini = @{}
- switch -Regex -File $file_path {
- "^\[(.+)\]" {
- $section = $matches[1]
- $ini.$section = @{}
- }
- "(.+?)\s*=(.*)" {
- $name = $matches[1].Trim()
- $value = $matches[2].Trim()
- if ($value -match "^\d+$") {
- $value = [int]$value
- } elseif ($value.StartsWith('"') -and $value.EndsWith('"')) {
- $value = $value.Substring(1, $value.Length - 2)
- }
-
- $ini.$section.$name = $value
- }
- }
-
- $ini
-}
-
-$secedit_ini_path = [IO.Path]::GetTempFileName()
-&SecEdit.exe /export /cfg $secedit_ini_path /quiet
-$secedit_ini = ConvertFrom-Ini -file_path $secedit_ini_path
-
-if ($secedit_ini.ContainsKey($section)) {
- $result.value = $secedit_ini.$section.$key
-} else {
- $result.value = $null
-}
-
-Exit-Json $result
diff --git a/test/integration/targets/incidental_win_security_policy/tasks/main.yml b/test/integration/targets/incidental_win_security_policy/tasks/main.yml
deleted file mode 100644
index 28fdb5ea..00000000
--- a/test/integration/targets/incidental_win_security_policy/tasks/main.yml
+++ /dev/null
@@ -1,41 +0,0 @@
----
-- name: get current entry for audit
- test_win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- register: before_value_audit
-
-- name: get current entry for guest
- test_win_security_policy:
- section: System Access
- key: NewGuestName
- register: before_value_guest
-
-- block:
- - name: set AuditSystemEvents entry before tests
- win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- value: 0
-
- - name: set NewGuestName entry before tests
- win_security_policy:
- section: System Access
- key: NewGuestName
- value: Guest
-
- - name: run tests
- include_tasks: tests.yml
-
- always:
- - name: reset entries for AuditSystemEvents
- win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- value: "{{before_value_audit.value}}"
-
- - name: reset entries for NewGuestName
- win_security_policy:
- section: System Access
- key: NewGuestName
- value: "{{before_value_guest.value}}"
diff --git a/test/integration/targets/incidental_win_security_policy/tasks/tests.yml b/test/integration/targets/incidental_win_security_policy/tasks/tests.yml
deleted file mode 100644
index 724b6010..00000000
--- a/test/integration/targets/incidental_win_security_policy/tasks/tests.yml
+++ /dev/null
@@ -1,186 +0,0 @@
----
-- name: fail with invalid section name
- win_security_policy:
- section: This is not a valid section
- key: KeyName
- value: 0
- register: fail_invalid_section
- failed_when: fail_invalid_section.msg != "The section 'This is not a valid section' does not exist in SecEdit.exe output ini"
-
-- name: fail with invalid key name
- win_security_policy:
- section: System Access
- key: InvalidKey
- value: 0
- register: fail_invalid_key
- failed_when: fail_invalid_key.msg != "The key 'InvalidKey' in section 'System Access' is not a valid key, cannot set this value"
-
-- name: change existing key check
- win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- value: 1
- register: change_existing_check
- check_mode: yes
-
-- name: get actual change existing key check
- test_win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- register: change_existing_actual_check
-
-- name: assert change existing key check
- assert:
- that:
- - change_existing_check is changed
- - change_existing_actual_check.value == 0
-
-- name: change existing key
- win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- value: 1
- register: change_existing
-
-- name: get actual change existing key
- test_win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- register: change_existing_actual
-
-- name: assert change existing key
- assert:
- that:
- - change_existing is changed
- - change_existing_actual.value == 1
-
-- name: change existing key again
- win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- value: 1
- register: change_existing_again
-
-- name: assert change existing key again
- assert:
- that:
- - change_existing_again is not changed
- - change_existing_again.value == 1
-
-- name: change existing key with string type
- win_security_policy:
- section: Event Audit
- key: AuditSystemEvents
- value: "1"
- register: change_existing_key_with_type
-
-- name: assert change existing key with string type
- assert:
- that:
- - change_existing_key_with_type is not changed
- - change_existing_key_with_type.value == "1"
-
-- name: change existing string key check
- win_security_policy:
- section: System Access
- key: NewGuestName
- value: New Guest
- register: change_existing_string_check
- check_mode: yes
-
-- name: get actual change existing string key check
- test_win_security_policy:
- section: System Access
- key: NewGuestName
- register: change_existing_string_actual_check
-
-- name: assert change existing string key check
- assert:
- that:
- - change_existing_string_check is changed
- - change_existing_string_actual_check.value == "Guest"
-
-- name: change existing string key
- win_security_policy:
- section: System Access
- key: NewGuestName
- value: New Guest
- register: change_existing_string
-
-- name: get actual change existing string key
- test_win_security_policy:
- section: System Access
- key: NewGuestName
- register: change_existing_string_actual
-
-- name: assert change existing string key
- assert:
- that:
- - change_existing_string is changed
- - change_existing_string_actual.value == "New Guest"
-
-- name: change existing string key again
- win_security_policy:
- section: System Access
- key: NewGuestName
- value: New Guest
- register: change_existing_string_again
-
-- name: assert change existing string key again
- assert:
- that:
- - change_existing_string_again is not changed
- - change_existing_string_again.value == "New Guest"
-
-- name: add policy setting
- win_security_policy:
- section: Privilege Rights
- # following key is empty by default
- key: SeCreateTokenPrivilege
- # add Guests
- value: '*S-1-5-32-546'
-
-- name: get actual policy setting
- test_win_security_policy:
- section: Privilege Rights
- key: SeCreateTokenPrivilege
- register: add_policy_setting_actual
-
-- name: assert add policy setting
- assert:
- that:
- - add_policy_setting_actual.value == '*S-1-5-32-546'
-
-- name: remove policy setting
- win_security_policy:
- section: Privilege Rights
- key: SeCreateTokenPrivilege
- value: ''
- diff: yes
- register: remove_policy_setting
-
-- name: get actual policy setting
- test_win_security_policy:
- section: Privilege Rights
- key: SeCreateTokenPrivilege
- register: remove_policy_setting_actual
-
-- name: assert remove policy setting
- assert:
- that:
- - remove_policy_setting is changed
- - remove_policy_setting.diff.prepared == "[Privilege Rights]\n-SeCreateTokenPrivilege = *S-1-5-32-546\n+SeCreateTokenPrivilege = "
- - remove_policy_setting_actual.value is none
-
-- name: remove policy setting again
- win_security_policy:
- section: Privilege Rights
- key: SeCreateTokenPrivilege
- value: ''
- register: remove_policy_setting_again
-
-- name: assert remove policy setting again
- assert:
- that:
- - remove_policy_setting_again is not changed
- - remove_policy_setting_again.value == ''
diff --git a/test/integration/targets/include_import/aliases b/test/integration/targets/include_import/aliases
index fff62d9f..1d28bdb2 100644
--- a/test/integration/targets/include_import/aliases
+++ b/test/integration/targets/include_import/aliases
@@ -1,2 +1,2 @@
shippable/posix/group5
-skip/aix
+context/controller
diff --git a/test/integration/targets/include_import/include_role_omit/playbook.yml b/test/integration/targets/include_import/include_role_omit/playbook.yml
new file mode 100644
index 00000000..a036906a
--- /dev/null
+++ b/test/integration/targets/include_import/include_role_omit/playbook.yml
@@ -0,0 +1,12 @@
+- hosts: localhost
+ gather_facts: false
+ vars:
+ include_role_omit: false
+ tasks:
+ - include_role:
+ name: foo
+ tasks_from: '{{ omit }}'
+
+ - assert:
+ that:
+ - include_role_omit is sameas(true)
diff --git a/test/integration/targets/include_import/include_role_omit/roles/foo/tasks/main.yml b/test/integration/targets/include_import/include_role_omit/roles/foo/tasks/main.yml
new file mode 100644
index 00000000..e27ca5b0
--- /dev/null
+++ b/test/integration/targets/include_import/include_role_omit/roles/foo/tasks/main.yml
@@ -0,0 +1,2 @@
+- set_fact:
+ include_role_omit: true
diff --git a/test/integration/targets/include_import/playbook/test_templated_filenames.yml b/test/integration/targets/include_import/playbook/test_templated_filenames.yml
new file mode 100644
index 00000000..2f78ab09
--- /dev/null
+++ b/test/integration/targets/include_import/playbook/test_templated_filenames.yml
@@ -0,0 +1,47 @@
+- name: test templating import_playbook with extra vars
+ import_playbook: "{{ pb }}"
+
+- name: test templating import_playbook with vars
+ import_playbook: "{{ test_var }}"
+ vars:
+ test_var: validate_templated_playbook.yml
+
+- name: test templating import_tasks
+ hosts: localhost
+ gather_facts: no
+ vars:
+ play_var: validate_templated_tasks.yml
+ tasks:
+ - name: test templating import_tasks with play vars
+ import_tasks: "{{ play_var }}"
+
+ - name: test templating import_tasks with task vars
+ import_tasks: "{{ task_var }}"
+ vars:
+ task_var: validate_templated_tasks.yml
+
+ - name: test templating import_tasks with extra vars
+ import_tasks: "{{ tasks }}"
+
+- name: test templating import_role from_files
+ hosts: localhost
+ gather_facts: no
+ vars:
+ play_var: templated.yml
+ tasks:
+ - name: test templating import_role tasks_from with play vars
+ import_role:
+ name: role1
+ tasks_from: "{{ play_var }}"
+
+ - name: test templating import_role tasks_from with task vars
+ import_role:
+ name: role1
+ tasks_from: "{{ task_var }}"
+ vars:
+ task_var: templated.yml
+
+ - name: test templating import_role tasks_from with extra vars
+ import_role:
+ name: role1
+ tasks_from: "{{ tasks_from }}"
diff --git a/test/integration/targets/include_import/playbook/validate_templated_playbook.yml b/test/integration/targets/include_import/playbook/validate_templated_playbook.yml
new file mode 100644
index 00000000..631ee9b4
--- /dev/null
+++ b/test/integration/targets/include_import/playbook/validate_templated_playbook.yml
@@ -0,0 +1,5 @@
+---
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - debug: msg="In imported playbook"
diff --git a/test/integration/targets/include_import/playbook/validate_templated_tasks.yml b/test/integration/targets/include_import/playbook/validate_templated_tasks.yml
new file mode 100644
index 00000000..16d682d1
--- /dev/null
+++ b/test/integration/targets/include_import/playbook/validate_templated_tasks.yml
@@ -0,0 +1 @@
+- debug: msg="In imported tasks"
diff --git a/test/integration/targets/include_import/roles/role1/tasks/templated.yml b/test/integration/targets/include_import/roles/role1/tasks/templated.yml
new file mode 100644
index 00000000..eb9a9976
--- /dev/null
+++ b/test/integration/targets/include_import/roles/role1/tasks/templated.yml
@@ -0,0 +1 @@
+- debug: msg="In imported role"
diff --git a/test/integration/targets/include_import/runme.sh b/test/integration/targets/include_import/runme.sh
index f2633032..7029ab6d 100755
--- a/test/integration/targets/include_import/runme.sh
+++ b/test/integration/targets/include_import/runme.sh
@@ -126,3 +126,12 @@ ANSIBLE_HOST_PATTERN_MISMATCH=error ansible-playbook empty_group_warning/playboo
ansible-playbook test_include_loop.yml "$@"
ansible-playbook test_include_loop_fqcn.yml "$@"
+
+ansible-playbook include_role_omit/playbook.yml "$@"
+
+# Test templating import_playbook, import_tasks, and import_role files
+ansible-playbook playbook/test_templated_filenames.yml -e "pb=validate_templated_playbook.yml tasks=validate_templated_tasks.yml tasks_from=templated.yml" "$@" | tee out.txt
+cat out.txt
+test "$(grep out.txt -ce 'In imported playbook')" = 2
+test "$(grep out.txt -ce 'In imported tasks')" = 3
+test "$(grep out.txt -ce 'In imported role')" = 3
diff --git a/test/integration/targets/include_import/undefined_var/playbook.yml b/test/integration/targets/include_import/undefined_var/playbook.yml
index 0584fa8a..6576d50a 100644
--- a/test/integration/targets/include_import/undefined_var/playbook.yml
+++ b/test/integration/targets/include_import/undefined_var/playbook.yml
@@ -26,8 +26,7 @@
- "_include_role_result is failed"
msg: "'include_role' did not evaluate it's attached condition and failed"
- - include: include_that_defines_var.yml
- static: yes
+ - import_tasks: include_that_defines_var.yml
when:
- "_undefined == 'yes'"
diff --git a/test/integration/targets/include_vars-ad-hoc/aliases b/test/integration/targets/include_vars-ad-hoc/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/include_vars-ad-hoc/aliases
+++ b/test/integration/targets/include_vars-ad-hoc/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/include_vars/tasks/main.yml b/test/integration/targets/include_vars/tasks/main.yml
index 799d7b26..db15ba3c 100644
--- a/test/integration/targets/include_vars/tasks/main.yml
+++ b/test/integration/targets/include_vars/tasks/main.yml
@@ -57,6 +57,8 @@
include_vars:
dir: vars
extensions: ['', 'yaml', 'yml', 'json']
+ ignore_files:
+ - no_auto_unsafe.yml
register: include_every_dir
- name: verify that the correct files have been loaded and overwrite based on alphabetical order
@@ -78,6 +80,7 @@
ignore_files:
- webapp.yml
- file_without_extension
+ - no_auto_unsafe.yml
register: include_without_webapp
- name: verify that the webapp.yml file was not included
@@ -162,3 +165,53 @@
that:
- "'my_custom_service' == service_name_fqcn"
- "'my_custom_service' == service_name_tmpl_fqcn"
+
+- name: Include a vars file with a hash variable
+ include_vars:
+ file: vars2/hashes/hash1.yml
+
+- name: Verify the hash variable
+ assert:
+ that:
+ - "{{ config | length }} == 3"
+ - "config.key0 == 0"
+ - "config.key1 == 0"
+ - "{{ config.key2 | length }} == 1"
+ - "config.key2.a == 21"
+
+- name: Include the second file to merge the hash variable
+ include_vars:
+ file: vars2/hashes/hash2.yml
+ hash_behaviour: merge
+
+- name: Verify that the hash is merged
+ assert:
+ that:
+ - "{{ config | length }} == 4"
+ - "config.key0 == 0"
+ - "config.key1 == 1"
+ - "{{ config.key2 | length }} == 2"
+ - "config.key2.a == 21"
+ - "config.key2.b == 22"
+ - "config.key3 == 3"
+
+- name: Include the second file again without hash_behaviour option
+ include_vars:
+ file: vars2/hashes/hash2.yml
+
+- name: Verify that the properties from the first file is cleared
+ assert:
+ that:
+ - "{{ config | length }} == 3"
+ - "config.key1 == 1"
+ - "{{ config.key2 | length }} == 1"
+ - "config.key2.b == 22"
+ - "config.key3 == 3"
+
+- include_vars:
+ file: no_auto_unsafe.yml
+ register: baz
+
+- assert:
+ that:
+ - baz.ansible_facts.foo|type_debug != "AnsibleUnsafeText"
diff --git a/test/integration/targets/include_vars/vars/no_auto_unsafe.yml b/test/integration/targets/include_vars/vars/no_auto_unsafe.yml
new file mode 100644
index 00000000..20e9ff3f
--- /dev/null
+++ b/test/integration/targets/include_vars/vars/no_auto_unsafe.yml
@@ -0,0 +1 @@
+foo: bar
diff --git a/test/integration/targets/include_vars/vars2/hashes/hash1.yml b/test/integration/targets/include_vars/vars2/hashes/hash1.yml
new file mode 100644
index 00000000..b0706f8f
--- /dev/null
+++ b/test/integration/targets/include_vars/vars2/hashes/hash1.yml
@@ -0,0 +1,5 @@
+---
+config:
+ key0: 0
+ key1: 0
+ key2: { a: 21 }
diff --git a/test/integration/targets/include_vars/vars2/hashes/hash2.yml b/test/integration/targets/include_vars/vars2/hashes/hash2.yml
new file mode 100644
index 00000000..1f2a9636
--- /dev/null
+++ b/test/integration/targets/include_vars/vars2/hashes/hash2.yml
@@ -0,0 +1,5 @@
+---
+config:
+ key1: 1
+ key2: { b: 22 }
+ key3: 3
diff --git a/test/integration/targets/include_when_parent_is_dynamic/aliases b/test/integration/targets/include_when_parent_is_dynamic/aliases
index 41c99f51..8278ec8b 100644
--- a/test/integration/targets/include_when_parent_is_dynamic/aliases
+++ b/test/integration/targets/include_when_parent_is_dynamic/aliases
@@ -1,2 +1,2 @@
shippable/posix/group3
-skip/python2.6 # include is controller only, and we no longer support Python 2.6 on the controller
+context/controller
diff --git a/test/integration/targets/include_when_parent_is_static/aliases b/test/integration/targets/include_when_parent_is_static/aliases
index 41c99f51..8278ec8b 100644
--- a/test/integration/targets/include_when_parent_is_static/aliases
+++ b/test/integration/targets/include_when_parent_is_static/aliases
@@ -1,2 +1,2 @@
shippable/posix/group3
-skip/python2.6 # include is controller only, and we no longer support Python 2.6 on the controller
+context/controller
diff --git a/test/integration/targets/includes/aliases b/test/integration/targets/includes/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/includes/aliases
+++ b/test/integration/targets/includes/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/includes/include_on_playbook_should_fail.yml b/test/integration/targets/includes/include_on_playbook_should_fail.yml
new file mode 100644
index 00000000..953459dc
--- /dev/null
+++ b/test/integration/targets/includes/include_on_playbook_should_fail.yml
@@ -0,0 +1 @@
+- include: test_includes3.yml
diff --git a/test/integration/targets/includes/roles/test_includes/tasks/branch_toplevel.yml b/test/integration/targets/includes/roles/test_includes/tasks/branch_toplevel.yml
index 62416705..30cd6f28 100644
--- a/test/integration/targets/includes/roles/test_includes/tasks/branch_toplevel.yml
+++ b/test/integration/targets/includes/roles/test_includes/tasks/branch_toplevel.yml
@@ -1,9 +1,11 @@
# 'canary2' used instead of 'canary', otherwise a "recursive loop detected in
# template string" occurs when both includes use static=yes
-- include: 'leaf_sublevel.yml canary2={{ canary }}'
- static: yes
+- import_tasks: leaf_sublevel.yml
+ vars:
+ canary2: '{{ canary }}'
when: 'nested_include_static|bool' # value for 'static' can not be a variable, hence use 'when'
-- include: 'leaf_sublevel.yml canary2={{ canary }}'
- static: no
+- include_tasks: leaf_sublevel.yml
+ vars:
+ canary2: '{{ canary }}'
when: 'not nested_include_static|bool'
diff --git a/test/integration/targets/includes/roles/test_includes/tasks/main.yml b/test/integration/targets/includes/roles/test_includes/tasks/main.yml
index 6fcac9eb..83ca468b 100644
--- a/test/integration/targets/includes/roles/test_includes/tasks/main.yml
+++ b/test/integration/targets/includes/roles/test_includes/tasks/main.yml
@@ -81,26 +81,34 @@
- included_handler
- verify_handler
-- include: branch_toplevel.yml canary=value1 nested_include_static=no
- static: no
+- include_tasks: branch_toplevel.yml
+ vars:
+ canary: value1
+ nested_include_static: 'no'
- assert:
that:
- 'canary_fact == "value1"'
-- include: branch_toplevel.yml canary=value2 nested_include_static=yes
- static: no
+- include_tasks: branch_toplevel.yml
+ vars:
+ canary: value2
+ nested_include_static: 'yes'
- assert:
that:
- 'canary_fact == "value2"'
-- include: branch_toplevel.yml canary=value3 nested_include_static=no
- static: yes
+- import_tasks: branch_toplevel.yml
+ vars:
+ canary: value3
+ nested_include_static: 'no'
- assert:
that:
- 'canary_fact == "value3"'
-- include: branch_toplevel.yml canary=value4 nested_include_static=yes
- static: yes
+- import_tasks: branch_toplevel.yml
+ vars:
+ canary: value4
+ nested_include_static: 'yes'
- assert:
that:
- 'canary_fact == "value4"'
diff --git a/test/integration/targets/includes/runme.sh b/test/integration/targets/includes/runme.sh
index 70ff105b..f4f0a016 100755
--- a/test/integration/targets/includes/runme.sh
+++ b/test/integration/targets/includes/runme.sh
@@ -5,3 +5,9 @@ set -eux
ansible-playbook test_includes.yml -i ../../inventory "$@"
ansible-playbook inherit_notify.yml "$@"
+
+echo "EXPECTED ERROR: Ensure we fail if using 'include' to include a playbook."
+set +e
+result="$(ansible-playbook -i ../../inventory include_on_playbook_should_fail.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! 'include' is not a valid attribute for a Play" <<< "$result"
diff --git a/test/integration/targets/includes/test_includes.yml b/test/integration/targets/includes/test_includes.yml
index 0bcebd4f..adeb80d2 100644
--- a/test/integration/targets/includes/test_includes.yml
+++ b/test/integration/targets/includes/test_includes.yml
@@ -1,7 +1,7 @@
-- include: test_includes2.yml parameter1=asdf parameter2=jkl
+- import_playbook: test_includes2.yml parameter1=asdf parameter2=jkl
-- include: test_includes3.yml
+- import_playbook: test_includes3.yml
-- include: test_include_free.yml
+- import_playbook: test_include_free.yml
-- include: test_include_host_pinned.yml
+- import_playbook: test_include_host_pinned.yml
diff --git a/test/integration/targets/includes_race/aliases b/test/integration/targets/includes_race/aliases
index fff62d9f..1d28bdb2 100644
--- a/test/integration/targets/includes_race/aliases
+++ b/test/integration/targets/includes_race/aliases
@@ -1,2 +1,2 @@
shippable/posix/group5
-skip/aix
+context/controller
diff --git a/test/integration/targets/infra/aliases b/test/integration/targets/infra/aliases
index 887d7029..71103238 100644
--- a/test/integration/targets/infra/aliases
+++ b/test/integration/targets/infra/aliases
@@ -1,3 +1,4 @@
shippable/posix/group3
needs/file/hacking/test-module.py
needs/file/lib/ansible/modules/ping.py
+context/controller
diff --git a/test/integration/targets/infra/runme.sh b/test/integration/targets/infra/runme.sh
index c4d84572..9e348b8c 100755
--- a/test/integration/targets/infra/runme.sh
+++ b/test/integration/targets/infra/runme.sh
@@ -30,10 +30,10 @@ PING_MODULE_PATH="../../../../lib/ansible/modules/ping.py"
../../../../hacking/test-module.py -m "$PING_MODULE_PATH"
# ensure test-module.py script works well
-../../../../hacking/test-module.py -m "$PING_MODULE_PATH" -I ansible_python_interpreter="$(which python)"
+../../../../hacking/test-module.py -m "$PING_MODULE_PATH" -I ansible_python_interpreter="${ANSIBLE_TEST_PYTHON_INTERPRETER}"
# ensure module.ansible_version is defined when using test-module.py
-../../../../hacking/test-module.py -m library/test.py -I ansible_python_interpreter="$(which python)" <<< '{"ANSIBLE_MODULE_ARGS": {}}'
+../../../../hacking/test-module.py -m library/test.py -I ansible_python_interpreter="${ANSIBLE_TEST_PYTHON_INTERPRETER}" <<< '{"ANSIBLE_MODULE_ARGS": {}}'
# ensure exercising module code locally works
python -m ansible.modules.file <<< '{"ANSIBLE_MODULE_ARGS": {"path": "/path/to/file", "state": "absent"}}'
diff --git a/test/integration/targets/interpreter_discovery_python/aliases b/test/integration/targets/interpreter_discovery_python/aliases
index 740ed1a5..0dfc90e7 100644
--- a/test/integration/targets/interpreter_discovery_python/aliases
+++ b/test/integration/targets/interpreter_discovery_python/aliases
@@ -1,2 +1,3 @@
shippable/posix/group1
non_local # workaround to allow override of ansible_python_interpreter; disables coverage on this integration target
+context/target
diff --git a/test/integration/targets/interpreter_discovery_python/tasks/main.yml b/test/integration/targets/interpreter_discovery_python/tasks/main.yml
index b8bafd15..770de0c5 100644
--- a/test/integration/targets/interpreter_discovery_python/tasks/main.yml
+++ b/test/integration/targets/interpreter_discovery_python/tasks/main.yml
@@ -76,10 +76,10 @@
ping:
register: legacy
- - name: check for dep warning (only on platforms where auto result is not /usr/bin/python and legacy is)
+ - name: check for warning (only on platforms where auto result is not /usr/bin/python and legacy is)
assert:
that:
- - legacy.deprecations | default([]) | length > 0
+ - legacy.warnings | default([]) | length > 0
# only check for a dep warning if legacy returned /usr/bin/python and auto didn't
when: legacy.ansible_facts.discovered_interpreter_python == '/usr/bin/python' and
auto_out.ansible_facts.discovered_interpreter_python != '/usr/bin/python'
diff --git a/test/integration/targets/interpreter_discovery_python_delegate_facts/aliases b/test/integration/targets/interpreter_discovery_python_delegate_facts/aliases
index dc9ac468..b4026b5f 100644
--- a/test/integration/targets/interpreter_discovery_python_delegate_facts/aliases
+++ b/test/integration/targets/interpreter_discovery_python_delegate_facts/aliases
@@ -1,2 +1,3 @@
shippable/posix/group1
non_local # this test requires interpreter discovery, which means code coverage must be disabled
+context/controller
diff --git a/test/integration/targets/inventory/aliases b/test/integration/targets/inventory/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/inventory/aliases
+++ b/test/integration/targets/inventory/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/module_utils_respawn/aliases b/test/integration/targets/inventory_advanced_host_list/aliases
index a6dafcf8..a6dafcf8 100644
--- a/test/integration/targets/module_utils_respawn/aliases
+++ b/test/integration/targets/inventory_advanced_host_list/aliases
diff --git a/test/integration/targets/inventory_advanced_host_list/runme.sh b/test/integration/targets/inventory_advanced_host_list/runme.sh
new file mode 100755
index 00000000..41b1f8b9
--- /dev/null
+++ b/test/integration/targets/inventory_advanced_host_list/runme.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+set -eux
+
+export ANSIBLE_INVENTORY_ENABLED=advanced_host_list
+
+# A few things to make it easier to grep against adhoc
+export ANSIBLE_LOAD_CALLBACK_PLUGINS=True
+export ANSIBLE_STDOUT_CALLBACK=oneline
+
+adhoc="$(ansible -i 'local[0:10],' -m ping --connection=local -e ansible_python_interpreter="{{ ansible_playbook_python }}" all -v)"
+
+for i in $(seq 0 10); do
+ grep -qE "local${i} \| SUCCESS.*\"ping\": \"pong\"" <<< "$adhoc"
+done
+
+set +e
+parse_fail="$(ansible -i 'local[1:j],' -m ping --connection=local all -v 2>&1)"
+set -e
+
+grep -q "Failed to parse local\[1:j\], with advanced_host_list" <<< "$parse_fail"
+
+# Intentionally missing comma, ensure we don't fatal.
+no_comma="$(ansible -i 'local[1:5]' -m ping --connection=local all -v 2>&1)"
+grep -q "No inventory was parsed" <<< "$no_comma"
+
+# Intentionally botched range (missing end number), ensure we don't fatal.
+no_end="$(ansible -i 'local[1:],' -m ping --connection=local -e ansible_python_interpreter="{{ ansible_playbook_python }}" all -vvv 2>&1)"
+grep -q "Unable to parse address from hostname, leaving unchanged:" <<< "$no_end"
+grep -q "host range must specify end value" <<< "$no_end"
+grep -q "local\[3:\] \| SUCCESS" <<< "$no_end"
+
+# Unset adhoc stuff
+unset ANSIBLE_LOAD_CALLBACK_PLUGINS ANSIBLE_STDOUT_CALLBACK
+
+ansible-playbook -i 'local100,local[100:110:2]' test_advanced_host_list.yml -v "$@"
diff --git a/test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml b/test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml
new file mode 100644
index 00000000..918078ae
--- /dev/null
+++ b/test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml
@@ -0,0 +1,9 @@
+- hosts: all
+ connection: local
+ vars:
+ ansible_python_interpreter: "{{ ansible_playbook_python }}"
+ tasks:
+ - assert:
+ that:
+ - inventory_hostname in ["local100", "local102", "local104", "local106", "local108", "local110", "local118"]
+ - inventory_hostname not in ["local101", "local103", "local105", "local107", "local109", "local111"]
diff --git a/test/integration/targets/inventory_cache/aliases b/test/integration/targets/inventory_cache/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/inventory_cache/aliases
+++ b/test/integration/targets/inventory_cache/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/inventory_constructed/keyed_group_default_value.yml b/test/integration/targets/inventory_constructed/keyed_group_default_value.yml
new file mode 100644
index 00000000..e4d0a76b
--- /dev/null
+++ b/test/integration/targets/inventory_constructed/keyed_group_default_value.yml
@@ -0,0 +1,5 @@
+plugin: constructed
+keyed_groups:
+ - key: tags
+ prefix: tag
+ default_value: "running"
diff --git a/test/integration/targets/inventory_constructed/keyed_group_list_default_value.yml b/test/integration/targets/inventory_constructed/keyed_group_list_default_value.yml
new file mode 100644
index 00000000..1c2d00e0
--- /dev/null
+++ b/test/integration/targets/inventory_constructed/keyed_group_list_default_value.yml
@@ -0,0 +1,5 @@
+plugin: constructed
+keyed_groups:
+ - key: roles
+ default_value: storage
+ prefix: host \ No newline at end of file
diff --git a/test/integration/targets/inventory_constructed/keyed_group_str_default_value.yml b/test/integration/targets/inventory_constructed/keyed_group_str_default_value.yml
new file mode 100644
index 00000000..ae3fd5ae
--- /dev/null
+++ b/test/integration/targets/inventory_constructed/keyed_group_str_default_value.yml
@@ -0,0 +1,5 @@
+plugin: constructed
+keyed_groups:
+ - key: os
+ default_value: "fedora"
+ prefix: host \ No newline at end of file
diff --git a/test/integration/targets/inventory_constructed/keyed_group_trailing_separator.yml b/test/integration/targets/inventory_constructed/keyed_group_trailing_separator.yml
new file mode 100644
index 00000000..cbe57c60
--- /dev/null
+++ b/test/integration/targets/inventory_constructed/keyed_group_trailing_separator.yml
@@ -0,0 +1,5 @@
+plugin: constructed
+keyed_groups:
+ - key: tags
+ prefix: tag
+ trailing_separator: False
diff --git a/test/integration/targets/inventory_constructed/runme.sh b/test/integration/targets/inventory_constructed/runme.sh
index 0cd1a293..91bbd66b 100755
--- a/test/integration/targets/inventory_constructed/runme.sh
+++ b/test/integration/targets/inventory_constructed/runme.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-set -ex
+set -eux
ansible-inventory -i static_inventory.yml -i constructed.yml --graph | tee out.txt
@@ -24,6 +24,33 @@ grep '@prefix_hostvalue1' out.txt
grep '@prefix_item0' out.txt
grep '@prefix_key0_value0' out.txt
+# keyed group with default value for key's value empty (dict)
+ansible-inventory -i tag_inventory.yml -i keyed_group_default_value.yml --graph | tee out.txt
+
+grep '@tag_name_host0' out.txt
+grep '@tag_environment_test' out.txt
+grep '@tag_status_running' out.txt
+
+# keyed group with default value for key's value empty (list)
+ansible-inventory -i tag_inventory.yml -i keyed_group_list_default_value.yml --graph | tee out.txt
+
+grep '@host_db' out.txt
+grep '@host_web' out.txt
+grep '@host_storage' out.txt
+
+# keyed group with default value for key's value empty (str)
+ansible-inventory -i tag_inventory.yml -i keyed_group_str_default_value.yml --graph | tee out.txt
+
+grep '@host_fedora' out.txt
+
+
+# keyed group with 'trailing_separator' set to 'False' for key's value empty
+ansible-inventory -i tag_inventory.yml -i keyed_group_trailing_separator.yml --graph | tee out.txt
+
+grep '@tag_name_host0' out.txt
+grep '@tag_environment_test' out.txt
+grep '@tag_status' out.txt
+
# test using use_vars_plugins
ansible-inventory -i invs/1/one.yml -i invs/2/constructed.yml --graph | tee out.txt
diff --git a/test/integration/targets/inventory_constructed/tag_inventory.yml b/test/integration/targets/inventory_constructed/tag_inventory.yml
new file mode 100644
index 00000000..acf810ea
--- /dev/null
+++ b/test/integration/targets/inventory_constructed/tag_inventory.yml
@@ -0,0 +1,12 @@
+all:
+ hosts:
+ host0:
+ tags:
+ name: "host0"
+ environment: "test"
+ status: ""
+ os: ""
+ roles:
+ - db
+ - web
+ - ""
diff --git a/test/integration/targets/inventory_yaml/aliases b/test/integration/targets/inventory_yaml/aliases
index f8e28c7e..a6dafcf8 100644
--- a/test/integration/targets/inventory_yaml/aliases
+++ b/test/integration/targets/inventory_yaml/aliases
@@ -1,2 +1 @@
shippable/posix/group1
-skip/aix
diff --git a/test/integration/targets/jinja2_native_types/aliases b/test/integration/targets/jinja2_native_types/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/jinja2_native_types/aliases
+++ b/test/integration/targets/jinja2_native_types/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/jinja_plugins/aliases b/test/integration/targets/jinja_plugins/aliases
new file mode 100644
index 00000000..1d28bdb2
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter.py b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter.py
new file mode 100644
index 00000000..36669532
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class FilterModule:
+ def filters(self):
+ raise TypeError('bad_collection_filter')
diff --git a/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/good_collection_filter.py b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/good_collection_filter.py
new file mode 100644
index 00000000..e2e7ffcd
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/good_collection_filter.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class FilterModule:
+ def filters(self):
+ return {
+ 'hello': lambda x: 'Hello, %s!' % x,
+ }
diff --git a/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/bad_collection_test.py b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/bad_collection_test.py
new file mode 100644
index 00000000..9fce5581
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/bad_collection_test.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class TestModule:
+ def tests(self):
+ raise TypeError('bad_collection_test')
diff --git a/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/good_collection_test.py b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/good_collection_test.py
new file mode 100644
index 00000000..a4ca2ff2
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/good_collection_test.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class TestModule:
+ def tests(self):
+ return {
+ 'world': lambda x: x.lower() == 'world',
+ }
diff --git a/test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py b/test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py
new file mode 100644
index 00000000..eebf39c9
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class FilterModule:
+ def filters(self):
+ raise TypeError('bad_filter')
diff --git a/test/integration/targets/jinja_plugins/filter_plugins/good_filter.py b/test/integration/targets/jinja_plugins/filter_plugins/good_filter.py
new file mode 100644
index 00000000..e2e7ffcd
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/filter_plugins/good_filter.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class FilterModule:
+ def filters(self):
+ return {
+ 'hello': lambda x: 'Hello, %s!' % x,
+ }
diff --git a/test/integration/targets/jinja_plugins/playbook.yml b/test/integration/targets/jinja_plugins/playbook.yml
new file mode 100644
index 00000000..789be659
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/playbook.yml
@@ -0,0 +1,10 @@
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - assert:
+ that:
+ - '"World"|hello == "Hello, World!"'
+ - '"World" is world'
+
+ - '"World"|foo.bar.hello == "Hello, World!"'
+ - '"World" is foo.bar.world'
diff --git a/test/integration/targets/jinja_plugins/tasks/main.yml b/test/integration/targets/jinja_plugins/tasks/main.yml
new file mode 100644
index 00000000..012ec954
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/tasks/main.yml
@@ -0,0 +1,22 @@
+- shell: ansible-playbook {{ verbosity }} playbook.yml
+ args:
+ chdir: '{{ role_path }}'
+ vars:
+ verbosity: "{{ '' if not ansible_verbosity else '-' ~ ('v' * ansible_verbosity) }}"
+ register: result
+
+- debug:
+ var: result
+
+- assert:
+ that:
+ - '"[WARNING]: Skipping filter plugin" in result.stderr'
+ - '"[WARNING]: Skipping test plugin" in result.stderr'
+ - |
+ result.stderr|regex_findall('bad_filter')|length == 2
+ - |
+ result.stderr|regex_findall('bad_test')|length == 2
+ - |
+ result.stderr|regex_findall('bad_collection_filter')|length == 2
+ - |
+ result.stderr|regex_findall('bad_collection_test')|length == 2
diff --git a/test/integration/targets/jinja_plugins/test_plugins/bad_test.py b/test/integration/targets/jinja_plugins/test_plugins/bad_test.py
new file mode 100644
index 00000000..0cc7a5a8
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/test_plugins/bad_test.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class TestModule:
+ def tests(self):
+ raise TypeError('bad_test')
diff --git a/test/integration/targets/jinja_plugins/test_plugins/good_test.py b/test/integration/targets/jinja_plugins/test_plugins/good_test.py
new file mode 100644
index 00000000..a4ca2ff2
--- /dev/null
+++ b/test/integration/targets/jinja_plugins/test_plugins/good_test.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2021 Matt Martz <matt@sivel.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class TestModule:
+ def tests(self):
+ return {
+ 'world': lambda x: x.lower() == 'world',
+ }
diff --git a/test/integration/targets/json_cleanup/aliases b/test/integration/targets/json_cleanup/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/json_cleanup/aliases
+++ b/test/integration/targets/json_cleanup/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/limit_inventory/aliases b/test/integration/targets/limit_inventory/aliases
index 3005e4b2..498fedd5 100644
--- a/test/integration/targets/limit_inventory/aliases
+++ b/test/integration/targets/limit_inventory/aliases
@@ -1 +1,2 @@
shippable/posix/group4
+context/controller
diff --git a/test/integration/targets/lineinfile/meta/main.yml b/test/integration/targets/lineinfile/meta/main.yml
index 98e60f78..a91e6847 100644
--- a/test/integration/targets/lineinfile/meta/main.yml
+++ b/test/integration/targets/lineinfile/meta/main.yml
@@ -18,3 +18,4 @@
dependencies:
- prepare_tests
+ - setup_remote_tmp_dir
diff --git a/test/integration/targets/lineinfile/tasks/main.yml b/test/integration/targets/lineinfile/tasks/main.yml
index cad926b3..3d4678c2 100644
--- a/test/integration/targets/lineinfile/tasks/main.yml
+++ b/test/integration/targets/lineinfile/tasks/main.yml
@@ -19,7 +19,7 @@
- name: deploy the test file for lineinfile
copy:
src: test.txt
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert that the test file was deployed
@@ -29,9 +29,62 @@
- "result.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51'"
- "result.state == 'file'"
+- name: "create a file that does not yet exist with `create: yes` and produce diff"
+ lineinfile:
+ dest: "{{ remote_tmp_dir }}/a/a.txt"
+ state: present
+ line: "First line"
+ create: yes
+ diff: yes
+ register: result1
+
+- name: assert that a diff was returned
+ assert:
+ that:
+ - result1.diff | length > 0
+
+- name: stat the new file
+ stat:
+ path: "{{ remote_tmp_dir }}/a/a.txt"
+ register: result
+
+- name: assert that the file exists
+ assert:
+ that:
+ - result.stat.exists
+
+- block:
+ - name: "EXPECTED FAILURE - test source file does not exist w/o `create: yes`"
+ lineinfile:
+ path: "/some/where/that/doesnotexist.txt"
+ state: present
+ line: "Doesn't matter"
+ - fail:
+ msg: "Should not get here"
+ rescue:
+ - name: Validate failure
+ assert:
+ that:
+ - "'Destination /some/where/that/doesnotexist.txt does not exist !' in ansible_failed_result.msg"
+
+- block:
+ - name: EXPECTED FAILURE - test invalid `validate` value
+ lineinfile:
+ path: "{{ remote_tmp_dir }}/test.txt"
+ state: present
+ line: "Doesn't matter"
+ validate: '/some/path'
+ - fail:
+ msg: "Should not get here"
+ rescue:
+ - name: Validate failure
+ assert:
+ that:
+ - "'validate must contain %s: /some/path' in ansible_failed_result.msg"
+
- name: insert a line at the beginning of the file, and back it up
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "New line at the beginning"
insertbefore: "BOF"
@@ -40,7 +93,7 @@
- name: insert a line at the beginning of the file again
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "New line at the beginning"
insertbefore: "BOF"
@@ -66,7 +119,7 @@
- name: stat the test after the insert at the head
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test hash is what we expect for the file with the insert at the head
@@ -76,7 +129,7 @@
- name: insert a line at the end of the file
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "New line at the end"
insertafter: "EOF"
@@ -90,7 +143,7 @@
- name: stat the test after the insert at the end
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after the insert at the end
@@ -100,7 +153,7 @@
- name: insert a line after the first line
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "New line after line 1"
insertafter: "^This is line 1$"
@@ -114,7 +167,7 @@
- name: stat the test after insert after the first line
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after the insert after the first line
@@ -124,7 +177,7 @@
- name: insert a line before the last line
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "New line before line 5"
insertbefore: "^This is line 5$"
@@ -138,7 +191,7 @@
- name: stat the test after the insert before the last line
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after the insert before the last line
@@ -148,7 +201,7 @@
- name: Replace a line with backrefs
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "This is line 3"
backrefs: yes
@@ -157,13 +210,13 @@
- name: Replace a line with backrefs again
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "This is line 3"
backrefs: yes
regexp: "^(REF) .* \\1$"
register: backrefs_result2
-- command: cat {{ output_dir }}/test.txt
+- command: cat {{ remote_tmp_dir }}/test.txt
- name: assert that the line with backrefs was changed
assert:
@@ -174,7 +227,7 @@
- name: stat the test after the backref line was replaced
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after backref line was replaced
@@ -184,7 +237,7 @@
- name: remove the middle line
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: absent
regexp: "^This is line 3$"
register: result
@@ -197,7 +250,7 @@
- name: stat the test after the middle line was removed
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after the middle line was removed
@@ -207,7 +260,7 @@
- name: run a validation script that succeeds
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: absent
regexp: "^This is line 5$"
validate: "true %s"
@@ -221,7 +274,7 @@
- name: stat the test after the validation succeeded
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after the validation succeeded
@@ -231,7 +284,7 @@
- name: run a validation script that fails
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: absent
regexp: "^This is line 1$"
validate: "/bin/false %s"
@@ -245,7 +298,7 @@
- name: stat the test after the validation failed
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches the previous after the validation failed
@@ -257,7 +310,7 @@
- name: use create=yes
lineinfile:
- dest: "{{ output_dir }}/new_test.txt"
+ dest: "{{ remote_tmp_dir }}/new_test.txt"
create: yes
insertbefore: BOF
state: present
@@ -272,7 +325,7 @@
- name: validate that the newly created file exists
stat:
- path: "{{ output_dir }}/new_test.txt"
+ path: "{{ remote_tmp_dir }}/new_test.txt"
register: result
ignore_errors: yes
@@ -303,12 +356,12 @@
- name: testnoeof deploy the file for lineinfile
copy:
src: testnoeof.txt
- dest: "{{ output_dir }}/testnoeof.txt"
+ dest: "{{ remote_tmp_dir }}/testnoeof.txt"
register: result
- name: testnoeof insert a line at the end of the file
lineinfile:
- dest: "{{ output_dir }}/testnoeof.txt"
+ dest: "{{ remote_tmp_dir }}/testnoeof.txt"
state: present
line: "New line at the end"
insertafter: "EOF"
@@ -322,7 +375,7 @@
- name: insert a multiple lines at the end of the file
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "This is a line\nwith \\n character"
insertafter: "EOF"
@@ -336,7 +389,7 @@
- name: testnoeof stat the no newline EOF test after the insert at the end
stat:
- path: "{{ output_dir }}/testnoeof.txt"
+ path: "{{ remote_tmp_dir }}/testnoeof.txt"
register: result
- name: testnoeof assert test checksum matches after the insert at the end
@@ -348,12 +401,12 @@
- name: testempty deploy the testempty file for lineinfile
copy:
src: testempty.txt
- dest: "{{ output_dir }}/testempty.txt"
+ dest: "{{ remote_tmp_dir }}/testempty.txt"
register: result
- name: testempty insert a line at the end of the file
lineinfile:
- dest: "{{ output_dir }}/testempty.txt"
+ dest: "{{ remote_tmp_dir }}/testempty.txt"
state: present
line: "New line at the end"
insertafter: "EOF"
@@ -367,7 +420,7 @@
- name: testempty stat the test after the insert at the end
stat:
- path: "{{ output_dir }}/testempty.txt"
+ path: "{{ remote_tmp_dir }}/testempty.txt"
register: result
- name: testempty assert test checksum matches after the insert at the end
@@ -376,7 +429,7 @@
- "result.stat.checksum == 'f440dc65ea9cec3fd496c1479ddf937e1b949412'"
- stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after inserting multiple lines
@@ -386,7 +439,7 @@
- name: replace a line with backrefs included in the line
lineinfile:
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
state: present
line: "New \\1 created with the backref"
backrefs: yes
@@ -401,7 +454,7 @@
- name: stat the test after the backref line was replaced
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: assert test checksum matches after backref line was replaced
@@ -414,7 +467,7 @@
- name: create a new file for testing quoting issues
file:
- dest: "{{ output_dir }}/test_quoting.txt"
+ dest: "{{ remote_tmp_dir }}/test_quoting.txt"
state: touch
register: result
@@ -425,7 +478,7 @@
- name: use with_items to add code-like strings to the quoting txt file
lineinfile:
- dest: "{{ output_dir }}/test_quoting.txt"
+ dest: "{{ remote_tmp_dir }}/test_quoting.txt"
line: "{{ item }}"
insertbefore: BOF
with_items:
@@ -447,7 +500,7 @@
- name: stat the quote test file
stat:
- path: "{{ output_dir }}/test_quoting.txt"
+ path: "{{ remote_tmp_dir }}/test_quoting.txt"
register: result
- name: assert test checksum matches after backref line was replaced
@@ -457,7 +510,7 @@
- name: insert a line into the quoted file with a single quote
lineinfile:
- dest: "{{ output_dir }}/test_quoting.txt"
+ dest: "{{ remote_tmp_dir }}/test_quoting.txt"
line: "import g'"
register: result
@@ -468,7 +521,7 @@
- name: stat the quote test file
stat:
- path: "{{ output_dir }}/test_quoting.txt"
+ path: "{{ remote_tmp_dir }}/test_quoting.txt"
register: result
- name: assert test checksum matches after backref line was replaced
@@ -478,7 +531,7 @@
- name: insert a line into the quoted file with many double quotation strings
lineinfile:
- dest: "{{ output_dir }}/test_quoting.txt"
+ dest: "{{ remote_tmp_dir }}/test_quoting.txt"
line: "\"quote\" and \"unquote\""
register: result
@@ -489,7 +542,7 @@
- name: stat the quote test file
stat:
- path: "{{ output_dir }}/test_quoting.txt"
+ path: "{{ remote_tmp_dir }}/test_quoting.txt"
register: result
- name: assert test checksum matches after backref line was replaced
@@ -503,7 +556,7 @@
- name: Deploy the testmultiple file
copy:
src: testmultiple.txt
- dest: "{{ output_dir }}/testmultiple.txt"
+ dest: "{{ remote_tmp_dir }}/testmultiple.txt"
register: result
- name: Assert that the testmultiple file was deployed
@@ -516,7 +569,7 @@
# Test insertafter
- name: Write the same line to a file inserted after different lines
lineinfile:
- path: "{{ output_dir }}/testmultiple.txt"
+ path: "{{ remote_tmp_dir }}/testmultiple.txt"
insertafter: "{{ item.regex }}"
line: "{{ item.replace }}"
register: _multitest_1
@@ -532,7 +585,7 @@
- name: Do the same thing again to check for changes
lineinfile:
- path: "{{ output_dir }}/testmultiple.txt"
+ path: "{{ remote_tmp_dir }}/testmultiple.txt"
insertafter: "{{ item.regex }}"
line: "{{ item.replace }}"
register: _multitest_2
@@ -548,7 +601,7 @@
- name: Stat the insertafter file
stat:
- path: "{{ output_dir }}/testmultiple.txt"
+ path: "{{ remote_tmp_dir }}/testmultiple.txt"
register: result
- name: Assert that the insertafter file matches expected checksum
@@ -561,7 +614,7 @@
- name: Deploy the testmultiple file
copy:
src: testmultiple.txt
- dest: "{{ output_dir }}/testmultiple.txt"
+ dest: "{{ remote_tmp_dir }}/testmultiple.txt"
register: result
- name: Assert that the testmultiple file was deployed
@@ -573,7 +626,7 @@
- name: Write the same line to a file inserted before different lines
lineinfile:
- path: "{{ output_dir }}/testmultiple.txt"
+ path: "{{ remote_tmp_dir }}/testmultiple.txt"
insertbefore: "{{ item.regex }}"
line: "{{ item.replace }}"
register: _multitest_3
@@ -589,7 +642,7 @@
- name: Do the same thing again to check for changes
lineinfile:
- path: "{{ output_dir }}/testmultiple.txt"
+ path: "{{ remote_tmp_dir }}/testmultiple.txt"
insertbefore: "{{ item.regex }}"
line: "{{ item.replace }}"
register: _multitest_4
@@ -605,7 +658,7 @@
- name: Stat the insertbefore file
stat:
- path: "{{ output_dir }}/testmultiple.txt"
+ path: "{{ remote_tmp_dir }}/testmultiple.txt"
register: result
- name: Assert that the insertbefore file matches expected checksum
@@ -620,7 +673,7 @@
- name: Deploy the test.conf file
copy:
src: test.conf
- dest: "{{ output_dir }}/test.conf"
+ dest: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the test.conf file was deployed
@@ -633,7 +686,7 @@
# Test instertafter
- name: Insert lines after with regexp
lineinfile:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
insertafter: "{{ item.after }}"
@@ -642,7 +695,7 @@
- name: Do the same thing again and check for changes
lineinfile:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
insertafter: "{{ item.after }}"
@@ -660,7 +713,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the file contents match what is expected
@@ -670,7 +723,7 @@
- name: Do the same thing a third time without regexp and check for changes
lineinfile:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
line: "{{ item.line }}"
insertafter: "{{ item.after }}"
with_items: "{{ test_befaf_regexp }}"
@@ -678,7 +731,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the file was changed when no regexp was provided
@@ -689,7 +742,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the file contents match what is expected
@@ -701,7 +754,7 @@
- name: Deploy the test.conf file
copy:
src: test.conf
- dest: "{{ output_dir }}/test.conf"
+ dest: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the test.conf file was deployed
@@ -713,7 +766,7 @@
- name: Insert lines before with regexp
lineinfile:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
insertbefore: "{{ item.before }}"
@@ -722,7 +775,7 @@
- name: Do the same thing again and check for changes
lineinfile:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
insertbefore: "{{ item.before }}"
@@ -740,7 +793,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the file contents match what is expected
@@ -750,7 +803,7 @@
- name: Do the same thing a third time without regexp and check for changes
lineinfile:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
line: "{{ item.line }}"
insertbefore: "{{ item.before }}"
with_items: "{{ test_befaf_regexp }}"
@@ -758,7 +811,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the file was changed when no regexp was provided
@@ -769,7 +822,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test.conf"
+ path: "{{ remote_tmp_dir }}/test.conf"
register: result
- name: Assert that the file contents match what is expected
@@ -780,25 +833,25 @@
- name: Copy empty file to test with insertbefore
copy:
src: testempty.txt
- dest: "{{ output_dir }}/testempty.txt"
+ dest: "{{ remote_tmp_dir }}/testempty.txt"
- name: Add a line to empty file with insertbefore
lineinfile:
- path: "{{ output_dir }}/testempty.txt"
+ path: "{{ remote_tmp_dir }}/testempty.txt"
line: top
insertbefore: '^not in the file$'
register: oneline_insbefore_test1
- name: Add a line to file with only one line using insertbefore
lineinfile:
- path: "{{ output_dir }}/testempty.txt"
+ path: "{{ remote_tmp_dir }}/testempty.txt"
line: top
insertbefore: '^not in the file$'
register: oneline_insbefore_test2
- name: Stat the file
stat:
- path: "{{ output_dir }}/testempty.txt"
+ path: "{{ remote_tmp_dir }}/testempty.txt"
register: oneline_insbefore_file
- name: Assert that insertebefore worked properly with a one line file
@@ -817,7 +870,7 @@
- name: Deploy the test file for lineinfile
copy:
src: test.txt
- dest: "{{ output_dir }}/test.txt"
+ dest: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: Assert that the test file was deployed
@@ -829,14 +882,14 @@
- name: Insert a line in the file using an empty string as a regular expression
lineinfile:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
regexp: ''
line: This is line 6
register: insert_empty_regexp
- name: Stat the file
stat:
- path: "{{ output_dir }}/test.txt"
+ path: "{{ remote_tmp_dir }}/test.txt"
register: result
- name: Assert that the file contents match what is expected and a warning was displayed
@@ -858,7 +911,7 @@
- name: Deploy the test file for lineinfile
copy:
src: teststring.txt
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
register: result
- name: Assert that the test file was deployed
@@ -870,14 +923,14 @@
- name: Insert a line in the file using an empty string as a search string
lineinfile:
- path: "{{ output_dir }}/teststring.txt"
+ path: "{{ remote_tmp_dir }}/teststring.txt"
search_string: ''
line: This is line 6
register: insert_empty_literal
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring.txt"
+ path: "{{ remote_tmp_dir }}/teststring.txt"
register: result
- name: Assert that the file contents match what is expected and a warning was displayed
@@ -901,7 +954,7 @@
- name: Deploy the firstmatch test file
copy:
src: firstmatch.txt
- dest: "{{ output_dir }}/firstmatch.txt"
+ dest: "{{ remote_tmp_dir }}/firstmatch.txt"
register: result
- name: Assert that the test file was deployed
@@ -913,7 +966,7 @@
- name: Insert a line before an existing line using firstmatch
lineinfile:
- path: "{{ output_dir }}/firstmatch.txt"
+ path: "{{ remote_tmp_dir }}/firstmatch.txt"
line: INSERT
insertafter: line1
firstmatch: yes
@@ -921,7 +974,7 @@
- name: Insert a line before an existing line using firstmatch again
lineinfile:
- path: "{{ output_dir }}/firstmatch.txt"
+ path: "{{ remote_tmp_dir }}/firstmatch.txt"
line: INSERT
insertafter: line1
firstmatch: yes
@@ -929,7 +982,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/firstmatch.txt"
+ path: "{{ remote_tmp_dir }}/firstmatch.txt"
register: result
- name: Assert that the file was modified appropriately
@@ -947,7 +1000,7 @@
- name: Deploy the test file
copy:
src: test_58923.txt
- dest: "{{ output_dir }}/test_58923.txt"
+ dest: "{{ remote_tmp_dir }}/test_58923.txt"
register: initial_file
- name: Assert that the test file was deployed
@@ -968,7 +1021,7 @@
# Regexp is not present in the file, so the line must be inserted after ^#!/bin/sh
- name: Add the line using firstmatch, regexp, and insertafter
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertafter: '^#!/bin/sh'
regexp: ^export FISHEYE_OPTS
firstmatch: true
@@ -977,12 +1030,12 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertafter_test1_file
- name: Add the line using firstmatch, regexp, and insertafter again
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertafter: '^#!/bin/sh'
regexp: ^export FISHEYE_OPTS
firstmatch: true
@@ -994,7 +1047,7 @@
# so nothing has been added:
- name: Stat the file again
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertafter_test2_file
- name: Assert insertafter tests gave the expected results
@@ -1009,7 +1062,7 @@
- name: Deploy the test file
copy:
src: test_58923.txt
- dest: "{{ output_dir }}/test_58923.txt"
+ dest: "{{ remote_tmp_dir }}/test_58923.txt"
register: initial_file
- name: Assert that the test file was deployed
@@ -1021,7 +1074,7 @@
- name: Insert the line using firstmatch and insertafter without regexp
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertafter: '^#!/bin/sh'
firstmatch: true
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
@@ -1029,12 +1082,12 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertafter_test3_file
- name: Insert the line using firstmatch and insertafter without regexp again
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertafter: '^#!/bin/sh'
firstmatch: true
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
@@ -1042,7 +1095,7 @@
- name: Stat the file again
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertafter_test4_file
- name: Assert insertafter without regexp tests gave the expected results
@@ -1058,7 +1111,7 @@
- name: Deploy the test file
copy:
src: test_58923.txt
- dest: "{{ output_dir }}/test_58923.txt"
+ dest: "{{ remote_tmp_dir }}/test_58923.txt"
register: initial_file
- name: Assert that the test file was deployed
@@ -1070,7 +1123,7 @@
- name: Add the line using regexp, firstmatch, and insertbefore
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertbefore: '^#!/bin/sh'
regexp: ^export FISHEYE_OPTS
firstmatch: true
@@ -1079,12 +1132,12 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertbefore_test1_file
- name: Add the line using regexp, firstmatch, and insertbefore again
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertbefore: '^#!/bin/sh'
regexp: ^export FISHEYE_OPTS
firstmatch: true
@@ -1093,7 +1146,7 @@
- name: Stat the file again
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertbefore_test2_file
- name: Assert insertbefore with regexp tests gave the expected results
@@ -1109,7 +1162,7 @@
- name: Deploy the test file
copy:
src: test_58923.txt
- dest: "{{ output_dir }}/test_58923.txt"
+ dest: "{{ remote_tmp_dir }}/test_58923.txt"
register: initial_file
- name: Assert that the test file was deployed
@@ -1121,7 +1174,7 @@
- name: Add the line using insertbefore and firstmatch
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertbefore: '^#!/bin/sh'
firstmatch: true
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
@@ -1129,12 +1182,12 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertbefore_test3_file
- name: Add the line using insertbefore and firstmatch again
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertbefore: '^#!/bin/sh'
firstmatch: true
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
@@ -1142,7 +1195,7 @@
- name: Stat the file again
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertbefore_test4_file
# Test when the line is presented in the file but
@@ -1151,7 +1204,7 @@
Add the line using insertbefore and firstmatch when the regexp line
is presented but not close to insertbefore spot
lineinfile:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
insertbefore: ' Darwin\*\) if \[ -z \"\$JAVA_HOME\" \] ; then'
firstmatch: true
line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m"
@@ -1159,7 +1212,7 @@
- name: Stat the file again
stat:
- path: "{{ output_dir }}/test_58923.txt"
+ path: "{{ remote_tmp_dir }}/test_58923.txt"
register: insertbefore_test5_file
- name: Assert insertbefore with regexp tests gave the expected results
@@ -1179,7 +1232,7 @@
- name: Deploy the test file
copy:
src: teststring_58923.txt
- dest: "{{ output_dir }}/teststring_58923.txt"
+ dest: "{{ remote_tmp_dir }}/teststring_58923.txt"
register: initial_file
- name: Assert that the test file was deployed
@@ -1200,7 +1253,7 @@
# literal is not present in the file, so the line must be inserted after ^#!/bin/sh
- name: Add the line using firstmatch, regexp, and insertafter
lineinfile:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
insertafter: '^#!/bin/sh'
search_string: export FISHEYE_OPTS
firstmatch: true
@@ -1209,12 +1262,12 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
register: insertafter_test1_file
- name: Add the line using firstmatch, literal, and insertafter again
lineinfile:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
insertafter: '^#!/bin/sh'
search_string: export FISHEYE_OPTS
firstmatch: true
@@ -1226,7 +1279,7 @@
# so nothing has been added:
- name: Stat the file again
stat:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
register: insertafter_test2_file
- name: Assert insertafter tests gave the expected results
@@ -1241,7 +1294,7 @@
- name: Deploy the test file
copy:
src: teststring_58923.txt
- dest: "{{ output_dir }}/teststring_58923.txt"
+ dest: "{{ remote_tmp_dir }}/teststring_58923.txt"
register: initial_file
- name: Assert that the test file was deployed
@@ -1253,7 +1306,7 @@
- name: Add the line using literal, firstmatch, and insertbefore
lineinfile:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
insertbefore: '^#!/bin/sh'
search_string: export FISHEYE_OPTS
firstmatch: true
@@ -1262,12 +1315,12 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
register: insertbefore_test1_file
- name: Add the line using literal, firstmatch, and insertbefore again
lineinfile:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
insertbefore: '^#!/bin/sh'
search_string: export FISHEYE_OPTS
firstmatch: true
@@ -1276,7 +1329,7 @@
- name: Stat the file again
stat:
- path: "{{ output_dir }}/teststring_58923.txt"
+ path: "{{ remote_tmp_dir }}/teststring_58923.txt"
register: insertbefore_test2_file
- name: Assert insertbefore with literal tests gave the expected results
@@ -1291,14 +1344,14 @@
# https://github.com/ansible/ansible/issues/63684
- name: Create a file by inserting a line
lineinfile:
- path: "{{ output_dir }}/testend.txt"
+ path: "{{ remote_tmp_dir }}/testend.txt"
create: yes
line: testline
register: testend1
- name: Insert a line at the end of the file
lineinfile:
- path: "{{ output_dir }}/testend.txt"
+ path: "{{ remote_tmp_dir }}/testend.txt"
insertafter: testline
regexp: line at the end
line: line at the end
@@ -1306,7 +1359,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/testend.txt"
+ path: "{{ remote_tmp_dir }}/testend.txt"
register: testend_file
- name: Assert inserting at the end gave the expected results.
@@ -1320,14 +1373,14 @@
- name: Create a file by inserting a line
lineinfile:
- path: "{{ output_dir }}/testendliteral.txt"
+ path: "{{ remote_tmp_dir }}/testendliteral.txt"
create: yes
line: testline
register: testend1
- name: Insert a line at the end of the file
lineinfile:
- path: "{{ output_dir }}/testendliteral.txt"
+ path: "{{ remote_tmp_dir }}/testendliteral.txt"
insertafter: testline
search_string: line at the end
line: line at the end
@@ -1335,7 +1388,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/testendliteral.txt"
+ path: "{{ remote_tmp_dir }}/testendliteral.txt"
register: testend_file
- name: Assert inserting at the end gave the expected results.
diff --git a/test/integration/targets/lineinfile/tasks/test_string01.yml b/test/integration/targets/lineinfile/tasks/test_string01.yml
index 6e0c12c3..b86cd09a 100644
--- a/test/integration/targets/lineinfile/tasks/test_string01.yml
+++ b/test/integration/targets/lineinfile/tasks/test_string01.yml
@@ -5,7 +5,7 @@
- name: deploy the test file for lineinfile string
copy:
src: teststring.txt
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
register: result
- name: assert that the test file was deployed
@@ -17,7 +17,7 @@
- name: insert a line at the beginning of the file, and back it up
lineinfile:
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
state: present
line: "New line at the beginning"
insertbefore: "BOF"
@@ -26,7 +26,7 @@
- name: insert a line at the beginning of the file again
lineinfile:
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
state: present
line: "New line at the beginning"
insertbefore: "BOF"
@@ -34,7 +34,7 @@
- name: Replace a line using string
lineinfile:
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
state: present
line: "Thi$ i^ [ine 3"
search_string: (\\w)(\\s+)([\\.,])
@@ -42,13 +42,13 @@
- name: Replace a line again using string
lineinfile:
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
state: present
line: "Thi$ i^ [ine 3"
search_string: (\\w)(\\s+)([\\.,])
register: backrefs_result2
-- command: cat {{ output_dir }}/teststring.txt
+- command: cat {{ remote_tmp_dir }}/teststring.txt
- name: assert that the line with backrefs was changed
assert:
@@ -59,7 +59,7 @@
- name: stat the test after the backref line was replaced
stat:
- path: "{{ output_dir }}/teststring.txt"
+ path: "{{ remote_tmp_dir }}/teststring.txt"
register: result
- name: assert test checksum matches after backref line was replaced
@@ -69,7 +69,7 @@
- name: remove the middle line using string
lineinfile:
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
state: absent
search_string: "Thi$ i^ [ine 3"
register: result
@@ -82,7 +82,7 @@
- name: stat the test after the middle line was removed
stat:
- path: "{{ output_dir }}/teststring.txt"
+ path: "{{ remote_tmp_dir }}/teststring.txt"
register: result
- name: assert test checksum matches after the middle line was removed
@@ -92,7 +92,7 @@
- name: run a validation script that succeeds using string
lineinfile:
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
state: absent
search_string: <FilesMatch ".py[45]?$">
validate: "true %s"
@@ -106,7 +106,7 @@
- name: stat the test after the validation succeeded
stat:
- path: "{{ output_dir }}/teststring.txt"
+ path: "{{ remote_tmp_dir }}/teststring.txt"
register: result
- name: assert test checksum matches after the validation succeeded
@@ -116,7 +116,7 @@
- name: run a validation script that fails using string
lineinfile:
- dest: "{{ output_dir }}/teststring.txt"
+ dest: "{{ remote_tmp_dir }}/teststring.txt"
state: absent
search_string: "This is line 1"
validate: "/bin/false %s"
@@ -130,7 +130,7 @@
- name: stat the test after the validation failed
stat:
- path: "{{ output_dir }}/teststring.txt"
+ path: "{{ remote_tmp_dir }}/teststring.txt"
register: result
- name: assert test checksum matches the previous after the validation failed
diff --git a/test/integration/targets/lineinfile/tasks/test_string02.yml b/test/integration/targets/lineinfile/tasks/test_string02.yml
index 886b290d..1fa48b85 100644
--- a/test/integration/targets/lineinfile/tasks/test_string02.yml
+++ b/test/integration/targets/lineinfile/tasks/test_string02.yml
@@ -5,7 +5,7 @@
- name: Deploy the teststring.conf file
copy:
src: teststring.conf
- dest: "{{ output_dir }}/teststring.conf"
+ dest: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the teststring.conf file was deployed
@@ -18,7 +18,7 @@
# Test instertafter
- name: Insert lines after with string
lineinfile:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
search_string: "{{ item.regexp }}"
line: "{{ item.line }}"
insertafter: "{{ item.after }}"
@@ -27,7 +27,7 @@
- name: Do the same thing again and check for changes
lineinfile:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
search_string: "{{ item.regexp }}"
line: "{{ item.line }}"
insertafter: "{{ item.after }}"
@@ -45,7 +45,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the file contents match what is expected
@@ -55,7 +55,7 @@
- name: Do the same thing a third time without string and check for changes
lineinfile:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
line: "{{ item.line }}"
insertafter: "{{ item.after }}"
with_items: "{{ test_befaf_regexp }}"
@@ -63,7 +63,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the file was changed when no string was provided
@@ -74,7 +74,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the file contents match what is expected
@@ -86,7 +86,7 @@
- name: Deploy the test.conf file
copy:
src: teststring.conf
- dest: "{{ output_dir }}/teststring.conf"
+ dest: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the teststring.conf file was deployed
@@ -98,7 +98,7 @@
- name: Insert lines before with string
lineinfile:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
search_string: "{{ item.regexp }}"
line: "{{ item.line }}"
insertbefore: "{{ item.before }}"
@@ -107,7 +107,7 @@
- name: Do the same thing again and check for changes
lineinfile:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
search_string: "{{ item.regexp }}"
line: "{{ item.line }}"
insertbefore: "{{ item.before }}"
@@ -125,7 +125,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the file contents match what is expected
@@ -135,7 +135,7 @@
- name: Do the same thing a third time without string and check for changes
lineinfile:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
line: "{{ item.line }}"
insertbefore: "{{ item.before }}"
with_items: "{{ test_befaf_regexp }}"
@@ -143,7 +143,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the file was changed when no string was provided
@@ -154,7 +154,7 @@
- name: Stat the file
stat:
- path: "{{ output_dir }}/teststring.conf"
+ path: "{{ remote_tmp_dir }}/teststring.conf"
register: result
- name: Assert that the file contents match what is expected
diff --git a/test/integration/targets/lookup_config/aliases b/test/integration/targets/lookup_config/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_config/aliases
+++ b/test/integration/targets/lookup_config/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_config/tasks/main.yml b/test/integration/targets/lookup_config/tasks/main.yml
index cda9aedc..356d2f80 100644
--- a/test/integration/targets/lookup_config/tasks/main.yml
+++ b/test/integration/targets/lookup_config/tasks/main.yml
@@ -39,6 +39,19 @@
ignore_errors: yes
register: lookup_config_7
+- name: remote user and port for ssh connection
+ set_fact:
+ ssh_user_and_port: '{{q("config", "remote_user", "port", plugin_type="connection", plugin_name="ssh")}}'
+ vars:
+ ansible_ssh_user: lola
+ ansible_ssh_port: 2022
+
+- name: remote_tmp for sh shell plugin
+ set_fact:
+ yolo_remote: '{{q("config", "remote_tmp", plugin_type="shell", plugin_name="sh")}}'
+ vars:
+ ansible_remote_tmp: yolo
+
- name: Verify lookup_config
assert:
that:
@@ -52,8 +65,10 @@
- lookup_config_4 is success
- 'lookup4|length == 0'
- lookup_config_5 is failed
- - '"must be a string and one of" in lookup_config_5.msg'
+ - '"valid values are" in lookup_config_5.msg'
- lookup_config_6 is failed
- '"Invalid setting identifier" in lookup_config_6.msg'
- lookup_config_7 is failed
- '"Invalid setting" in lookup_config_7.msg'
+ - ssh_user_and_port == ['lola', 2022]
+ - yolo_remote == ["yolo"]
diff --git a/test/integration/targets/lookup_csvfile/aliases b/test/integration/targets/lookup_csvfile/aliases
index 45489be8..765b70da 100644
--- a/test/integration/targets/lookup_csvfile/aliases
+++ b/test/integration/targets/lookup_csvfile/aliases
@@ -1,2 +1 @@
shippable/posix/group2
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_csvfile/tasks/main.yml b/test/integration/targets/lookup_csvfile/tasks/main.yml
index 14b79bd6..758da71e 100644
--- a/test/integration/targets/lookup_csvfile/tasks/main.yml
+++ b/test/integration/targets/lookup_csvfile/tasks/main.yml
@@ -1,15 +1,23 @@
-- set_fact:
- this_will_error: "{{ lookup('csvfile', 'file=people.csv delimiter=, col=1') }}"
+- name: using deprecated syntax but missing keyword
+ set_fact:
+ this_will_error: "{{ lookup('csvfile', 'file=people.csv, delimiter=, col=1') }}"
ignore_errors: yes
register: no_keyword
-- set_fact:
+- name: extra arg in k=v syntax (deprecated)
+ set_fact:
this_will_error: "{{ lookup('csvfile', 'foo file=people.csv delimiter=, col=1 thisarg=doesnotexist') }}"
ignore_errors: yes
register: invalid_arg
+- name: extra arg in config syntax
+ set_fact:
+ this_will_error: "{{ lookup('csvfile', 'foo', file='people.csv', delimiter=',' col=1, thisarg='doesnotexist') }}"
+ ignore_errors: yes
+ register: invalid_arg2
+
- set_fact:
- this_will_error: "{{ lookup('csvfile', 'foo file=doesnotexist delimiter=, col=1') }}"
+ this_will_error: "{{ lookup('csvfile', 'foo', file='doesnotexist', delimiter=',', col=1) }}"
ignore_errors: yes
register: missing_file
@@ -19,24 +27,30 @@
- no_keyword is failed
- >
"Search key is required but was not found" in no_keyword.msg
+ - invalid_arg is failed
+ - invalid_arg2 is failed
- >
- "not in paramvals" in invalid_arg.msg
+ "is not a valid option" in invalid_arg.msg
- missing_file is failed
- >
- "need string or buffer" in missing_file.msg or "expected str, bytes or os.PathLike object" in missing_file.msg
+ "need string or buffer" in missing_file.msg or
+ "expected str, bytes or os.PathLike object" in missing_file.msg or
+ "No such file or directory" in missing_file.msg
- name: Check basic comma-separated file
assert:
that:
- - lookup('csvfile', 'Smith file=people.csv delimiter=, col=1') == "Jane"
+ - lookup('csvfile', 'Smith', file='people.csv', delimiter=',', col=1) == "Jane"
- lookup('csvfile', 'German von Lastname file=people.csv delimiter=, col=1') == "Demo"
- name: Check tab-separated file
assert:
that:
- lookup('csvfile', 'electronics file=tabs.csv delimiter=TAB col=1') == "tvs"
- - lookup('csvfile', 'fruit file=tabs.csv delimiter=TAB col=1') == "bananas"
+ - "lookup('csvfile', 'fruit', file='tabs.csv', delimiter='TAB', col=1) == 'bananas'"
- lookup('csvfile', 'fruit file=tabs.csv delimiter="\t" col=1') == "bananas"
+ - lookup('csvfile', 'electronics', 'fruit', file='tabs.csv', delimiter='\t', col=1) == "tvs,bananas"
+ - lookup('csvfile', 'electronics', 'fruit', file='tabs.csv', delimiter='\t', col=1, wantlist=True) == ["tvs", "bananas"]
- name: Check \x1a-separated file
assert:
diff --git a/test/integration/targets/lookup_dict/aliases b/test/integration/targets/lookup_dict/aliases
index 07b87020..a6dafcf8 100644
--- a/test/integration/targets/lookup_dict/aliases
+++ b/test/integration/targets/lookup_dict/aliases
@@ -1,3 +1 @@
shippable/posix/group1
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_env/aliases b/test/integration/targets/lookup_env/aliases
index 07b87020..a6dafcf8 100644
--- a/test/integration/targets/lookup_env/aliases
+++ b/test/integration/targets/lookup_env/aliases
@@ -1,3 +1 @@
shippable/posix/group1
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_file/aliases b/test/integration/targets/lookup_file/aliases
index 07b87020..a6dafcf8 100644
--- a/test/integration/targets/lookup_file/aliases
+++ b/test/integration/targets/lookup_file/aliases
@@ -1,3 +1 @@
shippable/posix/group1
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_first_found/aliases b/test/integration/targets/lookup_first_found/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_first_found/aliases
+++ b/test/integration/targets/lookup_first_found/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_first_found/tasks/main.yml b/test/integration/targets/lookup_first_found/tasks/main.yml
index 87f2a404..e85f4f27 100644
--- a/test/integration/targets/lookup_first_found/tasks/main.yml
+++ b/test/integration/targets/lookup_first_found/tasks/main.yml
@@ -1,10 +1,9 @@
- name: test with_first_found
- #shell: echo {{ item }}
set_fact: "first_found={{ item }}"
with_first_found:
- - "{{ role_path + '/files/does_not_exist' }}"
- - "{{ role_path + '/files/foo1' }}"
- - "{{ role_path + '/files/bar1' }}"
+ - "does_not_exist"
+ - "foo1"
+ - "{{ role_path + '/files/bar1' }}" # will only hit this if dwim search is broken
- name: set expected
set_fact: first_expected="{{ role_path + '/files/foo1' }}"
@@ -24,6 +23,7 @@
vars:
params:
files: "not_a_file.yaml"
+ skip: True
- name: verify q(first_found) result
assert:
@@ -71,3 +71,16 @@
assert:
that:
- "this_not_set is not defined"
+
+- name: test legacy formats
+ set_fact: hatethisformat={{item}}
+ vars:
+ params:
+ files: not/a/file.yaml;hosts
+ paths: not/a/path:/etc
+ loop: "{{ q('first_found', params) }}"
+
+- name: verify /etc/hosts was found
+ assert:
+ that:
+ - "hatethisformat == '/etc/hosts'"
diff --git a/test/integration/targets/lookup_indexed_items/aliases b/test/integration/targets/lookup_indexed_items/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_indexed_items/aliases
+++ b/test/integration/targets/lookup_indexed_items/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_indexed_items/tasks/main.yml b/test/integration/targets/lookup_indexed_items/tasks/main.yml
index 84f5fbce..434fe0ff 100644
--- a/test/integration/targets/lookup_indexed_items/tasks/main.yml
+++ b/test/integration/targets/lookup_indexed_items/tasks/main.yml
@@ -14,3 +14,19 @@
- "x2 == 'set'"
- "x3 == 'set'"
- "x4 == 'set'"
+
+- block:
+ - name: "EXPECTED FAILURE - test not a list"
+ debug:
+ msg: "{{ item.0 }} is {{ item.1 }}"
+ with_indexed_items:
+ "a": 1
+
+ - fail:
+ msg: "should not get here"
+
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test not a list"
+ - ansible_failed_result.msg == "with_indexed_items expects a list"
diff --git a/test/integration/targets/lookup_ini/aliases b/test/integration/targets/lookup_ini/aliases
index f9f29ef3..b5983214 100644
--- a/test/integration/targets/lookup_ini/aliases
+++ b/test/integration/targets/lookup_ini/aliases
@@ -1,2 +1 @@
shippable/posix/group3
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_ini/lookup_case_check.properties b/test/integration/targets/lookup_ini/lookup_case_check.properties
new file mode 100644
index 00000000..ed3faaf8
--- /dev/null
+++ b/test/integration/targets/lookup_ini/lookup_case_check.properties
@@ -0,0 +1,2 @@
+name = captain
+NAME = fantastic
diff --git a/test/integration/targets/lookup_ini/mysql.ini b/test/integration/targets/lookup_ini/mysql.ini
new file mode 100644
index 00000000..fa62d87e
--- /dev/null
+++ b/test/integration/targets/lookup_ini/mysql.ini
@@ -0,0 +1,8 @@
+[mysqld]
+user = mysql
+pid-file = /var/run/mysqld/mysqld.pid
+skip-external-locking
+old_passwords = 1
+skip-bdb
+# we don't need ACID today
+skip-innodb
diff --git a/test/integration/targets/lookup_ini/runme.sh b/test/integration/targets/lookup_ini/runme.sh
index 76f836a9..6f44332b 100755
--- a/test/integration/targets/lookup_ini/runme.sh
+++ b/test/integration/targets/lookup_ini/runme.sh
@@ -2,5 +2,4 @@
set -eux
-ansible-playbook test_lookup_properties.yml -i inventory -v "$@"
-ansible-playbook test_errors.yml -i inventory -v "$@"
+ansible-playbook test_ini.yml -i inventory -v "$@"
diff --git a/test/integration/targets/lookup_ini/test_allow_no_value.yml b/test/integration/targets/lookup_ini/test_allow_no_value.yml
new file mode 100644
index 00000000..bfdc3765
--- /dev/null
+++ b/test/integration/targets/lookup_ini/test_allow_no_value.yml
@@ -0,0 +1,23 @@
+- name: Lookup test
+ hosts: testhost
+ tasks:
+ - name: "Read mysql.ini allow_none=False (default)"
+ set_fact:
+ test1: "{{ lookup('ini', 'user', file='mysql.ini', section='mysqld') }}"
+ register: result
+ ignore_errors: true
+
+ - name: "Read mysql.ini allow_no_value=True"
+ set_fact:
+ test2: "{{ lookup('ini', 'user', file='mysql.ini', section='mysqld', allow_no_value=True) }}"
+
+ - name: "Read mysql.ini allow_none=True"
+ set_fact:
+ test3: "{{ lookup('ini', 'skip-innodb', file='mysql.ini', section='mysqld', allow_none=True) }}"
+
+ - assert:
+ that:
+ - result is failed
+ - test2 == 'mysql'
+ - test3 == []
+ - test3|length == 0
diff --git a/test/integration/targets/lookup_ini/test_case_sensitive.yml b/test/integration/targets/lookup_ini/test_case_sensitive.yml
new file mode 100644
index 00000000..f66674ca
--- /dev/null
+++ b/test/integration/targets/lookup_ini/test_case_sensitive.yml
@@ -0,0 +1,31 @@
+- name: Test case sensitive option
+ hosts: all
+
+ tasks:
+ - name: Lookup a file with keys that differ only in case with case sensitivity enabled
+ debug:
+ msg: "{{ lookup('ini', 'name', file='duplicate_case_check.ini', section='reggae', case_sensitive=True) }}"
+ register: duplicate_case_sensitive_name
+
+ - name: Lookup a file with keys that differ only in case with case sensitivity enabled
+ debug:
+ msg: "{{ lookup('ini', 'NAME', file='duplicate_case_check.ini', section='reggae', case_sensitive=True) }}"
+ register: duplicate_case_sensitive_NAME
+
+ - name: Lookup a properties file with keys that differ only in case with case sensitivity enabled
+ debug:
+ msg: "{{ lookup('ini', 'name', file='lookup_case_check.properties', type='properties', case_sensitive=True) }}"
+ register: duplicate_case_sensitive_properties_name
+
+ - name: Lookup a properties file with keys that differ only in case with case sensitivity enabled
+ debug:
+ msg: "{{ lookup('ini', 'NAME', file='lookup_case_check.properties', type='properties', case_sensitive=True) }}"
+ register: duplicate_case_sensitive_properties_NAME
+
+ - name: Ensure the correct case-sensitive values were retieved
+ assert:
+ that:
+ - duplicate_case_sensitive_name.msg == 'bob'
+ - duplicate_case_sensitive_NAME.msg == 'marley'
+ - duplicate_case_sensitive_properties_name.msg == 'captain'
+ - duplicate_case_sensitive_properties_NAME.msg == 'fantastic'
diff --git a/test/integration/targets/lookup_ini/test_errors.yml b/test/integration/targets/lookup_ini/test_errors.yml
index b7b04d90..c1832a35 100644
--- a/test/integration/targets/lookup_ini/test_errors.yml
+++ b/test/integration/targets/lookup_ini/test_errors.yml
@@ -7,17 +7,17 @@
block:
- name: Lookup a file with duplicate keys
debug:
- msg: "{{ lookup('ini', 'reggae file=duplicate.ini section=reggae') }}"
+ msg: "{{ lookup('ini', 'name', file='duplicate.ini', section='reggae') }}"
ignore_errors: yes
register: duplicate
- name: Lookup a file with keys that differ only in case
debug:
- msg: "{{ lookup('ini', 'reggae file=duplicate_case_check.ini section=reggae') }}"
+ msg: "{{ lookup('ini', 'name', file='duplicate_case_check.ini', section='reggae') }}"
ignore_errors: yes
register: duplicate_case_sensitive
- - name: Ensure duplicate key errers were handled properly
+ - name: Ensure duplicate key errors were handled properly
assert:
that:
- duplicate is failed
@@ -27,7 +27,7 @@
- name: Lookup a file with a missing section
debug:
- msg: "{{ lookup('ini', 'reggae file=lookup.ini section=missing') }}"
+ msg: "{{ lookup('ini', 'name', file='lookup.ini', section='missing') }}"
ignore_errors: yes
register: missing_section
@@ -36,3 +36,27 @@
that:
- missing_section is failed
- "'No section' in missing_section.msg"
+
+ - name: Mix options type and push key out of order
+ debug:
+ msg: "{{ lookup('ini', 'file=lookup.ini', 'value1', section='value_section') }}"
+ register: bad_mojo
+ ignore_errors: yes
+
+ - name: Verify bad behavior reported an error
+ assert:
+ that:
+ - bad_mojo is failed
+ - '"No key to lookup was provided as first term with in string inline option" in bad_mojo.msg'
+
+ - name: Test invalid option
+ debug:
+ msg: "{{ lookup('ini', 'invalid=option') }}"
+ ignore_errors: yes
+ register: invalid_option
+
+ - name: Ensure invalid option failed
+ assert:
+ that:
+ - invalid_option is failed
+ - "'is not a valid option' in invalid_option.msg"
diff --git a/test/integration/targets/lookup_ini/test_ini.yml b/test/integration/targets/lookup_ini/test_ini.yml
new file mode 100644
index 00000000..11a5e57a
--- /dev/null
+++ b/test/integration/targets/lookup_ini/test_ini.yml
@@ -0,0 +1,4 @@
+- import_playbook: test_lookup_properties.yml
+- import_playbook: test_errors.yml
+- import_playbook: test_case_sensitive.yml
+- import_playbook: test_allow_no_value.yml
diff --git a/test/integration/targets/lookup_ini/test_lookup_properties.yml b/test/integration/targets/lookup_ini/test_lookup_properties.yml
index 3a414bbc..a6fc0f7d 100644
--- a/test/integration/targets/lookup_ini/test_lookup_properties.yml
+++ b/test/integration/targets/lookup_ini/test_lookup_properties.yml
@@ -5,8 +5,8 @@
- name: "read properties value"
set_fact:
test1: "{{lookup('ini', 'value1 type=properties file=lookup.properties')}}"
- test2: "{{lookup('ini', 'value2 type=properties file=lookup.properties')}}"
- test_dot: "{{lookup('ini', 'value.dot type=properties file=lookup.properties')}}"
+ test2: "{{lookup('ini', 'value2', type='properties', file='lookup.properties')}}"
+ test_dot: "{{lookup('ini', 'value.dot', type='properties', file='lookup.properties')}}"
field_with_space: "{{lookup('ini', 'field.with.space type=properties file=lookup.properties')}}"
- assert:
@@ -15,10 +15,10 @@
- name: "read ini value"
set_fact:
- value1_global: "{{lookup('ini', 'value1 section=global file=lookup.ini')}}"
- value2_global: "{{lookup('ini', 'value2 section=global file=lookup.ini')}}"
- value1_section1: "{{lookup('ini', 'value1 section=section1 file=lookup.ini')}}"
- field_with_unicode: "{{lookup('ini', 'unicode section=global file=lookup.ini')}}"
+ value1_global: "{{lookup('ini', 'value1', section='global', file='lookup.ini')}}"
+ value2_global: "{{lookup('ini', 'value2', section='global', file='lookup.ini')}}"
+ value1_section1: "{{lookup('ini', 'value1', section='section1', file='lookup.ini')}}"
+ field_with_unicode: "{{lookup('ini', 'unicode', section='global', file='lookup.ini')}}"
- debug: var={{item}}
with_items: [ 'value1_global', 'value2_global', 'value1_section1', 'field_with_unicode' ]
diff --git a/test/integration/targets/lookup_inventory_hostnames/aliases b/test/integration/targets/lookup_inventory_hostnames/aliases
index 45489be8..765b70da 100644
--- a/test/integration/targets/lookup_inventory_hostnames/aliases
+++ b/test/integration/targets/lookup_inventory_hostnames/aliases
@@ -1,2 +1 @@
shippable/posix/group2
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_items/aliases b/test/integration/targets/lookup_items/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_items/aliases
+++ b/test/integration/targets/lookup_items/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_lines/aliases b/test/integration/targets/lookup_lines/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_lines/aliases
+++ b/test/integration/targets/lookup_lines/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_list/aliases b/test/integration/targets/lookup_list/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_list/aliases
+++ b/test/integration/targets/lookup_list/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_nested/aliases b/test/integration/targets/lookup_nested/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_nested/aliases
+++ b/test/integration/targets/lookup_nested/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_password/aliases b/test/integration/targets/lookup_password/aliases
index 07b87020..a6dafcf8 100644
--- a/test/integration/targets/lookup_password/aliases
+++ b/test/integration/targets/lookup_password/aliases
@@ -1,3 +1 @@
shippable/posix/group1
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_pipe/aliases b/test/integration/targets/lookup_pipe/aliases
index 07b87020..a6dafcf8 100644
--- a/test/integration/targets/lookup_pipe/aliases
+++ b/test/integration/targets/lookup_pipe/aliases
@@ -1,3 +1 @@
shippable/posix/group1
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_random_choice/aliases b/test/integration/targets/lookup_random_choice/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_random_choice/aliases
+++ b/test/integration/targets/lookup_random_choice/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_sequence/aliases b/test/integration/targets/lookup_sequence/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_sequence/aliases
+++ b/test/integration/targets/lookup_sequence/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_sequence/tasks/main.yml b/test/integration/targets/lookup_sequence/tasks/main.yml
index 72181a42..bd0a4d80 100644
--- a/test/integration/targets/lookup_sequence/tasks/main.yml
+++ b/test/integration/targets/lookup_sequence/tasks/main.yml
@@ -61,3 +61,138 @@
- "ws_z_6 == 'stride_6'"
- "ws_z_host07 == 'host07'"
- "ws_z_host08 == 'host08'"
+
+- block:
+ - name: EXPECTED FAILURE - test invalid arg
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: start=0 junk=3
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test invalid arg"
+ - ansible_failed_result.msg in [expected1, expected2]
+ vars:
+ expected1: "unrecognized arguments to with_sequence: ['junk']"
+ expected2: "unrecognized arguments to with_sequence: [u'junk']"
+
+- block:
+ - name: EXPECTED FAILURE - test bad kv value
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: start=A end=3
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test bad kv value"
+ - ansible_failed_result.msg == "can't parse start=A as integer"
+
+- block:
+ - name: EXPECTED FAILURE - test bad simple form start value
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: A-4/2
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test bad simple form start value"
+ - ansible_failed_result.msg == "can't parse start=A as integer"
+
+- block:
+ - name: EXPECTED FAILURE - test bad simple form end value
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: 1-B/2
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test bad simple form end value"
+ - ansible_failed_result.msg == "can't parse end=B as integer"
+
+- block:
+ - name: EXPECTED FAILURE - test bad simple form stride value
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: 1-4/C
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test bad simple form stride value"
+ - ansible_failed_result.msg == "can't parse stride=C as integer"
+
+- block:
+ - name: EXPECTED FAILURE - test no count or end
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: start=1
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test no count or end"
+ - ansible_failed_result.msg == "must specify count or end in with_sequence"
+
+- block:
+ - name: EXPECTED FAILURE - test both count and end
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: start=1 end=4 count=2
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test both count and end"
+ - ansible_failed_result.msg == "can't specify both count and end in with_sequence"
+
+- block:
+ - name: EXPECTED FAILURE - test count backwards message
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: start=4 end=1 stride=2
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test count backwards message"
+ - ansible_failed_result.msg == "to count backwards make stride negative"
+
+- block:
+ - name: EXPECTED FAILURE - test count forward message
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: start=1 end=4 stride=-2
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test count forward message"
+ - ansible_failed_result.msg == "to count forward don't make stride negative"
+
+- block:
+ - name: EXPECTED FAILURE - test bad format string message
+ set_fact: "{{ 'x' + item }}={{ item }}"
+ with_sequence: start=1 end=4 format=d
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test bad format string message"
+ - ansible_failed_result.msg == expected
+ vars:
+ expected: "bad formatting string: d" \ No newline at end of file
diff --git a/test/integration/targets/lookup_subelements/aliases b/test/integration/targets/lookup_subelements/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_subelements/aliases
+++ b/test/integration/targets/lookup_subelements/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_template/aliases b/test/integration/targets/lookup_template/aliases
index 07b87020..a6dafcf8 100644
--- a/test/integration/targets/lookup_template/aliases
+++ b/test/integration/targets/lookup_template/aliases
@@ -1,3 +1 @@
shippable/posix/group1
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_template/tasks/main.yml b/test/integration/targets/lookup_template/tasks/main.yml
index df115766..36a8ee31 100644
--- a/test/integration/targets/lookup_template/tasks/main.yml
+++ b/test/integration/targets/lookup_template/tasks/main.yml
@@ -17,3 +17,11 @@
- assert:
that:
- "hello_world_string|trim == 'Hello world!'"
+
+- name: Test that we have a proper jinja search path in template lookup with different comment start and end string
+ set_fact:
+ hello_world_comment: "{{ lookup('template', 'hello_comment.txt', comment_start_string='[#', comment_end_string='#]') }}"
+
+- assert:
+ that:
+ - "hello_world_comment|trim == 'Hello world!'"
diff --git a/test/integration/targets/lookup_template/templates/hello_comment.txt b/test/integration/targets/lookup_template/templates/hello_comment.txt
new file mode 100644
index 00000000..92af4b37
--- /dev/null
+++ b/test/integration/targets/lookup_template/templates/hello_comment.txt
@@ -0,0 +1,2 @@
+[# Comment #]
+Hello world!
diff --git a/test/integration/targets/lookup_together/aliases b/test/integration/targets/lookup_together/aliases
index bc987654..765b70da 100644
--- a/test/integration/targets/lookup_together/aliases
+++ b/test/integration/targets/lookup_together/aliases
@@ -1,3 +1 @@
shippable/posix/group2
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_together/tasks/main.yml b/test/integration/targets/lookup_together/tasks/main.yml
index ee59a2ae..71365a15 100644
--- a/test/integration/targets/lookup_together/tasks/main.yml
+++ b/test/integration/targets/lookup_together/tasks/main.yml
@@ -12,3 +12,18 @@
- "b == '2'"
- "c == '3'"
- "d == '4'"
+
+- block:
+ - name: "EXPECTED FAILURE - test empty list"
+ debug:
+ msg: "{{ item.0 }} and {{ item.1 }}"
+ with_together: []
+
+ - fail:
+ msg: "should not get here"
+
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test empty list"
+ - ansible_failed_result.msg == "with_together requires at least one element in each list" \ No newline at end of file
diff --git a/test/integration/targets/lookup_unvault/aliases b/test/integration/targets/lookup_unvault/aliases
index 4a2ce27c..6bd893d4 100644
--- a/test/integration/targets/lookup_unvault/aliases
+++ b/test/integration/targets/lookup_unvault/aliases
@@ -1,3 +1,2 @@
shippable/posix/group2
needs/root
-skip/aix
diff --git a/test/integration/targets/lookup_url/aliases b/test/integration/targets/lookup_url/aliases
index 28990148..90ef161f 100644
--- a/test/integration/targets/lookup_url/aliases
+++ b/test/integration/targets/lookup_url/aliases
@@ -1,5 +1,3 @@
destructive
shippable/posix/group1
needs/httptester
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_varnames/aliases b/test/integration/targets/lookup_varnames/aliases
index 45489be8..765b70da 100644
--- a/test/integration/targets/lookup_varnames/aliases
+++ b/test/integration/targets/lookup_varnames/aliases
@@ -1,2 +1 @@
shippable/posix/group2
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_vars/aliases b/test/integration/targets/lookup_vars/aliases
index 07b87020..a6dafcf8 100644
--- a/test/integration/targets/lookup_vars/aliases
+++ b/test/integration/targets/lookup_vars/aliases
@@ -1,3 +1 @@
shippable/posix/group1
-skip/aix
-skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/lookup_vars/tasks/main.yml b/test/integration/targets/lookup_vars/tasks/main.yml
index f24d8657..57b05b8f 100644
--- a/test/integration/targets/lookup_vars/tasks/main.yml
+++ b/test/integration/targets/lookup_vars/tasks/main.yml
@@ -14,3 +14,43 @@
that:
- 'var_host_info[0] == ansible_host'
- 'var_host_info[1] == ansible_connection'
+
+- block:
+ - name: EXPECTED FAILURE - test invalid var
+ debug:
+ var: '{{ lookup("vars", "doesnotexist") }}'
+
+ - fail:
+ msg: "should not get here"
+
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test invalid var"
+ - expected in ansible_failed_result.msg
+ vars:
+ expected: "No variable found with this name: doesnotexist"
+
+- block:
+ - name: EXPECTED FAILURE - test invalid var type
+ debug:
+ var: '{{ lookup("vars", 42) }}'
+
+ - fail:
+ msg: "should not get here"
+
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test invalid var type"
+ - expected in ansible_failed_result.msg
+ vars:
+ expected: "Invalid setting identifier, \"42\" is not a string"
+
+- name: test default
+ set_fact:
+ expected_default_var: '{{ lookup("vars", "doesnotexist", default="some text") }}'
+
+- assert:
+ that:
+ - expected_default_var == "some text"
diff --git a/test/integration/targets/loop_control/aliases b/test/integration/targets/loop_control/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/loop_control/aliases
+++ b/test/integration/targets/loop_control/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/loops/aliases b/test/integration/targets/loops/aliases
index ed821c27..90ea9e12 100644
--- a/test/integration/targets/loops/aliases
+++ b/test/integration/targets/loops/aliases
@@ -1,2 +1,2 @@
shippable/posix/group2
-skip/aix
+context/controller
diff --git a/test/integration/targets/meta_tasks/aliases b/test/integration/targets/meta_tasks/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/meta_tasks/aliases
+++ b/test/integration/targets/meta_tasks/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/meta_tasks/runme.sh b/test/integration/targets/meta_tasks/runme.sh
index 3ee419cb..f5916ec7 100755
--- a/test/integration/targets/meta_tasks/runme.sh
+++ b/test/integration/targets/meta_tasks/runme.sh
@@ -49,4 +49,19 @@ for test_strategy in linear free; do
grep -q "META: ending play" <<< "$out"
grep -qv 'Failed to end using end_play' <<< "$out"
+
+ out="$(ansible-playbook test_end_play_serial_one.yml -i inventory.yml -e test_strategy=$test_strategy -vv "$@")"
+
+ [ "$(grep -c "Testing end_play on host" <<< "$out" )" -eq 1 ]
+ grep -q "META: ending play" <<< "$out"
+ grep -qv 'Failed to end using end_play' <<< "$out"
+done
+
+# test end_batch meta task
+for test_strategy in linear free; do
+ out="$(ansible-playbook test_end_batch.yml -i inventory.yml -e test_strategy=$test_strategy -vv "$@")"
+
+ [ "$(grep -c "Using end_batch" <<< "$out" )" -eq 2 ]
+ [ "$(grep -c "META: ending batch" <<< "$out" )" -eq 2 ]
+ grep -qv 'Failed to end_batch' <<< "$out"
done
diff --git a/test/integration/targets/meta_tasks/test_end_batch.yml b/test/integration/targets/meta_tasks/test_end_batch.yml
new file mode 100644
index 00000000..4af020af
--- /dev/null
+++ b/test/integration/targets/meta_tasks/test_end_batch.yml
@@ -0,0 +1,13 @@
+- name: Testing end_batch with strategy {{ test_strategy | default('linear') }}
+ hosts: testhost:testhost2
+ gather_facts: no
+ serial: 1
+ strategy: "{{ test_strategy | default('linear') }}"
+ tasks:
+ - debug:
+ msg: "Using end_batch, current host: {{ inventory_hostname }}, current batch: {{ ansible_play_batch }}"
+
+ - meta: end_batch
+
+ - fail:
+ msg: "Failed to end_batch, current host: {{ inventory_hostname }}, current batch: {{ ansible_play_batch }}"
diff --git a/test/integration/targets/meta_tasks/test_end_play_serial_one.yml b/test/integration/targets/meta_tasks/test_end_play_serial_one.yml
new file mode 100644
index 00000000..f838d4a6
--- /dev/null
+++ b/test/integration/targets/meta_tasks/test_end_play_serial_one.yml
@@ -0,0 +1,13 @@
+- name: Testing end_play with serial 1 and strategy {{ test_strategy | default('linear') }}
+ hosts: testhost:testhost2
+ gather_facts: no
+ serial: 1
+ strategy: "{{ test_strategy | default('linear') }}"
+ tasks:
+ - debug:
+ msg: "Testing end_play on host {{ inventory_hostname }}"
+
+ - meta: end_play
+
+ - fail:
+ msg: 'Failed to end using end_play'
diff --git a/test/integration/targets/missing_required_lib/aliases b/test/integration/targets/missing_required_lib/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/missing_required_lib/aliases
+++ b/test/integration/targets/missing_required_lib/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/module_defaults/action_plugins/debug.py b/test/integration/targets/module_defaults/action_plugins/debug.py
new file mode 100644
index 00000000..2584fd3d
--- /dev/null
+++ b/test/integration/targets/module_defaults/action_plugins/debug.py
@@ -0,0 +1,80 @@
+# Copyright 2012, Dag Wieers <dag@wieers.com>
+# Copyright 2016, Toshio Kuratomi <tkuratomi@ansible.com>
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible.errors import AnsibleUndefinedVariable
+from ansible.module_utils.six import string_types
+from ansible.module_utils._text import to_text
+from ansible.plugins.action import ActionBase
+
+
+class ActionModule(ActionBase):
+ ''' Print statements during execution '''
+
+ TRANSFERS_FILES = False
+ _VALID_ARGS = frozenset(('msg', 'var', 'verbosity'))
+
+ def run(self, tmp=None, task_vars=None):
+ if task_vars is None:
+ task_vars = dict()
+
+ if 'msg' in self._task.args and 'var' in self._task.args:
+ return {"failed": True, "msg": "'msg' and 'var' are incompatible options"}
+
+ result = super(ActionModule, self).run(tmp, task_vars)
+ del tmp # tmp no longer has any effect
+
+ # get task verbosity
+ verbosity = int(self._task.args.get('verbosity', 0))
+
+ if verbosity <= self._display.verbosity:
+ if 'msg' in self._task.args:
+ result['msg'] = self._task.args['msg']
+
+ elif 'var' in self._task.args:
+ try:
+ results = self._templar.template(self._task.args['var'], convert_bare=True, fail_on_undefined=True)
+ if results == self._task.args['var']:
+ # if results is not str/unicode type, raise an exception
+ if not isinstance(results, string_types):
+ raise AnsibleUndefinedVariable
+ # If var name is same as result, try to template it
+ results = self._templar.template("{{" + results + "}}", convert_bare=True, fail_on_undefined=True)
+ except AnsibleUndefinedVariable as e:
+ results = u"VARIABLE IS NOT DEFINED!"
+ if self._display.verbosity > 0:
+ results += u": %s" % to_text(e)
+
+ if isinstance(self._task.args['var'], (list, dict)):
+ # If var is a list or dict, use the type as key to display
+ result[to_text(type(self._task.args['var']))] = results
+ else:
+ result[self._task.args['var']] = results
+ else:
+ result['msg'] = 'Hello world!'
+
+ # force flag to make debug output module always verbose
+ result['_ansible_verbose_always'] = True
+ else:
+ result['skipped_reason'] = "Verbosity threshold not met."
+ result['skipped'] = True
+
+ result['failed'] = False
+
+ return result
diff --git a/test/integration/targets/module_defaults/aliases b/test/integration/targets/module_defaults/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/module_defaults/aliases
+++ b/test/integration/targets/module_defaults/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/meta/runtime.yml b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/meta/runtime.yml
index 62695fbc..081ee8c2 100644
--- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/meta/runtime.yml
+++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/meta/runtime.yml
@@ -1,5 +1,10 @@
action_groups:
testgroup:
+ # Test metadata 'extend_group' feature does not get stuck in a recursive loop
+ - metadata:
+ extend_group: othergroup
+ - metadata
+ - ping
- testns.testcoll.echo1
- testns.testcoll.echo2
# note we can define defaults for an action
@@ -7,3 +12,28 @@ action_groups:
# note we can define defaults in this group for actions/modules in another collection
- testns.othercoll.other_echoaction
- testns.othercoll.other_echo1
+ othergroup:
+ - metadata:
+ extend_group:
+ - testgroup
+ empty_metadata:
+ - metadata: {}
+ bad_metadata_format:
+ - unexpected_key:
+ key: value
+ metadata:
+ extend_group: testgroup
+ multiple_metadata:
+ - metadata:
+ extend_group: testgroup
+ - metadata:
+ extend_group: othergroup
+ bad_metadata_options:
+ - metadata:
+ unexpected_key: testgroup
+ bad_metadata_type:
+ - metadata: [testgroup]
+ bad_metadata_option_type:
+ - metadata:
+ extend_group:
+ name: testgroup
diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/metadata.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/metadata.py
new file mode 100644
index 00000000..6a818fd8
--- /dev/null
+++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/metadata.py
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: metadata
+version_added: 2.12
+short_description: Test module with a specific name
+description: Test module with a specific name
+options:
+ data:
+ description: Required option to test module_defaults work
+ required: True
+ type: str
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ data=dict(type='str', required=True),
+ ),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ping.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ping.py
new file mode 100644
index 00000000..2cb1fb23
--- /dev/null
+++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ping.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
+# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: ping
+version_added: historical
+short_description: Try to connect to host, verify a usable python and return C(pong) on success
+description:
+ - A trivial test module, this module always returns C(pong) on successful
+ contact. It does not make sense in playbooks, but it is useful from
+ C(/usr/bin/ansible) to verify the ability to login and that a usable Python is configured.
+ - This is NOT ICMP ping, this is just a trivial test module that requires Python on the remote-node.
+ - For Windows targets, use the M(ansible.windows.win_ping) module instead.
+ - For Network targets, use the M(ansible.netcommon.net_ping) module instead.
+options:
+ data:
+ description:
+ - Data to return for the C(ping) return value.
+ - If this parameter is set to C(crash), the module will cause an exception.
+ type: str
+ default: pong
+seealso:
+ - module: ansible.netcommon.net_ping
+ - module: ansible.windows.win_ping
+author:
+ - Ansible Core Team
+ - Michael DeHaan
+notes:
+ - Supports C(check_mode).
+'''
+
+EXAMPLES = '''
+# Test we can logon to 'webservers' and execute python with json lib.
+# ansible webservers -m ping
+
+- name: Example from an Ansible Playbook
+ ansible.builtin.ping:
+
+- name: Induce an exception to see what happens
+ ansible.builtin.ping:
+ data: crash
+'''
+
+RETURN = '''
+ping:
+ description: Value provided with the data parameter.
+ returned: success
+ type: str
+ sample: pong
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ data=dict(type='str', default='pong'),
+ ),
+ supports_check_mode=True
+ )
+
+ if module.params['data'] == 'crash':
+ raise Exception("boom")
+
+ result = dict(
+ ping=module.params['data'],
+ )
+
+ module.exit_json(**result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/module_defaults/library/legacy_ping.py b/test/integration/targets/module_defaults/library/legacy_ping.py
new file mode 100644
index 00000000..2cb1fb23
--- /dev/null
+++ b/test/integration/targets/module_defaults/library/legacy_ping.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
+# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: ping
+version_added: historical
+short_description: Try to connect to host, verify a usable python and return C(pong) on success
+description:
+ - A trivial test module, this module always returns C(pong) on successful
+ contact. It does not make sense in playbooks, but it is useful from
+ C(/usr/bin/ansible) to verify the ability to login and that a usable Python is configured.
+ - This is NOT ICMP ping, this is just a trivial test module that requires Python on the remote-node.
+ - For Windows targets, use the M(ansible.windows.win_ping) module instead.
+ - For Network targets, use the M(ansible.netcommon.net_ping) module instead.
+options:
+ data:
+ description:
+ - Data to return for the C(ping) return value.
+ - If this parameter is set to C(crash), the module will cause an exception.
+ type: str
+ default: pong
+seealso:
+ - module: ansible.netcommon.net_ping
+ - module: ansible.windows.win_ping
+author:
+ - Ansible Core Team
+ - Michael DeHaan
+notes:
+ - Supports C(check_mode).
+'''
+
+EXAMPLES = '''
+# Test we can logon to 'webservers' and execute python with json lib.
+# ansible webservers -m ping
+
+- name: Example from an Ansible Playbook
+ ansible.builtin.ping:
+
+- name: Induce an exception to see what happens
+ ansible.builtin.ping:
+ data: crash
+'''
+
+RETURN = '''
+ping:
+ description: Value provided with the data parameter.
+ returned: success
+ type: str
+ sample: pong
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ data=dict(type='str', default='pong'),
+ ),
+ supports_check_mode=True
+ )
+
+ if module.params['data'] == 'crash':
+ raise Exception("boom")
+
+ result = dict(
+ ping=module.params['data'],
+ )
+
+ module.exit_json(**result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/module_defaults/runme.sh b/test/integration/targets/module_defaults/runme.sh
index c19e607b..082f4e5b 100755
--- a/test/integration/targets/module_defaults/runme.sh
+++ b/test/integration/targets/module_defaults/runme.sh
@@ -3,3 +3,7 @@
set -eux
ansible-playbook test_defaults.yml "$@"
+
+ansible-playbook test_action_groups.yml "$@"
+
+ansible-playbook test_action_group_metadata.yml "$@"
diff --git a/test/integration/targets/module_defaults/tasks/main.yml b/test/integration/targets/module_defaults/tasks/main.yml
index 3ed960d3..747c2f92 100644
--- a/test/integration/targets/module_defaults/tasks/main.yml
+++ b/test/integration/targets/module_defaults/tasks/main.yml
@@ -39,7 +39,7 @@
module_defaults:
# Meaningless values to make sure that 'module_defaults' gets
# evaluated for this block
- foo:
+ ping:
bar: baz
block:
- debug:
diff --git a/test/integration/targets/module_defaults/templates/test_metadata_warning.yml.j2 b/test/integration/targets/module_defaults/templates/test_metadata_warning.yml.j2
new file mode 100644
index 00000000..b45aaba2
--- /dev/null
+++ b/test/integration/targets/module_defaults/templates/test_metadata_warning.yml.j2
@@ -0,0 +1,8 @@
+---
+- hosts: localhost
+ gather_facts: no
+ module_defaults:
+ group/{{ group_name }}:
+ data: value
+ tasks:
+ - ping:
diff --git a/test/integration/targets/module_defaults/test_action_group_metadata.yml b/test/integration/targets/module_defaults/test_action_group_metadata.yml
new file mode 100644
index 00000000..d2ba8dc2
--- /dev/null
+++ b/test/integration/targets/module_defaults/test_action_group_metadata.yml
@@ -0,0 +1,123 @@
+---
+- hosts: localhost
+ gather_facts: no
+ vars:
+ reset_color: '\x1b\[0m'
+ color: '\x1b\[[0-9];[0-9]{2}m'
+ tasks:
+
+ - template:
+ src: test_metadata_warning.yml.j2
+ dest: test_metadata_warning.yml
+ vars:
+ group_name: testns.testcoll.empty_metadata
+
+ - command: ansible-playbook test_metadata_warning.yml
+ register: result
+
+ - assert:
+ that: metadata_warning not in warnings
+ vars:
+ warnings: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ metadata_warning: "Invalid metadata was found"
+
+ - template:
+ src: test_metadata_warning.yml.j2
+ dest: test_metadata_warning.yml
+ vars:
+ group_name: testns.testcoll.bad_metadata_format
+
+ - command: ansible-playbook test_metadata_warning.yml
+ register: result
+
+ - assert:
+ that: metadata_warning in warnings
+ vars:
+ warnings: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ metadata_warning: >-
+ Invalid metadata was found for action_group testns.testcoll.bad_metadata_format while loading module_defaults.
+ The only expected key is metadata, but got keys: metadata, unexpected_key
+
+ - template:
+ src: test_metadata_warning.yml.j2
+ dest: test_metadata_warning.yml
+ vars:
+ group_name: testns.testcoll.multiple_metadata
+
+ - command: ansible-playbook test_metadata_warning.yml
+ register: result
+
+ - assert:
+ that: metadata_warning in warnings
+ vars:
+ warnings: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ metadata_warning: >-
+ Invalid metadata was found for action_group testns.testcoll.multiple_metadata while loading module_defaults.
+ The group contains multiple metadata entries.
+
+ - template:
+ src: test_metadata_warning.yml.j2
+ dest: test_metadata_warning.yml
+ vars:
+ group_name: testns.testcoll.bad_metadata_options
+
+ - command: 'ansible-playbook test_metadata_warning.yml'
+ register: result
+
+ - assert:
+ that: metadata_warning in warnings
+ vars:
+ warnings: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ metadata_warning: >-
+ Invalid metadata was found for action_group testns.testcoll.bad_metadata_options while loading module_defaults.
+ The metadata contains unexpected keys: unexpected_key
+
+ - template:
+ src: test_metadata_warning.yml.j2
+ dest: test_metadata_warning.yml
+ vars:
+ group_name: testns.testcoll.bad_metadata_type
+
+ - command: ansible-playbook test_metadata_warning.yml
+ register: result
+
+ - assert:
+ that: metadata_warning in warnings
+ vars:
+ warnings: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ metadata_warning: >-
+ Invalid metadata was found for action_group testns.testcoll.bad_metadata_type while loading module_defaults.
+ The metadata is not a dictionary. Got ['testgroup']
+
+ - template:
+ src: test_metadata_warning.yml.j2
+ dest: test_metadata_warning.yml
+ vars:
+ group_name: testns.testcoll.bad_metadata_option_type
+
+ - command: ansible-playbook test_metadata_warning.yml
+ register: result
+
+ - assert:
+ that: metadata_warning in warnings
+ vars:
+ warnings: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ metadata_warning: >-
+ Invalid metadata was found for action_group testns.testcoll.bad_metadata_option_type while loading module_defaults.
+ The metadata contains unexpected key types: extend_group is {'name': 'testgroup'} (expected type list)
+
+ - name: test disabling action_group metadata validation
+ command: ansible-playbook test_metadata_warning.yml
+ environment:
+ ANSIBLE_VALIDATE_ACTION_GROUP_METADATA: False
+ register: result
+
+ - assert:
+ that: metadata_warning not in warnings
+ vars:
+ warnings: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ metadata_warning: "Invalid metadata was found for action_group"
+
+ - file:
+ path: test_metadata_warning.yml
+ state: absent
diff --git a/test/integration/targets/module_defaults/test_action_groups.yml b/test/integration/targets/module_defaults/test_action_groups.yml
new file mode 100644
index 00000000..33a3c9c5
--- /dev/null
+++ b/test/integration/targets/module_defaults/test_action_groups.yml
@@ -0,0 +1,132 @@
+---
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: test ansible.legacy short group name
+ module_defaults:
+ group/testgroup:
+ data: test
+ block:
+ - legacy_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'pong'"
+
+ - ansible.legacy.legacy_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'pong'"
+
+ - ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - ansible.legacy.ping: # resolves to ansible.builtin.ping
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - ansible.builtin.ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - formerly_core_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - ansible.builtin.formerly_core_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - name: test group that includes a legacy action
+ module_defaults:
+ # As of 2.12, legacy actions must be included in the action group definition
+ group/testlegacy:
+ data: test
+ block:
+ - legacy_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - ansible.legacy.legacy_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - name: test ansible.builtin fully qualified group name
+ module_defaults:
+ group/ansible.builtin.testgroup:
+ data: test
+ block:
+ # ansible.builtin does not contain ansible.legacy
+ - legacy_ping:
+ register: result
+ - assert:
+ that: "result.ping != 'test'"
+
+ # ansible.builtin does not contain ansible.legacy
+ - ansible.legacy.legacy_ping:
+ register: result
+ - assert:
+ that: "result.ping != 'test'"
+
+ - ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ # Resolves to ansible.builtin.ping
+ - ansible.legacy.ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - ansible.builtin.ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - formerly_core_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - ansible.builtin.formerly_core_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - name: test collection group name
+ module_defaults:
+ group/testns.testcoll.testgroup:
+ data: test
+ block:
+ # Plugin resolving to a different collection does not get the default
+ - ping:
+ register: result
+ - assert:
+ that: "result.ping != 'test'"
+
+ - formerly_core_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - ansible.builtin.formerly_core_ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - testns.testcoll.ping:
+ register: result
+ - assert:
+ that: "result.ping == 'test'"
+
+ - metadata:
+ collections:
+ - testns.testcoll
diff --git a/test/integration/targets/module_defaults/test_defaults.yml b/test/integration/targets/module_defaults/test_defaults.yml
index 15b66362..70377f12 100644
--- a/test/integration/targets/module_defaults/test_defaults.yml
+++ b/test/integration/targets/module_defaults/test_defaults.yml
@@ -44,6 +44,51 @@
- debug: var=echo1_fq
+ - legacy_ping:
+ register: legacy_ping_1
+ module_defaults:
+ legacy_ping:
+ data: from task
+
+ - legacy_ping:
+ register: legacy_ping_2
+ module_defaults:
+ ansible.legacy.legacy_ping:
+ data: from task
+
+ - ansible.legacy.legacy_ping:
+ register: legacy_ping_3
+ module_defaults:
+ legacy_ping:
+ data: from task
+
+ - ansible.legacy.legacy_ping:
+ register: legacy_ping_4
+ module_defaults:
+ ansible.legacy.legacy_ping:
+ data: from task
+
+ - name: builtin uses legacy defaults
+ ansible.builtin.debug:
+ module_defaults:
+ debug:
+ msg: legacy default
+ register: builtin_legacy_defaults_1
+
+ - name: builtin uses legacy defaults
+ ansible.builtin.debug:
+ module_defaults:
+ ansible.legacy.debug:
+ msg: legacy default
+ register: builtin_legacy_defaults_2
+
+ - name: legacy does not use builtin defaults
+ ansible.legacy.debug:
+ register: legacy_builtin_defaults
+ module_defaults:
+ ansible.builtin.debug:
+ msg: legacy default
+
- assert:
that:
- "echoaction_fq.args_in == {'task_arg': 'from task', 'explicit_module_default': 'from playbook', 'group_module_default': 'from playbook' }"
@@ -56,5 +101,12 @@
- "other_echoaction_unq.args_in == {'task_arg': 'from task', 'group_module_default': 'from playbook' }"
- "other_echo1_fq.args_in == {'task_arg': 'from task', 'group_module_default': 'from playbook' }"
- "other_echo1_unq.args_in == {'task_arg': 'from task', 'group_module_default': 'from playbook' }"
+ - "legacy_ping_1.ping == 'from task'"
+ - "legacy_ping_2.ping == 'from task'"
+ - "legacy_ping_3.ping == 'from task'"
+ - "legacy_ping_4.ping == 'from task'"
+ - "legacy_builtin_defaults.msg == 'Hello world!'"
+ - "builtin_legacy_defaults_1.msg == 'legacy default'"
+ - "builtin_legacy_defaults_2.msg == 'legacy default'"
- include_tasks: tasks/main.yml
diff --git a/test/integration/targets/module_no_log/aliases b/test/integration/targets/module_no_log/aliases
index cbbb8804..2e263309 100644
--- a/test/integration/targets/module_no_log/aliases
+++ b/test/integration/targets/module_no_log/aliases
@@ -1,5 +1,5 @@
shippable/posix/group1
-skip/aix # not configured to log user.info to /var/log/syslog
+context/controller
skip/freebsd # not configured to log user.info to /var/log/syslog
skip/osx # not configured to log user.info to /var/log/syslog
skip/macos # not configured to log user.info to /var/log/syslog
diff --git a/test/integration/targets/module_precedence/aliases b/test/integration/targets/module_precedence/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/module_precedence/aliases
+++ b/test/integration/targets/module_precedence/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/module_tracebacks/aliases b/test/integration/targets/module_tracebacks/aliases
index 804f0460..757f4fb8 100644
--- a/test/integration/targets/module_tracebacks/aliases
+++ b/test/integration/targets/module_tracebacks/aliases
@@ -1,3 +1,3 @@
shippable/posix/group4
needs/ssh
-skip/aix
+context/controller
diff --git a/test/integration/targets/module_utils/aliases b/test/integration/targets/module_utils/aliases
index 2f5770ff..769d265d 100644
--- a/test/integration/targets/module_utils/aliases
+++ b/test/integration/targets/module_utils/aliases
@@ -1,3 +1,4 @@
shippable/posix/group3
needs/root
needs/target/setup_nobody
+context/target
diff --git a/test/integration/targets/module_utils/module_utils_basic_setcwd.yml b/test/integration/targets/module_utils/module_utils_basic_setcwd.yml
index 97dbf873..2b2b6dbd 100644
--- a/test/integration/targets/module_utils/module_utils_basic_setcwd.yml
+++ b/test/integration/targets/module_utils/module_utils_basic_setcwd.yml
@@ -15,8 +15,14 @@
become: yes
become_user: nobody # root can read cwd regardless of permissions, so a non-root user is required here
+ - name: get real path of home directory of the unprivileged user
+ raw: "{{ ansible_python_interpreter }} -c 'import os.path; print(os.path.realpath(os.path.expanduser(\"~\")))'"
+ register: home
+ become: yes
+ become_user: nobody
+
- name: verify AnsibleModule was able to adjust cwd as expected
assert:
that:
- missing.before != missing.after
- - unreadable.before != unreadable.after or unreadable.before == '/' # allow / fallback on macOS when using an unprivileged user
+ - unreadable.before != unreadable.after or unreadable.before == '/' or unreadable.before == home.stdout.strip() # allow / and $HOME fallback on macOS when using an unprivileged user
diff --git a/test/integration/targets/module_utils/module_utils_test.yml b/test/integration/targets/module_utils/module_utils_test.yml
index 96b2a9e0..a6019cda 100644
--- a/test/integration/targets/module_utils/module_utils_test.yml
+++ b/test/integration/targets/module_utils/module_utils_test.yml
@@ -57,8 +57,8 @@
- name: Assert that the deprecation message is given correctly
assert:
that:
- - result.deprecations[0].msg == "Alias 'baz' is deprecated. See the module docs for more information"
- - result.deprecations[0].version == '9.99'
+ - result.deprecations[-1].msg == "Alias 'baz' is deprecated. See the module docs for more information"
+ - result.deprecations[-1].version == '9.99'
- block:
- name: Get a string with a \0 in it
diff --git a/test/integration/targets/module_utils/module_utils_test_no_log.yml b/test/integration/targets/module_utils/module_utils_test_no_log.yml
index bad2efd4..2fa3e101 100644
--- a/test/integration/targets/module_utils/module_utils_test_no_log.yml
+++ b/test/integration/targets/module_utils/module_utils_test_no_log.yml
@@ -7,3 +7,6 @@
explicit_pass: abc
suboption:
explicit_sub_pass: def
+ environment:
+ SECRET_ENV: ghi
+ SECRET_SUB_ENV: jkl
diff --git a/test/integration/targets/module_utils/module_utils_vvvvv.yml b/test/integration/targets/module_utils/module_utils_vvvvv.yml
index 6a9f9201..fc2b0c1c 100644
--- a/test/integration/targets/module_utils/module_utils_vvvvv.yml
+++ b/test/integration/targets/module_utils/module_utils_vvvvv.yml
@@ -7,11 +7,10 @@
# Invocation usually is output with 3vs or more, our callback plugin displays it anyway
- name: Check no_log invocation results
command: ansible-playbook -i {{ inventory_file }} module_utils_test_no_log.yml
+ delegate_to: localhost
environment:
ANSIBLE_CALLBACK_PLUGINS: callback
ANSIBLE_STDOUT_CALLBACK: pure_json
- SECRET_ENV: ghi
- SECRET_SUB_ENV: jkl
register: no_log_invocation
- set_fact:
diff --git a/test/integration/targets/module_utils_common.respawn/aliases b/test/integration/targets/module_utils_common.respawn/aliases
new file mode 100644
index 00000000..a6dafcf8
--- /dev/null
+++ b/test/integration/targets/module_utils_common.respawn/aliases
@@ -0,0 +1 @@
+shippable/posix/group1
diff --git a/test/integration/targets/module_utils_respawn/library/respawnme.py b/test/integration/targets/module_utils_common.respawn/library/respawnme.py
index 6471dba4..6471dba4 100644
--- a/test/integration/targets/module_utils_respawn/library/respawnme.py
+++ b/test/integration/targets/module_utils_common.respawn/library/respawnme.py
diff --git a/test/integration/targets/module_utils_respawn/tasks/main.yml b/test/integration/targets/module_utils_common.respawn/tasks/main.yml
index 246c8f74..246c8f74 100644
--- a/test/integration/targets/module_utils_respawn/tasks/main.yml
+++ b/test/integration/targets/module_utils_common.respawn/tasks/main.yml
diff --git a/test/integration/targets/module_utils_distro/aliases b/test/integration/targets/module_utils_distro/aliases
new file mode 100644
index 00000000..8278ec8b
--- /dev/null
+++ b/test/integration/targets/module_utils_distro/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/module_utils_distro/meta/main.yml b/test/integration/targets/module_utils_distro/meta/main.yml
new file mode 100644
index 00000000..1810d4be
--- /dev/null
+++ b/test/integration/targets/module_utils_distro/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/test/integration/targets/module_utils_distro/runme.sh b/test/integration/targets/module_utils_distro/runme.sh
new file mode 100755
index 00000000..e5d3d053
--- /dev/null
+++ b/test/integration/targets/module_utils_distro/runme.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+set -eux
+
+# Ensure that when a non-distro 'distro' package is in PYTHONPATH, we fallback
+# to our bundled one.
+new_pythonpath="$OUTPUT_DIR/pythonpath"
+mkdir -p "$new_pythonpath/distro"
+touch "$new_pythonpath/distro/__init__.py"
+
+export PYTHONPATH="$new_pythonpath:$PYTHONPATH"
+
+# Sanity test to make sure the above worked
+set +e
+distro_id_fail="$(python -c 'import distro; distro.id' 2>&1)"
+set -e
+grep -q "AttributeError:.*has no attribute 'id'" <<< "$distro_id_fail"
+
+# ansible.module_utils.common.sys_info imports distro, and itself gets imported
+# in DataLoader, so all we have to do to test the fallback is run `ansible`.
+ansirun="$(ansible -i ../../inventory -a "echo \$PYTHONPATH" localhost)"
+grep -q "$new_pythonpath" <<< "$ansirun"
+
+rm -rf "$new_pythonpath"
diff --git a/test/integration/targets/module_utils_selinux/aliases b/test/integration/targets/module_utils_facts.system.selinux/aliases
index aab3ff52..ee281d27 100644
--- a/test/integration/targets/module_utils_selinux/aliases
+++ b/test/integration/targets/module_utils_facts.system.selinux/aliases
@@ -1,5 +1,4 @@
shippable/posix/group1
-skip/aix
skip/osx
skip/macos
skip/freebsd
diff --git a/test/integration/targets/module_utils_selinux/tasks/main.yml b/test/integration/targets/module_utils_facts.system.selinux/tasks/main.yml
index c599377b..c599377b 100644
--- a/test/integration/targets/module_utils_selinux/tasks/main.yml
+++ b/test/integration/targets/module_utils_facts.system.selinux/tasks/main.yml
diff --git a/test/integration/targets/module_utils_selinux/tasks/selinux.yml b/test/integration/targets/module_utils_facts.system.selinux/tasks/selinux.yml
index 6a2b159c..6a2b159c 100644
--- a/test/integration/targets/module_utils_selinux/tasks/selinux.yml
+++ b/test/integration/targets/module_utils_facts.system.selinux/tasks/selinux.yml
diff --git a/test/integration/targets/no_log/aliases b/test/integration/targets/no_log/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/no_log/aliases
+++ b/test/integration/targets/no_log/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/noexec/aliases b/test/integration/targets/noexec/aliases
index 66a77c7b..edabc85a 100644
--- a/test/integration/targets/noexec/aliases
+++ b/test/integration/targets/noexec/aliases
@@ -1,3 +1,4 @@
shippable/posix/group2
+context/controller
skip/docker
skip/macos
diff --git a/test/integration/targets/old_style_cache_plugins/aliases b/test/integration/targets/old_style_cache_plugins/aliases
index 05f65b71..c7c77ce6 100644
--- a/test/integration/targets/old_style_cache_plugins/aliases
+++ b/test/integration/targets/old_style_cache_plugins/aliases
@@ -1,4 +1,6 @@
+destructive
+needs/root
shippable/posix/group3
+context/controller
skip/osx
skip/macos
-disabled
diff --git a/test/integration/targets/old_style_cache_plugins/cleanup.yml b/test/integration/targets/old_style_cache_plugins/cleanup.yml
new file mode 100644
index 00000000..93f5cc58
--- /dev/null
+++ b/test/integration/targets/old_style_cache_plugins/cleanup.yml
@@ -0,0 +1,41 @@
+---
+- hosts: localhost
+ gather_facts: no
+ ignore_errors: yes
+ tasks:
+ - command: redis-cli keys
+
+ - name: delete cache keys
+ command: redis-cli del {{ item }}
+ loop:
+ - ansible_facts_localhost
+ - ansible_inventory_localhost
+ - ansible_cache_keys
+
+ - name: shutdown the server
+ command: redis-cli shutdown
+
+ - name: cleanup set up files
+ file:
+ path: "{{ item }}"
+ state: absent
+ loop:
+ - redis-stable.tar.gz
+
+ - name: remove executables
+ file:
+ state: absent
+ path: "/usr/local/bin/{{ item }}"
+ follow: no
+ become: yes
+ loop:
+ - redis-server
+ - redis-cli
+
+ - name: clean the rest of the files
+ file:
+ path: "{{ item }}"
+ state: absent
+ loop:
+ - ./redis-stable.tar.gz
+ - ./redis-stable
diff --git a/test/integration/targets/old_style_cache_plugins/inspect_cache.yml b/test/integration/targets/old_style_cache_plugins/inspect_cache.yml
new file mode 100644
index 00000000..72810e19
--- /dev/null
+++ b/test/integration/targets/old_style_cache_plugins/inspect_cache.yml
@@ -0,0 +1,36 @@
+---
+- hosts: localhost
+ gather_facts: no
+ vars:
+ json_cache: "{{ cache.stdout | from_json }}"
+ tasks:
+ - command: redis-cli get ansible_facts_localhost
+ register: cache
+ tags:
+ - always
+
+ - name: test that the cache only contains the set_fact var
+ assert:
+ that:
+ - "json_cache | length == 1"
+ - "json_cache.foo == ansible_facts.foo"
+ tags:
+ - set_fact
+
+ - name: test that the cache contains gathered facts and the var
+ assert:
+ that:
+ - "json_cache | length > 1"
+ - "json_cache.foo == 'bar'"
+ - "json_cache.ansible_distribution is defined"
+ tags:
+ - additive_gather_facts
+
+ - name: test that the cache contains only gathered facts
+ assert:
+ that:
+ - "json_cache | length > 1"
+ - "json_cache.foo is undefined"
+ - "json_cache.ansible_distribution is defined"
+ tags:
+ - gather_facts
diff --git a/test/integration/targets/old_style_cache_plugins/plugins/cache/configurable_redis.py b/test/integration/targets/old_style_cache_plugins/plugins/cache/configurable_redis.py
new file mode 100644
index 00000000..44b6cf93
--- /dev/null
+++ b/test/integration/targets/old_style_cache_plugins/plugins/cache/configurable_redis.py
@@ -0,0 +1,147 @@
+# (c) 2014, Brian Coca, Josh Drake, et al
+# (c) 2017 Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+ cache: configurable_redis
+ short_description: Use Redis DB for cache
+ description:
+ - This cache uses JSON formatted, per host records saved in Redis.
+ version_added: "1.9"
+ requirements:
+ - redis>=2.4.5 (python lib)
+ options:
+ _uri:
+ description:
+ - A colon separated string of connection information for Redis.
+ required: True
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_CONNECTION
+ ini:
+ - key: fact_caching_connection
+ section: defaults
+ _prefix:
+ description: User defined prefix to use when creating the DB entries
+ default: ansible_facts
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_PREFIX
+ ini:
+ - key: fact_caching_prefix
+ section: defaults
+ _timeout:
+ default: 86400
+ description: Expiration timeout for the cache plugin data
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_TIMEOUT
+ ini:
+ - key: fact_caching_timeout
+ section: defaults
+ type: integer
+'''
+
+import time
+import json
+
+from ansible import constants as C
+from ansible.errors import AnsibleError
+from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
+from ansible.plugins.cache import BaseCacheModule
+from ansible.utils.display import Display
+
+try:
+ from redis import StrictRedis, VERSION
+except ImportError:
+ raise AnsibleError("The 'redis' python module (version 2.4.5 or newer) is required for the redis fact cache, 'pip install redis'")
+
+display = Display()
+
+
+class CacheModule(BaseCacheModule):
+ """
+ A caching module backed by redis.
+ Keys are maintained in a zset with their score being the timestamp
+ when they are inserted. This allows for the usage of 'zremrangebyscore'
+ to expire keys. This mechanism is used or a pattern matched 'scan' for
+ performance.
+ """
+ def __init__(self, *args, **kwargs):
+ connection = []
+
+ super(CacheModule, self).__init__(*args, **kwargs)
+ if self.get_option('_uri'):
+ connection = self.get_option('_uri').split(':')
+ self._timeout = float(self.get_option('_timeout'))
+ self._prefix = self.get_option('_prefix')
+
+ self._cache = {}
+ self._db = StrictRedis(*connection)
+ self._keys_set = 'ansible_cache_keys'
+
+ def _make_key(self, key):
+ return self._prefix + key
+
+ def get(self, key):
+
+ if key not in self._cache:
+ value = self._db.get(self._make_key(key))
+ # guard against the key not being removed from the zset;
+ # this could happen in cases where the timeout value is changed
+ # between invocations
+ if value is None:
+ self.delete(key)
+ raise KeyError
+ self._cache[key] = json.loads(value, cls=AnsibleJSONDecoder)
+
+ return self._cache.get(key)
+
+ def set(self, key, value):
+
+ value2 = json.dumps(value, cls=AnsibleJSONEncoder, sort_keys=True, indent=4)
+ if self._timeout > 0: # a timeout of 0 is handled as meaning 'never expire'
+ self._db.setex(self._make_key(key), int(self._timeout), value2)
+ else:
+ self._db.set(self._make_key(key), value2)
+
+ if VERSION[0] == 2:
+ self._db.zadd(self._keys_set, time.time(), key)
+ else:
+ self._db.zadd(self._keys_set, {key: time.time()})
+ self._cache[key] = value
+
+ def _expire_keys(self):
+ if self._timeout > 0:
+ expiry_age = time.time() - self._timeout
+ self._db.zremrangebyscore(self._keys_set, 0, expiry_age)
+
+ def keys(self):
+ self._expire_keys()
+ return self._db.zrange(self._keys_set, 0, -1)
+
+ def contains(self, key):
+ self._expire_keys()
+ return (self._db.zrank(self._keys_set, key) is not None)
+
+ def delete(self, key):
+ if key in self._cache:
+ del self._cache[key]
+ self._db.delete(self._make_key(key))
+ self._db.zrem(self._keys_set, key)
+
+ def flush(self):
+ for key in self.keys():
+ self.delete(key)
+
+ def copy(self):
+ # TODO: there is probably a better way to do this in redis
+ ret = dict()
+ for key in self.keys():
+ ret[key] = self.get(key)
+ return ret
+
+ def __getstate__(self):
+ return dict()
+
+ def __setstate__(self, data):
+ self.__init__()
diff --git a/test/integration/targets/old_style_cache_plugins/plugins/cache/redis.py b/test/integration/targets/old_style_cache_plugins/plugins/cache/legacy_redis.py
index 9879dec9..9879dec9 100644
--- a/test/integration/targets/old_style_cache_plugins/plugins/cache/redis.py
+++ b/test/integration/targets/old_style_cache_plugins/plugins/cache/legacy_redis.py
diff --git a/test/integration/targets/old_style_cache_plugins/runme.sh b/test/integration/targets/old_style_cache_plugins/runme.sh
index 13911bd5..ffa6723b 100755
--- a/test/integration/targets/old_style_cache_plugins/runme.sh
+++ b/test/integration/targets/old_style_cache_plugins/runme.sh
@@ -4,77 +4,44 @@ set -eux
source virtualenv.sh
-# Run test if dependencies are installed
-failed_dep_1=$(ansible localhost -m pip -a "name=redis>=2.4.5 state=present" "$@" | tee out.txt | grep -c 'FAILED!' || true)
-cat out.txt
+trap 'ansible-playbook cleanup.yml' EXIT
-installed_redis=$(ansible localhost -m package -a "name=redis-server state=present" --become "$@" | tee out.txt | grep -c '"changed": true' || true)
-failed_dep_2=$(grep out.txt -ce 'FAILED!' || true)
-cat out.txt
+export PATH="$PATH:/usr/local/bin"
-started_redis=$(ansible localhost -m service -a "name=redis-server state=started" --become "$@" | tee out.txt | grep -c '"changed": true' || true)
-failed_dep_3=$(grep out.txt -ce 'FAILED!' || true)
-cat out.txt
+ansible-playbook setup_redis_cache.yml "$@"
-CLEANUP_REDIS () { if [ "${installed_redis}" -eq 1 ] ; then ansible localhost -m package -a "name=redis-server state=absent" --become ; fi }
-STOP_REDIS () { if [ "${installed_redis}" -ne 1 ] && [ "${started_redis}" -eq 1 ] ; then ansible localhost -m service -a "name=redis-server state=stopped" --become ; fi }
+# Cache should start empty
+redis-cli keys ansible_
+[ "$(redis-cli keys ansible_)" = "" ]
-if [ "${failed_dep_1}" -eq 1 ] || [ "${failed_dep_2}" -eq 1 ] || [ "${failed_dep_3}" -eq 1 ] ; then
- STOP_REDIS
- CLEANUP_REDIS
- exit 0
-fi
-
-export ANSIBLE_CACHE_PLUGIN=redis
-export ANSIBLE_CACHE_PLUGIN_CONNECTION=localhost:6379:0
export ANSIBLE_CACHE_PLUGINS=./plugins/cache
+export ANSIBLE_CACHE_PLUGIN_CONNECTION=localhost:6379:0
+export ANSIBLE_CACHE_PLUGIN_PREFIX='ansible_facts_'
+
+# Test legacy cache plugins (that use ansible.constants) and
+# new cache plugins that use config manager both work for facts.
+for fact_cache in legacy_redis configurable_redis; do
-# Use old redis for fact caching
-count=$(ansible-playbook test_fact_gathering.yml -vvv 2>&1 "$@" | tee out.txt | grep -c 'Gathering Facts' || true)
-failed_dep_version=$(grep out.txt -ce "'redis' python module (version 2.4.5 or newer) is required" || true)
-cat out.txt
-if [ "${failed_dep_version}" -eq 1 ] ; then
- STOP_REDIS
- CLEANUP_REDIS
- exit 0
-fi
-if [ "${count}" -ne 1 ] ; then
- STOP_REDIS
- CLEANUP_REDIS
- exit 1
-fi
+ export ANSIBLE_CACHE_PLUGIN="$fact_cache"
-# Attempt to use old redis for inventory caching; should not work
-export ANSIBLE_INVENTORY_CACHE=True
-export ANSIBLE_INVENTORY_CACHE_PLUGIN=redis
-export ANSIBLE_INVENTORY_ENABLED=test
-export ANSIBLE_INVENTORY_PLUGINS=./plugins/inventory
+ # test set_fact with cacheable: true
+ ansible-playbook test_fact_gathering.yml --tags set_fact "$@"
+ [ "$(redis-cli keys ansible_facts_localhost | wc -l)" -eq 1 ]
+ ansible-playbook inspect_cache.yml --tags set_fact "$@"
-ansible-inventory -i inventory_config --graph 2>&1 "$@" | tee out.txt | grep 'Cache options were provided but may not reconcile correctly unless set via set_options'
-res=$?
-cat out.txt
-if [ "${res}" -eq 1 ] ; then
- STOP_REDIS
- CLEANUP_REDIS
- exit 1
-fi
+ # cache gathered facts in addition
+ ansible-playbook test_fact_gathering.yml --tags gather_facts "$@"
+ ansible-playbook inspect_cache.yml --tags additive_gather_facts "$@"
-# Use new style redis for fact caching
-unset ANSIBLE_CACHE_PLUGINS
-count=$(ansible-playbook test_fact_gathering.yml -vvv "$@" | tee out.txt | grep -c 'Gathering Facts' || true)
-cat out.txt
-if [ "${count}" -ne 1 ] ; then
- STOP_REDIS
- CLEANUP_REDIS
- exit 1
-fi
+ # flush cache and only cache gathered facts
+ ansible-playbook test_fact_gathering.yml --flush-cache --tags gather_facts --tags flush "$@"
+ ansible-playbook inspect_cache.yml --tags gather_facts "$@"
-# Use new redis for inventory caching
-ansible-inventory -i inventory_config --graph "$@" 2>&1 | tee out.txt | grep 'host2'
-res=$?
-cat out.txt
+ redis-cli del ansible_facts_localhost
+ unset ANSIBLE_CACHE_PLUGIN
-STOP_REDIS
-CLEANUP_REDIS
+done
-exit $res
+# Legacy cache plugins need to be updated to use set_options/get_option to be compatible with inventory plugins.
+# Inventory plugins load cache options with the config manager.
+ansible-playbook test_inventory_cache.yml "$@"
diff --git a/test/integration/targets/old_style_cache_plugins/setup_redis_cache.yml b/test/integration/targets/old_style_cache_plugins/setup_redis_cache.yml
new file mode 100644
index 00000000..8aad37a3
--- /dev/null
+++ b/test/integration/targets/old_style_cache_plugins/setup_redis_cache.yml
@@ -0,0 +1,51 @@
+---
+- hosts: localhost
+ vars:
+ make: "{{ ( ansible_distribution != 'FreeBSD' ) | ternary('make', 'gmake') }}"
+ tasks:
+ - name: name ensure make is available
+ command: "which {{ make }}"
+ register: has_make
+ ignore_errors: yes
+
+ - command: apk add --no-cache make
+ when: "has_make is failed and ansible_distribution == 'Alpine'"
+ become: yes
+
+ - package:
+ name: "{{ make }}"
+ state: present
+ become: yes
+ when: "has_make is failed and ansible_distribution != 'Alpine'"
+
+ - name: get the latest stable redis server release
+ get_url:
+ url: http://download.redis.io/redis-stable.tar.gz
+ dest: ./
+
+ - name: unzip download
+ unarchive:
+ src: redis-stable.tar.gz
+ dest: ./
+
+ - command: "{{ make }}"
+ args:
+ chdir: redis-stable
+
+ - name: copy the executable into the path
+ copy:
+ src: "redis-stable/src/{{ item }}"
+ dest: /usr/local/bin/
+ mode: 755
+ become: yes
+ loop:
+ - redis-server
+ - redis-cli
+
+ - name: start the redis server in the background
+ command: redis-server --daemonize yes
+
+ - name: install dependency for the cache plugin
+ pip:
+ name: redis>2.4.5
+ state: present
diff --git a/test/integration/targets/old_style_cache_plugins/test_fact_gathering.yml b/test/integration/targets/old_style_cache_plugins/test_fact_gathering.yml
index 5c720b4e..2c77f0dd 100644
--- a/test/integration/targets/old_style_cache_plugins/test_fact_gathering.yml
+++ b/test/integration/targets/old_style_cache_plugins/test_fact_gathering.yml
@@ -1,6 +1,22 @@
---
- hosts: localhost
gather_facts: no
+ tags:
+ - flush
+ tasks:
+ - meta: clear_facts
- hosts: localhost
gather_facts: yes
+ gather_subset: min
+ tags:
+ - gather_facts
+
+- hosts: localhost
+ gather_facts: no
+ tags:
+ - set_fact
+ tasks:
+ - set_fact:
+ foo: bar
+ cacheable: true
diff --git a/test/integration/targets/old_style_cache_plugins/test_inventory_cache.yml b/test/integration/targets/old_style_cache_plugins/test_inventory_cache.yml
new file mode 100644
index 00000000..83b79831
--- /dev/null
+++ b/test/integration/targets/old_style_cache_plugins/test_inventory_cache.yml
@@ -0,0 +1,45 @@
+- hosts: localhost
+ gather_facts: no
+ vars:
+ reset_color: '\x1b\[0m'
+ color: '\x1b\[[0-9];[0-9]{2}m'
+ base_environment:
+ ANSIBLE_INVENTORY_PLUGINS: ./plugins/inventory
+ ANSIBLE_INVENTORY_ENABLED: test
+ ANSIBLE_INVENTORY_CACHE: true
+ ANSIBLE_CACHE_PLUGINS: ./plugins/cache
+ ANSIBLE_CACHE_PLUGIN_CONNECTION: localhost:6379:0
+ ANSIBLE_CACHE_PLUGIN_PREFIX: 'ansible_inventory_'
+ legacy_cache:
+ ANSIBLE_INVENTORY_CACHE_PLUGIN: legacy_redis
+ updated_cache:
+ ANSIBLE_INVENTORY_CACHE_PLUGIN: configurable_redis
+ tasks:
+ - name: legacy-style cache plugin should cause a warning
+ command: ansible-inventory -i inventory_config --graph
+ register: result
+ environment: "{{ base_environment | combine(legacy_cache) }}"
+
+ - name: test warning message
+ assert:
+ that:
+ - expected_warning in warning
+ - "'No inventory was parsed, only implicit localhost is available' in warning"
+ vars:
+ warning: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ expected_warning: "Cache options were provided but may not reconcile correctly unless set via set_options"
+
+ - name: cache plugin updated to use config manager should work
+ command: ansible-inventory -i inventory_config --graph
+ register: result
+ environment: "{{ base_environment | combine(updated_cache) }}"
+
+ - name: test warning message
+ assert:
+ that:
+ - unexpected_warning not in warning
+ - "'No inventory was parsed, only implicit localhost is available' not in warning"
+ - '"host1" in result.stdout'
+ vars:
+ warning: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
+ unexpected_warning: "Cache options were provided but may not reconcile correctly unless set via set_options"
diff --git a/test/integration/targets/old_style_modules_posix/aliases b/test/integration/targets/old_style_modules_posix/aliases
index b5983214..a3ada117 100644
--- a/test/integration/targets/old_style_modules_posix/aliases
+++ b/test/integration/targets/old_style_modules_posix/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/target
diff --git a/test/integration/targets/omit/aliases b/test/integration/targets/omit/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/omit/aliases
+++ b/test/integration/targets/omit/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/order/aliases b/test/integration/targets/order/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/order/aliases
+++ b/test/integration/targets/order/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/package/tasks/main.yml b/test/integration/targets/package/tasks/main.yml
index 853b4711..c8b75da4 100644
--- a/test/integration/targets/package/tasks/main.yml
+++ b/test/integration/targets/package/tasks/main.yml
@@ -143,4 +143,108 @@
- name: verify at command is installed
shell: which at
+ - name: remove at package
+ package:
+ name: at
+ state: absent
+ register: at_install0
+
+ - name: validate package removal
+ assert:
+ that:
+ - "at_install0 is changed"
+
when: ansible_distribution in package_distros
+
+##
+## yum
+##
+#Validation for new parameter 'use' in yum action plugin which aliases to 'use_backend'
+#Issue: https://github.com/ansible/ansible/issues/70774
+- block:
+ - name: verify if using both the parameters 'use' and 'use_backend' throw error
+ yum:
+ name: at
+ state: present
+ use_backend: yum
+ use: yum
+ ignore_errors: yes
+ register: result
+
+ - name: verify error
+ assert:
+ that:
+ - "'parameters are mutually exclusive' in result.msg"
+ - "not result is changed"
+
+ - name: verify if package installation is successful using 'use' parameter
+ yum:
+ name: at
+ state: present
+ use: dnf
+ register: result
+
+ - name: verify the result
+ assert:
+ that:
+ - "result is changed"
+
+ - name: remove at package
+ yum:
+ name: at
+ state: absent
+ use: dnf
+ register: result
+
+ - name: verify package removal
+ assert:
+ that:
+ - "result is changed"
+
+ - name: verify if package installation is successful using 'use_backend' parameter
+ yum:
+ name: at
+ state: present
+ use_backend: dnf
+ register: result
+
+ - name: verify the result
+ assert:
+ that:
+ - "result is changed"
+
+ - name: remove at package
+ yum:
+ name: at
+ state: absent
+ use_backend: dnf
+ register: result
+
+ - name: verify package removal
+ assert:
+ that:
+ - "result is changed"
+
+ - name: verify if package installation is successful without using 'use_backend' and 'use' parameters
+ yum:
+ name: at
+ state: present
+ register: result
+
+ - name: verify the result
+ assert:
+ that:
+ - "result is changed"
+
+ - name: remove at package
+ yum:
+ name: at
+ state: absent
+ register: result
+
+ - name: verify package removal
+ assert:
+ that:
+ - "result is changed"
+
+ when: ansible_distribution == "Fedora" \ No newline at end of file
diff --git a/test/integration/targets/parsing/aliases b/test/integration/targets/parsing/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/parsing/aliases
+++ b/test/integration/targets/parsing/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/path_lookups/aliases b/test/integration/targets/path_lookups/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/path_lookups/aliases
+++ b/test/integration/targets/path_lookups/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/path_lookups/play.yml b/test/integration/targets/path_lookups/play.yml
index 7321589b..233f972d 100644
--- a/test/integration/targets/path_lookups/play.yml
+++ b/test/integration/targets/path_lookups/play.yml
@@ -10,31 +10,31 @@
- copy: dest={{playbook_dir}}/files/testfile content='in files'
- copy: dest={{playbook_dir}}/testfile content='in local'
-- include: testplay.yml
+- import_playbook: testplay.yml
vars:
remove: nothing
role_out: in role files
play_out: in files
-- include: testplay.yml
+- import_playbook: testplay.yml
vars:
remove: roles/showfile/files/testfile
role_out: in role
play_out: in files
-- include: testplay.yml
+- import_playbook: testplay.yml
vars:
remove: roles/showfile/testfile
role_out: in role tasks
play_out: in files
-- include: testplay.yml
+- import_playbook: testplay.yml
vars:
remove: roles/showfile/tasks/testfile
role_out: in files
play_out: in files
-- include: testplay.yml
+- import_playbook: testplay.yml
vars:
remove: files/testfile
role_out: in local
diff --git a/test/integration/targets/path_with_comma_in_inventory/aliases b/test/integration/targets/path_with_comma_in_inventory/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/path_with_comma_in_inventory/aliases
+++ b/test/integration/targets/path_with_comma_in_inventory/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/pause/aliases b/test/integration/targets/pause/aliases
index 810f1ab6..b07d71c7 100644
--- a/test/integration/targets/pause/aliases
+++ b/test/integration/targets/pause/aliases
@@ -1,3 +1,3 @@
needs/target/setup_pexpect
shippable/posix/group1
-skip/aix
+context/controller # this is a controller-only action, the module is just for documentation
diff --git a/test/integration/targets/pip/tasks/pip.yml b/test/integration/targets/pip/tasks/pip.yml
index 572c7b6f..2b9ad561 100644
--- a/test/integration/targets/pip/tasks/pip.yml
+++ b/test/integration/targets/pip/tasks/pip.yml
@@ -310,18 +310,51 @@
- "not (pip_install_empty is changed)"
# https://github.com/ansible/ansible/issues/41043
-- name: do not consider an empty string as a version
- pip:
- name: q
- state: present
- version: ""
- virtualenv: "{{ output_dir }}/pipenv"
- register: pip_install_empty_version_string
+- block:
+ - name: Ensure previous virtualenv no longer exists
+ file:
+ state: absent
+ name: "{{ output_dir }}/pipenv"
-- name: ensure that task installation did not fail
- assert:
- that:
- - pip_install_empty_version_string is successful
+ - name: do not consider an empty string as a version
+ pip:
+ name: q
+ state: present
+ version: ""
+ virtualenv: "{{ output_dir }}/pipenv"
+ register: pip_empty_version_string
+
+ - name: test idempotency with empty string
+ pip:
+ name: q
+ state: present
+ version: ""
+ virtualenv: "{{ output_dir }}/pipenv"
+ register: pip_empty_version_string_idempotency
+
+ - name: test idempotency without empty string
+ pip:
+ name: q
+ state: present
+ virtualenv: "{{ output_dir }}/pipenv"
+ register: pip_no_empty_version_string_idempotency
+
+ # 'present' and version=="" is analogous to latest when first installed
+ - name: ensure we installed the latest version
+ pip:
+ name: q
+ state: latest
+ virtualenv: "{{ output_dir }}/pipenv"
+ register: pip_empty_version_idempotency
+
+ - name: ensure that installation worked and is idempotent
+ assert:
+ that:
+ - pip_empty_version_string is changed
+ - pip_empty_version_string is successful
+ - pip_empty_version_idempotency is not changed
+ - pip_no_empty_version_string_idempotency is not changed
+ - pip_empty_version_string_idempotency is not changed
# test version specifiers
- name: make sure no test_package installed now
diff --git a/test/integration/targets/pkg_resources/aliases b/test/integration/targets/pkg_resources/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/pkg_resources/aliases
+++ b/test/integration/targets/pkg_resources/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/play_iterator/aliases b/test/integration/targets/play_iterator/aliases
index 3005e4b2..498fedd5 100644
--- a/test/integration/targets/play_iterator/aliases
+++ b/test/integration/targets/play_iterator/aliases
@@ -1 +1,2 @@
shippable/posix/group4
+context/controller
diff --git a/test/integration/targets/playbook/aliases b/test/integration/targets/playbook/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/playbook/aliases
+++ b/test/integration/targets/playbook/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/playbook/empty.yml b/test/integration/targets/playbook/empty.yml
new file mode 100644
index 00000000..fe51488c
--- /dev/null
+++ b/test/integration/targets/playbook/empty.yml
@@ -0,0 +1 @@
+[]
diff --git a/test/integration/targets/playbook/empty_hosts.yml b/test/integration/targets/playbook/empty_hosts.yml
new file mode 100644
index 00000000..c9493c09
--- /dev/null
+++ b/test/integration/targets/playbook/empty_hosts.yml
@@ -0,0 +1,4 @@
+- hosts: []
+ tasks:
+ - debug:
+ msg: does not run
diff --git a/test/integration/targets/playbook/malformed_post_tasks.yml b/test/integration/targets/playbook/malformed_post_tasks.yml
new file mode 100644
index 00000000..4c134115
--- /dev/null
+++ b/test/integration/targets/playbook/malformed_post_tasks.yml
@@ -0,0 +1,2 @@
+- hosts: localhost
+ post_tasks: 123
diff --git a/test/integration/targets/playbook/malformed_pre_tasks.yml b/test/integration/targets/playbook/malformed_pre_tasks.yml
new file mode 100644
index 00000000..6c58477f
--- /dev/null
+++ b/test/integration/targets/playbook/malformed_pre_tasks.yml
@@ -0,0 +1,2 @@
+- hosts: localhost
+ pre_tasks: 123
diff --git a/test/integration/targets/playbook/malformed_roles.yml b/test/integration/targets/playbook/malformed_roles.yml
new file mode 100644
index 00000000..35db56e7
--- /dev/null
+++ b/test/integration/targets/playbook/malformed_roles.yml
@@ -0,0 +1,2 @@
+- hosts: localhost
+ roles: 123
diff --git a/test/integration/targets/playbook/malformed_tasks.yml b/test/integration/targets/playbook/malformed_tasks.yml
new file mode 100644
index 00000000..123c059f
--- /dev/null
+++ b/test/integration/targets/playbook/malformed_tasks.yml
@@ -0,0 +1,2 @@
+- hosts: localhost
+ tasks: 123
diff --git a/test/integration/targets/playbook/malformed_vars_prompt.yml b/test/integration/targets/playbook/malformed_vars_prompt.yml
new file mode 100644
index 00000000..5447197d
--- /dev/null
+++ b/test/integration/targets/playbook/malformed_vars_prompt.yml
@@ -0,0 +1,3 @@
+- hosts: localhost
+ vars_prompt:
+ - foo: bar
diff --git a/test/integration/targets/playbook/old_style_role.yml b/test/integration/targets/playbook/old_style_role.yml
new file mode 100644
index 00000000..015f263a
--- /dev/null
+++ b/test/integration/targets/playbook/old_style_role.yml
@@ -0,0 +1,3 @@
+- hosts: localhost
+ roles:
+ - foo,bar
diff --git a/test/integration/targets/playbook/remote_user_and_user.yml b/test/integration/targets/playbook/remote_user_and_user.yml
new file mode 100644
index 00000000..c9e2389d
--- /dev/null
+++ b/test/integration/targets/playbook/remote_user_and_user.yml
@@ -0,0 +1,6 @@
+- hosts: localhost
+ remote_user: a
+ user: b
+ tasks:
+ - debug:
+ msg: did not run
diff --git a/test/integration/targets/playbook/roles_null.yml b/test/integration/targets/playbook/roles_null.yml
new file mode 100644
index 00000000..d06bcd15
--- /dev/null
+++ b/test/integration/targets/playbook/roles_null.yml
@@ -0,0 +1,3 @@
+- name: null roles is okay
+ hosts: localhost
+ roles: null
diff --git a/test/integration/targets/playbook/runme.sh b/test/integration/targets/playbook/runme.sh
index 25e2e5a6..cc8d4957 100755
--- a/test/integration/targets/playbook/runme.sh
+++ b/test/integration/targets/playbook/runme.sh
@@ -7,3 +7,86 @@ ansible-playbook -i ../../inventory types.yml -v "$@"
# test timeout
ansible-playbook -i ../../inventory timeout.yml -v "$@"
+
+# our Play class allows for 'user' or 'remote_user', but not both.
+# first test that both user and remote_user work individually
+set +e
+result="$(ansible-playbook -i ../../inventory user.yml -v "$@" 2>&1)"
+set -e
+grep -q "worked with user" <<< "$result"
+grep -q "worked with remote_user" <<< "$result"
+
+# then test that the play errors if user and remote_user both exist
+echo "EXPECTED ERROR: Ensure we fail properly if a play has both user and remote_user."
+set +e
+result="$(ansible-playbook -i ../../inventory remote_user_and_user.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! both 'user' and 'remote_user' are set for this play." <<< "$result"
+
+# test that playbook errors if len(plays) == 0
+echo "EXPECTED ERROR: Ensure we fail properly if a playbook is an empty list."
+set +e
+result="$(ansible-playbook -i ../../inventory empty.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! A playbook must contain at least one play" <<< "$result"
+
+# test that play errors if len(hosts) == 0
+echo "EXPECTED ERROR: Ensure we fail properly if a play has 0 hosts."
+set +e
+result="$(ansible-playbook -i ../../inventory empty_hosts.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! Hosts list cannot be empty. Please check your playbook" <<< "$result"
+
+# test that play errors if tasks is malformed
+echo "EXPECTED ERROR: Ensure we fail properly if tasks is malformed."
+set +e
+result="$(ansible-playbook -i ../../inventory malformed_tasks.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! A malformed block was encountered while loading tasks: 123 should be a list or None" <<< "$result"
+
+# test that play errors if pre_tasks is malformed
+echo "EXPECTED ERROR: Ensure we fail properly if pre_tasks is malformed."
+set +e
+result="$(ansible-playbook -i ../../inventory malformed_pre_tasks.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! A malformed block was encountered while loading pre_tasks" <<< "$result"
+
+# test that play errors if post_tasks is malformed
+echo "EXPECTED ERROR: Ensure we fail properly if post_tasks is malformed."
+set +e
+result="$(ansible-playbook -i ../../inventory malformed_post_tasks.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! A malformed block was encountered while loading post_tasks" <<< "$result"
+
+# test roles: null -- it gets converted to [] internally
+ansible-playbook -i ../../inventory roles_null.yml -v "$@"
+
+# test roles: 123 -- errors
+echo "EXPECTED ERROR: Ensure we fail properly if roles is malformed."
+set +e
+result="$(ansible-playbook -i ../../inventory malformed_roles.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! A malformed role declaration was encountered." <<< "$result"
+
+# test roles: ["foo,bar"] -- errors about old style
+echo "EXPECTED ERROR: Ensure we fail properly if old style role is given."
+set +e
+result="$(ansible-playbook -i ../../inventory old_style_role.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! Invalid old style role requirement: foo,bar" <<< "$result"
+
+# test vars prompt that has no name
+echo "EXPECTED ERROR: Ensure we fail properly if vars_prompt has no name."
+set +e
+result="$(ansible-playbook -i ../../inventory malformed_vars_prompt.yml -v "$@" 2>&1)"
+set -e
+grep -q "ERROR! Invalid vars_prompt data structure, missing 'name' key" <<< "$result"
+
+# test vars_prompt: null
+ansible-playbook -i ../../inventory vars_prompt_null.yml -v "$@"
+
+# test vars_files: null
+ansible-playbook -i ../../inventory vars_files_null.yml -v "$@"
+
+# test vars_files: filename.yml
+ansible-playbook -i ../../inventory vars_files_string.yml -v "$@"
diff --git a/test/integration/targets/playbook/some_vars.yml b/test/integration/targets/playbook/some_vars.yml
new file mode 100644
index 00000000..78353654
--- /dev/null
+++ b/test/integration/targets/playbook/some_vars.yml
@@ -0,0 +1,2 @@
+a_variable: yep
+another: hi
diff --git a/test/integration/targets/playbook/user.yml b/test/integration/targets/playbook/user.yml
new file mode 100644
index 00000000..8b4029b8
--- /dev/null
+++ b/test/integration/targets/playbook/user.yml
@@ -0,0 +1,23 @@
+- hosts: localhost
+ tasks:
+ - command: whoami
+ register: whoami
+
+ - assert:
+ that:
+ - whoami is successful
+
+ - set_fact:
+ me: "{{ whoami.stdout }}"
+
+- hosts: localhost
+ user: "{{ me }}"
+ tasks:
+ - debug:
+ msg: worked with user ({{ me }})
+
+- hosts: localhost
+ remote_user: "{{ me }}"
+ tasks:
+ - debug:
+ msg: worked with remote_user ({{ me }})
diff --git a/test/integration/targets/playbook/vars_files_null.yml b/test/integration/targets/playbook/vars_files_null.yml
new file mode 100644
index 00000000..64c21c66
--- /dev/null
+++ b/test/integration/targets/playbook/vars_files_null.yml
@@ -0,0 +1,3 @@
+- name: null vars_files is okay
+ hosts: localhost
+ vars_files: null
diff --git a/test/integration/targets/playbook/vars_files_string.yml b/test/integration/targets/playbook/vars_files_string.yml
new file mode 100644
index 00000000..9191d3c1
--- /dev/null
+++ b/test/integration/targets/playbook/vars_files_string.yml
@@ -0,0 +1,6 @@
+- hosts: localhost
+ vars_files: some_vars.yml
+ tasks:
+ - assert:
+ that:
+ - 'a_variable == "yep"'
diff --git a/test/integration/targets/playbook/vars_prompt_null.yml b/test/integration/targets/playbook/vars_prompt_null.yml
new file mode 100644
index 00000000..4fdfa7c1
--- /dev/null
+++ b/test/integration/targets/playbook/vars_prompt_null.yml
@@ -0,0 +1,3 @@
+- name: null vars prompt is okay
+ hosts: localhost
+ vars_prompt: null
diff --git a/test/integration/targets/plugin_config_for_inventory/aliases b/test/integration/targets/plugin_config_for_inventory/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/plugin_config_for_inventory/aliases
+++ b/test/integration/targets/plugin_config_for_inventory/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/plugin_filtering/aliases b/test/integration/targets/plugin_filtering/aliases
index 3005e4b2..498fedd5 100644
--- a/test/integration/targets/plugin_filtering/aliases
+++ b/test/integration/targets/plugin_filtering/aliases
@@ -1 +1,2 @@
shippable/posix/group4
+context/controller
diff --git a/test/integration/targets/plugin_loader/aliases b/test/integration/targets/plugin_loader/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/plugin_loader/aliases
+++ b/test/integration/targets/plugin_loader/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/plugin_namespace/aliases b/test/integration/targets/plugin_namespace/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/plugin_namespace/aliases
+++ b/test/integration/targets/plugin_namespace/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/prepare_http_tests/tasks/kerberos.yml b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml
index 06feea1c..2678b468 100644
--- a/test/integration/targets/prepare_http_tests/tasks/kerberos.yml
+++ b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml
@@ -38,7 +38,9 @@
- name: Install python gssapi
pip:
name:
- - gssapi
+ - decorator < 5.0.0 ; python_version < '3.5' # decorator 5.0.5 and later require python 3.5 or later
+ - gssapi < 1.6.0 ; python_version <= '2.7' # gssapi 1.6.0 and later require python 3 or later
+ - gssapi ; python_version > '2.7'
- importlib ; python_version < '2.7'
state: present
extra_args: '-c {{ remote_constraints }}'
diff --git a/test/integration/targets/rel_plugin_loading/aliases b/test/integration/targets/rel_plugin_loading/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/rel_plugin_loading/aliases
+++ b/test/integration/targets/rel_plugin_loading/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/remote_tmp/aliases b/test/integration/targets/remote_tmp/aliases
index 757c9966..4b8559d9 100644
--- a/test/integration/targets/remote_tmp/aliases
+++ b/test/integration/targets/remote_tmp/aliases
@@ -1,2 +1,4 @@
shippable/posix/group3
skip/aix
+context/target
+needs/target/setup_remote_tmp_dir
diff --git a/test/integration/targets/remote_tmp/playbook.yml b/test/integration/targets/remote_tmp/playbook.yml
index 43f99ca5..5adef626 100644
--- a/test/integration/targets/remote_tmp/playbook.yml
+++ b/test/integration/targets/remote_tmp/playbook.yml
@@ -31,13 +31,16 @@
hosts: testhost
gather_facts: false
tasks:
+ - import_role:
+ name: ../setup_remote_tmp_dir
+
- file:
state: touch
- path: "{{ output_dir }}/65393"
+ path: "{{ remote_tmp_dir }}/65393"
- copy:
- src: "{{ output_dir }}/65393"
- dest: "{{ output_dir }}/65393.2"
+ src: "{{ remote_tmp_dir }}/65393"
+ dest: "{{ remote_tmp_dir }}/65393.2"
remote_src: true
- find:
@@ -52,6 +55,5 @@
- assert:
that:
- # Should only be AnsiballZ_find.py because find is actively running
- - result.files|length == 1
- - result.files[0].path.endswith('/AnsiballZ_find.py')
+ # Should find nothing since pipelining is used
+ - result.files|length == 0
diff --git a/test/integration/targets/remote_tmp/runme.sh b/test/integration/targets/remote_tmp/runme.sh
index 8d1eebd6..69efd6e0 100755
--- a/test/integration/targets/remote_tmp/runme.sh
+++ b/test/integration/targets/remote_tmp/runme.sh
@@ -2,4 +2,4 @@
set -ux
-ansible-playbook -i ../../inventory playbook.yml -e "output_dir=${OUTPUT_DIR}" -v "$@"
+ansible-playbook -i ../../inventory playbook.yml -v "$@"
diff --git a/test/integration/targets/retry_task_name_in_callback/aliases b/test/integration/targets/retry_task_name_in_callback/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/retry_task_name_in_callback/aliases
+++ b/test/integration/targets/retry_task_name_in_callback/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/roles/aliases b/test/integration/targets/roles/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/roles/aliases
+++ b/test/integration/targets/roles/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/roles/no_dupes.yml b/test/integration/targets/roles/no_dupes.yml
index 0ac9ff94..7e1ecb15 100644
--- a/test/integration/targets/roles/no_dupes.yml
+++ b/test/integration/targets/roles/no_dupes.yml
@@ -17,3 +17,13 @@
tasks:
- name: execute role c which depends on a
import_role: name=c
+
+- name: play should only show 1 invocation of a, as dependencies in this play are deduped by include_role
+ hosts: testhost
+ gather_facts: false
+ tags: [ 'intasks' ]
+ tasks:
+ - name: execute role b which depends on a
+ include_role: name=b
+ - name: execute role c which also depends on a
+ include_role: name=c
diff --git a/test/integration/targets/roles/runme.sh b/test/integration/targets/roles/runme.sh
index f2058ff1..5f11c1fc 100755
--- a/test/integration/targets/roles/runme.sh
+++ b/test/integration/targets/roles/runme.sh
@@ -5,9 +5,10 @@ set -eux
# test no dupes when dependencies in b and c point to a in roles:
[ "$(ansible-playbook no_dupes.yml -i ../../inventory --tags inroles "$@" | grep -c '"msg": "A"')" = "1" ]
[ "$(ansible-playbook no_dupes.yml -i ../../inventory --tags acrossroles "$@" | grep -c '"msg": "A"')" = "1" ]
+[ "$(ansible-playbook no_dupes.yml -i ../../inventory --tags intasks "$@" | grep -c '"msg": "A"')" = "1" ]
# but still dupe across plays
-[ "$(ansible-playbook no_dupes.yml -i ../../inventory "$@" | grep -c '"msg": "A"')" = "2" ]
+[ "$(ansible-playbook no_dupes.yml -i ../../inventory "$@" | grep -c '"msg": "A"')" = "3" ]
# include/import can execute another instance of role
[ "$(ansible-playbook allowed_dupes.yml -i ../../inventory --tags importrole "$@" | grep -c '"msg": "A"')" = "2" ]
diff --git a/test/integration/targets/roles_arg_spec/aliases b/test/integration/targets/roles_arg_spec/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/roles_arg_spec/aliases
+++ b/test/integration/targets/roles_arg_spec/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/roles_var_inheritance/aliases b/test/integration/targets/roles_var_inheritance/aliases
new file mode 100644
index 00000000..1d28bdb2
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/roles_var_inheritance/play.yml b/test/integration/targets/roles_var_inheritance/play.yml
new file mode 100644
index 00000000..170eef57
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/play.yml
@@ -0,0 +1,4 @@
+- hosts: localhost
+ roles:
+ - A
+ - B
diff --git a/test/integration/targets/roles_var_inheritance/roles/A/meta/main.yml b/test/integration/targets/roles_var_inheritance/roles/A/meta/main.yml
new file mode 100644
index 00000000..0e99e981
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/roles/A/meta/main.yml
@@ -0,0 +1,4 @@
+dependencies:
+ - role: common_dep
+ vars:
+ test_var: A
diff --git a/test/integration/targets/roles_var_inheritance/roles/B/meta/main.yml b/test/integration/targets/roles_var_inheritance/roles/B/meta/main.yml
new file mode 100644
index 00000000..4da17403
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/roles/B/meta/main.yml
@@ -0,0 +1,4 @@
+dependencies:
+ - role: common_dep
+ vars:
+ test_var: B
diff --git a/test/integration/targets/roles_var_inheritance/roles/child_nested_dep/vars/main.yml b/test/integration/targets/roles_var_inheritance/roles/child_nested_dep/vars/main.yml
new file mode 100644
index 00000000..6723fa07
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/roles/child_nested_dep/vars/main.yml
@@ -0,0 +1 @@
+var_precedence: dependency
diff --git a/test/integration/targets/roles_var_inheritance/roles/common_dep/meta/main.yml b/test/integration/targets/roles_var_inheritance/roles/common_dep/meta/main.yml
new file mode 100644
index 00000000..1ede7be8
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/roles/common_dep/meta/main.yml
@@ -0,0 +1,4 @@
+dependencies:
+ - role: nested_dep
+ vars:
+ nested_var: "{{ test_var }}"
diff --git a/test/integration/targets/roles_var_inheritance/roles/common_dep/vars/main.yml b/test/integration/targets/roles_var_inheritance/roles/common_dep/vars/main.yml
new file mode 100644
index 00000000..87b6b580
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/roles/common_dep/vars/main.yml
@@ -0,0 +1 @@
+var_precedence: parent
diff --git a/test/integration/targets/roles_var_inheritance/roles/nested_dep/meta/main.yml b/test/integration/targets/roles_var_inheritance/roles/nested_dep/meta/main.yml
new file mode 100644
index 00000000..231c6c14
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/roles/nested_dep/meta/main.yml
@@ -0,0 +1,3 @@
+allow_duplicates: yes
+dependencies:
+ - child_nested_dep
diff --git a/test/integration/targets/roles_var_inheritance/roles/nested_dep/tasks/main.yml b/test/integration/targets/roles_var_inheritance/roles/nested_dep/tasks/main.yml
new file mode 100644
index 00000000..c69070ca
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/roles/nested_dep/tasks/main.yml
@@ -0,0 +1,5 @@
+- debug:
+ var: nested_var
+
+- debug:
+ var: var_precedence
diff --git a/test/integration/targets/roles_var_inheritance/runme.sh b/test/integration/targets/roles_var_inheritance/runme.sh
new file mode 100755
index 00000000..791155a8
--- /dev/null
+++ b/test/integration/targets/roles_var_inheritance/runme.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook -i ../../inventory play.yml "$@" | tee out.txt
+
+test "$(grep out.txt -ce '"nested_var": "A"')" == 1
+test "$(grep out.txt -ce '"nested_var": "B"')" == 1
+test "$(grep out.txt -ce '"var_precedence": "dependency"')" == 2
diff --git a/test/integration/targets/rpm_key/tasks/main.yaml b/test/integration/targets/rpm_key/tasks/main.yaml
index 9f6fd4ec..6f71ca6e 100644
--- a/test/integration/targets/rpm_key/tasks/main.yaml
+++ b/test/integration/targets/rpm_key/tasks/main.yaml
@@ -1,2 +1,2 @@
- - include: 'rpm_key.yaml'
+ - include_tasks: 'rpm_key.yaml'
when: ansible_os_family == "RedHat"
diff --git a/test/integration/targets/run_modules/aliases b/test/integration/targets/run_modules/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/run_modules/aliases
+++ b/test/integration/targets/run_modules/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/set_fact/aliases b/test/integration/targets/set_fact/aliases
index 757c9966..10179323 100644
--- a/test/integration/targets/set_fact/aliases
+++ b/test/integration/targets/set_fact/aliases
@@ -1,2 +1,2 @@
shippable/posix/group3
-skip/aix
+context/controller # this is a controller-only action, the module is just for documentation
diff --git a/test/integration/targets/set_fact/runme.sh b/test/integration/targets/set_fact/runme.sh
index 781894a0..93093599 100755
--- a/test/integration/targets/set_fact/runme.sh
+++ b/test/integration/targets/set_fact/runme.sh
@@ -31,3 +31,6 @@ ANSIBLE_JINJA2_NATIVE=1 ansible-playbook -v set_fact_bool_conv_jinja2_native.yml
# Test parsing of values when using an empty string as a key
ansible-playbook -i inventory set_fact_empty_str_key.yml
+
+# https://github.com/ansible/ansible/issues/21088
+ansible-playbook -i inventory "$@" set_fact_auto_unsafe.yml
diff --git a/test/integration/targets/set_fact/set_fact_auto_unsafe.yml b/test/integration/targets/set_fact/set_fact_auto_unsafe.yml
new file mode 100644
index 00000000..b0fb4dcf
--- /dev/null
+++ b/test/integration/targets/set_fact/set_fact_auto_unsafe.yml
@@ -0,0 +1,10 @@
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - set_fact:
+ foo: bar
+ register: baz
+
+ - assert:
+ that:
+ - baz.ansible_facts.foo|type_debug != "AnsibleUnsafeText"
diff --git a/test/integration/targets/set_stats/aliases b/test/integration/targets/set_stats/aliases
new file mode 100644
index 00000000..a1b27a83
--- /dev/null
+++ b/test/integration/targets/set_stats/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group5
+context/controller # this is a controller-only action, the module is just for documentation
diff --git a/test/integration/targets/set_stats/runme.sh b/test/integration/targets/set_stats/runme.sh
new file mode 100755
index 00000000..27193dc8
--- /dev/null
+++ b/test/integration/targets/set_stats/runme.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+set -eux
+
+export ANSIBLE_SHOW_CUSTOM_STATS=yes
+
+# Simple tests
+ansible-playbook test_simple.yml -i "${INVENTORY_PATH}"
+
+# This playbook does two set_stats calls setting my_int to 10 and 15.
+# The aggregated output should add to 25.
+output=$(ansible-playbook test_aggregate.yml -i "${INVENTORY_PATH}" | grep -c '"my_int": 25')
+test "$output" -eq 1
diff --git a/test/integration/targets/set_stats/test_aggregate.yml b/test/integration/targets/set_stats/test_aggregate.yml
new file mode 100644
index 00000000..7f12895d
--- /dev/null
+++ b/test/integration/targets/set_stats/test_aggregate.yml
@@ -0,0 +1,13 @@
+---
+- hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: First set_stats
+ set_stats:
+ data:
+ my_int: 10
+
+ - name: Second set_stats
+ set_stats:
+ data:
+ my_int: 15
diff --git a/test/integration/targets/set_stats/test_simple.yml b/test/integration/targets/set_stats/test_simple.yml
new file mode 100644
index 00000000..0f62120d
--- /dev/null
+++ b/test/integration/targets/set_stats/test_simple.yml
@@ -0,0 +1,79 @@
+---
+- hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: test simple data with defaults
+ set_stats:
+ data:
+ my_int: 42
+ my_string: "foo"
+ register: result
+
+ - name: assert simple data return
+ assert:
+ that:
+ - result is succeeded
+ - not result.changed
+ - '"ansible_stats" in result'
+ - '"data" in result.ansible_stats'
+ - result.ansible_stats.data.my_int == 42
+ - result.ansible_stats.data.my_string == "foo"
+ - '"per_host" in result.ansible_stats'
+ - not result.ansible_stats.per_host
+ - '"aggregate" in result.ansible_stats'
+ - result.ansible_stats.aggregate
+
+ - name: test per_host and aggregate settings
+ set_stats:
+ data:
+ my_int: 42
+ per_host: yes
+ aggregate: no
+ register: result
+
+ - name: assert per_host and aggregate changes
+ assert:
+ that:
+ - result is succeeded
+ - not result.changed
+ - '"ansible_stats" in result'
+ - '"per_host" in result.ansible_stats'
+ - result.ansible_stats.per_host
+ - '"aggregate" in result.ansible_stats'
+ - not result.ansible_stats.aggregate
+
+ - name: Test bad call
+ block:
+ - name: "EXPECTED FAILURE - test invalid data type"
+ set_stats:
+ data:
+ - 1
+ - 2
+
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - test invalid data type"
+ - ansible_failed_result.msg == "The 'data' option needs to be a dictionary/hash"
+
+ - name: Test options from template
+ set_stats:
+ data:
+ my_string: "foo"
+ aggregate: "x"
+
+ - name: Test bad data
+ block:
+ - name: "EXPECTED FAILURE - bad data"
+ set_stats:
+ data:
+ .bad: 1
+ - fail:
+ msg: "should not get here"
+ rescue:
+ - assert:
+ that:
+ - ansible_failed_task.name == "EXPECTED FAILURE - bad data"
+ - ansible_failed_result.msg == "The variable name '.bad' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores."
diff --git a/test/integration/targets/setup_cron/defaults/main.yml b/test/integration/targets/setup_cron/defaults/main.yml
index e4b0123d..a6d1965f 100644
--- a/test/integration/targets/setup_cron/defaults/main.yml
+++ b/test/integration/targets/setup_cron/defaults/main.yml
@@ -1 +1 @@
-remote_dir: "{{ lookup('env', 'OUTPUT_DIR') }}"
+remote_dir: "{{ remote_tmp_dir }}"
diff --git a/test/integration/targets/setup_cron/meta/main.yml b/test/integration/targets/setup_cron/meta/main.yml
new file mode 100644
index 00000000..1810d4be
--- /dev/null
+++ b/test/integration/targets/setup_cron/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/test/integration/targets/setup_cron/tasks/main.yml b/test/integration/targets/setup_cron/tasks/main.yml
index c5a988e0..d7ce3303 100644
--- a/test/integration/targets/setup_cron/tasks/main.yml
+++ b/test/integration/targets/setup_cron/tasks/main.yml
@@ -82,3 +82,15 @@
FAKETIME: "+0y x10"
LD_PRELOAD: "/usr/lib/faketime/libfaketime.so.1"
when: ansible_distribution == 'Alpine'
+
+- name: See if /etc/pam.d/crond exists
+ stat:
+ path: /etc/pam.d/crond
+ register: pamd
+
+# https://github.com/lxc/lxc/issues/661#issuecomment-222444916
+# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=726661
+- name: Work around containers not being able to write to /proc/self/loginuid
+ command: sed -i '/pam_loginuid\.so$/ s/required/optional/' /etc/pam.d/crond
+ when:
+ - pamd.stat.exists
diff --git a/test/integration/targets/setup_paramiko/install-FreeBSD-11-python-2.yml b/test/integration/targets/setup_paramiko/install-FreeBSD-11-python-2.yml
deleted file mode 100644
index dec5b548..00000000
--- a/test/integration/targets/setup_paramiko/install-FreeBSD-11-python-2.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-- name: Install Paramiko for Python 2 on FreeBSD 11
- pkgng:
- name: py27-paramiko
diff --git a/test/integration/targets/setup_paramiko/install-FreeBSD-11-python-3.yml b/test/integration/targets/setup_paramiko/install-FreeBSD-11-python-3.yml
deleted file mode 100644
index eb01d00f..00000000
--- a/test/integration/targets/setup_paramiko/install-FreeBSD-11-python-3.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-- name: Downgrade to pip version 18.1 to work around a PEP 517 virtualenv bug
- # pip 19.0.0 added support for PEP 517
- # versions as recent as 19.0.3 fail to install paramiko in a virtualenv due to a BackendUnavailable exception
- # installation without a virtualenv succeeds
- pip:
- name: pip==18.1
-- name: Setup remote constraints
- include_tasks: setup-remote-constraints.yml
-- name: Install Paramiko for Python 3 on FreeBSD 11
- pip: # no py36-paramiko package exists for FreeBSD 11
- name: paramiko
- extra_args: "-c {{ remote_constraints }}"
diff --git a/test/integration/targets/setup_paramiko/install-FreeBSD-11.4-python-3.yml b/test/integration/targets/setup_paramiko/install-FreeBSD-11.4-python-3.yml
deleted file mode 100644
index 9a7bfb67..00000000
--- a/test/integration/targets/setup_paramiko/install-FreeBSD-11.4-python-3.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-- name: Install Paramiko for Python 3 on FreeBSD 11.4
- pkgng:
- name: py37-paramiko
diff --git a/test/integration/targets/setup_paramiko/install-FreeBSD-12-python-2.yml b/test/integration/targets/setup_paramiko/install-FreeBSD-12-python-2.yml
deleted file mode 100644
index 29e78969..00000000
--- a/test/integration/targets/setup_paramiko/install-FreeBSD-12-python-2.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-- name: Install Paramiko for Python 2 on FreeBSD 12
- pkgng:
- name: py27-paramiko
diff --git a/test/integration/targets/setup_paramiko/install-FreeBSD-12-python-3.yml b/test/integration/targets/setup_paramiko/install-FreeBSD-12-python-3.yml
deleted file mode 100644
index 2aa7b500..00000000
--- a/test/integration/targets/setup_paramiko/install-FreeBSD-12-python-3.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-- name: Install Paramiko for Python 3 on FreeBSD 12
- pkgng:
- name: py36-paramiko
diff --git a/test/integration/targets/setup_paramiko/install-FreeBSD-12.2-python-3.yml b/test/integration/targets/setup_paramiko/install-FreeBSD-12.2-python-3.yml
deleted file mode 100644
index 4fe6011b..00000000
--- a/test/integration/targets/setup_paramiko/install-FreeBSD-12.2-python-3.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-- name: Install Paramiko for Python 3 on FreeBSD 12.2
- pkgng:
- name: py37-paramiko
diff --git a/test/integration/targets/setup_paramiko/install-FreeBSD-python-3.yml b/test/integration/targets/setup_paramiko/install-FreeBSD-python-3.yml
new file mode 100644
index 00000000..27daf3cf
--- /dev/null
+++ b/test/integration/targets/setup_paramiko/install-FreeBSD-python-3.yml
@@ -0,0 +1,6 @@
+- name: Setup remote constraints
+ include_tasks: setup-remote-constraints.yml
+- name: Install Paramiko for Python 3 on FreeBSD
+ pip: # no package in pkg, just use pip
+ name: paramiko
+ extra_args: "-c {{ remote_constraints }}"
diff --git a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-2.yml b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-2.yml
deleted file mode 100644
index d27f831c..00000000
--- a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-2.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-- name: Uninstall Paramiko for Python 2 on FreeBSD 11
- pkgng:
- name: py27-paramiko
- state: absent
diff --git a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-3.yml b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-3.yml
deleted file mode 100644
index 33f292e8..00000000
--- a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11-python-3.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-- name: Uninstall Paramiko for Python 3 on FreeBSD 11
- pip: # no py36-paramiko package exists for FreeBSD 11
- name: paramiko
- state: absent
diff --git a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11.4-python-3.yml b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11.4-python-3.yml
deleted file mode 100644
index 86956fd9..00000000
--- a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-11.4-python-3.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-- name: Uninstall Paramiko for Python 3 on FreeBSD 11.4
- pkgng:
- name: py37-paramiko
- state: absent
diff --git a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-2.yml b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-2.yml
deleted file mode 100644
index 79352487..00000000
--- a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-2.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-- name: Uninstall Paramiko for Python 2 on FreeBSD 12
- pkgng:
- name: py27-paramiko
- state: absent
diff --git a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-3.yml b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-3.yml
deleted file mode 100644
index 46d26ca3..00000000
--- a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12-python-3.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-- name: Uninstall Paramiko for Python 3 on FreeBSD 12
- pkgng:
- name: py36-paramiko
- state: absent
diff --git a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12.2-python-3.yml b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12.2-python-3.yml
deleted file mode 100644
index 0359bf4c..00000000
--- a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-12.2-python-3.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-- name: Uninstall Paramiko for Python 3 on FreeBSD 12.2
- pkgng:
- name: py37-paramiko
- state: absent
diff --git a/test/integration/targets/setup_paramiko/uninstall-FreeBSD-python-3.yml b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-python-3.yml
new file mode 100644
index 00000000..d3d3739b
--- /dev/null
+++ b/test/integration/targets/setup_paramiko/uninstall-FreeBSD-python-3.yml
@@ -0,0 +1,4 @@
+- name: Uninstall Paramiko for Python 3 on FreeBSD
+ pip:
+ name: paramiko
+ state: absent
diff --git a/test/integration/targets/setup_remote_tmp_dir/defaults/main.yml b/test/integration/targets/setup_remote_tmp_dir/defaults/main.yml
new file mode 100644
index 00000000..3375fdf9
--- /dev/null
+++ b/test/integration/targets/setup_remote_tmp_dir/defaults/main.yml
@@ -0,0 +1,2 @@
+setup_remote_tmp_dir_skip_cleanup: no
+setup_remote_tmp_dir_cache_path: no
diff --git a/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml b/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml
index 229037c8..3c5b14f2 100644
--- a/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml
+++ b/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml
@@ -1,5 +1,7 @@
- name: delete temporary directory
include_tasks: default-cleanup.yml
+ when: not setup_remote_tmp_dir_skip_cleanup | bool
- name: delete temporary directory (windows)
include_tasks: windows-cleanup.yml
+ when: not setup_remote_tmp_dir_skip_cleanup | bool
diff --git a/test/integration/targets/setup_remote_tmp_dir/tasks/default.yml b/test/integration/targets/setup_remote_tmp_dir/tasks/default.yml
index 1e0f51b8..3be42eff 100644
--- a/test/integration/targets/setup_remote_tmp_dir/tasks/default.yml
+++ b/test/integration/targets/setup_remote_tmp_dir/tasks/default.yml
@@ -9,3 +9,4 @@
- name: record temporary directory
set_fact:
remote_tmp_dir: "{{ remote_tmp_dir.path }}"
+ cacheable: "{{ setup_remote_tmp_dir_cache_path | bool }}"
diff --git a/test/integration/targets/setup_rpm_repo/files/create-repo.py b/test/integration/targets/setup_rpm_repo/files/create-repo.py
deleted file mode 100644
index a4d10140..00000000
--- a/test/integration/targets/setup_rpm_repo/files/create-repo.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-from collections import namedtuple
-
-try:
- from rpmfluff import SimpleRpmBuild
- from rpmfluff import YumRepoBuild
-except ImportError:
- from rpmfluff.rpmbuild import SimpleRpmBuild
- from rpmfluff.yumrepobuild import YumRepoBuild
-
-try:
- from rpmfluff import can_use_rpm_weak_deps
-except ImportError:
- try:
- from rpmfluff.utils import can_use_rpm_weak_deps
- except ImportError:
- can_use_rpm_weak_deps = None
-
-RPM = namedtuple('RPM', ['name', 'version', 'release', 'epoch', 'recommends'])
-
-
-SPECS = [
- RPM('dinginessentail', '1.0', '1', None, None),
- RPM('dinginessentail', '1.0', '2', '1', None),
- RPM('dinginessentail', '1.1', '1', '1', None),
- RPM('dinginessentail-olive', '1.0', '1', None, None),
- RPM('dinginessentail-olive', '1.1', '1', None, None),
- RPM('landsidescalping', '1.0', '1', None, None),
- RPM('landsidescalping', '1.1', '1', None, None),
- RPM('dinginessentail-with-weak-dep', '1.0', '1', None, ['dinginessentail-weak-dep']),
- RPM('dinginessentail-weak-dep', '1.0', '1', None, None),
-]
-
-
-def main():
- try:
- arch = sys.argv[1]
- except IndexError:
- arch = 'x86_64'
-
- pkgs = []
- for spec in SPECS:
- pkg = SimpleRpmBuild(spec.name, spec.version, spec.release, [arch])
- pkg.epoch = spec.epoch
-
- if spec.recommends:
- # Skip packages that require weak deps but an older version of RPM is being used
- if not can_use_rpm_weak_deps or not can_use_rpm_weak_deps():
- continue
-
- for recommend in spec.recommends:
- pkg.add_recommends(recommend)
-
- pkgs.append(pkg)
-
- repo = YumRepoBuild(pkgs)
- repo.make(arch)
-
- for pkg in pkgs:
- pkg.clean()
-
- print(repo.repoDir)
-
-
-if __name__ == "__main__":
- main()
diff --git a/test/integration/targets/special_vars/aliases b/test/integration/targets/special_vars/aliases
index 2d9e6788..55b8ec06 100644
--- a/test/integration/targets/special_vars/aliases
+++ b/test/integration/targets/special_vars/aliases
@@ -1,2 +1,3 @@
shippable/posix/group2
needs/target/include_parent_role_vars
+context/controller
diff --git a/test/integration/targets/special_vars_hosts/aliases b/test/integration/targets/special_vars_hosts/aliases
new file mode 100644
index 00000000..1d28bdb2
--- /dev/null
+++ b/test/integration/targets/special_vars_hosts/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/special_vars_hosts/inventory b/test/integration/targets/special_vars_hosts/inventory
new file mode 100644
index 00000000..8d69e574
--- /dev/null
+++ b/test/integration/targets/special_vars_hosts/inventory
@@ -0,0 +1,3 @@
+successful ansible_connection=local ansible_host=127.0.0.1 ansible_python_interpreter="{{ ansible_playbook_python }}"
+failed ansible_connection=local ansible_host=127.0.0.1 ansible_python_interpreter="{{ ansible_playbook_python }}"
+unreachable ansible_connection=ssh ansible_host=127.0.0.1 ansible_port=1011 # IANA Reserved port
diff --git a/test/integration/targets/special_vars_hosts/playbook.yml b/test/integration/targets/special_vars_hosts/playbook.yml
new file mode 100644
index 00000000..e3d9e435
--- /dev/null
+++ b/test/integration/targets/special_vars_hosts/playbook.yml
@@ -0,0 +1,53 @@
+---
+- hosts: all
+ gather_facts: no
+ tasks:
+ - name: test magic vars for hosts without any failed/unreachable (no serial)
+ assert:
+ that:
+ - ansible_play_batch | length == 3
+ - ansible_play_hosts | length == 3
+ - ansible_play_hosts_all | length == 3
+ run_once: True
+
+ - ping:
+ failed_when: "inventory_hostname == 'failed'"
+
+ - meta: clear_host_errors
+
+- hosts: all
+ gather_facts: no
+ tasks:
+ - name: test host errors were cleared
+ assert:
+ that:
+ - ansible_play_batch | length == 3
+ - ansible_play_hosts | length == 3
+ - ansible_play_hosts_all | length == 3
+ run_once: True
+
+ - ping:
+ failed_when: "inventory_hostname == 'failed'"
+
+ - name: test magic vars exclude failed/unreachable hosts
+ assert:
+ that:
+ - ansible_play_batch | length == 1
+ - ansible_play_hosts | length == 1
+ - "ansible_play_batch == ['successful']"
+ - "ansible_play_hosts == ['successful']"
+ - ansible_play_hosts_all | length == 3
+ run_once: True
+
+- hosts: all
+ gather_facts: no
+ tasks:
+ - name: test failed/unreachable persists between plays
+ assert:
+ that:
+ - ansible_play_batch | length == 1
+ - ansible_play_hosts | length == 1
+ - "ansible_play_batch == ['successful']"
+ - "ansible_play_hosts == ['successful']"
+ - ansible_play_hosts_all | length == 3
+ run_once: True
diff --git a/test/integration/targets/special_vars_hosts/runme.sh b/test/integration/targets/special_vars_hosts/runme.sh
new file mode 100755
index 00000000..81c1d9be
--- /dev/null
+++ b/test/integration/targets/special_vars_hosts/runme.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook -i ./inventory playbook.yml "$@" | tee out.txt
+grep 'unreachable=2' out.txt
+grep 'failed=2' out.txt
diff --git a/test/integration/targets/split/aliases b/test/integration/targets/split/aliases
new file mode 100644
index 00000000..87958830
--- /dev/null
+++ b/test/integration/targets/split/aliases
@@ -0,0 +1,2 @@
+context/target
+shippable/posix/group1
diff --git a/test/integration/targets/split/tasks/main.yml b/test/integration/targets/split/tasks/main.yml
new file mode 100644
index 00000000..ead1c536
--- /dev/null
+++ b/test/integration/targets/split/tasks/main.yml
@@ -0,0 +1,30 @@
+- name: Get control host details
+ setup:
+ delegate_to: localhost
+ register: control_host
+- name: Get managed host details
+ setup:
+ register: managed_host
+- name: Check split state
+ stat:
+ path: "{{ output_dir }}"
+ register: split
+ ignore_errors: yes
+- name: Build non-split status message
+ set_fact:
+ message: "
+ {{ control_host.ansible_facts.ansible_distribution }} {{ control_host.ansible_facts.ansible_distribution_version }}
+ {{ control_host.ansible_facts.ansible_python.executable }} ({{ control_host.ansible_facts.ansible_python_version }}) ->
+ {{ managed_host.ansible_facts.ansible_python.executable }} ({{ managed_host.ansible_facts.ansible_python_version }})"
+ when: split is success and split.stat.exists
+- name: Build split status message
+ set_fact:
+ message: "
+ {{ control_host.ansible_facts.ansible_distribution }} {{ control_host.ansible_facts.ansible_distribution_version }}
+ {{ control_host.ansible_facts.ansible_python.executable }} ({{ control_host.ansible_facts.ansible_python_version }}) ->
+ {{ managed_host.ansible_facts.ansible_distribution }} {{ managed_host.ansible_facts.ansible_distribution_version }}
+ {{ managed_host.ansible_facts.ansible_python.executable }} ({{ managed_host.ansible_facts.ansible_python_version }})"
+ when: split is not success or not split.stat.exists
+- name: Show host details
+ debug:
+ msg: "{{ message }}"
diff --git a/test/integration/targets/subversion/roles/subversion/defaults/main.yml b/test/integration/targets/subversion/roles/subversion/defaults/main.yml
index f989345a..e647d598 100644
--- a/test/integration/targets/subversion/roles/subversion/defaults/main.yml
+++ b/test/integration/targets/subversion/roles/subversion/defaults/main.yml
@@ -1,11 +1,10 @@
---
apache_port: 11386 # cannot use 80 as httptester overrides this
-output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}"
-subversion_test_dir: '{{ output_dir }}/svn-test'
+subversion_test_dir: /tmp/ansible-svn-test-dir
subversion_server_dir: /tmp/ansible-svn # cannot use a path in the home dir without userdir or granting exec permission to the apache user
subversion_repo_name: ansible-test-repo
subversion_repo_url: http://127.0.0.1:{{ apache_port }}/svn/{{ subversion_repo_name }}
subversion_repo_auth_url: http://127.0.0.1:{{ apache_port }}/svnauth/{{ subversion_repo_name }}
subversion_username: subsvn_user'''
subversion_password: Password123!
-subversion_external_repo_url: https://github.com/ansible/ansible-base-test-container # GitHub serves SVN
+subversion_external_repo_url: https://github.com/ansible/ansible.github.com # GitHub serves SVN
diff --git a/test/integration/targets/subversion/roles/subversion/tasks/setup.yml b/test/integration/targets/subversion/roles/subversion/tasks/setup.yml
index cab9151a..3cf5af56 100644
--- a/test/integration/targets/subversion/roles/subversion/tasks/setup.yml
+++ b/test/integration/targets/subversion/roles/subversion/tasks/setup.yml
@@ -44,13 +44,6 @@
chdir: '{{ subversion_server_dir }}'
creates: '{{ subversion_server_dir }}/{{ subversion_repo_name }}'
-- name: apply ownership for all SVN directories
- file:
- path: '{{ subversion_server_dir }}'
- owner: '{{ apache_user }}'
- group: '{{ apache_group }}'
- recurse: True
-
- name: add test user to htpasswd for Subversion site
htpasswd:
path: '{{ subversion_server_dir }}/svn-auth-users'
@@ -58,11 +51,22 @@
password: '{{ subversion_password }}'
state: present
+- name: apply ownership for all SVN directories
+ file:
+ path: '{{ subversion_server_dir }}'
+ owner: '{{ apache_user }}'
+ group: '{{ apache_group }}'
+ recurse: True
+
- name: start test Apache SVN site - non Red Hat
command: apachectl -k start -f {{ subversion_server_dir }}/subversion.conf
+ async: 3600 # We kill apache manually in the clean up phase
+ poll: 0
when: ansible_os_family not in ['RedHat', 'Alpine']
# On Red Hat based OS', we can't use apachectl to start up own instance, just use the raw httpd
- name: start test Apache SVN site - Red Hat
command: httpd -k start -f {{ subversion_server_dir }}/subversion.conf
+ async: 3600 # We kill apache manually in the clean up phase
+ poll: 0
when: ansible_os_family in ['RedHat', 'Alpine']
diff --git a/test/integration/targets/subversion/runme.sh b/test/integration/targets/subversion/runme.sh
index f505e581..c39bdc00 100755
--- a/test/integration/targets/subversion/runme.sh
+++ b/test/integration/targets/subversion/runme.sh
@@ -4,7 +4,7 @@ set -eu
cleanup() {
echo "Cleanup"
- ansible-playbook runme.yml -e "output_dir=${OUTPUT_DIR}" "$@" --tags cleanup
+ ansible-playbook runme.yml -i "${INVENTORY_PATH}" "$@" --tags cleanup
echo "Done"
}
@@ -13,16 +13,19 @@ trap cleanup INT TERM EXIT
export ANSIBLE_ROLES_PATH=roles/
# Ensure subversion is set up
-ansible-playbook runme.yml "$@" -v --tags setup
+ansible-playbook runme.yml -i "${INVENTORY_PATH}" "$@" -v --tags setup
# Test functionality
-ansible-playbook runme.yml "$@" -v --tags tests
+ansible-playbook runme.yml -i "${INVENTORY_PATH}" "$@" -v --tags tests
# Test a warning is displayed for versions < 1.10.0 when a password is provided
-ansible-playbook runme.yml "$@" --tags warnings 2>&1 | tee out.txt
+ansible-playbook runme.yml -i "${INVENTORY_PATH}" "$@" --tags warnings 2>&1 | tee out.txt
-version="$(svn --version -q)"
-secure=$(python -c "from distutils.version import LooseVersion; print(LooseVersion('$version') >= LooseVersion('1.10.0'))")
+version=$(ANSIBLE_FORCE_COLOR=0 ansible -i "${INVENTORY_PATH}" -m shell -a 'svn --version -q' testhost 2>/dev/null | tail -n 1)
+
+echo "svn --version is '${version}'"
+
+secure=$(python -c "from ansible.module_utils.compat.version import LooseVersion; print(LooseVersion('$version') >= LooseVersion('1.10.0'))")
if [[ "${secure}" = "False" ]] && [[ "$(grep -c 'To securely pass credentials, upgrade svn to version 1.10.0' out.txt)" -eq 1 ]]; then
echo "Found the expected warning"
diff --git a/test/integration/targets/subversion/runme.yml b/test/integration/targets/subversion/runme.yml
index c67d7b89..71c5e4b8 100644
--- a/test/integration/targets/subversion/runme.yml
+++ b/test/integration/targets/subversion/runme.yml
@@ -1,5 +1,5 @@
---
-- hosts: localhost
+- hosts: testhost
tasks:
- name: load OS specific vars
include_vars: '{{ item }}'
diff --git a/test/integration/targets/tags/aliases b/test/integration/targets/tags/aliases
index 757c9966..8278ec8b 100644
--- a/test/integration/targets/tags/aliases
+++ b/test/integration/targets/tags/aliases
@@ -1,2 +1,2 @@
shippable/posix/group3
-skip/aix
+context/controller
diff --git a/test/integration/targets/task_ordering/aliases b/test/integration/targets/task_ordering/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/task_ordering/aliases
+++ b/test/integration/targets/task_ordering/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/task_ordering/tasks/main.yml b/test/integration/targets/task_ordering/tasks/main.yml
index 4a7828bf..a666006b 100644
--- a/test/integration/targets/task_ordering/tasks/main.yml
+++ b/test/integration/targets/task_ordering/tasks/main.yml
@@ -1,7 +1,7 @@
- set_fact:
temppath: "{{ remote_tmp_dir }}/output.txt"
-- include: taskorder-include.yml
+- include_tasks: taskorder-include.yml
with_items:
- 1
- 2
diff --git a/test/integration/targets/tasks/aliases b/test/integration/targets/tasks/aliases
index a6dafcf8..13e01f0c 100644
--- a/test/integration/targets/tasks/aliases
+++ b/test/integration/targets/tasks/aliases
@@ -1 +1,2 @@
shippable/posix/group1
+context/controller
diff --git a/test/integration/targets/tempfile/aliases b/test/integration/targets/tempfile/aliases
new file mode 100644
index 00000000..a6dafcf8
--- /dev/null
+++ b/test/integration/targets/tempfile/aliases
@@ -0,0 +1 @@
+shippable/posix/group1
diff --git a/test/integration/targets/tempfile/meta/main.yml b/test/integration/targets/tempfile/meta/main.yml
new file mode 100644
index 00000000..1810d4be
--- /dev/null
+++ b/test/integration/targets/tempfile/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/test/integration/targets/tempfile/tasks/main.yml b/test/integration/targets/tempfile/tasks/main.yml
new file mode 100644
index 00000000..2d783e6f
--- /dev/null
+++ b/test/integration/targets/tempfile/tasks/main.yml
@@ -0,0 +1,63 @@
+- name: Create a temporary file with defaults
+ tempfile:
+ register: temp_file_default
+
+- name: Create a temporary directory with defaults
+ tempfile:
+ state: directory
+ register: temp_dir_default
+
+- name: Create a temporary file with optional parameters
+ tempfile:
+ path: "{{ remote_tmp_dir }}"
+ prefix: hello.
+ suffix: .goodbye
+ register: temp_file_options
+
+- name: Create a temporary directory with optional parameters
+ tempfile:
+ state: directory
+ path: "{{ remote_tmp_dir }}"
+ prefix: hello.
+ suffix: .goodbye
+ register: temp_dir_options
+
+- name: Create a temporary file in a non-existent directory
+ tempfile:
+ path: "{{ remote_tmp_dir }}/does_not_exist"
+ register: temp_file_non_existent_path
+ ignore_errors: yes
+
+- name: Create a temporary directory in a non-existent directory
+ tempfile:
+ state: directory
+ path: "{{ remote_tmp_dir }}/does_not_exist"
+ register: temp_dir_non_existent_path
+ ignore_errors: yes
+
+- name: Check results
+ assert:
+ that:
+ - temp_file_default is changed
+ - temp_file_default.state == 'file'
+ - temp_file_default.path | basename | split('.') | first == 'ansible'
+
+ - temp_dir_default is changed
+ - temp_dir_default.state == 'directory'
+ - temp_dir_default.path | basename | split('.') | first == 'ansible'
+
+ - temp_file_options is changed
+ - temp_file_options.state == 'file'
+ - temp_file_options.path.startswith(remote_tmp_dir)
+ - temp_file_options.path | basename | split('.') | first == 'hello'
+ - temp_file_options.path | basename | split('.') | last == 'goodbye'
+
+ - temp_dir_options is changed
+ - temp_dir_options.state == 'directory'
+ - temp_dir_options.path.startswith(remote_tmp_dir)
+ - temp_dir_options.path | basename | split('.') | first == 'hello'
+ - temp_dir_options.path | basename | split('.') | last == 'goodbye'
+
+ - temp_file_non_existent_path is failed
+
+ - temp_dir_non_existent_path is failed
diff --git a/test/integration/targets/template/aliases b/test/integration/targets/template/aliases
index f0c24d20..327f088b 100644
--- a/test/integration/targets/template/aliases
+++ b/test/integration/targets/template/aliases
@@ -1,3 +1,3 @@
needs/root
shippable/posix/group5
-skip/aix
+context/controller # this "module" is actually an action that runs on the controller
diff --git a/test/integration/targets/template/files/custom_comment_string.expected b/test/integration/targets/template/files/custom_comment_string.expected
new file mode 100644
index 00000000..f3a08f7d
--- /dev/null
+++ b/test/integration/targets/template/files/custom_comment_string.expected
@@ -0,0 +1,2 @@
+Before
+After
diff --git a/test/integration/targets/template/runme.sh b/test/integration/targets/template/runme.sh
index a4f0bbe5..78f8d7b5 100755
--- a/test/integration/targets/template/runme.sh
+++ b/test/integration/targets/template/runme.sh
@@ -4,8 +4,8 @@ set -eux
ANSIBLE_ROLES_PATH=../ ansible-playbook template.yml -i ../../inventory -v "$@"
-# Test for #35571
-ansible testhost -i testhost, -m debug -a 'msg={{ hostvars["localhost"] }}' -e "vars1={{ undef }}" -e "vars2={{ vars1 }}"
+# Test for https://github.com/ansible/ansible/pull/35571
+ansible testhost -i testhost, -m debug -a 'msg={{ hostvars["localhost"] }}' -e "vars1={{ undef() }}" -e "vars2={{ vars1 }}"
# Test for https://github.com/ansible/ansible/issues/27262
ansible-playbook ansible_managed.yml -c ansible_managed.cfg -i ../../inventory -v "$@"
diff --git a/test/integration/targets/template/tasks/main.yml b/test/integration/targets/template/tasks/main.yml
index c5744d0d..f8848ef5 100644
--- a/test/integration/targets/template/tasks/main.yml
+++ b/test/integration/targets/template/tasks/main.yml
@@ -141,6 +141,26 @@
- 'import_as_with_context_diff_result.stdout == ""'
- "import_as_with_context_diff_result.rc == 0"
+# VERIFY comment_start_string and comment_end_string
+
+- name: Render a template with "comment_start_string" set to [#
+ template:
+ src: custom_comment_string.j2
+ dest: "{{output_dir}}/custom_comment_string.templated"
+ comment_start_string: "[#"
+ comment_end_string: "#]"
+ register: custom_comment_string_result
+
+- name: Get checksum of known good custom_comment_string.expected
+ stat:
+ path: "{{role_path}}/files/custom_comment_string.expected"
+ register: custom_comment_string_good
+
+- name: Verify templated custom_comment_string matches known good using checksum
+ assert:
+ that:
+ - "custom_comment_string_result.checksum == custom_comment_string_good.stat.checksum"
+
# VERIFY trim_blocks
- name: Render a template with "trim_blocks" set to False
@@ -727,4 +747,4 @@
- out.stdout == "bar=lookedup_bar"
# aliases file requires root for template tests so this should be safe
-- include: backup_test.yml
+- import_tasks: backup_test.yml
diff --git a/test/integration/targets/template/templates/custom_comment_string.j2 b/test/integration/targets/template/templates/custom_comment_string.j2
new file mode 100644
index 00000000..db0af48a
--- /dev/null
+++ b/test/integration/targets/template/templates/custom_comment_string.j2
@@ -0,0 +1,3 @@
+Before
+[# Test comment_start_string #]
+After
diff --git a/test/integration/targets/template_jinja2_latest/aliases b/test/integration/targets/template_jinja2_latest/aliases
index 2a89ae7e..b9c19e3d 100644
--- a/test/integration/targets/template_jinja2_latest/aliases
+++ b/test/integration/targets/template_jinja2_latest/aliases
@@ -1,5 +1,5 @@
needs/root
shippable/posix/group2
needs/target/template
-skip/aix
+context/controller
needs/file/test/lib/ansible_test/_data/requirements/constraints.txt
diff --git a/test/integration/targets/template_jinja2_non_native/aliases b/test/integration/targets/template_jinja2_non_native/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/template_jinja2_non_native/aliases
+++ b/test/integration/targets/template_jinja2_non_native/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/templating_lookups/aliases b/test/integration/targets/templating_lookups/aliases
index f8e28c7e..13e01f0c 100644
--- a/test/integration/targets/templating_lookups/aliases
+++ b/test/integration/targets/templating_lookups/aliases
@@ -1,2 +1,2 @@
shippable/posix/group1
-skip/aix
+context/controller
diff --git a/test/integration/targets/templating_settings/aliases b/test/integration/targets/templating_settings/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/templating_settings/aliases
+++ b/test/integration/targets/templating_settings/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/test_core/aliases b/test/integration/targets/test_core/aliases
index 041b0cc7..70a7b7a9 100644
--- a/test/integration/targets/test_core/aliases
+++ b/test/integration/targets/test_core/aliases
@@ -1,2 +1 @@
shippable/posix/group5
-skip/python2.6 # tests are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/test_files/aliases b/test/integration/targets/test_files/aliases
index 041b0cc7..70a7b7a9 100644
--- a/test/integration/targets/test_files/aliases
+++ b/test/integration/targets/test_files/aliases
@@ -1,2 +1 @@
shippable/posix/group5
-skip/python2.6 # tests are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/test_mathstuff/aliases b/test/integration/targets/test_mathstuff/aliases
index 041b0cc7..70a7b7a9 100644
--- a/test/integration/targets/test_mathstuff/aliases
+++ b/test/integration/targets/test_mathstuff/aliases
@@ -1,2 +1 @@
shippable/posix/group5
-skip/python2.6 # tests are controller only, and we no longer support Python 2.6 on the controller
diff --git a/test/integration/targets/throttle/aliases b/test/integration/targets/throttle/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/throttle/aliases
+++ b/test/integration/targets/throttle/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/unarchive/tasks/test_download.yml b/test/integration/targets/unarchive/tasks/test_download.yml
index 6b17449b..241f11b6 100644
--- a/test/integration/targets/unarchive/tasks/test_download.yml
+++ b/test/integration/targets/unarchive/tasks/test_download.yml
@@ -4,31 +4,41 @@
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
-- name: Install packages to make TLS connections work on CentOS 6
- pip:
- name:
- - urllib3==1.10.2
- - ndg_httpsclient==0.4.4
- - pyOpenSSL==16.2.0
- state: present
- when:
- - ansible_facts.distribution == 'CentOS'
- - not ansible_facts.python.has_sslcontext
-
-- name: unarchive a tar from an URL
- unarchive:
- src: "https://releases.ansible.com/ansible/ansible-latest.tar.gz"
- dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
- mode: "0700"
- remote_src: yes
- register: unarchive13
-
-- name: Test that unarchive succeeded
- assert:
- that:
- - "unarchive13.changed == true"
-
-- name: remove our tar.gz unarchive destination
- file:
- path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
- state: absent
+- name: Test TLS download
+ block:
+ - name: Install packages to make TLS connections work on CentOS 6
+ pip:
+ name:
+ - urllib3==1.10.2
+ - ndg_httpsclient==0.4.4
+ - pyOpenSSL==16.2.0
+ state: present
+ when:
+ - ansible_facts.distribution == 'CentOS'
+ - not ansible_facts.python.has_sslcontext
+ - name: unarchive a tar from an URL
+ unarchive:
+ src: "https://releases.ansible.com/ansible/ansible-latest.tar.gz"
+ dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
+ mode: "0700"
+ remote_src: yes
+ register: unarchive13
+ - name: Test that unarchive succeeded
+ assert:
+ that:
+ - "unarchive13.changed == true"
+ always:
+ - name: Uninstall CentOS 6 TLS connections packages
+ pip:
+ name:
+ - urllib3
+ - ndg_httpsclient
+ - pyOpenSSL
+ state: absent
+ when:
+ - ansible_facts.distribution == 'CentOS'
+ - not ansible_facts.python.has_sslcontext
+ - name: remove our tar.gz unarchive destination
+ file:
+ path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
+ state: absent
diff --git a/test/integration/targets/unarchive/tasks/test_include.yml b/test/integration/targets/unarchive/tasks/test_include.yml
index 3ed30fa3..04842e0e 100644
--- a/test/integration/targets/unarchive/tasks/test_include.yml
+++ b/test/integration/targets/unarchive/tasks/test_include.yml
@@ -15,6 +15,7 @@
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.zip"
dest: "{{ remote_tmp_dir }}/include-zip"
+ remote_src: yes
include:
- FOO-UNAR.TXT
@@ -39,6 +40,7 @@
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive-multi.tar"
dest: "{{ remote_tmp_dir }}/include-tar"
+ remote_src: yes
include:
- foo-unarchive-777.txt
@@ -61,6 +63,7 @@
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive-multi.tar"
dest: "{{ remote_tmp_dir }}/include-tar"
+ remote_src: yes
include:
- foo-unarchive-777.txt
exclude:
diff --git a/test/integration/targets/unarchive/tasks/test_owner_group.yml b/test/integration/targets/unarchive/tasks/test_owner_group.yml
index 95f1457e..227ad9ce 100644
--- a/test/integration/targets/unarchive/tasks/test_owner_group.yml
+++ b/test/integration/targets/unarchive/tasks/test_owner_group.yml
@@ -155,6 +155,8 @@
user:
name: testuser
state: absent
+ remove: yes
+ force: yes
- name: Remove testgroup
group:
diff --git a/test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml b/test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml
index 257692e1..e99f0380 100644
--- a/test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml
+++ b/test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml
@@ -41,6 +41,8 @@
user:
name: testuser
state: absent
+ remove: yes
+ force: yes
- name: Remove testgroup
group:
diff --git a/test/integration/targets/unarchive/tasks/test_unprivileged_user.yml b/test/integration/targets/unarchive/tasks/test_unprivileged_user.yml
index e4c2bec5..7022bba1 100644
--- a/test/integration/targets/unarchive/tasks/test_unprivileged_user.yml
+++ b/test/integration/targets/unarchive/tasks/test_unprivileged_user.yml
@@ -75,7 +75,9 @@
name: unarchivetest1
state: absent
remove: yes
- become: no
+ force: yes
+ become: yes
+ become_user: root
- name: Remove user home directory on macOS
file:
diff --git a/test/integration/targets/undefined/aliases b/test/integration/targets/undefined/aliases
index 70a7b7a9..1d28bdb2 100644
--- a/test/integration/targets/undefined/aliases
+++ b/test/integration/targets/undefined/aliases
@@ -1 +1,2 @@
shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/undefined/tasks/main.yml b/test/integration/targets/undefined/tasks/main.yml
index de6681a0..bbd82845 100644
--- a/test/integration/targets/undefined/tasks/main.yml
+++ b/test/integration/targets/undefined/tasks/main.yml
@@ -11,7 +11,8 @@
- assert:
that:
- - '"%r"|format(undef) == "AnsibleUndefined"'
+ - '"%r"|format(an_undefined_var) == "AnsibleUndefined"'
+ - '"%r"|format(undef()) == "AnsibleUndefined"'
# The existence of AnsibleUndefined in a templating result
# prevents safe_eval from turning the value into a python object
- names is string
diff --git a/test/integration/targets/unicode/aliases b/test/integration/targets/unicode/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/unicode/aliases
+++ b/test/integration/targets/unicode/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/unsafe_writes/aliases b/test/integration/targets/unsafe_writes/aliases
index 4fb7a116..cf954afc 100644
--- a/test/integration/targets/unsafe_writes/aliases
+++ b/test/integration/targets/unsafe_writes/aliases
@@ -1,6 +1,8 @@
+context/target
needs/root
skip/freebsd
skip/osx
skip/macos
skip/aix
shippable/posix/group3
+needs/target/setup_remote_tmp_dir
diff --git a/test/integration/targets/unsafe_writes/basic.yml b/test/integration/targets/unsafe_writes/basic.yml
index 410726ad..99a3195f 100644
--- a/test/integration/targets/unsafe_writes/basic.yml
+++ b/test/integration/targets/unsafe_writes/basic.yml
@@ -1,9 +1,23 @@
- hosts: testhost
gather_facts: false
- vars:
- testudir: '{{output_dir}}/unsafe_writes_test'
- testufile: '{{testudir}}/unreplacablefile.txt'
tasks:
+ - import_role:
+ name: ../setup_remote_tmp_dir
+ - name: define test directory
+ set_fact:
+ testudir: '{{remote_tmp_dir}}/unsafe_writes_test'
+ - name: define test file
+ set_fact:
+ testufile: '{{testudir}}/unreplacablefile.txt'
+ - name: define test environment with unsafe writes set
+ set_fact:
+ test_env:
+ ANSIBLE_UNSAFE_WRITES: "{{ lookup('env', 'ANSIBLE_UNSAFE_WRITES') }}"
+ when: lookup('env', 'ANSIBLE_UNSAFE_WRITES')
+ - name: define test environment without unsafe writes set
+ set_fact:
+ test_env: {}
+ when: not lookup('env', 'ANSIBLE_UNSAFE_WRITES')
- name: test unsafe_writes on immutable dir (file cannot be atomically replaced)
block:
- name: create target dir
@@ -61,6 +75,7 @@
msg: "Failed with envvar: {{env_enabled}}, due AUW: to {{q('env', 'ANSIBLE_UNSAFE_WRITES')}}"
that:
- env_enabled and copy_with_env is changed or not env_enabled and copy_with_env is failed
+ environment: "{{ test_env }}"
always:
- name: remove immutable flag from dir to prevent issues with cleanup
file: path={{testudir}} state=directory attributes="-i"
diff --git a/test/integration/targets/unsafe_writes/runme.sh b/test/integration/targets/unsafe_writes/runme.sh
index 791a5676..619ce025 100755
--- a/test/integration/targets/unsafe_writes/runme.sh
+++ b/test/integration/targets/unsafe_writes/runme.sh
@@ -3,10 +3,10 @@
set -eux
# test w/o fallback env var
-ansible-playbook basic.yml -i ../../inventory -e "output_dir=${OUTPUT_DIR}" "$@"
+ansible-playbook basic.yml -i ../../inventory "$@"
# test enabled fallback env var
-ANSIBLE_UNSAFE_WRITES=1 ansible-playbook basic.yml -i ../../inventory -e "output_dir=${OUTPUT_DIR}" "$@"
+ANSIBLE_UNSAFE_WRITES=1 ansible-playbook basic.yml -i ../../inventory "$@"
# test disnabled fallback env var
-ANSIBLE_UNSAFE_WRITES=0 ansible-playbook basic.yml -i ../../inventory -e "output_dir=${OUTPUT_DIR}" "$@"
+ANSIBLE_UNSAFE_WRITES=0 ansible-playbook basic.yml -i ../../inventory "$@"
diff --git a/test/integration/targets/until/aliases b/test/integration/targets/until/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/until/aliases
+++ b/test/integration/targets/until/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/unvault/aliases b/test/integration/targets/unvault/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/unvault/aliases
+++ b/test/integration/targets/unvault/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/uri/meta/main.yml b/test/integration/targets/uri/meta/main.yml
index 39b94950..2c2155ab 100644
--- a/test/integration/targets/uri/meta/main.yml
+++ b/test/integration/targets/uri/meta/main.yml
@@ -2,4 +2,3 @@ dependencies:
- prepare_tests
- prepare_http_tests
- setup_remote_tmp_dir
- - setup_remote_constraints
diff --git a/test/integration/targets/uri/tasks/main.yml b/test/integration/targets/uri/tasks/main.yml
index 4cefc6b3..700e7f10 100644
--- a/test/integration/targets/uri/tasks/main.yml
+++ b/test/integration/targets/uri/tasks/main.yml
@@ -228,6 +228,33 @@
headers:
Cookie: "fake=fake_value"
+- name: test unredirected_headers
+ uri:
+ url: 'https://{{ httpbin_host }}/redirect-to?status_code=301&url=/basic-auth/user/passwd'
+ user: user
+ password: passwd
+ force_basic_auth: true
+ unredirected_headers:
+ - authorization
+ ignore_errors: true
+ register: unredirected_headers
+
+- name: test omitting unredirected headers
+ uri:
+ url: 'https://{{ httpbin_host }}/redirect-to?status_code=301&url=/basic-auth/user/passwd'
+ user: user
+ password: passwd
+ force_basic_auth: true
+ register: redirected_headers
+
+- name: ensure unredirected_headers caused auth to fail
+ assert:
+ that:
+ - unredirected_headers is failed
+ - unredirected_headers.status == 401
+ - redirected_headers is successful
+ - redirected_headers.status == 200
+
- name: test PUT
uri:
url: 'https://{{ httpbin_host }}/put'
@@ -339,10 +366,25 @@
with_items: "{{ uri_os_packages[ansible_os_family].step2 | default([]) }}"
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
+- name: create constraints path
+ set_fact:
+ remote_constraints: "{{ remote_tmp_dir }}/constraints.txt"
+ when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
+
+- name: create constraints file
+ copy:
+ content: |
+ cryptography == 2.1.4
+ idna == 2.5
+ pyopenssl == 17.5.0
+ six == 1.13.0
+ urllib3 == 1.23
+ dest: "{{ remote_constraints }}"
+ when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
+
- name: install urllib3 and pyopenssl via pip
pip:
name: "{{ item }}"
- state: latest
extra_args: "-c {{ remote_constraints }}"
with_items:
- urllib3
@@ -474,6 +516,16 @@
- multipart.json.form.text_form_field1 == 'value1'
- multipart.json.form.text_form_field2 == 'value2'
+# https://github.com/ansible/ansible/issues/74276 - verifies we don't have a traceback
+- name: multipart/form-data with invalid value
+ uri:
+ url: https://{{ httpbin_host }}/post
+ method: POST
+ body_format: form-multipart
+ body:
+ integer_value: 1
+ register: multipart_invalid
+ failed_when: 'multipart_invalid.msg != "failed to parse body as form-multipart: value must be a string, or mapping, cannot be type int"'
- name: Validate invalid method
uri:
diff --git a/test/integration/targets/user/tasks/main.yml b/test/integration/targets/user/tasks/main.yml
index d3bae056..5e1d2d22 100644
--- a/test/integration/targets/user/tasks/main.yml
+++ b/test/integration/targets/user/tasks/main.yml
@@ -37,3 +37,5 @@
- import_tasks: test_password_lock.yml
- import_tasks: test_password_lock_new_user.yml
- import_tasks: test_local.yml
+- import_tasks: test_umask.yml
+ when: ansible_facts.system == 'Linux'
diff --git a/test/integration/targets/user/tasks/test_umask.yml b/test/integration/targets/user/tasks/test_umask.yml
new file mode 100644
index 00000000..9e162976
--- /dev/null
+++ b/test/integration/targets/user/tasks/test_umask.yml
@@ -0,0 +1,57 @@
+---
+- name: remove comments of /etc/login.defs
+ command: sed -e '/^[ \t]*#/d' /etc/login.defs
+ register: logindefs
+
+- block:
+ - name: Create user with 000 umask
+ user:
+ name: umaskuser_test_1
+ umask: "000"
+ register: umaskuser_test_1
+
+ - name: Create user with 077 umask
+ user:
+ name: umaskuser_test_2
+ umask: "077"
+ register: umaskuser_test_2
+
+ - name: check permissions on created home folder
+ stat:
+ path: "{{ user_home_prefix[ansible_facts.system] }}/umaskuser_test_1"
+ register: umaskuser_test_1_path
+
+ - name: check permissions on created home folder
+ stat:
+ path: "{{ user_home_prefix[ansible_facts.system] }}/umaskuser_test_2"
+ register: umaskuser_test_2_path
+
+ - name: remove created users
+ user:
+ name: "{{ item }}"
+ state: absent
+ register: umaskuser_test_remove
+ loop:
+ - umaskuser_test_1
+ - umaskuser_test_2
+
+ - name: Ensure correct umask has been set on created users
+ assert:
+ that:
+ - umaskuser_test_1_path.stat.mode == "0777"
+ - umaskuser_test_2_path.stat.mode == "0700"
+ - umaskuser_test_remove is changed
+ when: logindefs.stdout_lines is not search ("HOME_MODE")
+
+- name: Create user with setting both umask and local
+ user:
+ name: umaskuser_test_3
+ umask: "077"
+ local: true
+ register: umaskuser_test_3
+ ignore_errors: true
+
+- name: Ensure task has been failed
+ assert:
+ that:
+ - umaskuser_test_3 is failed
diff --git a/test/integration/targets/var_blending/aliases b/test/integration/targets/var_blending/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/var_blending/aliases
+++ b/test/integration/targets/var_blending/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/var_precedence/aliases b/test/integration/targets/var_precedence/aliases
index 3005e4b2..498fedd5 100644
--- a/test/integration/targets/var_precedence/aliases
+++ b/test/integration/targets/var_precedence/aliases
@@ -1 +1,2 @@
shippable/posix/group4
+context/controller
diff --git a/test/integration/targets/var_reserved/aliases b/test/integration/targets/var_reserved/aliases
index 765b70da..90ea9e12 100644
--- a/test/integration/targets/var_reserved/aliases
+++ b/test/integration/targets/var_reserved/aliases
@@ -1 +1,2 @@
shippable/posix/group2
+context/controller
diff --git a/test/integration/targets/var_templating/aliases b/test/integration/targets/var_templating/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/var_templating/aliases
+++ b/test/integration/targets/var_templating/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/vault/runme_change_pip_installed.sh b/test/integration/targets/vault/runme_change_pip_installed.sh
deleted file mode 100755
index 5ab2a8ec..00000000
--- a/test/integration/targets/vault/runme_change_pip_installed.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-
-# start by removing pycrypto and cryptography
-
-pip uninstall -y cryptography
-pip uninstall -y pycrypto
-
-./runme.sh
-
-# now just pycrypto
-pip install --user pycrypto
-
-./runme.sh
-
-
-# now just cryptography
-
-pip uninstall -y pycrypto
-pip install --user cryptography
-
-./runme.sh
-
-# now both
-
-pip install --user pycrypto
-
-./runme.sh
diff --git a/test/integration/targets/want_json_modules_posix/aliases b/test/integration/targets/want_json_modules_posix/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/want_json_modules_posix/aliases
+++ b/test/integration/targets/want_json_modules_posix/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/yaml_parsing/aliases b/test/integration/targets/yaml_parsing/aliases
index b5983214..8278ec8b 100644
--- a/test/integration/targets/yaml_parsing/aliases
+++ b/test/integration/targets/yaml_parsing/aliases
@@ -1 +1,2 @@
shippable/posix/group3
+context/controller
diff --git a/test/integration/targets/yum/filter_plugins/filter_list_of_tuples_by_first_param.py b/test/integration/targets/yum/filter_plugins/filter_list_of_tuples_by_first_param.py
new file mode 100644
index 00000000..27f38ce5
--- /dev/null
+++ b/test/integration/targets/yum/filter_plugins/filter_list_of_tuples_by_first_param.py
@@ -0,0 +1,25 @@
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible.errors import AnsibleError, AnsibleFilterError
+
+
+def filter_list_of_tuples_by_first_param(lst, search, startswith=False):
+ out = []
+ for element in lst:
+ if startswith:
+ if element[0].startswith(search):
+ out.append(element)
+ else:
+ if search in element[0]:
+ out.append(element)
+ return out
+
+
+class FilterModule(object):
+ ''' filter '''
+
+ def filters(self):
+ return {
+ 'filter_list_of_tuples_by_first_param': filter_list_of_tuples_by_first_param,
+ }
diff --git a/test/integration/targets/yum/tasks/cacheonly.yml b/test/integration/targets/yum/tasks/cacheonly.yml
new file mode 100644
index 00000000..03cbd0e9
--- /dev/null
+++ b/test/integration/targets/yum/tasks/cacheonly.yml
@@ -0,0 +1,16 @@
+---
+- name: Test cacheonly (clean before testing)
+ command: yum clean all
+
+- name: Try installing from cache where it has been cleaned
+ yum:
+ name: sos
+ state: latest
+ cacheonly: true
+ register: yum_result
+ ignore_errors: true
+
+- name: Verify yum failure
+ assert:
+ that:
+ - "yum_result is failed"
diff --git a/test/integration/targets/yum/tasks/main.yml b/test/integration/targets/yum/tasks/main.yml
index 3a7f4cf5..157124a9 100644
--- a/test/integration/targets/yum/tasks/main.yml
+++ b/test/integration/targets/yum/tasks/main.yml
@@ -10,7 +10,7 @@
name:
- sos
state: absent
-
+
- import_tasks: yum.yml
always:
- name: remove installed packages
@@ -69,3 +69,14 @@
- import_tasks: lock.yml
when:
- ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux']
+
+- import_tasks: multiarch.yml
+ when:
+ - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux']
+ - ansible_architecture == 'x86_64'
+ # Our output parsing expects us to be on yum, not dnf
+ - ansible_distribution_major_version is version('7', '<=')
+
+- import_tasks: cacheonly.yml
+ when:
+ - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux', 'Fedora']
diff --git a/test/integration/targets/yum/tasks/multiarch.yml b/test/integration/targets/yum/tasks/multiarch.yml
new file mode 100644
index 00000000..bced634c
--- /dev/null
+++ b/test/integration/targets/yum/tasks/multiarch.yml
@@ -0,0 +1,154 @@
+- block:
+ - name: Set up test yum repo
+ yum_repository:
+ name: multiarch-test-repo
+ description: ansible-test multiarch test repo
+ baseurl: "{{ multiarch_repo_baseurl }}"
+ gpgcheck: no
+ repo_gpgcheck: no
+
+ - name: Install two out of date packages from the repo
+ yum:
+ name:
+ - multiarch-a-1.0
+ - multiarch-b-1.0
+ register: outdated
+
+ - name: See what we installed
+ command: rpm -q multiarch-a multiarch-b
+ register: rpm_q
+
+ # Here we assume we're running on x86_64 (and limit to this in main.yml)
+ # (avoid comparing ansible_architecture because we only have test RPMs
+ # for i686 and x86_64 and ansible_architecture could be other things.)
+ - name: Assert that we got the right architecture
+ assert:
+ that:
+ - outdated is changed
+ - outdated.changes.installed | length == 2
+ - rpm_q.stdout_lines | length == 2
+ - rpm_q.stdout_lines[0].endswith('x86_64')
+ - rpm_q.stdout_lines[1].endswith('x86_64')
+
+ - name: Install the same versions, but i686 instead
+ yum:
+ name:
+ - multiarch-a-1.0*.i686
+ - multiarch-b-1.0*.i686
+ register: outdated_i686
+
+ - name: See what we installed
+ command: rpm -q multiarch-a multiarch-b
+ register: rpm_q
+
+ - name: Assert that all four are installed
+ assert:
+ that:
+ - outdated_i686 is changed
+ - outdated.changes.installed | length == 2
+ - rpm_q.stdout_lines | length == 4
+
+ - name: Update them all to 2.0
+ yum:
+ name: multiarch-*
+ state: latest
+ update_only: true
+ register: yum_latest
+
+ - name: Assert that all were updated and shown in results
+ assert:
+ that:
+ - yum_latest is changed
+ # This is just testing UI stability. The behavior is arguably not
+ # correct, because multiple packages are being updated. But the
+ # "because of (at least)..." wording kinda locks us in to only
+ # showing one update in this case. :(
+ - yum_latest.changes.updated | length == 1
+
+ - name: Downgrade them so we can upgrade them a different way
+ yum:
+ name:
+ - multiarch-a-1.0*
+ - multiarch-b-1.0*
+ allow_downgrade: true
+ register: downgrade
+
+ - name: See what we installed
+ command: rpm -q multiarch-a multiarch-b --queryformat '%{name}-%{version}.%{arch}\n'
+ register: rpm_q
+
+ - name: Ensure downgrade worked
+ assert:
+ that:
+ - downgrade is changed
+ - rpm_q.stdout_lines | sort == ['multiarch-a-1.0.i686', 'multiarch-a-1.0.x86_64', 'multiarch-b-1.0.i686', 'multiarch-b-1.0.x86_64']
+
+ # This triggers a different branch of logic that the partial wildcard
+ # above, but we're limited to check_mode here since it's '*'.
+ - name: Upgrade with full wildcard
+ yum:
+ name: '*'
+ state: latest
+ update_only: true
+ update_cache: true
+ check_mode: true
+ register: full_wildcard
+
+ # https://github.com/ansible/ansible/issues/73284
+ - name: Ensure we report things correctly (both arches)
+ assert:
+ that:
+ - full_wildcard is changed
+ - full_wildcard.changes.updated | filter_list_of_tuples_by_first_param('multiarch', startswith=True) | length == 4
+
+ - name: Downgrade them so we can upgrade them a different way
+ yum:
+ name:
+ - multiarch-a-1.0*
+ - multiarch-b-1.0*
+ allow_downgrade: true
+ register: downgrade
+
+ - name: Try to install again via virtual provides, should be unchanged
+ yum:
+ name:
+ - virtual-provides-multiarch-a
+ - virtual-provides-multiarch-b
+ state: present
+ register: install_vp
+
+ - name: Ensure the above did not change
+ assert:
+ that:
+ - install_vp is not changed
+
+ - name: Try to upgrade via virtual provides
+ yum:
+ name:
+ - virtual-provides-multiarch-a
+ - virtual-provides-multiarch-b
+ state: latest
+ update_only: true
+ register: upgrade_vp
+
+ - name: Ensure we report things correctly (both arches)
+ assert:
+ that:
+ - upgrade_vp is changed
+ # This is just testing UI stability, like above.
+ # We'll only have one package in "updated" per spec, even though
+ # (in this case) two are getting updated per spec.
+ - upgrade_vp.changes.updated | length == 2
+
+ always:
+ - name: Remove test yum repo
+ yum_repository:
+ name: multiarch-test-repo
+ state: absent
+
+ - name: Remove all test packages installed
+ yum:
+ name:
+ - multiarch-*
+ - virtual-provides-multiarch-*
+ state: absent
diff --git a/test/integration/targets/yum/tasks/repo.yml b/test/integration/targets/yum/tasks/repo.yml
index c1a7a016..f312b1ca 100644
--- a/test/integration/targets/yum/tasks/repo.yml
+++ b/test/integration/targets/yum/tasks/repo.yml
@@ -703,3 +703,27 @@
yum:
name: dinginessentail,dinginessentail-olive,landsidescalping
state: absent
+
+- block:
+ - yum:
+ name: dinginessentail
+ state: present
+
+ - yum:
+ list: dinginessentail*
+ register: list_out
+
+ - set_fact:
+ passed: true
+ loop: "{{ list_out.results }}"
+ when: item.yumstate == 'installed'
+
+ - name: Test that there is yumstate=installed in the result
+ assert:
+ that:
+ - passed is defined
+ always:
+ - name: Clean up
+ yum:
+ name: dinginessentail
+ state: absent
diff --git a/test/integration/targets/yum/tasks/yum.yml b/test/integration/targets/yum/tasks/yum.yml
index 7abfea17..e1caa852 100644
--- a/test/integration/targets/yum/tasks/yum.yml
+++ b/test/integration/targets/yum/tasks/yum.yml
@@ -867,3 +867,18 @@
- test-package-that-provides-toaster
- toaster
state: absent
+
+- yum:
+ list: "{{ package1 }}"
+ register: list_out
+
+- name: check that both yum and dnf return envra
+ assert:
+ that:
+ - '"envra" in list_out["results"][0]'
+
+- name: check that dnf returns nevra for backwards compat
+ assert:
+ that:
+ - '"nevra" in list_out["results"][0]'
+ when: ansible_pkg_mgr == 'dnf'
diff --git a/test/integration/targets/yum/vars/main.yml b/test/integration/targets/yum/vars/main.yml
new file mode 100644
index 00000000..2be15132
--- /dev/null
+++ b/test/integration/targets/yum/vars/main.yml
@@ -0,0 +1 @@
+multiarch_repo_baseurl: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/yum/multiarch-test-repo/RPMS/
diff --git a/test/integration/targets/yum_repository/tasks/main.yml b/test/integration/targets/yum_repository/tasks/main.yml
index d8195775..90866523 100644
--- a/test/integration/targets/yum_repository/tasks/main.yml
+++ b/test/integration/targets/yum_repository/tasks/main.yml
@@ -106,6 +106,11 @@
module_hotfixes: no
register: test_repo_add1
+ - name: Get repo file contents
+ slurp:
+ path: "{{ '/etc/yum.repos.d/' ~ yum_repository_test_repo.name ~ '2.repo' }}"
+ register: slurp
+
- name: check that options are correctly getting written to the repo file
assert:
that:
@@ -116,8 +121,7 @@
- "'keepalive = 0' in repo_file_contents"
- "'module_hotfixes = 0' in repo_file_contents"
vars:
- repo_file: "{{ '/etc/yum.repos.d/' ~ yum_repository_test_repo.name ~ '2.repo' }}"
- repo_file_contents: "{{ lookup('file', repo_file) }}"
+ repo_file_contents: "{{ slurp.content | b64decode }}"
- name: check new config doesn't change (Idempotant)
yum_repository:
@@ -163,7 +167,7 @@
description: Testing list feature
baseurl:
- "{{ yum_repository_test_repo.baseurl }}"
- - "{{ yum_repository_test_repo.baseurl | replace('download[0-9]?\\.', 'download2\\.', 1) }}"
+ - "{{ yum_repository_test_repo.baseurl ~ 'another_baseurl' }}"
gpgkey:
- gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-{{ ansible_facts.distribution_major_version }}
- gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG2-KEY-EPEL-{{ ansible_facts.distribution_major_version }}
@@ -175,16 +179,20 @@
- ddd
notify: remove listtest repo
+ - name: Get repo file
+ slurp:
+ path: /etc/yum.repos.d/listtest.repo
+ register: slurp
+
- name: Assert that lists were properly inserted
assert:
that:
- - url_hostname in repofile
- - url_hostname2 in repofile
+ - yum_repository_test_repo.baseurl in repofile
+ - another_baseurl in repofile
- "'RPM-GPG-KEY-EPEL' in repofile"
- "'RPM-GPG2-KEY-EPEL' in repofile"
- "'aaa bbb' in repofile"
- "'ccc ddd' in repofile"
vars:
- repofile: "{{ lookup('file', '/etc/yum.repos.d/listtest.repo') }}"
- url_hostname: "{{ yum_repository_test_repo.baseurl | urlsplit('hostname') }}"
- url_hostname2: "{{ url_hostname | replace('download[0-9]?\\.', 'download2\\.', 1) }}"
+ repofile: "{{ slurp.content | b64decode }}"
+ another_baseurl: "{{ yum_repository_test_repo.baseurl ~ 'another_baseurl' }}"