diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:16:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:16:49 +0000 |
commit | 48e387c5c12026a567eb7b293a3a590241c0cecb (patch) | |
tree | 80f2573be2d7d534b8ac4d2a852fe43f7ac35324 /test/integration | |
parent | Releasing progress-linux version 2.16.6-1~progress7.99u1. (diff) | |
download | ansible-core-48e387c5c12026a567eb7b293a3a590241c0cecb.tar.xz ansible-core-48e387c5c12026a567eb7b293a3a590241c0cecb.zip |
Merging upstream version 2.17.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/integration')
576 files changed, 3550 insertions, 4235 deletions
diff --git a/test/integration/targets/ansiballz_python/library/check_rlimit_and_maxfd.py b/test/integration/targets/ansiballz_python/library/check_rlimit_and_maxfd.py index a01ee99..cc3949b 100644 --- a/test/integration/targets/ansiballz_python/library/check_rlimit_and_maxfd.py +++ b/test/integration/targets/ansiballz_python/library/check_rlimit_and_maxfd.py @@ -3,8 +3,7 @@ # Copyright 2018 Red Hat | Ansible # 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 __future__ import annotations import resource import subprocess diff --git a/test/integration/targets/ansiballz_python/library/custom_module.py b/test/integration/targets/ansiballz_python/library/custom_module.py index 625823e..2436bb2 100644 --- a/test/integration/targets/ansiballz_python/library/custom_module.py +++ b/test/integration/targets/ansiballz_python/library/custom_module.py @@ -1,7 +1,6 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ..module_utils.basic import AnsibleModule # pylint: disable=relative-beyond-top-level from ..module_utils.custom_util import forty_two # pylint: disable=relative-beyond-top-level diff --git a/test/integration/targets/ansiballz_python/library/sys_check.py b/test/integration/targets/ansiballz_python/library/sys_check.py index aa22fe6..8454c07 100644 --- a/test/integration/targets/ansiballz_python/library/sys_check.py +++ b/test/integration/targets/ansiballz_python/library/sys_check.py @@ -2,8 +2,7 @@ # https://github.com/ansible/ansible/issues/64664 # https://github.com/ansible/ansible/issues/64479 -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import sys diff --git a/test/integration/targets/ansiballz_python/module_utils/custom_util.py b/test/integration/targets/ansiballz_python/module_utils/custom_util.py index 0393db4..c9e7ffd 100644 --- a/test/integration/targets/ansiballz_python/module_utils/custom_util.py +++ b/test/integration/targets/ansiballz_python/module_utils/custom_util.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def forty_two(): diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py index 9fa25b4..a6203b9 100644 --- a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py +++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py @@ -1,9 +1,7 @@ # (c) 2020 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 +from __future__ import annotations DOCUMENTATION = ''' cache: notjsonfile diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py index dfc1271..eb5f5f3 100644 --- a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py +++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py @@ -1,8 +1,7 @@ # Copyright (c) 2018 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 +from __future__ import annotations DOCUMENTATION = ''' inventory: statichost diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py index 639d3c6..43ac4b2 100644 --- a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py +++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py @@ -1,10 +1,8 @@ # (c) 2020 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) +from __future__ import annotations -__metaclass__ = type DOCUMENTATION = """ lookup: noop diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py index a1caeb1..814cd0a 100644 --- a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py +++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py @@ -1,12 +1,11 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = """ module: fakemodule broken: - short_desciption: fake module + short_description: fake module description: - this is a fake module version_added: 1.0.0 diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py index 4479f23..b7dcf51 100644 --- a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py +++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py index fb0e319..b017112 100644 --- a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py +++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py index ae0f75e..61de5f4 100644 --- a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py +++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' vars: noop_vars_plugin diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py index ea4a722..32abc43 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py @@ -1,9 +1,7 @@ # (c) 2020 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 +from __future__ import annotations DOCUMENTATION = ''' cache: notjsonfile diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/filter_subdir/in_subdir.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/filter_subdir/in_subdir.py index a8924e1..d912c02 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/filter_subdir/in_subdir.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/filter_subdir/in_subdir.py @@ -1,8 +1,6 @@ # 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 +from __future__ import annotations from ansible.utils.display import Display diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/grouped.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/grouped.py index a10c7aa..47ac9c4 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/grouped.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/grouped.py @@ -1,8 +1,6 @@ # 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 +from __future__ import annotations from ansible.utils.display import Display diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py index 1870b8e..60c60f9 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py @@ -1,8 +1,7 @@ # Copyright (c) 2018 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 +from __future__ import annotations DOCUMENTATION = ''' inventory: statichost diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py index 7a64a5d..7f69395 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py @@ -1,10 +1,8 @@ # (c) 2020 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) +from __future__ import annotations -__metaclass__ = type DOCUMENTATION = """ lookup: noop diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/database/database_type/subdir_module.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/database/database_type/subdir_module.py index dd41305..a7bcf50 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/database/database_type/subdir_module.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/database/database_type/subdir_module.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py index 6d18c08..39c4c61 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = """ diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py index 4479f23..b7dcf51 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py index aaaecb8..81e8fb8 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = r''' @@ -65,6 +64,15 @@ seealso: description: See also the Ansible docsite. - ref: foo_bar description: Some foo bar. +notes: + - This is a note. + - |- + This is a multi-paragraph note. + + This is its second paragraph. + This is just another line in the second paragraph. + Eventually this will break into a new line, + depending with which line width this is rendered. ''' EXAMPLES = ''' diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/test_test.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/test_test.py index f1c2b3a..160256c 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/test_test.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/test_test.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def yolo(value): diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py index 94e7feb..93c076b 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' vars: noop_vars_plugin diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml index bc6af69..ce79629 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml @@ -19,6 +19,10 @@ argument_specs: description: - Longer description for testns.testcol.testrole alternate entry point. author: Ansible Core (@ansible) + attributes: + check_mode: + description: Can run in check_mode and return changed status prediction without modifying target + support: full options: altopt1: description: altopt1 description diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/deprecation.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/deprecation.py index 3942d72..fdb85ab 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/deprecation.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/deprecation.py @@ -2,8 +2,7 @@ # 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 __future__ import annotations class ModuleDocFragment(object): diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/module.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/module.py index a572363..5fbc352 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/module.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/module.py @@ -2,8 +2,7 @@ # 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 __future__ import annotations class ModuleDocFragment(object): diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/plugin.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/plugin.py index 2fe4e4a..eddd61e 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/plugin.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/plugin.py @@ -2,8 +2,7 @@ # 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 __future__ import annotations class ModuleDocFragment(object): diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/version_added.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/version_added.py index 73e5f2f..d901404 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/version_added.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/version_added.py @@ -2,8 +2,7 @@ # 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 __future__ import annotations class ModuleDocFragment(object): diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol3/plugins/modules/test1.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol3/plugins/modules/test1.py index 02dfb89..1d2f370 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol3/plugins/modules/test1.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol3/plugins/modules/test1.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = """ diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol4/plugins/modules/test2.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol4/plugins/modules/test2.py index ddb0c11..d41920b 100644 --- a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol4/plugins/modules/test2.py +++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol4/plugins/modules/test2.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = """ diff --git a/test/integration/targets/ansible-doc/fakecollrole.output b/test/integration/targets/ansible-doc/fakecollrole.output index 3ae9077..77ac928 100644 --- a/test/integration/targets/ansible-doc/fakecollrole.output +++ b/test/integration/targets/ansible-doc/fakecollrole.output @@ -1,15 +1,20 @@ -> TESTNS.TESTCOL.TESTROLE (/ansible/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol) +> ROLE: *testns.testcol.testrole* (test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol) -ENTRY POINT: alternate - testns.testcol.testrole short description for alternate entry point +ENTRY POINT: *alternate* - testns.testcol.testrole short description for alternate entry point - Longer description for testns.testcol.testrole alternate entry - point. + Longer description for testns.testcol.testrole alternate + entry point. -OPTIONS (= is mandatory): +Options (= indicates it is required): -= altopt1 - altopt1 description - type: int += altopt1 altopt1 description + type: int +ATTRIBUTES: + + `check_mode:` + description: Can run in check_mode and return changed status prediction without modifying + target + support: full AUTHOR: Ansible Core (@ansible) diff --git a/test/integration/targets/ansible-doc/fakemodule.output b/test/integration/targets/ansible-doc/fakemodule.output index 4fb0776..42fbaad 100644 --- a/test/integration/targets/ansible-doc/fakemodule.output +++ b/test/integration/targets/ansible-doc/fakemodule.output @@ -1,16 +1,13 @@ -> TESTNS.TESTCOL.FAKEMODULE (./collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py) +> MODULE testns.testcol.fakemodule (./collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py) - this is a fake module + this is a fake module -ADDED IN: version 1.0.0 of testns.testcol +OPTIONS (= indicates it is required): -OPTIONS (= is mandatory): - -- _notreal - really not a real option +- _notreal really not a real option default: null - AUTHOR: me SHORT_DESCIPTION: fake module + diff --git a/test/integration/targets/ansible-doc/fakerole.output b/test/integration/targets/ansible-doc/fakerole.output index bcb53dc..3f4302a 100644 --- a/test/integration/targets/ansible-doc/fakerole.output +++ b/test/integration/targets/ansible-doc/fakerole.output @@ -1,32 +1,36 @@ -> TEST_ROLE1 (/ansible/test/integration/targets/ansible-doc/roles/normal_role1) +> ROLE: *test_role1* (test/integration/targets/ansible-doc/roles/test_role1) -ENTRY POINT: main - test_role1 from roles subdir +ENTRY POINT: *main* - test_role1 from roles subdir - In to am attended desirous raptures *declared* diverted - confined at. Collected instantly remaining up certainly to - `necessary' as. Over walk dull into son boy door went new. At - or happiness commanded daughters as. Is `handsome' an declared - at received in extended vicinity subjects. Into miss on he - over been late pain an. Only week bore boy what fat case left - use. Match round scale now style far times. Your me past an - much. + In to am attended desirous raptures *declared* diverted + confined at. Collected instantly remaining up certainly to + `necessary' as. Over walk dull into son boy door went new. + At or happiness commanded daughters as. Is `handsome` an + declared at received in extended vicinity subjects. Into + miss on he over been late pain an. Only week bore boy what + fat case left use. Match round scale now style far times. + Your me past an much. -OPTIONS (= is mandatory): +Options (= indicates it is required): -= myopt1 - First option. - type: str += myopt1 First option. + type: str -- myopt2 - Second option - default: 8000 - type: int +- myopt2 Second option + default: 8000 + type: int -- myopt3 - Third option. - choices: [choice1, choice2] - default: null - type: str +- myopt3 Third option. + choices: [choice1, choice2] + default: null + type: str +ATTRIBUTES: + + `diff_mode:` + description: Will return details on what has changed (or possibly needs changing in + check_mode), when in diff mode + details: Not all modules used support this + support: partial AUTHOR: John Doe (@john), Jane Doe (@jane) diff --git a/test/integration/targets/ansible-doc/filter_plugins/other.py b/test/integration/targets/ansible-doc/filter_plugins/other.py index 1bc2e17..3392dd5 100644 --- a/test/integration/targets/ansible-doc/filter_plugins/other.py +++ b/test/integration/targets/ansible-doc/filter_plugins/other.py @@ -1,8 +1,6 @@ # 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 +from __future__ import annotations from ansible.utils.display import Display diff --git a/test/integration/targets/ansible-doc/fix-urls.py b/test/integration/targets/ansible-doc/fix-urls.py index 1379a4e..a8e0576 100644 --- a/test/integration/targets/ansible-doc/fix-urls.py +++ b/test/integration/targets/ansible-doc/fix-urls.py @@ -1,4 +1,5 @@ """Unwrap URLs to docs.ansible.com and remove version""" +from __future__ import annotations import re import sys diff --git a/test/integration/targets/ansible-doc/library/double_doc.py b/test/integration/targets/ansible-doc/library/double_doc.py index 6f0412a..80bd3dd 100644 --- a/test/integration/targets/ansible-doc/library/double_doc.py +++ b/test/integration/targets/ansible-doc/library/double_doc.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = r''' diff --git a/test/integration/targets/ansible-doc/library/test_docs.py b/test/integration/targets/ansible-doc/library/test_docs.py index 39ae372..ba7817d 100644 --- a/test/integration/targets/ansible-doc/library/test_docs.py +++ b/test/integration/targets/ansible-doc/library/test_docs.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-doc/library/test_docs_missing_description.py b/test/integration/targets/ansible-doc/library/test_docs_missing_description.py index 6ed4183..40f39ef 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_missing_description.py +++ b/test/integration/targets/ansible-doc/library/test_docs_missing_description.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/library/test_docs_no_metadata.py b/test/integration/targets/ansible-doc/library/test_docs_no_metadata.py index 4ea86f0..b4344e9 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_no_metadata.py +++ b/test/integration/targets/ansible-doc/library/test_docs_no_metadata.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/library/test_docs_no_status.py b/test/integration/targets/ansible-doc/library/test_docs_no_status.py index 1b0db4e..f870e66 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_no_status.py +++ b/test/integration/targets/ansible-doc/library/test_docs_no_status.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-doc/library/test_docs_non_iterable_status.py b/test/integration/targets/ansible-doc/library/test_docs_non_iterable_status.py index 63d080f..6e78ea7 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_non_iterable_status.py +++ b/test/integration/targets/ansible-doc/library/test_docs_non_iterable_status.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-doc/library/test_docs_removed_precedence.py b/test/integration/targets/ansible-doc/library/test_docs_removed_precedence.py index 3de1c69..fdba64e 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_removed_precedence.py +++ b/test/integration/targets/ansible-doc/library/test_docs_removed_precedence.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/library/test_docs_removed_status.py b/test/integration/targets/ansible-doc/library/test_docs_removed_status.py index cb48c16..18f32a2 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_removed_status.py +++ b/test/integration/targets/ansible-doc/library/test_docs_removed_status.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-doc/library/test_docs_returns.py b/test/integration/targets/ansible-doc/library/test_docs_returns.py index 77c1376..d21abf3 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_returns.py +++ b/test/integration/targets/ansible-doc/library/test_docs_returns.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/library/test_docs_returns_broken.py b/test/integration/targets/ansible-doc/library/test_docs_returns_broken.py index d6d6264..0c3119b 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_returns_broken.py +++ b/test/integration/targets/ansible-doc/library/test_docs_returns_broken.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/library/test_docs_suboptions.py b/test/integration/targets/ansible-doc/library/test_docs_suboptions.py index c922d1d..7f93e22 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_suboptions.py +++ b/test/integration/targets/ansible-doc/library/test_docs_suboptions.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/library/test_docs_yaml_anchors.py b/test/integration/targets/ansible-doc/library/test_docs_yaml_anchors.py index bec0292..419f350 100644 --- a/test/integration/targets/ansible-doc/library/test_docs_yaml_anchors.py +++ b/test/integration/targets/ansible-doc/library/test_docs_yaml_anchors.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/library/test_no_docs.py b/test/integration/targets/ansible-doc/library/test_no_docs.py index 5503aed..2db81ae 100644 --- a/test/integration/targets/ansible-doc/library/test_no_docs.py +++ b/test/integration/targets/ansible-doc/library/test_no_docs.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-doc/library/test_no_docs_no_metadata.py b/test/integration/targets/ansible-doc/library/test_no_docs_no_metadata.py index 4887268..fb70e53 100644 --- a/test/integration/targets/ansible-doc/library/test_no_docs_no_metadata.py +++ b/test/integration/targets/ansible-doc/library/test_no_docs_no_metadata.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/ansible-doc/library/test_no_docs_no_status.py b/test/integration/targets/ansible-doc/library/test_no_docs_no_status.py index f90c5c7..dba36d1 100644 --- a/test/integration/targets/ansible-doc/library/test_no_docs_no_status.py +++ b/test/integration/targets/ansible-doc/library/test_no_docs_no_status.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-doc/library/test_no_docs_non_iterable_status.py b/test/integration/targets/ansible-doc/library/test_no_docs_non_iterable_status.py index 44fbede..0d22a1e 100644 --- a/test/integration/targets/ansible-doc/library/test_no_docs_non_iterable_status.py +++ b/test/integration/targets/ansible-doc/library/test_no_docs_non_iterable_status.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_adj_docs.py b/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_adj_docs.py index 81d401d..810521f 100644 --- a/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_adj_docs.py +++ b/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_adj_docs.py @@ -1,5 +1,4 @@ # Copyright (c) 2022 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 +from __future__ import annotations diff --git a/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_docs.py b/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_docs.py index 4fd63aa..449f392 100644 --- a/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_docs.py +++ b/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_docs.py @@ -1,8 +1,7 @@ # Copyright (c) 2022 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 +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-doc/noop.output b/test/integration/targets/ansible-doc/noop.output index 567150a..842f91d 100644 --- a/test/integration/targets/ansible-doc/noop.output +++ b/test/integration/targets/ansible-doc/noop.output @@ -15,6 +15,7 @@ "filename": "./collections/ansible_collections/testns/testcol/plugins/lookup/noop.py", "lookup": "noop", "options": {}, + "plugin_name": "testns.testcol.noop", "short_description": "returns input", "version_added": "1.0.0", "version_added_collection": "testns.testcol2" diff --git a/test/integration/targets/ansible-doc/noop_vars_plugin.output b/test/integration/targets/ansible-doc/noop_vars_plugin.output index 5c42af3..46b0be7 100644 --- a/test/integration/targets/ansible-doc/noop_vars_plugin.output +++ b/test/integration/targets/ansible-doc/noop_vars_plugin.output @@ -32,6 +32,7 @@ "type": "str" } }, + "plugin_name": "testns.testcol.noop_vars_plugin", "short_description": "Do NOT load host and group vars", "vars": "noop_vars_plugin" }, diff --git a/test/integration/targets/ansible-doc/notjsonfile.output b/test/integration/targets/ansible-doc/notjsonfile.output index a73b1a9..9ad5d1f 100644 --- a/test/integration/targets/ansible-doc/notjsonfile.output +++ b/test/integration/targets/ansible-doc/notjsonfile.output @@ -146,6 +146,7 @@ "version_added_collection": "testns.testcol2" } }, + "plugin_name": "testns.testcol.notjsonfile", "short_description": "JSON formatted files.", "version_added": "0.7.0", "version_added_collection": "testns.testcol" diff --git a/test/integration/targets/ansible-doc/randommodule-text-verbose.output b/test/integration/targets/ansible-doc/randommodule-text-verbose.output new file mode 100644 index 0000000..cfcba46 --- /dev/null +++ b/test/integration/targets/ansible-doc/randommodule-text-verbose.output @@ -0,0 +1,79 @@ +Using /home/bcoca/.ansible.cfg as config file +> MODULE testns.testcol.randommodule (/home/bcoca/work/ansible/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py) + + A random module. +DEPRECATED: + Reason: Test deprecation + Will be removed in: Ansible 3.0.0 + Alternatives: Use some other module + +OPTIONS (= indicates it is required): + +- sub Suboptions. + set_via: + env: + - added_in: version 1.0.0 of ansible-core + deprecated: + alternative: none + removed_in: 2.0.0 + version: 2.0.0 + why: Test deprecation + name: TEST_ENV + default: null + 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 + +ADDED_IN: version 1.0.0 of testns.testcol + +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/randommodule-text.output b/test/integration/targets/ansible-doc/randommodule-text.output index ca36134..e890516 100644 --- a/test/integration/targets/ansible-doc/randommodule-text.output +++ b/test/integration/targets/ansible-doc/randommodule-text.output @@ -1,28 +1,24 @@ -> TESTNS.TESTCOL.RANDOMMODULE (./collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py) - - A random module. See `foo=bar' (of role foo.bar.baz, main - entrypoint) for how this is used in the [foo.bar.baz]'s `main' - entrypoint. See the docsite <https://docs.ansible.com/ansible- - core/devel/> for more information on ansible-core. This module - is not related to the [ansible.builtin.copy] module. - ------------- You might also be interested in - ansible_python_interpreter. Sometimes you have [broken markup] - that will result in error messages. - -ADDED IN: version 1.0.0 of testns.testcol - +> MODULE testns.testcol.randommodule (./collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py) + + A random module. + See `foo=bar' (of role foo.bar.baz, main entrypoint) for how this is + used in the [[foo.bar.baz]]'s `main' entrypoint. + See the docsite <https://docs.ansible.com/ansible-core/devel/> for + more information on ansible-core. + This module is not related to the [ansible.builtin.copy] module. + ------------- You might also be interested in + ansible_python_interpreter. + Sometimes you have [broken markup] that will result in error + messages. DEPRECATED: - Reason: Test deprecation Will be removed in: Ansible 3.0.0 Alternatives: Use some other module +OPTIONS (= indicates it is required): -OPTIONS (= is mandatory): - -- sub - Suboptions. Contains `sub.subtest', which can be set to `123'. - You can use `TEST_ENV' to set this. +- sub Suboptions. Contains `sub.subtest', which can be set to `123'. + You can use `TEST_ENV' to set this. set_via: env: - deprecated: @@ -33,47 +29,40 @@ OPTIONS (= is mandatory): name: TEST_ENV default: null type: dict - - OPTIONS: - - - subtest2 - Another suboption. Useful when [ansible.builtin.shuffle] - is used with value `[a,b,),d\]'. - default: null - type: float - added in: version 1.1.0 - - - - SUBOPTIONS: - - - subtest - A suboption. Not compatible to `path=c:\foo(1).txt' (of - module ansible.builtin.copy). - default: null - type: int - added in: version 1.1.0 of testns.testcol - - -- test - Some text. Consider not using `foo=bar'. + options: + + - subtest2 Another suboption. Useful when [[ansible.builtin.shuffle]] + is used with value `[a,b,),d\]'. + default: null + type: float + added in: version 1.1.0 + suboptions: + + - subtest A suboption. Not compatible to `path=c:\foo(1).txt' (of + module ansible.builtin.copy). + default: null + type: int + added in: version 1.1.0 of testns.testcol + +- test Some text. Consider not using `foo=bar'. default: null type: str - added in: version 1.2.0 of testns.testcol - -- testcol2option - An option taken from testcol2 +- 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 +- testcol2option2 Another option taken from testcol2 default: null type: str +NOTES: + * This is a note. + * This is a multi-paragraph note. + This is its second paragraph. This is just another line + in the second paragraph. Eventually this will break into + a new line, depending with which line width this is + rendered. SEE ALSO: * Module ansible.builtin.ping @@ -93,40 +82,32 @@ SEE ALSO: Some foo bar. https://docs.ansible.com/ansible-core/devel/#stq=foo_bar&stp=1 - AUTHOR: Ansible Core Team EXAMPLES: - - RETURN VALUES: -- a_first - A first result. Use `a_first=foo(bar\baz)bam'. + +- a_first A first result. Use `a_first=foo(bar\baz)bam'. returned: success type: str -- m_middle - This should be in the middle. - Has some more data. - Check out `m_middle.suboption' and compare it to `a_first=foo' - and `value' (of lookup plugin community.general.foo). +- m_middle This should be in the middle. + Has some more data. + Check out `m_middle.suboption' and compare it to + `a_first=foo' and `value' (of lookup plugin + community.general.foo). returned: success and 1st of month type: dict + contains: - CONTAINS: - - - suboption - A suboption. - choices: [ARF, BARN, c_without_capital_first_letter] - type: str - added in: version 1.4.0 of testns.testcol - + - 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. +- 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/randommodule.output b/test/integration/targets/ansible-doc/randommodule.output index f40202a..58eb459 100644 --- a/test/integration/targets/ansible-doc/randommodule.output +++ b/test/integration/targets/ansible-doc/randommodule.output @@ -21,6 +21,10 @@ "filename": "./collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py", "has_action": false, "module": "randommodule", + "notes": [ + "This is a note.", + "This is a multi-paragraph note.\n\nThis is its second paragraph.\nThis is just another line in the second paragraph.\nEventually this will break into a new line,\ndepending with which line width this is rendered." + ], "options": { "sub": { "description": "Suboptions. Contains O(sub.subtest), which can be set to V(123). You can use E(TEST_ENV) to set this.", @@ -74,6 +78,7 @@ "type": "str" } }, + "plugin_name": "testns.testcol.randommodule", "seealso": [ { "module": "ansible.builtin.ping" diff --git a/test/integration/targets/ansible-doc/roles/test_role1/meta/argument_specs.yml b/test/integration/targets/ansible-doc/roles/test_role1/meta/argument_specs.yml index 0315a1f..42857cd 100644 --- a/test/integration/targets/ansible-doc/roles/test_role1/meta/argument_specs.yml +++ b/test/integration/targets/ansible-doc/roles/test_role1/meta/argument_specs.yml @@ -11,7 +11,11 @@ argument_specs: author: - John Doe (@john) - Jane Doe (@jane) - + attributes: + diff_mode: + description: Will return details on what has changed (or possibly needs changing in check_mode), when in diff mode + support: partial + details: Not all modules used support this options: myopt1: description: diff --git a/test/integration/targets/ansible-doc/runme.sh b/test/integration/targets/ansible-doc/runme.sh index b525766..1cfe211 100755 --- a/test/integration/targets/ansible-doc/runme.sh +++ b/test/integration/targets/ansible-doc/runme.sh @@ -6,7 +6,7 @@ set -eu verbosity=0 # default to silent output for naked grep; -vvv+ will adjust this -export GREP_OPTS=-q +GREP_OPTS=(-q) # shell tracing output is very large from this script; only enable if >= -vvv was passed while getopts :v opt @@ -18,47 +18,52 @@ done if (( verbosity >= 3 )); then - set -x; - export GREP_OPTS= ; + set -x + GREP_OPTS=() fi echo "running playbook-backed docs tests" ansible-playbook test.yml -i inventory "$@" # test keyword docs -ansible-doc -t keyword -l | grep $GREP_OPTS 'vars_prompt: list of variables to prompt for.' -ansible-doc -t keyword vars_prompt | grep $GREP_OPTS 'description: list of variables to prompt for.' -ansible-doc -t keyword asldkfjaslidfhals 2>&1 | grep $GREP_OPTS 'Skipping Invalid keyword' +ansible-doc -t keyword -l | grep "${GREP_OPTS[@]}" 'vars_prompt: list of variables to prompt for.' +ansible-doc -t keyword vars_prompt | grep "${GREP_OPTS[@]}" 'description: list of variables to prompt for.' +ansible-doc -t keyword asldkfjaslidfhals 2>&1 | grep "${GREP_OPTS[@]}" 'Skipping Invalid keyword' # collections testing ( unset ANSIBLE_PLAYBOOK_DIR +export ANSIBLE_NOCOLOR=1 + cd "$(dirname "$0")" echo "test fakemodule docs from collection" # we use sed to strip the module path from the first line -current_out="$(ansible-doc --playbook-dir ./ testns.testcol.fakemodule | sed '1 s/\(^> TESTNS\.TESTCOL\.FAKEMODULE\).*(.*)$/\1/')" -expected_out="$(sed '1 s/\(^> TESTNS\.TESTCOL\.FAKEMODULE\).*(.*)$/\1/' fakemodule.output)" +current_out="$(ansible-doc --playbook-dir ./ testns.testcol.fakemodule | sed '1 s/\(^> MODULE testns\.testcol\.fakemodule\).*(.*)$/\1/')" +expected_out="$(sed '1 s/\(^> MODULE testns\.testcol\.fakemodule\).*(.*)$/\1/' fakemodule.output)" test "$current_out" == "$expected_out" echo "test randommodule docs from collection" # we use sed to strip the plugin path from the first line, and fix-urls.py to unbreak and replace URLs from stable-X branches -current_out="$(ansible-doc --playbook-dir ./ testns.testcol.randommodule | sed '1 s/\(^> TESTNS\.TESTCOL\.RANDOMMODULE\).*(.*)$/\1/' | python fix-urls.py)" -expected_out="$(sed '1 s/\(^> TESTNS\.TESTCOL\.RANDOMMODULE\).*(.*)$/\1/' randommodule-text.output)" +current_out="$(ansible-doc --playbook-dir ./ testns.testcol.randommodule | sed '1 s/\(^> MODULE testns\.testcol\.randommodule\).*(.*)$/\1/' | python fix-urls.py)" +expected_out="$(sed '1 s/\(^> MODULE testns\.testcol\.randommodule\).*(.*)$/\1/' randommodule-text.output)" test "$current_out" == "$expected_out" echo "test yolo filter docs from collection" # we use sed to strip the plugin path from the first line, and fix-urls.py to unbreak and replace URLs from stable-X branches -current_out="$(ansible-doc --playbook-dir ./ testns.testcol.yolo --type test | sed '1 s/\(^> TESTNS\.TESTCOL\.YOLO\).*(.*)$/\1/' | python fix-urls.py)" -expected_out="$(sed '1 s/\(^> TESTNS\.TESTCOL\.YOLO\).*(.*)$/\1/' yolo-text.output)" +current_out="$(ansible-doc --playbook-dir ./ testns.testcol.yolo --type test | sed '1 s/\(^> TEST testns\.testcol\.yolo\).*(.*)$/\1/' | python fix-urls.py)" +expected_out="$(sed '1 s/\(^> TEST testns\.testcol\.yolo\).*(.*)$/\1/' yolo-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 name" + echo "ensure we do work with valid collection name for list" -ansible-doc --list testns.testcol --playbook-dir ./ 2>&1 | grep $GREP_OPTS -v "Invalid collection name" +ansible-doc --list testns.testcol --playbook-dir ./ 2>&1 | grep "${GREP_OPTS[@]}" -v "Invalid collection name" echo "ensure we dont break on invalid collection name for list" -ansible-doc --list testns.testcol.fakemodule --playbook-dir ./ 2>&1 | grep $GREP_OPTS "Invalid collection name" +ansible-doc --list testns.testcol.fakemodule --playbook-dir ./ 2>&1 | grep "${GREP_OPTS[@]}" "Invalid collection name" echo "filter list with more than one collection (1/2)" output=$(ansible-doc --list testns.testcol3 testns.testcol4 --playbook-dir ./ 2>&1 | wc -l) @@ -96,12 +101,12 @@ do list_result=$(ansible-doc -l -t ${ptype} --playbook-dir ./ testns.testcol) metadata_result=$(ansible-doc --metadata-dump --no-fail-on-errors -t ${ptype} --playbook-dir ./ testns.testcol) for name in "${expected_names[@]}"; do - echo "${list_result}" | grep $GREP_OPTS "testns.testcol.${name}" - echo "${metadata_result}" | grep $GREP_OPTS "testns.testcol.${name}" + echo "${list_result}" | grep "${GREP_OPTS[@]}" "testns.testcol.${name}" + echo "${metadata_result}" | grep "${GREP_OPTS[@]}" "testns.testcol.${name}" done # ensure we get error if passing invalid collection, much less any plugins - ansible-doc -l -t ${ptype} bogus.boguscoll 2>&1 | grep $GREP_OPTS "unable to locate collection" + ansible-doc -l -t ${ptype} bogus.boguscoll 2>&1 | grep "${GREP_OPTS[@]}" "unable to locate collection" # TODO: do we want per namespace? # ensure we get 1 plugins when restricting namespace @@ -113,24 +118,24 @@ done echo "testing role text output" # we use sed to strip the role path from the first line -current_role_out="$(ansible-doc -t role -r ./roles test_role1 | sed '1 s/\(^> TEST_ROLE1\).*(.*)$/\1/')" -expected_role_out="$(sed '1 s/\(^> TEST_ROLE1\).*(.*)$/\1/' fakerole.output)" +current_role_out="$(ansible-doc -t role -r ./roles test_role1 | sed '1 s/\(^> ROLE: \*test_role1\*\).*(.*)$/\1/')" +expected_role_out="$(sed '1 s/\(^> ROLE: \*test_role1\*\).*(.*)$/\1/' fakerole.output)" test "$current_role_out" == "$expected_role_out" echo "testing multiple role entrypoints" # Two collection roles are defined, but only 1 has a role arg spec with 2 entry points output=$(ansible-doc -t role -l --playbook-dir . testns.testcol | wc -l) -test "$output" -eq 2 +test "$output" -eq 4 echo "test listing roles with multiple collection filters" # Two collection roles are defined, but only 1 has a role arg spec with 2 entry points output=$(ansible-doc -t role -l --playbook-dir . testns.testcol2 testns.testcol | wc -l) -test "$output" -eq 2 +test "$output" -eq 4 echo "testing standalone roles" # Include normal roles (no collection filter) output=$(ansible-doc -t role -l --playbook-dir . | wc -l) -test "$output" -eq 3 +test "$output" -eq 8 echo "testing role precedence" # Test that a role in the playbook dir with the same name as a role in the @@ -141,8 +146,8 @@ output=$(ansible-doc -t role -l --playbook-dir . | grep -c "test_role1 from play test "$output" -eq 0 echo "testing role entrypoint filter" -current_role_out="$(ansible-doc -t role --playbook-dir . testns.testcol.testrole -e alternate| sed '1 s/\(^> TESTNS\.TESTCOL\.TESTROLE\).*(.*)$/\1/')" -expected_role_out="$(sed '1 s/\(^> TESTNS\.TESTCOL\.TESTROLE\).*(.*)$/\1/' fakecollrole.output)" +current_role_out="$(ansible-doc -t role --playbook-dir . testns.testcol.testrole -e alternate| sed '1 s/\(^> ROLE: \*testns\.testcol\.testrole\*\).*(.*)$/\1/')" +expected_role_out="$(sed '1 s/\(^> ROLE: \*testns\.testcol\.testrole\*\).*(.*)$/\1/' fakecollrole.output)" test "$current_role_out" == "$expected_role_out" ) @@ -230,7 +235,7 @@ echo "testing sidecar docs for jinja plugins" [ "$(ansible-doc -t filter --playbook-dir ./ ansible.legacy.donothing| wc -l)" -gt "0" ] echo "testing no docs and no sidecar" -ansible-doc -t filter --playbook-dir ./ nodocs 2>&1| grep $GREP_OPTS -c 'missing documentation' || true +ansible-doc -t filter --playbook-dir ./ nodocs 2>&1| grep "${GREP_OPTS[@]}" -c 'missing documentation' || true echo "testing sidecar docs for module" [ "$(ansible-doc -M ./library test_win_module| wc -l)" -gt "0" ] @@ -249,7 +254,7 @@ echo "testing no duplicates for plugins that only exist in ansible.builtin when [ "$(ansible-doc -l -t filter --playbook-dir ./ |grep -c 'b64encode')" -eq "1" ] echo "testing with playbook dir, legacy should override" -ansible-doc -t filter split --playbook-dir ./ |grep $GREP_OPTS histerical +ansible-doc -t filter split --playbook-dir ./ -v|grep "${GREP_OPTS[@]}" histerical pyc_src="$(pwd)/filter_plugins/other.py" pyc_1="$(pwd)/filter_plugins/split.pyc" @@ -258,11 +263,11 @@ trap 'rm -rf "$pyc_1" "$pyc_2"' EXIT echo "testing pyc files are not used as adjacent documentation" python -c "import py_compile; py_compile.compile('$pyc_src', cfile='$pyc_1')" -ansible-doc -t filter split --playbook-dir ./ |grep $GREP_OPTS histerical +ansible-doc -t filter split --playbook-dir ./ -v|grep "${GREP_OPTS[@]}" histerical echo "testing pyc files are not listed as plugins" python -c "import py_compile; py_compile.compile('$pyc_src', cfile='$pyc_2')" test "$(ansible-doc -l -t module --playbook-dir ./ 2>&1 1>/dev/null |grep -c "notaplugin")" == 0 echo "testing without playbook dir, builtin should return" -ansible-doc -t filter split 2>&1 |grep $GREP_OPTS -v histerical +ansible-doc -t filter split -v 2>&1 |grep "${GREP_OPTS[@]}" -v histerical diff --git a/test/integration/targets/ansible-doc/test.yml b/test/integration/targets/ansible-doc/test.yml index a8c992e..f981401 100644 --- a/test/integration/targets/ansible-doc/test.yml +++ b/test/integration/targets/ansible-doc/test.yml @@ -2,6 +2,12 @@ gather_facts: no environment: ANSIBLE_LIBRARY: "{{ playbook_dir }}/library" + ANSIBLE_NOCOLOR: 1 + ANSIBLE_DEPRECATION_WARNINGS: 1 + vars: + # avoid header that has full path and won't work across random paths for tests + actual_output_clean: '{{ actual_output.splitlines()[1:] }}' + expected_output_clean: '{{ expected_output.splitlines()[1:] }}' tasks: - name: module with missing description return docs command: ansible-doc test_docs_missing_description @@ -16,34 +22,32 @@ in result.stderr - name: module with suboptions (avoid first line as it has full path) - shell: ansible-doc test_docs_suboptions| tail -n +2 + shell: ansible-doc test_docs_suboptions| tail -n +3 register: result ignore_errors: true - set_fact: - actual_output: >- - {{ result.stdout | regex_replace('^(> [A-Z_]+ +\().+library/([a-z_]+.py)\)$', '\1library/\2)', multiline=true) }} + actual_output: "{{ result.stdout }}" expected_output: "{{ lookup('file', 'test_docs_suboptions.output') }}" - assert: that: - result is succeeded - - actual_output == expected_output + - actual_output_clean == expected_output_clean - name: module with return docs - shell: ansible-doc test_docs_returns| tail -n +2 + shell: ansible-doc test_docs_returns| tail -n +3 register: result ignore_errors: true - set_fact: - actual_output: >- - {{ result.stdout | regex_replace('^(> [A-Z_]+ +\().+library/([a-z_]+.py)\)$', '\1library/\2)', multiline=true) }} + actual_output: "{{ result.stdout }}" expected_output: "{{ lookup('file', 'test_docs_returns.output') }}" - assert: that: - result is succeeded - - actual_output == expected_output + - actual_output_clean == expected_output_clean - name: module with broken return docs command: ansible-doc test_docs_returns_broken @@ -68,7 +72,7 @@ - assert: that: - '"WARNING" not in result.stderr' - - '"TEST_DOCS " in result.stdout' + - '"test_docs" in result.stdout' - '"AUTHOR: Ansible Core Team" in result.stdout' - name: documented module without metadata @@ -77,7 +81,7 @@ - assert: that: - '"WARNING" not in result.stderr' - - '"TEST_DOCS_NO_METADATA " in result.stdout' + - '"test_docs_no_metadata " in result.stdout' - '"AUTHOR: Ansible Core Team" in result.stdout' - name: documented module with no status in metadata @@ -86,7 +90,7 @@ - assert: that: - '"WARNING" not in result.stderr' - - '"TEST_DOCS_NO_STATUS " in result.stdout' + - '"test_docs_no_status " in result.stdout' - '"AUTHOR: Ansible Core Team" in result.stdout' - name: documented module with non-iterable status in metadata @@ -95,7 +99,7 @@ - assert: that: - '"WARNING" not in result.stderr' - - '"TEST_DOCS_NON_ITERABLE_STATUS " in result.stdout' + - '"test_docs_non_iterable_status " in result.stdout' - '"AUTHOR: Ansible Core Team" in result.stdout' - name: documented module with removed status @@ -105,7 +109,7 @@ - assert: that: - '"WARNING" not in result.stderr' - - '"TEST_DOCS_REMOVED_STATUS " in result.stdout' + - '"test_docs_removed_status " in result.stdout' - '"AUTHOR: Ansible Core Team" in result.stdout' - name: empty module @@ -138,15 +142,18 @@ - '"Alternatives: new_module" in result.stdout' - name: documented module with YAML anchors - shell: ansible-doc test_docs_yaml_anchors |tail -n +2 + shell: ansible-doc test_docs_yaml_anchors |tail -n +3 register: result + - set_fact: actual_output: >- {{ result.stdout | regex_replace('^(> [A-Z_]+ +\().+library/([a-z_]+.py)\)$', '\1library/\2)', multiline=true) }} expected_output: "{{ lookup('file', 'test_docs_yaml_anchors.output') }}" + - assert: that: - actual_output == expected_output + - actual_output_clean == expected_output_clean - name: ensure 'donothing' adjacent filter is loaded assert: @@ -154,19 +161,23 @@ - "'x' == ('x'|donothing)" - name: docs for deprecated plugin - command: ansible-doc deprecated_with_docs -t lookup + command: ansible-doc deprecated_with_docs -t lookup --playbook-dir ./ register: result + - assert: that: - - '"WARNING" not in result.stderr' - - '"DEPRECATED_WITH_DOCS " in result.stdout' + - '"[WARNING]" not in result.stderr' + - '"[DEPRECATION WARNING]" in result.stderr' + - '"deprecated_with_docs " in result.stdout' - '"AUTHOR: Ansible Core Team" in result.stdout' - name: adjacent docs for deprecated plugin - command: ansible-doc deprecated_with_adj_docs -t lookup + command: ansible-doc deprecated_with_adj_docs -t lookup --playbook-dir ./ register: result + - assert: that: - - '"WARNING" not in result.stderr' - - '"DEPRECATED_WITH_ADJ_DOCS " in result.stdout' + - '"[WARNING]" not in result.stderr' + - '"[DEPRECATION WARNING]" in result.stderr' + - '"deprecated_with_adj_docs " in result.stdout' - '"AUTHOR: Ansible Core Team" in result.stdout' diff --git a/test/integration/targets/ansible-doc/test_docs_returns.output b/test/integration/targets/ansible-doc/test_docs_returns.output index 3e23645..3fea978 100644 --- a/test/integration/targets/ansible-doc/test_docs_returns.output +++ b/test/integration/targets/ansible-doc/test_docs_returns.output @@ -1,33 +1,27 @@ - - Test module + Test module AUTHOR: Ansible Core Team EXAMPLES: - - RETURN VALUES: -- a_first - A first result. + +- a_first A first result. returned: success type: str -- m_middle - This should be in the middle. - Has some more data +- m_middle This should be in the middle. + Has some more data returned: success and 1st of month type: dict + contains: - CONTAINS: - - - suboption - A suboption. - choices: [ARF, BARN, c_without_capital_first_letter] - type: str + - suboption A suboption. + choices: [ARF, BARN, c_without_capital_first_letter] + type: str -- z_last - A last result. +- z_last A last result. returned: success type: str + diff --git a/test/integration/targets/ansible-doc/test_docs_suboptions.output b/test/integration/targets/ansible-doc/test_docs_suboptions.output index 350f90f..2ca3377 100644 --- a/test/integration/targets/ansible-doc/test_docs_suboptions.output +++ b/test/integration/targets/ansible-doc/test_docs_suboptions.output @@ -1,42 +1,32 @@ + Test module - Test module +OPTIONS (= indicates it is required): -OPTIONS (= is mandatory): - -- with_suboptions - An option with suboptions. - Use with care. +- with_suboptions An option with suboptions. + Use with care. default: null type: dict + suboptions: - SUBOPTIONS: - - - a_first - The first suboption. - default: null - type: str - - - m_middle - The suboption in the middle. - Has its own suboptions. - default: null - - SUBOPTIONS: + - a_first The first suboption. + default: null + type: str - - a_suboption - A sub-suboption. - default: null - type: str + - m_middle The suboption in the middle. + Has its own suboptions. + default: null + suboptions: - - z_last - The last suboption. + - a_suboption A sub-suboption. default: null type: str + - z_last The last suboption. + default: null + type: str AUTHOR: Ansible Core Team EXAMPLES: - diff --git a/test/integration/targets/ansible-doc/test_docs_yaml_anchors.output b/test/integration/targets/ansible-doc/test_docs_yaml_anchors.output index 5eb2eee..abe26a4 100644 --- a/test/integration/targets/ansible-doc/test_docs_yaml_anchors.output +++ b/test/integration/targets/ansible-doc/test_docs_yaml_anchors.output @@ -1,46 +1,35 @@ + Test module - Test module +OPTIONS (= indicates it is required): -OPTIONS (= is mandatory): - -- at_the_top - Short desc +- at_the_top Short desc default: some string type: str -- egress - Egress firewall rules +- egress Egress firewall rules default: null elements: dict type: list + suboptions: - SUBOPTIONS: - - = port - Rule port - type: int + = port Rule port + type: int -- ingress - Ingress firewall rules +- ingress Ingress firewall rules default: null elements: dict type: list + suboptions: - SUBOPTIONS: - - = port - Rule port - type: int + = port Rule port + type: int -- last_one - Short desc +- last_one Short desc default: some string type: str - AUTHOR: Ansible Core Team EXAMPLES: - diff --git a/test/integration/targets/ansible-doc/yolo-text.output b/test/integration/targets/ansible-doc/yolo-text.output index 647a4f6..f9d4fe8 100644 --- a/test/integration/targets/ansible-doc/yolo-text.output +++ b/test/integration/targets/ansible-doc/yolo-text.output @@ -1,14 +1,12 @@ -> TESTNS.TESTCOL.YOLO (./collections/ansible_collections/testns/testcol/plugins/test/yolo.yml) +> TEST testns.testcol.yolo (./collections/ansible_collections/testns/testcol/plugins/test/yolo.yml) - This is always true + This is always true -OPTIONS (= is mandatory): +OPTIONS (= indicates it is required): -= _input - does not matter += _input does not matter type: raw - SEE ALSO: * Module ansible.builtin.test The official documentation on the @@ -33,15 +31,13 @@ SEE ALSO: Some foo bar. https://docs.ansible.com/ansible-core/devel/#stq=foo_bar&stp=1 - NAME: yolo EXAMPLES: - {{ 'anything' is yolo }} - RETURN VALUES: -- output - always true + +- output always true type: boolean + diff --git a/test/integration/targets/ansible-doc/yolo.output b/test/integration/targets/ansible-doc/yolo.output index b54cc2d..9083fd5 100644 --- a/test/integration/targets/ansible-doc/yolo.output +++ b/test/integration/targets/ansible-doc/yolo.output @@ -14,6 +14,7 @@ "type": "raw" } }, + "plugin_name": "testns.testcol.yolo", "seealso": [ { "module": "ansible.builtin.test" diff --git a/test/integration/targets/ansible-galaxy-collection-cli/files/empty_manifest_galaxy.yml b/test/integration/targets/ansible-galaxy-collection-cli/files/empty_manifest_galaxy.yml new file mode 100644 index 0000000..e43ba41 --- /dev/null +++ b/test/integration/targets/ansible-galaxy-collection-cli/files/empty_manifest_galaxy.yml @@ -0,0 +1,8 @@ +namespace: ns +name: col +version: 3.0.0 +readme: README.rst +license_file: GPL +authors: + - Ansible +manifest: diff --git a/test/integration/targets/ansible-galaxy-collection-cli/files/expected_empty.txt b/test/integration/targets/ansible-galaxy-collection-cli/files/expected_empty.txt new file mode 100644 index 0000000..f1e0f8f --- /dev/null +++ b/test/integration/targets/ansible-galaxy-collection-cli/files/expected_empty.txt @@ -0,0 +1,117 @@ +foo.txt +MANIFEST.json +FILES.json +README.rst +GPL +LICENSES/ +LICENSES/MIT.txt +.reuse/ +.reuse/dep5 +changelogs/ +docs/ +playbooks/ +plugins/ +roles/ +tests/ +changelogs/fragments/ +changelogs/fragments/bar.yaml +changelogs/fragments/foo.yml +docs/docsite/ +docs/docsite/apple.j2 +docs/docsite/bar.yml +docs/docsite/baz.yaml +docs/docsite/foo.rst +docs/docsite/orange.txt +docs/docsite/qux.json +docs/foobar/ +docs/foobar/qux/ +docs/foobar/qux/baz.txt +playbooks/bar.yaml +playbooks/baz.json +playbooks/foo.yml +plugins/action/ +plugins/become/ +plugins/cache/ +plugins/callback/ +plugins/cliconf/ +plugins/connection/ +plugins/doc_fragments/ +plugins/filter/ +plugins/httpapi/ +plugins/inventory/ +plugins/lookup/ +plugins/module_utils/ +plugins/modules/ +plugins/netconf/ +plugins/shell/ +plugins/strategy/ +plugins/terminal/ +plugins/test/ +plugins/vars/ +plugins/action/test.py +plugins/become/bar.yml +plugins/become/baz.yaml +plugins/become/test.py +plugins/cache/bar.yml +plugins/cache/baz.yaml +plugins/cache/test.py +plugins/callback/bar.yml +plugins/callback/baz.yaml +plugins/callback/test.py +plugins/cliconf/bar.yml +plugins/cliconf/baz.yaml +plugins/cliconf/test.py +plugins/connection/bar.yml +plugins/connection/baz.yaml +plugins/connection/test.py +plugins/doc_fragments/test.py +plugins/filter/bar.yml +plugins/filter/baz.yaml +plugins/filter/test.py +plugins/httpapi/bar.yml +plugins/httpapi/baz.yaml +plugins/httpapi/test.py +plugins/inventory/bar.yml +plugins/inventory/baz.yaml +plugins/inventory/test.py +plugins/lookup/bar.yml +plugins/lookup/baz.yaml +plugins/lookup/test.py +plugins/module_utils/bar.ps1 +plugins/module_utils/test.py +plugins/modules/bar.yaml +plugins/modules/test2.py +plugins/modules/foo.yml +plugins/modules/qux.ps1 +plugins/netconf/bar.yml +plugins/netconf/baz.yaml +plugins/netconf/test.py +plugins/shell/bar.yml +plugins/shell/baz.yaml +plugins/shell/test.py +plugins/strategy/bar.yml +plugins/strategy/baz.yaml +plugins/strategy/test.py +plugins/terminal/test.py +plugins/test/bar.yml +plugins/test/baz.yaml +plugins/test/test.py +plugins/vars/bar.yml +plugins/vars/bar.yml.license +plugins/vars/baz.yaml +plugins/vars/test.py +roles/foo/ +roles/foo/tasks/ +roles/foo/templates/ +roles/foo/vars/ +roles/foo/tasks/main.yml +roles/foo/templates/foo.j2 +roles/foo/vars/main.yaml +tests/integration/ +tests/units/ +tests/integration/targets/ +tests/integration/targets/foo/ +tests/integration/targets/foo/aliases +tests/integration/targets/foo/tasks/ +tests/integration/targets/foo/tasks/main.yml +tests/units/test_foo.py diff --git a/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py b/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py index 60c43cc..e5c3359 100644 --- a/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py +++ b/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sys import pathlib diff --git a/test/integration/targets/ansible-galaxy-collection-cli/tasks/manifest.yml b/test/integration/targets/ansible-galaxy-collection-cli/tasks/manifest.yml index 5f37c72..ee0a4ab 100644 --- a/test/integration/targets/ansible-galaxy-collection-cli/tasks/manifest.yml +++ b/test/integration/targets/ansible-galaxy-collection-cli/tasks/manifest.yml @@ -3,7 +3,7 @@ args: executable: '{{ ansible_facts.python.executable }}' -- name: Copy galaxy.yml with manifest_directives_full +- name: Copy galaxy.yml copy: src: galaxy.yml dest: '{{ output_dir }}/test_manifest_collection/galaxy.yml' @@ -55,3 +55,32 @@ - assert: that: - artifact_contents.stdout_lines|sort == lookup('file', 'expected_full_manifest.txt').splitlines()|sort + +- name: Create test collection dir + script: make_collection_dir.py "{{ output_dir }}/test_manifest_empty_collection" + args: + executable: '{{ ansible_facts.python.executable }}' + +- name: Copy galaxy.yml with empty_manifest_galaxy + copy: + src: empty_manifest_galaxy.yml + dest: '{{ output_dir }}/test_manifest_empty_collection/galaxy.yml' + +- name: Build collection + command: ansible-galaxy collection build --output-path {{ output_dir|quote }} -vvv + args: + chdir: '{{ output_dir }}/test_manifest_empty_collection' + +- name: Get artifact contents + command: tar tzf '{{ output_dir }}/ns-col-3.0.0.tar.gz' + register: artifact_contents + +- debug: + var: artifact_contents.stdout_lines|sort + +- debug: + var: lookup('file', 'expected_empty.txt').splitlines()|sort + +- assert: + that: + - artifact_contents.stdout_lines|sort == lookup('file', 'expected_empty.txt').splitlines()|sort diff --git a/test/integration/targets/ansible-galaxy-collection/files/build_bad_tar.py b/test/integration/targets/ansible-galaxy-collection/files/build_bad_tar.py index 6182e86..25fb5dd 100644 --- a/test/integration/targets/ansible-galaxy-collection/files/build_bad_tar.py +++ b/test/integration/targets/ansible-galaxy-collection/files/build_bad_tar.py @@ -3,8 +3,7 @@ # Copyright: (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 +from __future__ import annotations import hashlib import io @@ -12,6 +11,7 @@ import json import os import sys import tarfile +from ansible.module_utils.common.file import S_IRWXU_RXG_RXO manifest = { 'collection_info': { @@ -47,7 +47,7 @@ files = { def add_file(tar_file, filename, b_content, update_files=True): tar_info = tarfile.TarInfo(filename) tar_info.size = len(b_content) - tar_info.mode = 0o0755 + tar_info.mode = S_IRWXU_RXG_RXO tar_file.addfile(tarinfo=tar_info, fileobj=io.BytesIO(b_content)) if update_files: diff --git a/test/integration/targets/ansible-galaxy-collection/files/test_module.py b/test/integration/targets/ansible-galaxy-collection/files/test_module.py index d7e4814..d4bb3c3 100644 --- a/test/integration/targets/ansible-galaxy-collection/files/test_module.py +++ b/test/integration/targets/ansible-galaxy-collection/files/test_module.py @@ -4,8 +4,7 @@ # (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 +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/ansible-galaxy-collection/handlers/main.yml b/test/integration/targets/ansible-galaxy-collection/handlers/main.yml new file mode 100644 index 0000000..d58a516 --- /dev/null +++ b/test/integration/targets/ansible-galaxy-collection/handlers/main.yml @@ -0,0 +1,7 @@ +- name: uninstall gpg + command: brew uninstall gpg + become: yes + become_user: >- + {{ brew_stat.stat.pw_name }} + environment: + HOMEBREW_NO_AUTO_UPDATE: True diff --git a/test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py b/test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py index c1f5e1d..90397a5 100644 --- a/test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py +++ b/test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py @@ -3,8 +3,7 @@ # Copyright: (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 +from __future__ import annotations DOCUMENTATION = ''' --- diff --git a/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py b/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py index 423edd9..b7d262a 100644 --- a/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py +++ b/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py @@ -3,8 +3,7 @@ # Copyright: (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 +from __future__ import annotations ANSIBLE_METADATA = { 'metadata_version': '1.1', diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/download.yml b/test/integration/targets/ansible-galaxy-collection/tasks/download.yml index a554c27..8a2fa56 100644 --- a/test/integration/targets/ansible-galaxy-collection/tasks/download.yml +++ b/test/integration/targets/ansible-galaxy-collection/tasks/download.yml @@ -170,6 +170,33 @@ - '"Downloading collection ''ansible_test.my_collection:1.0.0'' to" in download_collection.stdout' - download_collection_actual.stat.exists +- block: + - name: create skeleton collection for trailing slash test + command: ansible-galaxy collection init trailing_dir.name --init-path "{{ galaxy_dir }}" + + - name: install collection with directory source and trailing slash - {{ test_id }} + command: ansible-galaxy collection download '{{ galaxy_dir }}/trailing_dir/name/' {{ galaxy_verbosity }} + args: + chdir: '{{ galaxy_dir }}/download' + register: download_dir_slash + + - name: get result of install collections with with trailing slash - {{ test_id }} + stat: + path: '{{ galaxy_dir }}/download/collections/trailing_dir-name-1.0.0.tar.gz' + register: download_dir_slash_actual + + - name: assert install collections with with trailing slash - {{ test_id }} + assert: + that: + - '"Downloading collection ''trailing_dir.name:1.0.0'' to" in download_dir_slash.stdout' + - download_dir_slash_actual.stat.exists + + always: + - name: remove trailing dir skeleton + file: + path: '{{ galaxy_dir }}/trailing_dir' + state: absent + - name: remove test download dir file: path: '{{ galaxy_dir }}/download' diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/init.yml b/test/integration/targets/ansible-galaxy-collection/tasks/init.yml index 46198fe..6a00553 100644 --- a/test/integration/targets/ansible-galaxy-collection/tasks/init.yml +++ b/test/integration/targets/ansible-galaxy-collection/tasks/init.yml @@ -128,11 +128,18 @@ - link: custom_skeleton/galaxy.yml source: galaxy.yml + - name: create j2 file + copy: + dest: "{{ galaxy_dir }}/scratch/skeleton/custom_skeleton/README.j2" + content: !unsafe | + Requires ansible-core >={{ min_ansible_version }} + - name: initialize a collection using the skeleton - command: ansible-galaxy collection init ansible_test.my_collection {{ init_path }} {{ skeleton }} + command: ansible-galaxy collection init ansible_test.my_collection {{ init_path }} {{ skeleton }} {{ extra }} vars: init_path: '--init-path {{ galaxy_dir }}/scratch/skeleton' skeleton: '--collection-skeleton {{ galaxy_dir }}/scratch/skeleton/custom_skeleton' + extra: '-e min_ansible_version="2.17"' - name: stat expected collection contents stat: @@ -143,6 +150,7 @@ - plugins/inventory - galaxy.yml - plugins/inventory/foo.py + - README - assert: that: @@ -150,7 +158,18 @@ - stat_result.results[1].stat.islnk - stat_result.results[2].stat.islnk - stat_result.results[3].stat.isreg + - stat_result.results[4].stat.isreg + + - name: Verify the README was templated successfully + copy: + dest: "{{ galaxy_dir }}/scratch/skeleton/ansible_test/my_collection/README" + content: | + Requires ansible-core >=2.17 + register: validate_readme_content + - assert: + that: + - not validate_readme_content.changed always: - name: cleanup file: diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/install.yml b/test/integration/targets/ansible-galaxy-collection/tasks/install.yml index 9237826..5959110 100644 --- a/test/integration/targets/ansible-galaxy-collection/tasks/install.yml +++ b/test/integration/targets/ansible-galaxy-collection/tasks/install.yml @@ -1141,6 +1141,33 @@ - (install_concrete_pre_actual.results[0].content | b64decode | from_json).collection_info.version == '1.1.0-beta.1' - (install_concrete_pre_actual.results[1].content | b64decode | from_json).collection_info.version == '1.0.0' +- block: + - name: create skeleton collection for trailing slash test + command: ansible-galaxy collection init trailing_dir.name --init-path "{{ galaxy_dir }}/scratch" + + - name: install collection with directory source and trailing slash - {{ test_id }} + command: ansible-galaxy collection install '{{ galaxy_dir }}/scratch/trailing_dir/name/' {{ galaxy_verbosity }} + environment: + ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections' + register: install_dir_slash + + - name: get result of install collections with with trailing slash - {{ test_id }} + slurp: + path: '{{ galaxy_dir }}/ansible_collections/trailing_dir/name/MANIFEST.json' + register: install_dir_slash_actual + + - name: assert install collections with with trailing slash - {{ test_id }} + assert: + that: + - '"Installing ''trailing_dir.name:1.0.0'' to" in install_dir_slash.stdout' + - (install_dir_slash_actual.content | b64decode | from_json).collection_info.version == '1.0.0' + + always: + - name: remove trailing dir skeleton + file: + path: '{{ galaxy_dir }}/scratch/trailing_dir' + state: absent + - name: remove collection dir after round of testing - {{ test_id }} file: path: '{{ galaxy_dir }}/ansible_collections' diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/setup_gpg.yml b/test/integration/targets/ansible-galaxy-collection/tasks/setup_gpg.yml index ddc4d8a..66fe220 100644 --- a/test/integration/targets/ansible-galaxy-collection/tasks/setup_gpg.yml +++ b/test/integration/targets/ansible-galaxy-collection/tasks/setup_gpg.yml @@ -7,6 +7,27 @@ - absent - directory +- when: ansible_facts.distribution == 'MacOSX' + block: + - name: MACOS | Find brew binary + command: which brew + register: brew_which + + - name: MACOS | Get owner of brew binary + stat: + path: >- + {{ brew_which.stdout }} + register: brew_stat + + - command: brew install gpg + become: yes + become_user: >- + {{ brew_stat.stat.pw_name }} + environment: + HOMEBREW_NO_AUTO_UPDATE: True + notify: + - uninstall gpg + - name: get username for generating key command: whoami register: user diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/verify.yml b/test/integration/targets/ansible-galaxy-collection/tasks/verify.yml index 0fe2f82..2ad9c83 100644 --- a/test/integration/targets/ansible-galaxy-collection/tasks/verify.yml +++ b/test/integration/targets/ansible-galaxy-collection/tasks/verify.yml @@ -270,6 +270,16 @@ path: '{{ galaxy_dir }}/ansible_collections/ansible_test/verify/plugins/modules/test_new_dir' state: directory +- name: create a new ignore directory + file: + path: '{{ galaxy_dir }}/ansible_collections/ansible_test/verify/plugins/modules/__pycache__' + state: directory + +- name: create a new ignore file + file: + path: '{{ galaxy_dir }}/ansible_collections/ansible_test/verify/plugins/modules/__pycache__/test.cpython-311.pyc' + state: touch + - name: verify modified collection locally-only (should fail) command: ansible-galaxy collection verify --offline ansible_test.verify register: verify @@ -282,6 +292,7 @@ - "'plugins/modules/test_module.py' in verify.stdout" - "'plugins/modules/test_new_file.py' in verify.stdout" - "'plugins/modules/test_new_dir' in verify.stdout" + - "'plugins/modules/__pycache__/test.cpython-311.pyc' not in verify.stdout" # TODO: add a test for offline Galaxy signature metadata diff --git a/test/integration/targets/ansible-galaxy-role/files/create-role-archive.py b/test/integration/targets/ansible-galaxy-role/files/create-role-archive.py index 4876663..3e8424b 100755 --- a/test/integration/targets/ansible-galaxy-role/files/create-role-archive.py +++ b/test/integration/targets/ansible-galaxy-role/files/create-role-archive.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Create a role archive which overwrites an arbitrary file.""" +from __future__ import annotations import argparse import os diff --git a/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/common_vars/subdir/group0/main.yml b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/common_vars/subdir/group0/main.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/common_vars/subdir/group0/main.yml diff --git a/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/main.yml b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/main.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/main.yml diff --git a/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/handlers/utils.yml b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/handlers/utils.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/handlers/utils.yml diff --git a/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/meta/main.yml b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/meta/main.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/meta/main.yml diff --git a/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/tasks/utils/suite.yml b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/tasks/utils/suite.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/integration/targets/ansible-galaxy-role/files/safe-symlinks/tasks/utils/suite.yml diff --git a/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml b/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml index 8a60b2e..deb544b 100644 --- a/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml +++ b/test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml @@ -1,78 +1,38 @@ -- name: create test directories - file: - path: '{{ remote_tmp_dir }}/dir-traversal/{{ item }}' - state: directory - loop: - - source - - target - - roles - -- name: create subdir in the role content to test relative symlinks - file: - dest: '{{ remote_tmp_dir }}/dir-traversal/source/role_subdir' - state: directory - -- copy: - dest: '{{ remote_tmp_dir }}/dir-traversal/source/role_subdir/.keep' - content: '' - -- set_fact: - installed_roles: "{{ remote_tmp_dir | realpath }}/dir-traversal/roles" - -- name: build role with symlink to a directory in the role - script: - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - cmd: create-role-archive.py safe-link-dir.tar ./ role_subdir/.. - executable: '{{ ansible_playbook_python }}' - -- name: install role successfully - command: - cmd: 'ansible-galaxy role install --roles-path {{ remote_tmp_dir }}/dir-traversal/roles safe-link-dir.tar' - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - register: galaxy_install_ok - -- name: check for the directory symlink in the role - stat: - path: "{{ installed_roles }}/safe-link-dir.tar/symlink" - register: symlink_in_role - -- assert: - that: - - symlink_in_role.stat.exists - - symlink_in_role.stat.lnk_source == installed_roles + '/safe-link-dir.tar' - -- name: remove tarfile for next test - file: - path: '{{ remote_tmp_dir }}/dir-traversal/source/safe-link-dir.tar' - state: absent - -- name: build role with safe relative symlink - script: - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - cmd: create-role-archive.py safe.tar ./ role_subdir/../context.txt - executable: '{{ ansible_playbook_python }}' - -- name: install role successfully - command: - cmd: 'ansible-galaxy role install --roles-path {{ remote_tmp_dir }}/dir-traversal/roles safe.tar' - chdir: '{{ remote_tmp_dir }}/dir-traversal/source' - register: galaxy_install_ok - -- name: check for symlink in role - stat: - path: "{{ installed_roles }}/safe.tar/symlink" - register: symlink_in_role - -- assert: - that: - - symlink_in_role.stat.exists - - symlink_in_role.stat.lnk_source == installed_roles + '/safe.tar/context.txt' - -- name: remove test directories - file: - path: '{{ remote_tmp_dir }}/dir-traversal/{{ item }}' - state: absent - loop: - - source - - target - - roles +- delegate_to: localhost + block: + - name: Create archive + command: "tar -cf safe-symlinks.tar {{ role_path }}/files/safe-symlinks" + args: + chdir: "{{ remote_tmp_dir }}" + + - name: Install role successfully + command: ansible-galaxy role install --roles-path '{{ remote_tmp_dir }}/roles' safe-symlinks.tar + args: + chdir: "{{ remote_tmp_dir }}" + + - name: Validate each of the symlinks exists + stat: + path: "{{ remote_tmp_dir }}/roles/safe-symlinks.tar/{{ item }}" + loop: + - defaults/main.yml + - handlers/utils.yml + register: symlink_stat + + - assert: + that: + - symlink_stat.results[0].stat.exists + - symlink_stat.results[0].stat.lnk_source == ((dest, 'roles/safe-symlinks.tar/defaults/common_vars/subdir/group0/main.yml') | path_join) + - symlink_stat.results[1].stat.exists + - symlink_stat.results[1].stat.lnk_source == ((dest, 'roles/safe-symlinks.tar/tasks/utils/suite.yml') | path_join) + vars: + dest: "{{ remote_tmp_dir | realpath }}" + + always: + - name: Clean up + file: + path: "{{ item }}" + state: absent + delegate_to: localhost + loop: + - "{{ remote_tmp_dir }}/roles/" + - "{{ remote_tmp_dir }}/safe-symlinks.tar" diff --git a/test/integration/targets/ansible-galaxy/files/testserver.py b/test/integration/targets/ansible-galaxy/files/testserver.py index 8cca6a8..077ae13 100644 --- a/test/integration/targets/ansible-galaxy/files/testserver.py +++ b/test/integration/targets/ansible-galaxy/files/testserver.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import http.server import socketserver diff --git a/test/integration/targets/ansible-inventory/filter_plugins/toml.py b/test/integration/targets/ansible-inventory/filter_plugins/toml.py index 997173c..6d05cf4 100644 --- a/test/integration/targets/ansible-inventory/filter_plugins/toml.py +++ b/test/integration/targets/ansible-inventory/filter_plugins/toml.py @@ -1,9 +1,7 @@ # (c) 2017, 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 +from __future__ import annotations import functools diff --git a/test/integration/targets/ansible-playbook-callbacks/callback_list_include_role_fail.expected b/test/integration/targets/ansible-playbook-callbacks/callback_list_include_role_fail.expected new file mode 100644 index 0000000..ea2f4fe --- /dev/null +++ b/test/integration/targets/ansible-playbook-callbacks/callback_list_include_role_fail.expected @@ -0,0 +1,9 @@ +1 __init__ +7 v2_on_any +1 v2_playbook_on_play_start +1 v2_playbook_on_start +1 v2_playbook_on_stats +1 v2_playbook_on_task_start +1 v2_runner_on_failed +1 v2_runner_on_ok +1 v2_runner_on_start diff --git a/test/integration/targets/ansible-playbook-callbacks/callbacks_list.expected b/test/integration/targets/ansible-playbook-callbacks/callbacks_list.expected index 1d064a2..4a785ac 100644 --- a/test/integration/targets/ansible-playbook-callbacks/callbacks_list.expected +++ b/test/integration/targets/ansible-playbook-callbacks/callbacks_list.expected @@ -1,8 +1,8 @@ 1 __init__ -92 v2_on_any +93 v2_on_any 1 v2_on_file_diff 4 v2_playbook_on_handler_task_start - 2 v2_playbook_on_include + 3 v2_playbook_on_include 1 v2_playbook_on_no_hosts_matched 3 v2_playbook_on_notify 3 v2_playbook_on_play_start diff --git a/test/integration/targets/ansible-playbook-callbacks/include_role-fail.yml b/test/integration/targets/ansible-playbook-callbacks/include_role-fail.yml new file mode 100644 index 0000000..fbfeb46 --- /dev/null +++ b/test/integration/targets/ansible-playbook-callbacks/include_role-fail.yml @@ -0,0 +1,5 @@ +- hosts: localhost + gather_facts: false + tasks: + - include_role: + name: does-not-exist diff --git a/test/integration/targets/ansible-playbook-callbacks/runme.sh b/test/integration/targets/ansible-playbook-callbacks/runme.sh index 933863e..77a5d9b 100755 --- a/test/integration/targets/ansible-playbook-callbacks/runme.sh +++ b/test/integration/targets/ansible-playbook-callbacks/runme.sh @@ -5,8 +5,11 @@ set -eux export ANSIBLE_CALLBACK_PLUGINS=../support-callback_plugins/callback_plugins export ANSIBLE_ROLES_PATH=../ export ANSIBLE_STDOUT_CALLBACK=callback_debug -export ANSIBLE_HOST_PATTERN_MISMATCH=warning - -ansible-playbook all-callbacks.yml 2>/dev/null | sort | uniq -c | tee callbacks_list.out +ANSIBLE_HOST_PATTERN_MISMATCH=warning ansible-playbook all-callbacks.yml 2>/dev/null | sort | uniq -c | tee callbacks_list.out diff -w callbacks_list.out callbacks_list.expected + +for strategy in linear free; do + ANSIBLE_STRATEGY=$strategy ansible-playbook include_role-fail.yml 2>/dev/null | sort | uniq -c | tee callback_list_include_role_fail.out + diff -w callback_list_include_role_fail.out callback_list_include_role_fail.expected +done diff --git a/test/integration/targets/ansible-runner/aliases b/test/integration/targets/ansible-runner/aliases deleted file mode 100644 index f4caffd..0000000 --- a/test/integration/targets/ansible-runner/aliases +++ /dev/null @@ -1,4 +0,0 @@ -shippable/posix/group5 -context/controller -skip/macos -skip/freebsd diff --git a/test/integration/targets/ansible-runner/files/adhoc_example1.py b/test/integration/targets/ansible-runner/files/adhoc_example1.py deleted file mode 100644 index fe7f944..0000000 --- a/test/integration/targets/ansible-runner/files/adhoc_example1.py +++ /dev/null @@ -1,28 +0,0 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import json -import sys -import ansible_runner - -# the first positional arg should be where the artifacts live -output_dir = sys.argv[1] - -# this calls a single module directly, aka "adhoc" mode -r = ansible_runner.run( - private_data_dir=output_dir, - host_pattern='localhost', - module='shell', - module_args='whoami' -) - -data = { - 'rc': r.rc, - 'status': r.status, - 'events': [x['event'] for x in r.events], - 'stats': r.stats -} - -# insert this header for the flask controller -print('#STARTJSON') -json.dump(data, sys.stdout) diff --git a/test/integration/targets/ansible-runner/files/playbook_example1.py b/test/integration/targets/ansible-runner/files/playbook_example1.py deleted file mode 100644 index 550c185..0000000 --- a/test/integration/targets/ansible-runner/files/playbook_example1.py +++ /dev/null @@ -1,41 +0,0 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import json -import os -import sys -import ansible_runner - - -PLAYBOOK = ''' -- hosts: localhost - gather_facts: False - tasks: - - set_fact: - foo: bar -''' - -# the first positional arg should be where the artifacts live -output_dir = sys.argv[1] - -invdir = os.path.join(output_dir, 'inventory') -if not os.path.isdir(invdir): - os.makedirs(invdir) -with open(os.path.join(invdir, 'hosts'), 'w') as f: - f.write('localhost\n') -pbfile = os.path.join(output_dir, 'test.yml') -with open(pbfile, 'w') as f: - f.write(PLAYBOOK) - -r = ansible_runner.run(private_data_dir=output_dir, playbook='test.yml') - -data = { - 'rc': r.rc, - 'status': r.status, - 'events': [x['event'] for x in r.events], - 'stats': r.stats -} - -# insert this header for the flask controller -print('#STARTJSON') -json.dump(data, sys.stdout) diff --git a/test/integration/targets/ansible-runner/filter_plugins/parse.py b/test/integration/targets/ansible-runner/filter_plugins/parse.py deleted file mode 100644 index 7842f6c..0000000 --- a/test/integration/targets/ansible-runner/filter_plugins/parse.py +++ /dev/null @@ -1,17 +0,0 @@ -from __future__ import (absolute_import, division, print_function) - -__metaclass__ = type - -import re -import json - - -def parse_json(value): - return json.dumps(json.loads(re.sub('^.*\n#STARTJSON\n', '', value, flags=re.DOTALL)), indent=4, sort_keys=True) - - -class FilterModule(object): - def filters(self): - return { - 'parse_json': parse_json, - } diff --git a/test/integration/targets/ansible-runner/inventory b/test/integration/targets/ansible-runner/inventory deleted file mode 100644 index 009f6c3..0000000 --- a/test/integration/targets/ansible-runner/inventory +++ /dev/null @@ -1 +0,0 @@ -# no hosts required, test only requires implicit localhost diff --git a/test/integration/targets/ansible-runner/runme.sh b/test/integration/targets/ansible-runner/runme.sh deleted file mode 100755 index 97e6f4d..0000000 --- a/test/integration/targets/ansible-runner/runme.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -source virtualenv.sh - -ANSIBLE_ROLES_PATH=../ ansible-playbook test.yml -i inventory "$@" diff --git a/test/integration/targets/ansible-runner/tasks/adhoc_example1.yml b/test/integration/targets/ansible-runner/tasks/adhoc_example1.yml deleted file mode 100644 index ce174f1..0000000 --- a/test/integration/targets/ansible-runner/tasks/adhoc_example1.yml +++ /dev/null @@ -1,14 +0,0 @@ -- name: execute the script - command: "'{{ ansible_python_interpreter }}' '{{ role_path }}/files/adhoc_example1.py' '{{ lookup('env', 'OUTPUT_DIR') }}'" - register: script - -- name: parse script output - # work around for ansible-runner showing ansible warnings on stdout - set_fact: - adexec1_json: "{{ script.stdout | parse_json }}" - -- assert: - that: - - "adexec1_json.rc == 0" - - "adexec1_json.events|length == 4" - - "'localhost' in adexec1_json.stats.ok" diff --git a/test/integration/targets/ansible-runner/tasks/main.yml b/test/integration/targets/ansible-runner/tasks/main.yml deleted file mode 100644 index ba6a3a2..0000000 --- a/test/integration/targets/ansible-runner/tasks/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- block: - - include_tasks: setup.yml - - include_tasks: adhoc_example1.yml - - include_tasks: playbook_example1.yml diff --git a/test/integration/targets/ansible-runner/tasks/playbook_example1.yml b/test/integration/targets/ansible-runner/tasks/playbook_example1.yml deleted file mode 100644 index 1fedb53..0000000 --- a/test/integration/targets/ansible-runner/tasks/playbook_example1.yml +++ /dev/null @@ -1,21 +0,0 @@ -- name: execute the script - command: "'{{ ansible_python_interpreter }}' '{{ role_path }}/files/playbook_example1.py' '{{ lookup('env', 'OUTPUT_DIR') }}'" - register: script - -- name: parse script output - # work around for ansible-runner showing ansible warnings on stdout - set_fact: - pbexec_json: "{{ script.stdout | parse_json }}" - expected_events: - - playbook_on_start - - playbook_on_play_start - - playbook_on_task_start - - runner_on_start - - runner_on_ok - - playbook_on_stats - -- assert: - that: - - "pbexec_json.rc == 0" - - "pbexec_json.events == expected_events" - - "'localhost' in pbexec_json.stats.ok" diff --git a/test/integration/targets/ansible-runner/tasks/setup.yml b/test/integration/targets/ansible-runner/tasks/setup.yml deleted file mode 100644 index 7ee66b2..0000000 --- a/test/integration/targets/ansible-runner/tasks/setup.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: Install ansible-runner - pip: - name: ansible-runner - version: 2.2.0 diff --git a/test/integration/targets/ansible-runner/test.yml b/test/integration/targets/ansible-runner/test.yml deleted file mode 100644 index 113f8e7..0000000 --- a/test/integration/targets/ansible-runner/test.yml +++ /dev/null @@ -1,3 +0,0 @@ -- hosts: localhost - roles: - - ansible-runner diff --git a/test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py b/test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py index 06e7782..c960bfe 100644 --- a/test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py +++ b/test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py @@ -1,2 +1,5 @@ +from __future__ import annotations + + def test_me(): pass diff --git a/test/integration/targets/ansible-test-config/ansible_collections/ns/col/plugins/module_utils/test.py b/test/integration/targets/ansible-test-config/ansible_collections/ns/col/plugins/module_utils/test.py index 962dba2..47450f0 100644 --- a/test/integration/targets/ansible-test-config/ansible_collections/ns/col/plugins/module_utils/test.py +++ b/test/integration/targets/ansible-test-config/ansible_collections/ns/col/plugins/module_utils/test.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sys import os diff --git a/test/integration/targets/ansible-test-config/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py b/test/integration/targets/ansible-test-config/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py index b320a15..07b8512 100644 --- a/test/integration/targets/ansible-test-config/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py +++ b/test/integration/targets/ansible-test-config/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible_collections.ns.col.plugins.module_utils import test diff --git a/test/integration/targets/ansible-test-container/runme.py b/test/integration/targets/ansible-test-container/runme.py index 3c86b6d..be51852 100755 --- a/test/integration/targets/ansible-test-container/runme.py +++ b/test/integration/targets/ansible-test-container/runme.py @@ -23,7 +23,8 @@ import time import typing as t UNPRIVILEGED_USER_NAME = 'ansible-test' -CGROUP_SYSTEMD = pathlib.Path('/sys/fs/cgroup/systemd') +CGROUP_ROOT = pathlib.Path('/sys/fs/cgroup') +CGROUP_SYSTEMD = CGROUP_ROOT / 'systemd' LOG_PATH = pathlib.Path('/tmp/results') # The value of /proc/*/loginuid when it is not set. @@ -127,6 +128,16 @@ def main() -> None: sys.exit(1) +def get_container_completion_entries() -> dict[str, dict[str, str]]: + """Parse and return the ansible-test container completion entries.""" + completion_lines = pathlib.Path(os.environ['PYTHONPATH'], '../test/lib/ansible_test/_data/completion/docker.txt').read_text().splitlines() + + # TODO: consider including testing for the collection default image + entries = {name: value for name, value in (parse_completion_entry(line) for line in completion_lines) if name != 'default'} + + return entries + + def get_test_scenarios() -> list[TestScenario]: """Generate and return a list of test scenarios.""" @@ -136,10 +147,7 @@ def get_test_scenarios() -> list[TestScenario]: if not available_engines: raise ApplicationError(f'No supported container engines found: {", ".join(supported_engines)}') - completion_lines = pathlib.Path(os.environ['PYTHONPATH'], '../test/lib/ansible_test/_data/completion/docker.txt').read_text().splitlines() - - # TODO: consider including testing for the collection default image - entries = {name: value for name, value in (parse_completion_entry(line) for line in completion_lines) if name != 'default'} + entries = get_container_completion_entries() unprivileged_user = User.get(UNPRIVILEGED_USER_NAME) @@ -160,7 +168,6 @@ def get_test_scenarios() -> list[TestScenario]: for engine in available_engines: # TODO: figure out how to get tests passing using docker without disabling selinux disable_selinux = os_release.id == 'fedora' and engine == 'docker' and cgroup != 'none' - expose_cgroup_v1 = cgroup == 'v1-only' and get_docker_info(engine).cgroup_version != 1 debug_systemd = cgroup != 'none' # The sleep+pkill used to support the cgroup probe causes problems with the centos6 container. @@ -173,8 +180,7 @@ def get_test_scenarios() -> list[TestScenario]: # See: https://access.redhat.com/solutions/6816771 enable_sha1 = os_release.id == 'rhel' and os_release.version_id.startswith('9.') and container_name == 'centos6' - if cgroup != 'none' and get_docker_info(engine).cgroup_version == 1 and not have_cgroup_systemd(): - expose_cgroup_v1 = True # the host uses cgroup v1 but there is no systemd cgroup and the container requires cgroup support + cgroup_version = get_docker_info(engine).cgroup_version user_scenarios = [ # TODO: test rootless docker @@ -193,6 +199,20 @@ def get_test_scenarios() -> list[TestScenario]: user_scenarios.append(UserScenario()) for user_scenario in user_scenarios: + expose_cgroup_version: int | None = None # by default the host is assumed to provide sufficient cgroup support for the container and scenario + + if cgroup == 'v1-only' and cgroup_version != 1: + expose_cgroup_version = 1 # the container requires cgroup v1 support and the host does not use cgroup v1 + elif cgroup != 'none' and not have_systemd(): + # the container requires cgroup support and the host does not use systemd + if cgroup_version == 1: + expose_cgroup_version = 1 # cgroup v1 mount required + elif cgroup_version == 2 and engine == 'podman' and user_scenario.actual != ROOT_USER: + # Running a systemd container on a non-systemd host with cgroup v2 fails for rootless podman. + # It may be possible to support this scenario, but the necessary configuration to do so is unknown. + display.warning(f'Skipping testing of {container_name!r} with rootless podman because the host uses cgroup v2 without systemd.') + continue + scenarios.append( TestScenario( user_scenario=user_scenario, @@ -200,7 +220,7 @@ def get_test_scenarios() -> list[TestScenario]: container_name=container_name, image=image, disable_selinux=disable_selinux, - expose_cgroup_v1=expose_cgroup_v1, + expose_cgroup_version=expose_cgroup_version, enable_sha1=enable_sha1, debug_systemd=debug_systemd, probe_cgroups=probe_cgroups, @@ -226,16 +246,19 @@ def run_test(scenario: TestScenario) -> TestResult: if scenario.probe_cgroups: target_only_options = ['--dev-probe-cgroups', str(LOG_PATH)] + entries = get_container_completion_entries() + alpine_container = [name for name in entries if name.startswith('alpine')][0] + commands = [ # The cgroup probe is only performed for the first test of the target. # There's no need to repeat the probe again for the same target. # The controller will be tested separately as a target. # This ensures that both the probe and no-probe code paths are functional. [*integration, *integration_options, *target_only_options], - # For the split test we'll use alpine3 as the controller. There are two reasons for this: + # For the split test we'll use Alpine Linux as the controller. There are two reasons for this: # 1) It doesn't require the cgroup v1 hack, so we can test a target that doesn't need that. # 2) It doesn't require disabling selinux, so we can test a target that doesn't need that. - [*integration, '--controller', 'docker:alpine3', *integration_options], + [*integration, '--controller', f'docker:{alpine_container}', *integration_options], ] common_env: dict[str, str] = {} @@ -282,7 +305,7 @@ def run_test(scenario: TestScenario) -> TestResult: message = '' - if scenario.expose_cgroup_v1: + if scenario.expose_cgroup_version == 1: prepare_cgroup_systemd(scenario.user_scenario.actual.name, scenario.engine) try: @@ -307,7 +330,7 @@ def run_test(scenario: TestScenario) -> TestResult: if scenario.disable_selinux: run_command('setenforce', 'enforcing') - if scenario.expose_cgroup_v1: + if scenario.expose_cgroup_version == 1: dirs = remove_cgroup_systemd() else: dirs = list_group_systemd() @@ -398,9 +421,9 @@ def cleanup_podman() -> tuple[str, ...]: return tuple(sorted(set(cleanup))) -def have_cgroup_systemd() -> bool: - """Return True if the container host has a systemd cgroup.""" - return pathlib.Path(CGROUP_SYSTEMD).is_dir() +def have_systemd() -> bool: + """Return True if the host uses systemd.""" + return pathlib.Path('/run/systemd/system').is_dir() def prepare_cgroup_systemd(username: str, engine: str) -> None: @@ -556,7 +579,7 @@ class TestScenario: container_name: str image: str disable_selinux: bool - expose_cgroup_v1: bool + expose_cgroup_version: int | None enable_sha1: bool debug_systemd: bool probe_cgroups: bool @@ -574,8 +597,8 @@ class TestScenario: if self.disable_selinux: tags.append('selinux: permissive') - if self.expose_cgroup_v1: - tags.append('cgroup: v1') + if self.expose_cgroup_version is not None: + tags.append(f'cgroup: {self.expose_cgroup_version}') if self.enable_sha1: tags.append('sha1: enabled') @@ -950,6 +973,15 @@ class DnfBootstrapper(Bootstrapper): # See: https://github.com/containers/netavark/issues/491 packages.append('netavark-1.0.2') + if os_release.id == 'fedora' and os_release.version_id == '39': + # In Fedora 39, the current version of containerd, 1.6.23, prevents Docker from working. + # The previously tested version, 1.6.19, did not have this issue. + # See: https://bugzilla.redhat.com/show_bug.cgi?id=2237396 + run_command( + 'dnf', 'install', '-y', + 'https://kojipkgs.fedoraproject.org/packages/containerd/1.6.19/2.fc39/x86_64/containerd-1.6.19-2.fc39.x86_64.rpm' + ) + if os_release.id == 'rhel': # As of the release of RHEL 9.1, installing podman on RHEL 9.0 results in a non-fatal error at install time: # @@ -1050,17 +1082,22 @@ class ApkBootstrapper(Bootstrapper): def run(cls) -> None: """Run the bootstrapper.""" # The `openssl` package is used to generate hashed passwords. - # crun added as podman won't install it as dep if runc is present - # but we don't want runc as it fails - # The edge `crun` package installed below requires ip6tables, and in - # edge, the `iptables` package includes `ip6tables`, but in 3.18 they - # are separate. Remove `ip6tables` once we update to 3.19. - packages = ['docker', 'podman', 'openssl', 'crun', 'ip6tables'] + # The `crun` package must be explicitly installed since podman won't install it as dep if `runc` is present. + packages = ['docker', 'podman', 'openssl', 'crun'] + + if os_release.version_id.startswith('3.18.'): + # The 3.19 `crun` package installed below requires `ip6tables`, but depends on the `iptables` package. + # In 3.19, the `iptables` package includes `ip6tables`, but in 3.18 they are separate packages. + # Remove once 3.18 is no longer tested. + packages.append('ip6tables') run_command('apk', 'add', *packages) - # 3.18 only contains crun 1.8.4, to get 1.9.2 to resolve the run/shm issue, install crun from 3.19 - # Remove once we update to 3.19 - run_command('apk', 'upgrade', '-U', '--repository=http://dl-cdn.alpinelinux.org/alpine/v3.19/community', 'crun') + + if os_release.version_id.startswith('3.18.'): + # 3.18 only contains `crun` 1.8.4, to get a newer version that resolves the run/shm issue, install `crun` from 3.19. + # Remove once 3.18 is no longer tested. + run_command('apk', 'upgrade', '-U', '--repository=http://dl-cdn.alpinelinux.org/alpine/v3.19/community', 'crun') + run_command('service', 'docker', 'start') run_command('modprobe', 'tun') diff --git a/test/integration/targets/ansible-test-coverage/ansible_collections/ns/col/plugins/module_utils/test_util.py b/test/integration/targets/ansible-test-coverage/ansible_collections/ns/col/plugins/module_utils/test_util.py index 481c4b8..e8d6b91 100644 --- a/test/integration/targets/ansible-test-coverage/ansible_collections/ns/col/plugins/module_utils/test_util.py +++ b/test/integration/targets/ansible-test-coverage/ansible_collections/ns/col/plugins/module_utils/test_util.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def test_coverage(): diff --git a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/doc_fragments/ps_util.py b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/doc_fragments/ps_util.py index e69844b..c8e8b70 100644 --- a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/doc_fragments/ps_util.py +++ b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/doc_fragments/ps_util.py @@ -3,8 +3,7 @@ # Copyright (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 +from __future__ import annotations class ModuleDocFragment: diff --git a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/module_utils/my_util.py b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/module_utils/my_util.py index b9c531c..ff10e2d 100644 --- a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/module_utils/my_util.py +++ b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/module_utils/my_util.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def hello(name): diff --git a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/modules/hello.py b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/modules/hello.py index c8a0cf7..a685933 100644 --- a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/modules/hello.py +++ b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/modules/hello.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: hello diff --git a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py index 7df8710..84a49ac 100644 --- a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py +++ b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from .....plugins.module_utils.my_util import hello diff --git a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py index 95ee057..46c9de1 100644 --- a/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py +++ b/test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from .....plugins.modules.hello import say_hello diff --git a/test/integration/targets/ansible-test-integration-targets/test.py b/test/integration/targets/ansible-test-integration-targets/test.py index 8effb64..10fa2d4 100755 --- a/test/integration/targets/ansible-test-integration-targets/test.py +++ b/test/integration/targets/ansible-test-integration-targets/test.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import annotations import subprocess import unittest diff --git a/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/module_utils/my_util.py b/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/module_utils/my_util.py index b9c531c..ff10e2d 100644 --- a/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/module_utils/my_util.py +++ b/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/module_utils/my_util.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def hello(name): diff --git a/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/modules/hello.py b/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/modules/hello.py index 033b6c9..06ff6d4 100644 --- a/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/modules/hello.py +++ b/test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/modules/hello.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: hello diff --git a/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/run-with-pty.py b/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/run-with-pty.py index 4639152..b4ccb7b 100755 --- a/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/run-with-pty.py +++ b/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/run-with-pty.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Run a command using a PTY.""" +from __future__ import annotations import sys diff --git a/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/tests/integration/targets/no-tty/assert-no-tty.py b/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/tests/integration/targets/no-tty/assert-no-tty.py index a2b094e..d7f3eb7 100755 --- a/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/tests/integration/targets/no-tty/assert-no-tty.py +++ b/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/tests/integration/targets/no-tty/assert-no-tty.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Assert no TTY is available.""" +from __future__ import annotations import sys diff --git a/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/vendored_pty.py b/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/vendored_pty.py index bc70803..346bae3 100644 --- a/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/vendored_pty.py +++ b/test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/vendored_pty.py @@ -7,6 +7,7 @@ # See: W. Richard Stevens. 1992. Advanced Programming in the # UNIX Environment. Chapter 19. # Author: Steen Lumholt -- with additions by Guido. +from __future__ import annotations from select import select import os diff --git a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/a/b/lookup2.py b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/a/b/lookup2.py index 5cd2cf0..950b26b 100644 --- a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/a/b/lookup2.py +++ b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/a/b/lookup2.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = """ name: lookup2 diff --git a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/lookup1.py b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/lookup1.py index e274f19..45d37f2 100644 --- a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/lookup1.py +++ b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/lookup1.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = """ name: lookup1 diff --git a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/a/b/module2.py b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/a/b/module2.py index 6fafa19..500beaa 100644 --- a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/a/b/module2.py +++ b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/a/b/module2.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: module2 diff --git a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/module1.py b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/module1.py index 8847f5b..45e3977 100644 --- a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/module1.py +++ b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/module1.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: module1 diff --git a/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor1.py b/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor1.py index f662b97..3cf63c0 100644 --- a/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor1.py +++ b/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor1.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = ''' name: vendor1 diff --git a/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor2.py b/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor2.py index 38860b0..d22f718 100644 --- a/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor2.py +++ b/test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor2.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = ''' name: vendor2 diff --git a/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/do-not-check-me.py b/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/do-not-check-me.py index ca25269..9d3779d 100644 --- a/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/do-not-check-me.py +++ b/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/do-not-check-me.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.module_utils.pycompat24 import get_exception diff --git a/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/plugins/modules/check-me.py b/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/plugins/modules/check-me.py index ca25269..9d3779d 100644 --- a/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/plugins/modules/check-me.py +++ b/test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/plugins/modules/check-me.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.module_utils.pycompat24 import get_exception diff --git a/test/integration/targets/ansible-test-sanity-no-get-exception/expected.txt b/test/integration/targets/ansible-test-sanity-no-get-exception/expected.txt index 4c432cb..d076bb7 100644 --- a/test/integration/targets/ansible-test-sanity-no-get-exception/expected.txt +++ b/test/integration/targets/ansible-test-sanity-no-get-exception/expected.txt @@ -1,2 +1,2 @@ -plugins/modules/check-me.py:1:44: do not use `get_exception` -plugins/modules/check-me.py:5:4: do not use `get_exception` +plugins/modules/check-me.py:3:44: do not use `get_exception` +plugins/modules/check-me.py:7:4: do not use `get_exception` diff --git a/test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/plugins/lookup/deprecated.py b/test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/plugins/lookup/deprecated.py index b7908b6..1066e64 100644 --- a/test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/plugins/lookup/deprecated.py +++ b/test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/plugins/lookup/deprecated.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = ''' name: deprecated diff --git a/test/integration/targets/ansible-test-sanity-pylint/expected.txt b/test/integration/targets/ansible-test-sanity-pylint/expected.txt index df7bbc2..9c53a30 100644 --- a/test/integration/targets/ansible-test-sanity-pylint/expected.txt +++ b/test/integration/targets/ansible-test-sanity-pylint/expected.txt @@ -1 +1 @@ -plugins/lookup/deprecated.py:27:0: collection-deprecated-version: Deprecated version ('2.0.0') found in call to Display.deprecated or AnsibleModule.deprecate +plugins/lookup/deprecated.py:26:0: collection-deprecated-version: Deprecated version ('2.0.0') found in call to Display.deprecated or AnsibleModule.deprecate diff --git a/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/do-not-check-me.py b/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/do-not-check-me.py index 9b9c7e6..9f70d26 100644 --- a/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/do-not-check-me.py +++ b/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/do-not-check-me.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import urllib.request diff --git a/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/plugins/modules/check-me.py b/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/plugins/modules/check-me.py index 9b9c7e6..9f70d26 100644 --- a/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/plugins/modules/check-me.py +++ b/test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/plugins/modules/check-me.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import urllib.request diff --git a/test/integration/targets/ansible-test-sanity-replace-urlopen/expected.txt b/test/integration/targets/ansible-test-sanity-replace-urlopen/expected.txt index 4dd1bfb..45835fa 100644 --- a/test/integration/targets/ansible-test-sanity-replace-urlopen/expected.txt +++ b/test/integration/targets/ansible-test-sanity-replace-urlopen/expected.txt @@ -1 +1 @@ -plugins/modules/check-me.py:5:20: use `ansible.module_utils.urls.open_url` instead of `urlopen` +plugins/modules/check-me.py:7:20: use `ansible.module_utils.urls.open_url` instead of `urlopen` diff --git a/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/do-not-check-me.py b/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/do-not-check-me.py index 7f7f9f5..a3ea929 100644 --- a/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/do-not-check-me.py +++ b/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/do-not-check-me.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import six diff --git a/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/plugins/modules/check-me.py b/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/plugins/modules/check-me.py index 7f7f9f5..a3ea929 100644 --- a/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/plugins/modules/check-me.py +++ b/test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/plugins/modules/check-me.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import six diff --git a/test/integration/targets/ansible-test-sanity-use-compat-six/expected.txt b/test/integration/targets/ansible-test-sanity-use-compat-six/expected.txt index 42ba83b..c3b005d 100644 --- a/test/integration/targets/ansible-test-sanity-use-compat-six/expected.txt +++ b/test/integration/targets/ansible-test-sanity-use-compat-six/expected.txt @@ -1 +1 @@ -plugins/modules/check-me.py:1:1: use `ansible.module_utils.six` instead of `six` +plugins/modules/check-me.py:3:1: use `ansible.module_utils.six` instead of `six` diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/_not_deprecated.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/_not_deprecated.py new file mode 100644 index 0000000..4b4b091 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/_not_deprecated.py @@ -0,0 +1,22 @@ +#!/usr/bin/python +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +DOCUMENTATION = ''' +module: _not_deprecated +short_description: This module is not deprecated +description: Its name has a leading underscore, but it is not deprecated. +author: + - Ansible Core Team +''' + +EXAMPLES = '''#''' +RETURN = '''''' + +from ansible.module_utils.basic import AnsibleModule + + +if __name__ == '__main__': + module = AnsibleModule(argument_spec=dict()) + module.exit_json() diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_1.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_1.py index 1b23b49..7f53b26 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_1.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_1.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: check_mode_attribute_1 diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_2.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_2.py index 0687e9f..263e5b8 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_2.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_2.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: check_mode_attribute_2 diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_3.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_3.py index 61226e6..a2bf699 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_3.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_3.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: check_mode_attribute_3 diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_4.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_4.py index 1cb7813..0d442e8 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_4.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_4.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: check_mode_attribute_4 diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_5.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_5.py index a8d8556..86bc94f 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_5.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_5.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: check_mode_attribute_5 diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_6.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_6.py index cd5a4fb..966d62c 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_6.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_6.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: check_mode_attribute_6 diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_7.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_7.py index 73d976c..0b77937 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_7.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_7.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: check_mode_attribute_7 diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/import_order.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/import_order.py index f4f3c9b..84c2ed9 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/import_order.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/import_order.py @@ -1,9 +1,8 @@ #!/usr/bin/python # 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 +from __future__ import annotations -__metaclass__ = type from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_extra_key.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_extra_key.py new file mode 100644 index 0000000..04807a1 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_extra_key.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +DOCUMENTATION = ''' +module: invalid_argument_spec_extra_key +short_description: Invalid argument spec extra key schema test module +description: Invalid argument spec extra key schema test module +author: + - Ansible Core Team +options: + foo: + description: foo + type: str +''' + +EXAMPLES = '''#''' +RETURN = '''''' + +from ansible.module_utils.basic import AnsibleModule + + +def main(): + AnsibleModule( + argument_spec=dict( + foo=dict( + type='str', + extra_key='bar', + ), + ), + ) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_incorrect_context.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_incorrect_context.py new file mode 100644 index 0000000..6e3d244 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_incorrect_context.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +DOCUMENTATION = ''' +module: invalid_argument_spec_incorrect_context +short_description: Invalid argument spec incorrect context schema test module +description: Invalid argument spec incorrect context schema test module +author: + - Ansible Core Team +options: + foo: + description: foo + type: str +''' + +EXAMPLES = '''#''' +RETURN = '''''' + +from ansible.module_utils.basic import AnsibleModule + + +def main(): + AnsibleModule( + argument_spec=dict( + foo=dict( + type='str', + context='bar', + ), + ), + ) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_choice_value.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_choice_value.py new file mode 100644 index 0000000..42b315d --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_choice_value.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +DOCUMENTATION = """ +module: invalid_choice_value +short_description: Test for equal length of chocies with correct options +description: Test for equal length of chocies with correct options +author: + - Ansible Core Team +options: + caching: + description: + - Type of Caching. + type: str + choices: + - ReadOnly + - ReadWrite +""" + +EXAMPLES = """#""" +RETURN = """""" + +from ansible.module_utils.basic import AnsibleModule + + +if __name__ == "__main__": + module = AnsibleModule( + argument_spec=dict(caching=dict(type="str", choices=["ReadOnly", "ReadOnly"])), + supports_check_mode=False, + ) + module.exit_json() diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_yaml_syntax.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_yaml_syntax.py index 5dd753f..7931798 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_yaml_syntax.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_yaml_syntax.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' - key: "value"wrong diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/no_callable.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/no_callable.py index 176376a..7004c70 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/no_callable.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/no_callable.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: no_callable diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/semantic_markup.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/semantic_markup.py index 587731d..86eca45 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/semantic_markup.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/semantic_markup.py @@ -1,9 +1,8 @@ #!/usr/bin/python # 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 +from __future__ import annotations -__metaclass__ = type DOCUMENTATION = r''' module: semantic_markup diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/sidecar.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/sidecar.py index 8377c40..c5289b8 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/sidecar.py +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/sidecar.py @@ -1,5 +1,6 @@ #!/usr/bin/python # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/unsupported_extension.nope b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/unsupported_extension.nope new file mode 100644 index 0000000..28ec361 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/unsupported_extension.nope @@ -0,0 +1,2 @@ +This file has an extension which is not supported by validate-modules. +It should not be treated as a Python file or have Python-specific rules applied to it. diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/valid_argument_spec_context.py b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/valid_argument_spec_context.py new file mode 100644 index 0000000..2aa67ab --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/valid_argument_spec_context.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +DOCUMENTATION = ''' +module: valid_argument_spec_context +short_description: Valid argument spec context schema test module +description: Valid argument spec context schema test module +author: + - Ansible Core Team +options: + foo: + description: foo + type: str +''' + +EXAMPLES = '''#''' +RETURN = '''''' + +from ansible.module_utils.basic import AnsibleModule + + +def main(): + AnsibleModule( + argument_spec=dict( + foo=dict( + type='str', + context=dict( + extra_key='bar', + ), + ), + ), + ) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/ansible-test-sanity-validate-modules/expected.txt b/test/integration/targets/ansible-test-sanity-validate-modules/expected.txt index ca6e52a..3ae113c 100644 --- a/test/integration/targets/ansible-test-sanity-validate-modules/expected.txt +++ b/test/integration/targets/ansible-test-sanity-validate-modules/expected.txt @@ -3,12 +3,15 @@ plugins/modules/check_mode_attribute_1.py:0:0: attributes-check-mode: The module plugins/modules/check_mode_attribute_2.py:0:0: attributes-check-mode: The module does not declare support for check mode, but the check_mode attribute's support value is 'partial' and not 'none' plugins/modules/check_mode_attribute_3.py:0:0: attributes-check-mode: The module does declare support for check mode, but the check_mode attribute's support value is 'none' plugins/modules/check_mode_attribute_4.py:0:0: attributes-check-mode-details: The module declares it does not fully support check mode, but has no details on what exactly that means -plugins/modules/import_order.py:8:0: import-before-documentation: Import found before documentation variables. All imports must appear below DOCUMENTATION/EXAMPLES/RETURN. +plugins/modules/import_order.py:7:0: import-before-documentation: Import found before documentation variables. All imports must appear below DOCUMENTATION/EXAMPLES/RETURN. +plugins/modules/invalid_argument_spec_extra_key.py:0:0: invalid-ansiblemodule-schema: AnsibleModule.argument_spec.foo.extra_key: extra keys not allowed @ data['argument_spec']['foo']['extra_key']. Got 'bar' +plugins/modules/invalid_argument_spec_incorrect_context.py:0:0: invalid-ansiblemodule-schema: AnsibleModule.argument_spec.foo.context: expected dict for dictionary value @ data['argument_spec']['foo']['context']. Got 'bar' +plugins/modules/invalid_choice_value.py:0:0: doc-choices-do-not-match-spec: Argument 'caching' in argument_spec defines choices as (['ReadOnly', 'ReadOnly']) but documentation defines choices as (['ReadOnly', 'ReadWrite']) plugins/modules/invalid_yaml_syntax.py:0:0: deprecation-mismatch: "meta/runtime.yml" and DOCUMENTATION.deprecation do not agree. plugins/modules/invalid_yaml_syntax.py:0:0: missing-documentation: No DOCUMENTATION provided -plugins/modules/invalid_yaml_syntax.py:8:15: documentation-syntax-error: DOCUMENTATION is not valid YAML -plugins/modules/invalid_yaml_syntax.py:12:15: invalid-examples: EXAMPLES is not valid YAML -plugins/modules/invalid_yaml_syntax.py:16:15: return-syntax-error: RETURN is not valid YAML +plugins/modules/invalid_yaml_syntax.py:7:15: documentation-syntax-error: DOCUMENTATION is not valid YAML +plugins/modules/invalid_yaml_syntax.py:11:15: invalid-examples: EXAMPLES is not valid YAML +plugins/modules/invalid_yaml_syntax.py:15:15: return-syntax-error: RETURN is not valid YAML plugins/modules/semantic_markup.py:0:0: invalid-documentation-markup: DOCUMENTATION.options.a11.suboptions.b1.description.0: While parsing "V(C\(" at index 1: Unnecessarily escaped "(" @ data['options']['a11']['suboptions']['b1']['description'][0]. Got 'V(C\\(foo\\)).' plugins/modules/semantic_markup.py:0:0: invalid-documentation-markup: DOCUMENTATION.options.a11.suboptions.b1.description.2: While parsing "P(foo.bar#baz)" at index 1: Plugin name "foo.bar" is not a FQCN @ data['options']['a11']['suboptions']['b1']['description'][2]. Got 'P(foo.bar#baz).' plugins/modules/semantic_markup.py:0:0: invalid-documentation-markup: DOCUMENTATION.options.a11.suboptions.b1.description.3: While parsing "P(foo.bar.baz)" at index 1: Parameter "foo.bar.baz" is not of the form FQCN#type @ data['options']['a11']['suboptions']['b1']['description'][3]. Got 'P(foo.bar.baz).' @@ -24,3 +27,5 @@ plugins/modules/semantic_markup.py:0:0: invalid-documentation-markup: Directive plugins/modules/semantic_markup.py:0:0: invalid-documentation-markup: Directive "O(foo.bar=1)" contains a non-existing option "foo.bar" plugins/modules/semantic_markup.py:0:0: invalid-documentation-markup: Directive "RV(bam)" contains a non-existing return value "bam" plugins/modules/semantic_markup.py:0:0: invalid-documentation-markup: Directive "RV(does.not.exist=true)" contains a non-existing return value "does.not.exist" +plugins/modules/unsupported_extension.nope:0:0: invalid-extension: Official Ansible modules must have a .py extension for python modules or a .ps1 for powershell modules +plugins/modules/unsupported_extension.nope:0:0: missing-gplv3-license: GPLv3 license header not found in the first 20 lines of the module diff --git a/test/integration/targets/ansible-test-sanity-yamllint/aliases b/test/integration/targets/ansible-test-sanity-yamllint/aliases new file mode 100644 index 0000000..7741d44 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-yamllint/aliases @@ -0,0 +1,4 @@ +shippable/posix/group3 # runs in the distro test containers +shippable/generic/group1 # runs in the default test container +context/controller +needs/target/collection diff --git a/test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/inventory/inventory1.py b/test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/inventory/inventory1.py new file mode 100644 index 0000000..b358e53 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/inventory/inventory1.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +DOCUMENTATION = r""" +--- + module: module2 + short_description: Hello test module + description: Hello test module. + options: + plugin: + required: true + description: name of the plugin (cache_host) + author: + - Ansible Core Team +""" + +EXAMPLES = r""" +--- + +first_doc: +some_key: + +--- + +second_doc: +some_key: + +""" + +RETURN = r""" +--- +--- +""" + +from ansible.plugins.inventory import BaseInventoryPlugin + + +class InventoryModule(BaseInventoryPlugin): + + NAME = 'inventory1' diff --git a/test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/modules/module1.py b/test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/modules/module1.py new file mode 100644 index 0000000..14e7239 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/modules/module1.py @@ -0,0 +1,40 @@ +#!/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 annotations + +DOCUMENTATION = r""" +module: module1 +short_description: Hello test module +description: Hello test module. +options: {} +author: + - Ansible Core Team +short_description: Duplicate short description +""" + +EXAMPLES = r""" +- minimal: +""" + +RETURN = r""" +invalid_yaml: + bad_indent: + usual_indent: +""" + +from ansible.module_utils.basic import AnsibleModule + + +def main(): + module = AnsibleModule( + argument_spec={}, + ) + + module.exit_json() + + +if __name__ == "__main__": + main() diff --git a/test/integration/targets/ansible-test-sanity-yamllint/expected.txt b/test/integration/targets/ansible-test-sanity-yamllint/expected.txt new file mode 100644 index 0000000..c9ba525 --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-yamllint/expected.txt @@ -0,0 +1,4 @@ +plugins/inventory/inventory1.py:34:1: multiple-yaml-documents: RETURN: expected a single document in the stream +plugins/modules/module1.py:15:1: key-duplicates: DOCUMENTATION: duplication of key "short_description" in mapping +plugins/modules/module1.py:25:3: error: RETURN: syntax error: expected <block end>, but found '<block mapping start>' (syntax) +plugins/modules/module1.py:25:3: unparsable-with-libyaml: RETURN: while parsing a block mapping - did not find expected key diff --git a/test/integration/targets/ansible-test-sanity-yamllint/runme.sh b/test/integration/targets/ansible-test-sanity-yamllint/runme.sh new file mode 100755 index 0000000..a333ccb --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-yamllint/runme.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -eu + +source ../collection/setup.sh + +set -x + +ansible-test sanity --test yamllint --color --lint --failure-ok "${@}" > actual.txt + +diff -u "${TEST_DIR}/expected.txt" actual.txt diff --git a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/bad.py b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/bad.py index 16e0bc8..617353b 100644 --- a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/bad.py +++ b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/bad.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = ''' name: bad diff --git a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/world.py b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/world.py index 5cdd096..093447d 100644 --- a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/world.py +++ b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/world.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = ''' name: world diff --git a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/modules/bad.py b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/modules/bad.py index 8780e35..72d859a 100644 --- a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/modules/bad.py +++ b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/modules/bad.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: bad diff --git a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/plugin_utils/check_pylint.py b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/plugin_utils/check_pylint.py index 1fe4dfa..6ec9023 100644 --- a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/plugin_utils/check_pylint.py +++ b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/plugin_utils/check_pylint.py @@ -2,8 +2,7 @@ These test cases verify ansible-test version constraints for pylint and its dependencies across Python versions. The initial test cases were discovered while testing various Python versions against ansible/ansible. """ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations # Python 3.8 fails with astroid 2.2.5 but works on 2.3.3 # syntax-error: Cannot import 'string' due to syntax error 'invalid syntax (<unknown>, line 109)' diff --git a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/random_directory/bad.py b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/random_directory/bad.py index e34d1c3..ec2aefa 100644 --- a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/random_directory/bad.py +++ b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/random_directory/bad.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations # This is not an allowed import, but since this file is in a plugins/ subdirectory that is not checked, # the import sanity test will not complain. diff --git a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/tests/integration/targets/hello/files/bad.py b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/tests/integration/targets/hello/files/bad.py index a5d896f..d793196 100644 --- a/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/tests/integration/targets/hello/files/bad.py +++ b/test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/tests/integration/targets/hello/files/bad.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations import tempfile diff --git a/test/integration/targets/ansible-test-units-assertions/ansible_collections/ns/col/tests/unit/plugins/modules/test_assertion.py b/test/integration/targets/ansible-test-units-assertions/ansible_collections/ns/col/tests/unit/plugins/modules/test_assertion.py index e172200..6b60ae6 100644 --- a/test/integration/targets/ansible-test-units-assertions/ansible_collections/ns/col/tests/unit/plugins/modules/test_assertion.py +++ b/test/integration/targets/ansible-test-units-assertions/ansible_collections/ns/col/tests/unit/plugins/modules/test_assertion.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def test_assertion(): diff --git a/test/integration/targets/ansible-test-units-constraints/ansible_collections/ns/col/tests/unit/plugins/modules/test_constraints.py b/test/integration/targets/ansible-test-units-constraints/ansible_collections/ns/col/tests/unit/plugins/modules/test_constraints.py index 857e8e5..2b50101 100644 --- a/test/integration/targets/ansible-test-units-constraints/ansible_collections/ns/col/tests/unit/plugins/modules/test_constraints.py +++ b/test/integration/targets/ansible-test-units-constraints/ansible_collections/ns/col/tests/unit/plugins/modules/test_constraints.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations import botocore diff --git a/test/integration/targets/ansible-test-units-forked/ansible_collections/ns/col/tests/unit/plugins/modules/test_ansible_forked.py b/test/integration/targets/ansible-test-units-forked/ansible_collections/ns/col/tests/unit/plugins/modules/test_ansible_forked.py index 828099c..8ce7d43 100644 --- a/test/integration/targets/ansible-test-units-forked/ansible_collections/ns/col/tests/unit/plugins/modules/test_ansible_forked.py +++ b/test/integration/targets/ansible-test-units-forked/ansible_collections/ns/col/tests/unit/plugins/modules/test_ansible_forked.py @@ -1,7 +1,6 @@ """Unit tests to verify the functionality of the ansible-forked pytest plugin.""" -from __future__ import absolute_import, division, print_function +from __future__ import annotations -__metaclass__ = type import os import pytest diff --git a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/module_utils/my_util.py b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/module_utils/my_util.py index b9c531c..ff10e2d 100644 --- a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/module_utils/my_util.py +++ b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/module_utils/my_util.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def hello(name): diff --git a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/modules/hello.py b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/modules/hello.py index 033b6c9..06ff6d4 100644 --- a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/modules/hello.py +++ b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/modules/hello.py @@ -1,8 +1,7 @@ #!/usr/bin/python # 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 __future__ import annotations DOCUMENTATION = ''' module: hello diff --git a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py index 7df8710..84a49ac 100644 --- a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py +++ b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from .....plugins.module_utils.my_util import hello diff --git a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py index 95ee057..46c9de1 100644 --- a/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py +++ b/test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from .....plugins.modules.hello import say_hello diff --git a/test/integration/targets/ansible-test/venv-pythons.py b/test/integration/targets/ansible-test/venv-pythons.py index 97998bc..a22ff28 100755 --- a/test/integration/targets/ansible-test/venv-pythons.py +++ b/test/integration/targets/ansible-test/venv-pythons.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Return target Python options for use with ansible-test.""" +from __future__ import annotations import argparse import os diff --git a/test/integration/targets/ansible-vault/faux-editor.py b/test/integration/targets/ansible-vault/faux-editor.py index b67c747..fdf01eb 100755 --- a/test/integration/targets/ansible-vault/faux-editor.py +++ b/test/integration/targets/ansible-vault/faux-editor.py @@ -16,8 +16,7 @@ # ansible-vault is a script that encrypts/decrypts YAML files. See # https://docs.ansible.com/ansible/latest/user_guide/vault.html for more details. -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import sys import time diff --git a/test/integration/targets/ansible-vault/password-script.py b/test/integration/targets/ansible-vault/password-script.py index 1b7f02b..a65b01d 100755 --- a/test/integration/targets/ansible-vault/password-script.py +++ b/test/integration/targets/ansible-vault/password-script.py @@ -16,8 +16,7 @@ # ansible-vault is a script that encrypts/decrypts YAML files. See # https://docs.ansible.com/ansible/latest/user_guide/vault.html for more details. -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import sys diff --git a/test/integration/targets/ansible-vault/runme.sh b/test/integration/targets/ansible-vault/runme.sh index 98399ec..3630dd5 100755 --- a/test/integration/targets/ansible-vault/runme.sh +++ b/test/integration/targets/ansible-vault/runme.sh @@ -603,6 +603,6 @@ ansible-vault encrypt salted_test3 --vault-password-file example1_password "$@" out=$(diff salted_test1 salted_test2) [ "${out}" == "" ] -# shoudl be diff +# should be diff out=$(diff salted_test1 salted_test3 || true) [ "${out}" != "" ] diff --git a/test/integration/targets/ansible-vault/script/vault-secret.sh b/test/integration/targets/ansible-vault/script/vault-secret.sh index 3aa1c2e..7d29998 100755 --- a/test/integration/targets/ansible-vault/script/vault-secret.sh +++ b/test/integration/targets/ansible-vault/script/vault-secret.sh @@ -2,17 +2,14 @@ set -eu -# shellcheck disable=SC2086 -basename="$(basename $0)" -# shellcheck disable=SC2046 -# shellcheck disable=SC2086 -dirname="$(basename $(dirname $0))" +basename="$(basename "$0")" +dirname="$(basename "$(dirname "$0")")" basename_prefix="get-password" default_password="foo-bar" case "${basename}" in "${basename_prefix}"-*) - password="${default_password}-${basename#${basename_prefix}-}" + password="${default_password}-${basename#"${basename_prefix}-"}" ;; *) password="${default_password}" diff --git a/test/integration/targets/ansible-vault/symlink/get-password-symlink b/test/integration/targets/ansible-vault/symlink/get-password-symlink index 3aa1c2e..7d29998 100755 --- a/test/integration/targets/ansible-vault/symlink/get-password-symlink +++ b/test/integration/targets/ansible-vault/symlink/get-password-symlink @@ -2,17 +2,14 @@ set -eu -# shellcheck disable=SC2086 -basename="$(basename $0)" -# shellcheck disable=SC2046 -# shellcheck disable=SC2086 -dirname="$(basename $(dirname $0))" +basename="$(basename "$0")" +dirname="$(basename "$(dirname "$0")")" basename_prefix="get-password" default_password="foo-bar" case "${basename}" in "${basename_prefix}"-*) - password="${default_password}-${basename#${basename_prefix}-}" + password="${default_password}-${basename#"${basename_prefix}-"}" ;; *) password="${default_password}" diff --git a/test/integration/targets/ansible-vault/test-vault-client.py b/test/integration/targets/ansible-vault/test-vault-client.py index ee46188..c16e309 100755 --- a/test/integration/targets/ansible-vault/test-vault-client.py +++ b/test/integration/targets/ansible-vault/test-vault-client.py @@ -1,8 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', diff --git a/test/integration/targets/ansible/callback_plugins/callback_meta.py b/test/integration/targets/ansible/callback_plugins/callback_meta.py index e19c80f..2494b14 100644 --- a/test/integration/targets/ansible/callback_plugins/callback_meta.py +++ b/test/integration/targets/ansible/callback_plugins/callback_meta.py @@ -1,8 +1,7 @@ # (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 +from __future__ import annotations from ansible.plugins.callback import CallbackBase import os diff --git a/test/integration/targets/ansible_log/aliases b/test/integration/targets/ansible_log/aliases new file mode 100644 index 0000000..498fedd --- /dev/null +++ b/test/integration/targets/ansible_log/aliases @@ -0,0 +1,2 @@ +shippable/posix/group4 +context/controller diff --git a/test/integration/targets/ansible_log/logit.yml b/test/integration/targets/ansible_log/logit.yml new file mode 100644 index 0000000..8015726 --- /dev/null +++ b/test/integration/targets/ansible_log/logit.yml @@ -0,0 +1,4 @@ +- hosts: localhost + gather_facts: false + tasks: + - ping: diff --git a/test/integration/targets/ansible_log/runme.sh b/test/integration/targets/ansible_log/runme.sh new file mode 100755 index 0000000..5295146 --- /dev/null +++ b/test/integration/targets/ansible_log/runme.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -eux + +ALOG=${OUTPUT_DIR}/ansible_log_test.log + +ansible-playbook logit.yml +[ ! -f "${ALOG}" ] + +ANSIBLE_LOG_PATH=${ALOG} ansible-playbook logit.yml +[ -f "${ALOG}" ] +grep -q 'ping' "${ALOG}" + +rm "${ALOG}" +# inline grep should fail if EXEC was present +set +e +ANSIBLE_LOG_PATH=${ALOG} ANSIBLE_LOG_VERBOSITY=3 ansible-playbook -v logit.yml | tee /dev/stderr | grep -q EXEC +rc=$? +set -e +if [ "$rc" == "0" ]; then + false # fail if we found EXEC in stdout +fi +grep -q EXEC "${ALOG}" + +# Test that setting verbosity with no log won't crash +ANSIBLE_LOG_VERBOSITY=2 ansible-playbook logit.yml diff --git a/test/integration/targets/any_errors_fatal/31543.yml b/test/integration/targets/any_errors_fatal/31543.yml new file mode 100644 index 0000000..19b0ba8 --- /dev/null +++ b/test/integration/targets/any_errors_fatal/31543.yml @@ -0,0 +1,12 @@ +- hosts: testhost,testhost2 + gather_facts: false + any_errors_fatal: true + tasks: + - block: + - fail: + when: inventory_hostname == 'testhost' + always: + - debug: + + - debug: + msg: SHOULD NOT HAPPEN diff --git a/test/integration/targets/any_errors_fatal/36308.yml b/test/integration/targets/any_errors_fatal/36308.yml new file mode 100644 index 0000000..ec5d1ae --- /dev/null +++ b/test/integration/targets/any_errors_fatal/36308.yml @@ -0,0 +1,14 @@ +- hosts: testhost + gather_facts: false + any_errors_fatal: true + force_handlers: true + tasks: + - command: echo + notify: + - handler1 + + - fail: + handlers: + - name: handler1 + debug: + msg: handler1 ran diff --git a/test/integration/targets/any_errors_fatal/73246.yml b/test/integration/targets/any_errors_fatal/73246.yml new file mode 100644 index 0000000..50f20d9 --- /dev/null +++ b/test/integration/targets/any_errors_fatal/73246.yml @@ -0,0 +1,11 @@ +- hosts: testhost + gather_facts: false + any_errors_fatal: true + tasks: + - block: + - block: + - fail: + always: + - block: + - debug: + msg: PASSED diff --git a/test/integration/targets/any_errors_fatal/80981.yml b/test/integration/targets/any_errors_fatal/80981.yml new file mode 100644 index 0000000..51cf8df --- /dev/null +++ b/test/integration/targets/any_errors_fatal/80981.yml @@ -0,0 +1,17 @@ +- hosts: testhost,testhost2 + gather_facts: false + any_errors_fatal: true + tasks: + - block: + - fail: + when: inventory_hostname == "testhost" + - name: any_errors_fatal fails all hosts when any of them fails + debug: + msg: SHOULD NOT HAPPEN + rescue: + - name: Rescues both hosts + debug: + msg: rescue + - name: You can recover from fatal errors by adding a rescue section to the block. + debug: + msg: recovered diff --git a/test/integration/targets/any_errors_fatal/runme.sh b/test/integration/targets/any_errors_fatal/runme.sh index c54ea8d..58f0ddf 100755 --- a/test/integration/targets/any_errors_fatal/runme.sh +++ b/test/integration/targets/any_errors_fatal/runme.sh @@ -35,3 +35,17 @@ for test_name in test_include_role test_include_tasks; do exit 1 fi done + +ansible-playbook -i inventory "$@" 31543.yml | tee out.txt +[ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] + +ansible-playbook -i inventory "$@" 36308.yml | tee out.txt +[ "$(grep -c 'handler1 ran' out.txt)" -eq 1 ] + +ansible-playbook -i inventory "$@" 73246.yml | tee out.txt +[ "$(grep -c 'PASSED' out.txt)" -eq 1 ] + +ansible-playbook -i inventory "$@" 80981.yml | tee out.txt +[ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] +[ "$(grep -c 'rescue' out.txt)" -eq 2 ] +[ "$(grep -c 'recovered' out.txt)" -eq 2 ] diff --git a/test/integration/targets/apt/tasks/apt.yml b/test/integration/targets/apt/tasks/apt.yml index a0bc199..55ab51d 100644 --- a/test/integration/targets/apt/tasks/apt.yml +++ b/test/integration/targets/apt/tasks/apt.yml @@ -594,3 +594,26 @@ - elpa-yaml-mode state: absent purge: yes + +# https://github.com/ansible/ansible/issues/82611 +- name: clean apt cache + apt: + clean: true + +- name: check for /var/cache/apt/pkgcache.bin + stat: + path: /var/cache/apt/pkgcache.bin + register: pkgcache_bin + +- name: check for /var/cache/apt/srcpkgcache.bin + stat: + path: /var/cache/apt/srcpkgcache.bin + register: srcpkgcache_bin + +- name: verify apt cache files are cleaned + assert: + that: + - not pkgcache_bin.stat.exists + - not srcpkgcache_bin.stat.exists + fail_msg: "apt cache files still exist." + success_msg: "apt cache files are cleaned." diff --git a/test/integration/targets/apt/tasks/url-with-deps.yml b/test/integration/targets/apt/tasks/url-with-deps.yml index 7c70eb9..7e628c9 100644 --- a/test/integration/targets/apt/tasks/url-with-deps.yml +++ b/test/integration/targets/apt/tasks/url-with-deps.yml @@ -48,9 +48,37 @@ - dpkg_result is successful - dpkg_result.rc == 0 + - name: Install package from local repo + apt: + deb: "{{ repodir }}/dists/stable/main/binary-all/baz_1.0.0_all.deb" + install_recommends: yes + register: apt_url_deps + + - name: check to make sure we installed the package + shell: dpkg -l | grep baz + failed_when: False + register: baz_dpkg_result + + - name: check to make sure we installed the package's recommends + shell: dpkg -l | grep rolldice + failed_when: False + register: rolldice_dpkg_result + + - name: verify real installation of bar + assert: + that: + - apt_url_deps is changed + - baz_dpkg_result is successful + - baz_dpkg_result.rc == 0 + - rolldice_dpkg_result is successful + - rolldice_dpkg_result.rc == 0 + always: - - name: uninstall echo-hello with apt + - name: uninstall packages with apt apt: - pkg: echo-hello + pkg: + - echo-hello + - rolldice + - baz state: absent purge: yes diff --git a/test/integration/targets/apt_repository/tasks/apt.yml b/test/integration/targets/apt_repository/tasks/apt.yml index 2ddf414..d3175f4 100644 --- a/test/integration/targets/apt_repository/tasks/apt.yml +++ b/test/integration/targets/apt_repository/tasks/apt.yml @@ -3,21 +3,15 @@ - set_fact: test_ppa_name: 'ppa:git-core/ppa' test_ppa_filename: 'git-core' - test_ppa_spec: 'deb http://ppa.launchpad.net/git-core/ppa/ubuntu {{ansible_distribution_release}} main' + test_ppa_spec: 'deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu {{ansible_distribution_release}} main' test_ppa_key: 'E1DF1F24' # http://keyserver.ubuntu.com:11371/pks/lookup?search=0xD06AAF4C11DAB86DF421421EFE6B20ECA7AD98A1&op=index - name: show python version debug: var=ansible_python_version -- name: use python-apt - set_fact: - python_apt: python-apt - when: ansible_python_version is version('3', '<') - - name: use python3-apt set_fact: python_apt: python3-apt - when: ansible_python_version is version('3', '>=') # UNINSTALL 'python-apt' # The `apt_repository` module has the smarts to auto-install `python-apt`. To @@ -254,6 +248,87 @@ - result.msg == 'Please set argument \'repo\' to a non-empty value' # +# TEST: keep symlink +# +- import_tasks: 'cleanup.yml' + +- name: install local-apt-repository with apt + apt: pkg=local-apt-repository state=present + +- name: Check if local apt repo file is a symlink + stat: + path: /etc/apt/sources.list.d/local-apt-repository.list + register: stat_result + +- name: Assert if local apt repo file is a symlink + assert: + that: + - stat_result.stat.islnk is defined and stat_result.stat.islnk + - stat_result.stat.lnk_source == "/usr/lib/local-apt-repository/local-apt-repository.list" + +- name: Try installing an invalid repo + apt_repository: + repo: deb http://dl.google.com/linux/chrome/deb2/ stable main + state: present + filename: google-chrome + ignore_errors: true + +- name: Check the stat for the given symlink + stat: + path: /etc/apt/sources.list.d/local-apt-repository.list + register: stat_result2 + +- name: Assert that the symlink is intact after apt_repository operation + assert: + that: + - stat_result2.stat.islnk is defined and stat_result2.stat.islnk + - stat_result2.stat.lnk_source == "/usr/lib/local-apt-repository/local-apt-repository.list" + +- name: uninstall local-apt-repository with apt + apt: pkg=local-apt-repository state=absent purge=yes + +# +# TEST: PPA HTTPS URL +# +- name: Add PPA using HTTPS URL + apt_repository: + repo: 'ppa:deadsnakes' + filename: 'deadsnakes' + state: present + register: result + +- name: Check if PPA using HTTPS URL is added + assert: + that: + - 'result.changed' + - 'result.state == "present"' + - 'result.repo == "ppa:deadsnakes"' + +- name: 'examine source file' + stat: + path: '/etc/apt/sources.list.d/deadsnakes.list' + register: source_file + +- name: 'assert source file exists' + assert: + that: + - 'source_file.stat.exists == True' + +- name: Check if the PPA URL + shell: "grep 'https://ppa.launchpadcontent.net' /etc/apt/sources.list.d/deadsnakes.list" + register: r + +- name: Test if PPA URL points to https URL + assert: + that: + - r.changed + - "'https://ppa.launchpadcontent.net' in r.stdout" + +- name: Remove PPA file + file: + path: '/etc/apt/sources.list.d/deadsnakes.list' + state: absent +# # TEARDOWN # - import_tasks: 'cleanup.yml' diff --git a/test/integration/targets/argspec/library/argspec.py b/test/integration/targets/argspec/library/argspec.py index 2d86d77..6db16d7 100644 --- a/test/integration/targets/argspec/library/argspec.py +++ b/test/integration/targets/argspec/library/argspec.py @@ -2,8 +2,7 @@ # Copyright: (c) 2020, Matt Martz <matt@sivel.net> # 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 __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/assemble/tasks/main.yml b/test/integration/targets/assemble/tasks/main.yml index 14eea3f..add95f9 100644 --- a/test/integration/targets/assemble/tasks/main.yml +++ b/test/integration/targets/assemble/tasks/main.yml @@ -152,3 +152,19 @@ that: - "result.state == 'file'" - "result.checksum == '505359f48c65b3904127cf62b912991d4da7ed6d'" + +- name: test assemble with diff + assemble: + src: "./" + dest: "{{remote_tmp_dir}}/assembled11" + remote_src: false + diff: true + register: result + +- name: assert the fragments were assembled with diff + assert: + that: + - result.changed + - result.diff.after is defined + - result.diff.before is defined + - "result.state == 'file'" diff --git a/test/integration/targets/async/library/async_test.py b/test/integration/targets/async/library/async_test.py index f89bd10..3905679 100644 --- a/test/integration/targets/async/library/async_test.py +++ b/test/integration/targets/async/library/async_test.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/async/tasks/main.yml b/test/integration/targets/async/tasks/main.yml index 491be96..6518207 100644 --- a/test/integration/targets/async/tasks/main.yml +++ b/test/integration/targets/async/tasks/main.yml @@ -310,3 +310,30 @@ - assert: that: - '"ASYNC OK on localhost" in check_task_disabled_output.stdout' + +- name: test 'hidden' async, gather_facts does internal on parallel true. Ensure it won't freeze in check_mode due to async_status not supporting it. + gather_facts: + parallel: true + timeout: 60 + check_mode: true + when: "ansible_facts['os_family'] != 'Darwin'" + vars: + ansible_facts_modules: + - setup + - package_facts + - service_facts + +- name: test async in check mode + check_mode: true + block: + - setup: + async: 60 + poll: 0 + register: gf_async + - async_status: + jid: "{{ gf_async['ansible_job_id'] }}" + register: gf_done + until: gf_done is finished + retries: 100 + delay: 10 + timeout: 30 diff --git a/test/integration/targets/async_extra_data/library/junkping.py b/test/integration/targets/async_extra_data/library/junkping.py index b61d965..6ad3c11 100644 --- a/test/integration/targets/async_extra_data/library/junkping.py +++ b/test/integration/targets/async_extra_data/library/junkping.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/async_fail/action_plugins/normal.py b/test/integration/targets/async_fail/action_plugins/normal.py index 297cbd9..a288290 100644 --- a/test/integration/targets/async_fail/action_plugins/normal.py +++ b/test/integration/targets/async_fail/action_plugins/normal.py @@ -14,8 +14,7 @@ # # 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 __future__ import annotations from ansible.errors import AnsibleError from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/async_fail/library/async_test.py b/test/integration/targets/async_fail/library/async_test.py index e0cbd6f..e94a6a5 100644 --- a/test/integration/targets/async_fail/library/async_test.py +++ b/test/integration/targets/async_fail/library/async_test.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/become/aliases b/test/integration/targets/become/aliases index 0c490f1..2d93d9a 100644 --- a/test/integration/targets/become/aliases +++ b/test/integration/targets/become/aliases @@ -2,3 +2,4 @@ destructive shippable/posix/group1 context/target gather_facts/no +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/become_unprivileged/action_plugins/tmpdir.py b/test/integration/targets/become_unprivileged/action_plugins/tmpdir.py index b7cbb7a..8985961 100644 --- a/test/integration/targets/become_unprivileged/action_plugins/tmpdir.py +++ b/test/integration/targets/become_unprivileged/action_plugins/tmpdir.py @@ -1,6 +1,4 @@ -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/builtin_vars_prompt/test-vars_prompt.py b/test/integration/targets/builtin_vars_prompt/test-vars_prompt.py index 93958fc..435a7eb 100644 --- a/test/integration/targets/builtin_vars_prompt/test-vars_prompt.py +++ b/test/integration/targets/builtin_vars_prompt/test-vars_prompt.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import os import pexpect diff --git a/test/integration/targets/callback_default/callback_default.out.include_role_fails.stderr b/test/integration/targets/callback_default/callback_default.out.include_role_fails.stderr new file mode 100644 index 0000000..315f17b --- /dev/null +++ b/test/integration/targets/callback_default/callback_default.out.include_role_fails.stderr @@ -0,0 +1,12 @@ ++ ansible-playbook -i inventory test_include_role_fails.yml +++ set +x +ERROR! the role 'does-not-exist' was not found in TEST_PATH/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:TEST_PATH + +The error appears to be in 'TEST_PATH/test_include_role_fails.yml': line 5, column 15, but may +be elsewhere in the file depending on the exact syntax problem. + +The offending line appears to be: + + - include_role: + name: does-not-exist + ^ here diff --git a/test/integration/targets/callback_default/callback_default.out.include_role_fails.stdout b/test/integration/targets/callback_default/callback_default.out.include_role_fails.stdout new file mode 100644 index 0000000..adfd21b --- /dev/null +++ b/test/integration/targets/callback_default/callback_default.out.include_role_fails.stdout @@ -0,0 +1,9 @@ + +PLAY [testhost] **************************************************************** + +TASK [include_role : does-not-exist] ******************************************* +fatal: [testhost]: FAILED! => {"changed": false, "reason": "the role 'does-not-exist' was not found in TEST_PATH/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:TEST_PATH\n\nThe error appears to be in 'TEST_PATH/test_include_role_fails.yml': line 5, column 15, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n - include_role:\n name: does-not-exist\n ^ here\n"} + +PLAY RECAP ********************************************************************* +testhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 + diff --git a/test/integration/targets/callback_default/callback_default.out.result_format_yaml_lossy_verbose.stdout b/test/integration/targets/callback_default/callback_default.out.result_format_yaml_lossy_verbose.stdout index ed45575..51f0251 100644 --- a/test/integration/targets/callback_default/callback_default.out.result_format_yaml_lossy_verbose.stdout +++ b/test/integration/targets/callback_default/callback_default.out.result_format_yaml_lossy_verbose.stdout @@ -166,7 +166,7 @@ changed: [testhost] => mode: '0644' owner: root size: 3 - src: .../source + src: .../.source.txt state: file uid: 0 diff --git a/test/integration/targets/callback_default/callback_default.out.result_format_yaml_verbose.stdout b/test/integration/targets/callback_default/callback_default.out.result_format_yaml_verbose.stdout index 3a121a5..8fd5b4f 100644 --- a/test/integration/targets/callback_default/callback_default.out.result_format_yaml_verbose.stdout +++ b/test/integration/targets/callback_default/callback_default.out.result_format_yaml_verbose.stdout @@ -173,7 +173,7 @@ changed: [testhost] => mode: '0644' owner: root size: 3 - src: .../source + src: .../.source.txt state: file uid: 0 diff --git a/test/integration/targets/callback_default/runme.sh b/test/integration/targets/callback_default/runme.sh index a815132..4dab4f4 100755 --- a/test/integration/targets/callback_default/runme.sh +++ b/test/integration/targets/callback_default/runme.sh @@ -25,16 +25,15 @@ run_test() { { ansible-playbook -i inventory "$playbook" "${@:3}" \ > >(set +x; tee "${OUTFILE}.${testname}.stdout"); } \ 2> >(set +x; tee "${OUTFILE}.${testname}.stderr" >&2) - # Scrub deprication warning that shows up in Python 2.6 on CentOS 6 - sed -i -e '/RandomPool_DeprecationWarning/d' "${OUTFILE}.${testname}.stderr" sed -i -e 's/included: .*\/test\/integration/included: ...\/test\/integration/g' "${OUTFILE}.${testname}.stdout" sed -i -e 's/@@ -1,1 +1,1 @@/@@ -1 +1 @@/g' "${OUTFILE}.${testname}.stdout" sed -i -e 's/: .*\/test_diff\.txt/: ...\/test_diff.txt/g' "${OUTFILE}.${testname}.stdout" - sed -i -e "s#${ANSIBLE_PLAYBOOK_DIR}#TEST_PATH#g" "${OUTFILE}.${testname}.stdout" + sed -i -e "s#${ANSIBLE_PLAYBOOK_DIR}#TEST_PATH#g" "${OUTFILE}.${testname}.stdout" "${OUTFILE}.${testname}.stderr" + sed -i -e "s#/var/root/#/root/#g" "${OUTFILE}.${testname}.stdout" "${OUTFILE}.${testname}.stderr" # macos sed -i -e 's/^Using .*//g' "${OUTFILE}.${testname}.stdout" sed -i -e 's/[0-9]:[0-9]\{2\}:[0-9]\{2\}\.[0-9]\{6\}/0:00:00.000000/g' "${OUTFILE}.${testname}.stdout" sed -i -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\.[0-9]\{6\}/0000-00-00 00:00:00.000000/g' "${OUTFILE}.${testname}.stdout" - sed -i -e 's#: .*/source$#: .../source#g' "${OUTFILE}.${testname}.stdout" + sed -i -e 's#: .*/\.source\.txt$#: .../.source.txt#g' "${OUTFILE}.${testname}.stdout" sed -i -e '/secontext:/d' "${OUTFILE}.${testname}.stdout" sed -i -e 's/group: wheel/group: root/g' "${OUTFILE}.${testname}.stdout" @@ -47,7 +46,7 @@ run_test_dryrun() { # optional, pass --check to run a dry run local chk=${2:-} - # outout was recorded w/o cowsay, ensure we reproduce the same + # output was recorded w/o cowsay, ensure we reproduce the same export ANSIBLE_NOCOWS=1 # This needed to satisfy shellcheck that can not accept unquoted variable @@ -58,8 +57,6 @@ run_test_dryrun() { { $cmd \ > >(set +x; tee "${OUTFILE}.${testname}.stdout"); } \ 2> >(set +x; tee "${OUTFILE}.${testname}.stderr" >&2) - # Scrub deprication warning that shows up in Python 2.6 on CentOS 6 - sed -i -e '/RandomPool_DeprecationWarning/d' "${OUTFILE}.${testname}.stderr" diff -u "${ORIGFILE}.${testname}.stdout" "${OUTFILE}.${testname}.stdout" || diff_failure diff -u "${ORIGFILE}.${testname}.stderr" "${OUTFILE}.${testname}.stderr" || diff_failure @@ -132,6 +129,10 @@ export ANSIBLE_CHECK_MODE_MARKERS=0 run_test default test.yml +set +e +ANSIBLE_CALLBACKS_ENABLED=default run_test include_role_fails test_include_role_fails.yml +set -e + # 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 @@ -177,7 +178,7 @@ export ANSIBLE_DISPLAY_OK_HOSTS=1 export ANSIBLE_DISPLAY_FAILED_STDERR=1 export ANSIBLE_TIMEOUT=1 -# Check if UNREACHBLE is available in stderr +# Check if UNREACHABLE is available in stderr set +e ansible-playbook -i inventory test_2.yml > >(set +x; tee "${BASEFILE}.unreachable.stdout";) 2> >(set +x; tee "${BASEFILE}.unreachable.stderr" >&2) || true set -e diff --git a/test/integration/targets/callback_default/test_include_role_fails.yml b/test/integration/targets/callback_default/test_include_role_fails.yml new file mode 100644 index 0000000..3749c90 --- /dev/null +++ b/test/integration/targets/callback_default/test_include_role_fails.yml @@ -0,0 +1,5 @@ +- hosts: testhost + gather_facts: false + tasks: + - include_role: + name: does-not-exist diff --git a/test/integration/targets/cli/test-cli.py b/test/integration/targets/cli/test-cli.py index 9893d66..8d961ff 100644 --- a/test/integration/targets/cli/test-cli.py +++ b/test/integration/targets/cli/test-cli.py @@ -2,9 +2,7 @@ # Copyright (c) 2019 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 +from __future__ import annotations import os diff --git a/test/integration/targets/cli/test_k_and_K.py b/test/integration/targets/cli/test_k_and_K.py index f7077fb..fe9575c 100644 --- a/test/integration/targets/cli/test_k_and_K.py +++ b/test/integration/targets/cli/test_k_and_K.py @@ -1,9 +1,7 @@ #!/usr/bin/env python # 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 +from __future__ import annotations import os import sys diff --git a/test/integration/targets/collection/update-ignore.py b/test/integration/targets/collection/update-ignore.py index 92a702c..fb363f1 100755 --- a/test/integration/targets/collection/update-ignore.py +++ b/test/integration/targets/collection/update-ignore.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Rewrite a sanity ignore file to expand Python versions for import ignores and write the file out with the correct Ansible version in the name.""" +from __future__ import annotations import os import sys diff --git a/test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py b/test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py index d0fdba7..1167149 100644 --- a/test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py +++ b/test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py @@ -1,3 +1,5 @@ #!/usr/bin/python +from __future__ import annotations + from ansible.module_utils.basic import AnsibleModule AnsibleModule({}).exit_json(ping='duplicate.name.pong') diff --git a/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/coll_in_sys/plugins/modules/systestmodule.py b/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/coll_in_sys/plugins/modules/systestmodule.py index cba3812..eb05be2 100644 --- a/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/coll_in_sys/plugins/modules/systestmodule.py +++ b/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/coll_in_sys/plugins/modules/systestmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/maskedmodule.py b/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/maskedmodule.py index e3db81b..9694c59 100644 --- a/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/maskedmodule.py +++ b/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/maskedmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/testmodule.py b/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/testmodule.py index cba3812..eb05be2 100644 --- a/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/testmodule.py +++ b/test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/testmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/builtin/plugins/modules/ping.py b/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/builtin/plugins/modules/ping.py index 0747670..a6ff449 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/builtin/plugins/modules/ping.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/builtin/plugins/modules/ping.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/bullcoll/plugins/modules/bullmodule.py b/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/bullcoll/plugins/modules/bullmodule.py index 5ea354e..b190930 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/bullcoll/plugins/modules/bullmodule.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/ansible/bullcoll/plugins/modules/bullmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testbroken/plugins/filter/broken_filter.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testbroken/plugins/filter/broken_filter.py index 51fe852..9ffb201 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testbroken/plugins/filter/broken_filter.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testbroken/plugins/filter/broken_filter.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations class FilterModule(object): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/roles/non_coll_role/library/embedded_module.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/roles/non_coll_role/library/embedded_module.py index 54402d1..76c1f52 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/roles/non_coll_role/library/embedded_module.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/roles/non_coll_role/library/embedded_module.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/action_subdir/subdir_ping_action.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/action_subdir/subdir_ping_action.py index 5af7334..2d108e2 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/action_subdir/subdir_ping_action.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/action_subdir/subdir_ping_action.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/bypass_host_loop.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/bypass_host_loop.py index b15493d..2625e1c 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/bypass_host_loop.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/bypass_host_loop.py @@ -1,8 +1,7 @@ # Copyright: (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 +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/plugin_lookup.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/plugin_lookup.py index 3fa41e8..950e04c 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/plugin_lookup.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/plugin_lookup.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action import ActionBase from ansible.plugins import loader diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/subclassed_normal.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/subclassed_normal.py index f0eff30..a35a0b7 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/subclassed_normal.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/subclassed_normal.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action.normal import ActionModule as NormalAction diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/uses_redirected_import.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/uses_redirected_import.py index 701d7b4..4c36ab4 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/uses_redirected_import.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/uses_redirected_import.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action import ActionBase from ansible.module_utils.formerly_core import thingtocall diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/callback/usercallback.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/callback/usercallback.py index b534df2..3eb9764 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/callback/usercallback.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/callback/usercallback.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.callback import CallbackBase diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/connection/localconn.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/connection/localconn.py index 77f8050..2872005 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/connection/localconn.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/connection/localconn.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.common.text.converters import to_native from ansible.plugins.connection import ConnectionBase diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/doc_fragments/frag.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/doc_fragments/frag.py index 4549f2d..8fbcb36 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/doc_fragments/frag.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/doc_fragments/frag.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations class ModuleDocFragment(object): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/filter_subdir/my_subdir_filters.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/filter_subdir/my_subdir_filters.py index a5498a4..c8e4f84 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/filter_subdir/my_subdir_filters.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/filter_subdir/my_subdir_filters.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def test_subdir_filter(data): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters.py index 0ce239e..ea56506 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def testfilter(data): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters2.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters2.py index 0723922..29e22d3 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters2.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters2.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def testfilter2(data): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/lookup_subdir/my_subdir_lookup.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/lookup_subdir/my_subdir_lookup.py index dd9818c..f6d6575 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/lookup_subdir/my_subdir_lookup.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/lookup_subdir/my_subdir_lookup.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.lookup import LookupBase diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup.py index 1cf3d28..a843850 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.lookup import LookupBase diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup2.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup2.py index bda671f..2ca2de3 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup2.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup2.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.lookup import LookupBase diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/base.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/base.py index 0654d18..778c2be 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/base.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/base.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible_collections.testns.testcoll.plugins.module_utils import secondary import ansible_collections.testns.testcoll.plugins.module_utils.secondary diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/leaf.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/leaf.py index ad84710..8ccc89a 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/leaf.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/leaf.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def thingtocall(): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/nested_same/nested_same/nested_same.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/nested_same/nested_same/nested_same.py index 7740756..aeb55ab 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/nested_same/nested_same/nested_same.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/nested_same/nested_same/nested_same.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def nested_same(): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/secondary.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/secondary.py index 9a31568..a7d7c5e 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/secondary.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/secondary.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def thingtocall(): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/submod.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/submod.py index 3c24bc4..dbf27a8 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/submod.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/submod.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def thingtocall(): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init.py index b48a717..8bcb936 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init.py @@ -1,6 +1,5 @@ # NB: this module should never be loaded, since we'll see the subpkg_with_init package dir first -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def thingtocall(): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/__init__.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/__init__.py index d424796..665c96a 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/__init__.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/__init__.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations # exercise relative imports in package init; they behave differently from .mod_in_subpkg_with_init import thingtocall as submod_thingtocall diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/mod_in_subpkg_with_init.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/mod_in_subpkg_with_init.py index 27747da..8fab672 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/mod_in_subpkg_with_init.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/mod_in_subpkg_with_init.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def thingtocall(): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/deprecated_ping.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/deprecated_ping.py index 9698ba6..0dd956a 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/deprecated_ping.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/deprecated_ping.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/module_subdir/subdir_ping_module.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/module_subdir/subdir_ping_module.py index 5a70174..05d8d12 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/module_subdir/subdir_ping_module.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/module_subdir/subdir_ping_module.py @@ -1,7 +1,6 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/ping.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/ping.py index 2ca079c..fc8568e 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/ping.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/ping.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule.py index e2efada..6ec24b4 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule_bad_docfrags.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule_bad_docfrags.py index 46ccb76..d39efc8 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule_bad_docfrags.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule_bad_docfrags.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_base_mu_granular_nested_import.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_base_mu_granular_nested_import.py index 4054e36..23d214d 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_base_mu_granular_nested_import.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_base_mu_granular_nested_import.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_collection_redirected_mu.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_collection_redirected_mu.py index b169fde..9020036 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_collection_redirected_mu.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_collection_redirected_mu.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_core_redirected_mu.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_core_redirected_mu.py index 28a0772..c735dbf 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_core_redirected_mu.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_core_redirected_mu.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_flat_import.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_flat_import.py index 295d432..c96028a 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_flat_import.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_flat_import.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_granular_import.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_granular_import.py index 3794f49..1327af9 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_granular_import.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_granular_import.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_module_import_from.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_module_import_from.py index 559e3e5..ae4bb23 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_module_import_from.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_module_import_from.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing.py index 6f3a19d..1d8c0c3 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ..module_utils import bogusmu # pylint: disable=relative-beyond-top-level,unused-import diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_collection.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_collection.py index 6f2320d..c76e0e9 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_collection.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_collection.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ..module_utils import missing_redirect_target_collection # pylint: disable=relative-beyond-top-level,unused-import diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_module.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_module.py index de5c2e5..e7fce3e 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_module.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_module.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ..module_utils import missing_redirect_target_module # pylint: disable=relative-beyond-top-level,unused-import diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_func.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_func.py index 26fa53c..f757666 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_func.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_func.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_module.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_module.py index e017c14..91ecfea 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_module.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_module.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests.py index ba610fb..294a215 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def testtest(data): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests2.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests2.py index 183944f..05c969d 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests2.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests2.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def testtest(data): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/test_subdir/my_subdir_tests.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/test_subdir/my_subdir_tests.py index 98a8f89..a28fb52 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/test_subdir/my_subdir_tests.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/test_subdir/my_subdir_tests.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def subdir_test(data): diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/vars/custom_vars.py b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/vars/custom_vars.py index da4e776..e1997ae 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/vars/custom_vars.py +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/vars/custom_vars.py @@ -15,8 +15,7 @@ # 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 __future__ import annotations DOCUMENTATION = ''' vars: custom_vars diff --git a/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/action/action1.py b/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/action/action1.py index e9f9731..43f8ec3 100644 --- a/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/action/action1.py +++ b/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/action/action1.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/modules/action1.py b/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/modules/action1.py index 66bb5a4..03b1651 100644 --- a/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/modules/action1.py +++ b/test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/modules/action1.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/collections/collections/ansible_collections/me/mycoll2/plugins/modules/module1.py b/test/integration/targets/collections/collections/ansible_collections/me/mycoll2/plugins/modules/module1.py index 00bb993..b0d3f6d 100644 --- a/test/integration/targets/collections/collections/ansible_collections/me/mycoll2/plugins/modules/module1.py +++ b/test/integration/targets/collections/collections/ansible_collections/me/mycoll2/plugins/modules/module1.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', diff --git a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/cache/custom_jsonfile.py b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/cache/custom_jsonfile.py index 7605dc4..393a43f 100644 --- a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/cache/custom_jsonfile.py +++ b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/cache/custom_jsonfile.py @@ -2,9 +2,7 @@ # (c) 2017 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 +from __future__ import annotations DOCUMENTATION = ''' cache: jsonfile diff --git a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/inventory/statichost.py b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/inventory/statichost.py index 9269648..b2405e3 100644 --- a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/inventory/statichost.py +++ b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/inventory/statichost.py @@ -1,8 +1,7 @@ # Copyright (c) 2018 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 +from __future__ import annotations DOCUMENTATION = ''' inventory: statichost diff --git a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/module_utils/sub1/foomodule.py b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/module_utils/sub1/foomodule.py index eeffe01..baf4485 100644 --- a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/module_utils/sub1/foomodule.py +++ b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/module_utils/sub1/foomodule.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def importme(): diff --git a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/modules/contentadjmodule.py b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/modules/contentadjmodule.py index 0fa98eb..a7f7f00 100644 --- a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/modules/contentadjmodule.py +++ b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/modules/contentadjmodule.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/vars/custom_adj_vars.py b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/vars/custom_adj_vars.py index 0cd9a1d..b98fe7b 100644 --- a/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/vars/custom_adj_vars.py +++ b/test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/vars/custom_adj_vars.py @@ -15,8 +15,7 @@ # 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 __future__ import annotations DOCUMENTATION = ''' vars: custom_adj_vars diff --git a/test/integration/targets/collections/custom_vars_plugins/v1_vars_plugin.py b/test/integration/targets/collections/custom_vars_plugins/v1_vars_plugin.py index b5792d8..ce79baa 100644 --- a/test/integration/targets/collections/custom_vars_plugins/v1_vars_plugin.py +++ b/test/integration/targets/collections/custom_vars_plugins/v1_vars_plugin.py @@ -15,15 +15,14 @@ # 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 __future__ import annotations DOCUMENTATION = ''' vars: v1_vars_plugin version_added: "2.10" short_description: load host and group vars description: - - 3rd party vars plugin to test loading host and group vars without requiring whitelisting and without a plugin-specific stage option + - Third-party vars plugin to test loading host and group vars without enabling and without a plugin-specific stage option options: ''' diff --git a/test/integration/targets/collections/custom_vars_plugins/v2_vars_plugin.py b/test/integration/targets/collections/custom_vars_plugins/v2_vars_plugin.py index fc14016..a6894ac 100644 --- a/test/integration/targets/collections/custom_vars_plugins/v2_vars_plugin.py +++ b/test/integration/targets/collections/custom_vars_plugins/v2_vars_plugin.py @@ -15,15 +15,14 @@ # 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 __future__ import annotations DOCUMENTATION = ''' vars: v2_vars_plugin version_added: "2.10" short_description: load host and group vars description: - - 3rd party vars plugin to test loading host and group vars without requiring whitelisting and with a plugin-specific stage option + - Third party vars plugin to test loading host and group vars without enabling and with a plugin-specific stage option options: stage: choices: ['all', 'inventory', 'task'] diff --git a/test/integration/targets/collections/filter_plugins/override_formerly_core_masked_filter.py b/test/integration/targets/collections/filter_plugins/override_formerly_core_masked_filter.py index 600b1fd..228de42 100644 --- a/test/integration/targets/collections/filter_plugins/override_formerly_core_masked_filter.py +++ b/test/integration/targets/collections/filter_plugins/override_formerly_core_masked_filter.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def override_formerly_core_masked_filter(*args, **kwargs): diff --git a/test/integration/targets/collections/library/ping.py b/test/integration/targets/collections/library/ping.py index 7a416a6..d770577 100644 --- a/test/integration/targets/collections/library/ping.py +++ b/test/integration/targets/collections/library/ping.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/collections/runme.sh b/test/integration/targets/collections/runme.sh index 5f11abe..13352aa 100755 --- a/test/integration/targets/collections/runme.sh +++ b/test/integration/targets/collections/runme.sh @@ -6,6 +6,7 @@ export ANSIBLE_COLLECTIONS_PATH=$PWD/collection_root_user:$PWD/collection_root_s export ANSIBLE_GATHERING=explicit export ANSIBLE_GATHER_SUBSET=minimal export ANSIBLE_HOST_PATTERN_MISMATCH=error +export NO_COLOR=1 unset ANSIBLE_COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH # ensure we can call collection module @@ -72,8 +73,11 @@ cat out.txt test "$(grep out.txt -ce 'deprecation1' -ce 'deprecation2' -ce 'deprecation3')" == 3 grep out.txt -e 'redirecting (type: filter) testns.testredirect.multi_redirect_filter to testns.testredirect.redirect_filter1' +grep out.txt -e 'Filter "testns.testredirect.multi_redirect_filter"' grep out.txt -e 'redirecting (type: filter) testns.testredirect.redirect_filter1 to testns.testredirect.redirect_filter2' +grep out.txt -e 'Filter "testns.testredirect.redirect_filter1"' grep out.txt -e 'redirecting (type: filter) testns.testredirect.redirect_filter2 to testns.testcoll.testfilter' +grep out.txt -e 'Filter "testns.testredirect.redirect_filter2"' echo "--- validating collections support in playbooks/roles" # run test playbooks @@ -148,3 +152,12 @@ fi ./vars_plugin_tests.sh ./test_task_resolved_plugin.sh + +# Test tombstoned module/action plugins include the location of the fatal task +cat <<EOF > test_dead_ping_error.yml +- hosts: localhost + gather_facts: no + tasks: + - dead_ping: +EOF +ansible-playbook test_dead_ping_error.yml 2>&1 >/dev/null | grep -e 'line 4, column 5' diff --git a/test/integration/targets/collections/test_plugins/override_formerly_core_masked_test.py b/test/integration/targets/collections/test_plugins/override_formerly_core_masked_test.py index 11c7f7a..3a70685 100644 --- a/test/integration/targets/collections/test_plugins/override_formerly_core_masked_test.py +++ b/test/integration/targets/collections/test_plugins/override_formerly_core_masked_test.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def override_formerly_core_masked_test(value, *args, **kwargs): 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 index fa4d514..da81928 100644 --- 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 @@ -1,7 +1,6 @@ # 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 __future__ import annotations from ansible.plugins.action import ActionBase 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 index f1242e1..ba71668 100644 --- 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 @@ -1,8 +1,7 @@ # (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 +from __future__ import annotations DOCUMENTATION = ''' name: display_resolved_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 index fa4d514..da81928 100644 --- 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 @@ -1,7 +1,6 @@ # 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 __future__ import annotations from ansible.plugins.action import ActionBase 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 index 8f31226..ddfa909 100644 --- 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 @@ -3,8 +3,7 @@ # 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 __future__ import annotations DOCUMENTATION = ''' --- 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 index 4fd7587..98fccbb 100644 --- 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 @@ -3,8 +3,7 @@ # 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 __future__ import annotations DOCUMENTATION = ''' --- diff --git a/test/integration/targets/collections/testcoll2/plugins/modules/testmodule2.py b/test/integration/targets/collections/testcoll2/plugins/modules/testmodule2.py index 7f6eb02..f8db43e 100644 --- a/test/integration/targets/collections/testcoll2/plugins/modules/testmodule2.py +++ b/test/integration/targets/collections/testcoll2/plugins/modules/testmodule2.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], diff --git a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/filter/test_filter.py b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/filter/test_filter.py index dca094b..aea1bba 100644 --- a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/filter/test_filter.py +++ b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/filter/test_filter.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def filter_name(a): diff --git a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_name.py b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_name.py index d0af703..4a8d042 100644 --- a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_name.py +++ b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_name.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.lookup import LookupBase diff --git a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_no_future_boilerplate.py b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_no_future_boilerplate.py index 79e80f6..5dda8b2 100644 --- a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_no_future_boilerplate.py +++ b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_no_future_boilerplate.py @@ -1,6 +1,6 @@ # do not add future boilerplate to this plugin # specifically, do not add absolute_import, as the purpose of this plugin is to test implicit relative imports on Python 2.x -__metaclass__ = type +from __future__ import annotations from ansible.plugins.lookup import LookupBase diff --git a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/test/test_test.py b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/test/test_test.py index 1739072..bec061d 100644 --- a/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/test/test_test.py +++ b/test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/test/test_test.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def test_name_ok(value): diff --git a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util1.py b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util1.py index 196b4ab..6da2705 100644 --- a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util1.py +++ b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util1.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def one(): diff --git a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util2.py b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util2.py index 0d985bf..50baed0 100644 --- a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util2.py +++ b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util2.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from .my_util1 import one diff --git a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util3.py b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util3.py index 1529d7b..f04b870 100644 --- a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util3.py +++ b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util3.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from . import my_util2 diff --git a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/my_module.py b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/my_module.py index 0cdf500..e3848eb 100644 --- a/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/my_module.py +++ b/test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/my_module.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule from ..module_utils.my_util2 import two diff --git a/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/ansible_collections/python/dist/plugins/modules/boo.py b/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/ansible_collections/python/dist/plugins/modules/boo.py index a2313b1..a70c606 100644 --- a/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/ansible_collections/python/dist/plugins/modules/boo.py +++ b/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/ansible_collections/python/dist/plugins/modules/boo.py @@ -2,8 +2,7 @@ """Say hello.""" -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-foo/ansible_collections/python/dist/plugins/modules/boo.py b/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-foo/ansible_collections/python/dist/plugins/modules/boo.py index 1ef0333..415e826 100644 --- a/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-foo/ansible_collections/python/dist/plugins/modules/boo.py +++ b/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-foo/ansible_collections/python/dist/plugins/modules/boo.py @@ -2,8 +2,7 @@ """Say hello in Ukrainian.""" -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/collections_runtime_pythonpath/runme.sh b/test/integration/targets/collections_runtime_pythonpath/runme.sh index 38c6c64..2ec8e7d 100755 --- a/test/integration/targets/collections_runtime_pythonpath/runme.sh +++ b/test/integration/targets/collections_runtime_pythonpath/runme.sh @@ -9,10 +9,7 @@ export PIP_DISABLE_PIP_VERSION_CHECK=1 source virtualenv.sh ->&2 echo \ - === Test that the module \ - gets picked up if discoverable \ - via PYTHONPATH env var === +>&2 echo '=== Test that the module gets picked up if discoverable via PYTHONPATH env var ===' PYTHONPATH="${PWD}/ansible-collection-python-dist-boo:$PYTHONPATH" \ ansible \ -m python.dist.boo \ @@ -21,10 +18,7 @@ ansible \ "$@" | grep -E '"greeting": "Hello, Bob!",' ->&2 echo \ - === Test that the module \ - gets picked up if installed \ - into site-packages === +>&2 echo '=== Test that the module gets picked up if installed into site-packages ===' python -m pip install pep517 ( # Build a binary Python dist (a wheel) using PEP517: cp -r ansible-collection-python-dist-boo "${OUTPUT_DIR}/" @@ -45,10 +39,7 @@ ansible \ "$@" | grep -E '"greeting": "Hello, Frodo!",' ->&2 echo \ - === Test that ansible_collections \ - root takes precedence over \ - PYTHONPATH/site-packages === +>&2 echo '=== Test that ansible_collections root takes precedence over PYTHONPATH/site-packages ===' # This is done by injecting a module with the same FQCN # into another collection root. ANSIBLE_COLLECTIONS_PATH="${PWD}/ansible-collection-python-dist-foo" \ diff --git a/test/integration/targets/command_shell/tasks/main.yml b/test/integration/targets/command_shell/tasks/main.yml index 2cc365d..e2fe122 100644 --- a/test/integration/targets/command_shell/tasks/main.yml +++ b/test/integration/targets/command_shell/tasks/main.yml @@ -543,15 +543,9 @@ - 'parent_dir_cd.stdout.endswith(remote_tmp_dir ~ "/www")' - 'parent_dir_chdir.stdout.endswith(remote_tmp_dir ~ "/www_root")' -- name: Set print error command for Python 2 - set_fact: - print_error_command: print >> sys.stderr, msg - when: ansible_facts.python_version is version('3', '<') - - name: Set print error command for Python 3 set_fact: print_error_command: print(msg, file=sys.stderr) - when: ansible_facts.python_version is version('3', '>=') - name: run command with strip command: '{{ ansible_python_interpreter }} -c "import sys; msg=''hello \n \r''; print(msg); {{ print_error_command }}"' diff --git a/test/integration/targets/common_network/test_plugins/is_mac.py b/test/integration/targets/common_network/test_plugins/is_mac.py index 6a4d409..6267281 100644 --- a/test/integration/targets/common_network/test_plugins/is_mac.py +++ b/test/integration/targets/common_network/test_plugins/is_mac.py @@ -1,8 +1,7 @@ # Copyright: (c) 2020, Matt Martz <matt@sivel.net> # 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 __future__ import annotations from ansible.module_utils.common.network import is_mac diff --git a/test/integration/targets/config/files/types.env b/test/integration/targets/config/files/types.env index b5fc43e..675d206 100644 --- a/test/integration/targets/config/files/types.env +++ b/test/integration/targets/config/files/types.env @@ -9,3 +9,6 @@ ANSIBLE_TYPES_NOTVALID= # totallynotvalid(list): does nothihng, just for testing values ANSIBLE_TYPES_TOTALLYNOTVALID= + +# str_mustunquote(string): does nothihng, just for testing values +ANSIBLE_TYPES_STR_MUSTUNQUOTE= diff --git a/test/integration/targets/config/files/types.ini b/test/integration/targets/config/files/types.ini index c04b6d5..15af0a3 100644 --- a/test/integration/targets/config/files/types.ini +++ b/test/integration/targets/config/files/types.ini @@ -11,3 +11,8 @@ totallynotvalid= # (list) does nothihng, just for testing values valid= + +[string_values] +# (string) does nothihng, just for testing values +str_mustunquote= + diff --git a/test/integration/targets/config/files/types.vars b/test/integration/targets/config/files/types.vars index d1427fc..7c9d1fe 100644 --- a/test/integration/targets/config/files/types.vars +++ b/test/integration/targets/config/files/types.vars @@ -13,3 +13,7 @@ ansible_types_notvalid: '' # totallynotvalid(list): does nothihng, just for testing values ansible_types_totallynotvalid: '' + +# str_mustunquote(string): does nothihng, just for testing values +ansible_types_str_mustunquote: '' + diff --git a/test/integration/targets/config/lookup_plugins/bogus.py b/test/integration/targets/config/lookup_plugins/bogus.py index 34dc98a..3a31c35 100644 --- a/test/integration/targets/config/lookup_plugins/bogus.py +++ b/test/integration/targets/config/lookup_plugins/bogus.py @@ -1,10 +1,8 @@ # (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) +from __future__ import annotations -__metaclass__ = type DOCUMENTATION = """ name: bogus diff --git a/test/integration/targets/config/lookup_plugins/casting.py b/test/integration/targets/config/lookup_plugins/casting.py new file mode 100644 index 0000000..4e7338d --- /dev/null +++ b/test/integration/targets/config/lookup_plugins/casting.py @@ -0,0 +1,59 @@ +# (c) 2021 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + + +DOCUMENTATION = """ + name: casting + 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 + test_list: + description: does nothihng, just for testing values + type: list + test_int: + description: does nothihng, just to test casting + type: int + test_bool: + description: does nothihng, just to test casting + type: bool + test_str: + description: does nothihng, just to test casting + type: str +""" + +EXAMPLES = """ +- name: like some other plugins, this is mostly useless + debug: msg={{ q('casting', [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) + + for cast in (list, int, bool, str): + option = 'test_%s' % str(cast).replace("<class '", '').replace("'>", '') + value = self.get_option(option) + if value is None or type(value) is cast: + continue + raise Exception('%s is not a %s: got %s/%s' % (option, cast, type(value), value)) + + return terms diff --git a/test/integration/targets/config/lookup_plugins/casting_individual.py b/test/integration/targets/config/lookup_plugins/casting_individual.py new file mode 100644 index 0000000..af1f60a --- /dev/null +++ b/test/integration/targets/config/lookup_plugins/casting_individual.py @@ -0,0 +1,58 @@ +# (c) 2021 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + + +DOCUMENTATION = """ + name: casting_individual + 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 + test_list: + description: does nothihng, just for testing values + type: list + test_int: + description: does nothihng, just to test casting + type: int + test_bool: + description: does nothihng, just to test casting + type: bool + test_str: + description: does nothihng, just to test casting + type: str +""" + +EXAMPLES = """ +- name: like some other plugins, this is mostly useless + debug: msg={{ q('casting_individual', [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): + + for cast in (list, int, bool, str): + option = 'test_%s' % str(cast).replace("<class '", '').replace("'>", '') + if option in kwargs: + self.set_option(option, kwargs[option]) + value = self.get_option(option) + if type(value) is not cast: + raise Exception('%s is not a %s: got %s/%s' % (option, cast, type(value), value)) + + return terms diff --git a/test/integration/targets/config/lookup_plugins/types.py b/test/integration/targets/config/lookup_plugins/types.py index d309229..0b1e978 100644 --- a/test/integration/targets/config/lookup_plugins/types.py +++ b/test/integration/targets/config/lookup_plugins/types.py @@ -1,10 +1,8 @@ # (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) +from __future__ import annotations -__metaclass__ = type DOCUMENTATION = """ name: types @@ -56,6 +54,16 @@ DOCUMENTATION = """ - name: ANSIBLE_TYPES_TOTALLYNOTVALID vars: - name: ansible_types_totallynotvalid + str_mustunquote: + description: does nothihng, just for testing values + type: string + ini: + - section: string_values + key: str_mustunquote + env: + - name: ANSIBLE_TYPES_STR_MUSTUNQUOTE + vars: + - name: ansible_types_str_mustunquote """ EXAMPLES = """ diff --git a/test/integration/targets/config/runme.sh b/test/integration/targets/config/runme.sh index 5b999e3..b7a5244 100755 --- a/test/integration/targets/config/runme.sh +++ b/test/integration/targets/config/runme.sh @@ -2,9 +2,8 @@ set -eux -# ignore empty env var and use default -# shellcheck disable=SC1007 -ANSIBLE_TIMEOUT= ansible -m ping testhost -i ../../inventory "$@" +# use default timeout +ANSIBLE_TIMEOUT='' ansible -m ping testhost -i ../../inventory "$@" # env var is wrong type, this should be a fatal error pointing at the setting ANSIBLE_TIMEOUT='lola' ansible -m ping testhost -i ../../inventory "$@" 2>&1|grep 'Invalid type for configuration option setting: DEFAULT_TIMEOUT (from env: ANSIBLE_TIMEOUT)' diff --git a/test/integration/targets/config/type_munging.cfg b/test/integration/targets/config/type_munging.cfg index d6aeaab..14b84cb 100644 --- a/test/integration/targets/config/type_munging.cfg +++ b/test/integration/targets/config/type_munging.cfg @@ -6,3 +6,6 @@ valid = 1, 2, 3 mustunquote = '1', '2', '3' notvalid = [1, 2, 3] totallynotvalid = ['1', '2', '3'] + +[string_values] +str_mustunquote = 'foo' diff --git a/test/integration/targets/config/types.yml b/test/integration/targets/config/types.yml index 650a96f..fe7e6df 100644 --- a/test/integration/targets/config/types.yml +++ b/test/integration/targets/config/types.yml @@ -1,7 +1,7 @@ - hosts: localhost gather_facts: false tasks: - - name: ensures we got the list we expected + - name: ensures we got the values we expected block: - name: initialize plugin debug: msg={{ lookup('types', 'starting test') }} @@ -11,6 +11,7 @@ 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") }}' + str_mustunquote: '{{ lookup("config", "str_mustunquote", plugin_type="lookup", plugin_name="types") }}' - assert: that: @@ -18,8 +19,10 @@ - 'mustunquote|type_debug == "list"' - 'notvalid|type_debug == "list"' - 'totallynotvalid|type_debug == "list"' + - 'str_mustunquote|type_debug == "AnsibleUnsafeText"' - valid[0]|int == 1 - mustunquote[0]|int == 1 - "notvalid[0] == '[1'" # using 'and true' to avoid quote hell - totallynotvalid[0] == "['1'" and True + - str_mustunquote == "foo" diff --git a/test/integration/targets/config/validation.yml b/test/integration/targets/config/validation.yml index 1c81e66..20800e0 100644 --- a/test/integration/targets/config/validation.yml +++ b/test/integration/targets/config/validation.yml @@ -15,3 +15,10 @@ - bad_input is failed - '"Invalid value " in bad_input.msg' - '"valid values are:" in bad_input.msg' + + - name: test config option casting + set_fact: + direct: "{{ lookup('casting', 1, test_list=[1,2,3], test_int=1, test_bool=True, test_str='lola') }}" + from_strings: "{{ lookup('casting', 1, test_list='1,2,3', test_int='1', test_bool='true', test_str='lola') }}" + direct_individual: "{{ lookup('casting_individual', 1, test_list='1,2,3', test_int='1', test_bool='true', test_str='lola') }}" + from_strings_individual: "{{ lookup('casting_individual', 1, test_list='1,2,3', test_int='1', test_bool='true', test_str='lola') }}" diff --git a/test/integration/targets/connection_delegation/action_plugins/delegation_action.py b/test/integration/targets/connection_delegation/action_plugins/delegation_action.py index 9d419e7..3a8e1ca 100644 --- a/test/integration/targets/connection_delegation/action_plugins/delegation_action.py +++ b/test/integration/targets/connection_delegation/action_plugins/delegation_action.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/connection_delegation/connection_plugins/delegation_connection.py b/test/integration/targets/connection_delegation/connection_plugins/delegation_connection.py index f61846c..4a7e1d3 100644 --- a/test/integration/targets/connection_delegation/connection_plugins/delegation_connection.py +++ b/test/integration/targets/connection_delegation/connection_plugins/delegation_connection.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = """ author: Ansible Core Team diff --git a/test/integration/targets/connection_remote_is_local/connection_plugins/remote_is_local.py b/test/integration/targets/connection_remote_is_local/connection_plugins/remote_is_local.py index 818bca4..20a309f 100644 --- a/test/integration/targets/connection_remote_is_local/connection_plugins/remote_is_local.py +++ b/test/integration/targets/connection_remote_is_local/connection_plugins/remote_is_local.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/connection_ssh/runme.sh b/test/integration/targets/connection_ssh/runme.sh index ad817c8..5fee431 100755 --- a/test/integration/targets/connection_ssh/runme.sh +++ b/test/integration/targets/connection_ssh/runme.sh @@ -66,7 +66,7 @@ fi # sftp ./posix.sh "$@" # scp -ANSIBLE_SCP_IF_SSH=true ./posix.sh "$@" "${scp_args[@]}" +ANSIBLE_SSH_TRANSFER_METHOD=scp ./posix.sh "$@" "${scp_args[@]}" # piped ANSIBLE_SSH_TRANSFER_METHOD=piped ./posix.sh "$@" diff --git a/test/integration/targets/copy/tasks/dest_in_non_existent_directories.yml b/test/integration/targets/copy/tasks/dest_in_non_existent_directories.yml index c86caa1..12d47b3 100644 --- a/test/integration/targets/copy/tasks/dest_in_non_existent_directories.yml +++ b/test/integration/targets/copy/tasks/dest_in_non_existent_directories.yml @@ -2,13 +2,13 @@ # checks that dest is created - name: Ensure that dest top directory doesn't exist file: - path: '{{ remote_dir }}/{{ item.dest.split("/")[0] }}' + path: '{{ remote_dir }}/{{ item.dest.split("/")[0] }}' state: absent - name: Copy file, dest is a nonexistent target directory copy: - src: '{{ item.src }}' - dest: '{{ remote_dir }}/{{ item.dest }}' + src: '{{ item.src }}' + dest: '{{ remote_dir }}/{{ item.dest }}' register: copy_result - name: assert copy worked diff --git a/test/integration/targets/copy/tasks/dest_in_non_existent_directories_remote_src.yml b/test/integration/targets/copy/tasks/dest_in_non_existent_directories_remote_src.yml index fad53e7..d42318f 100644 --- a/test/integration/targets/copy/tasks/dest_in_non_existent_directories_remote_src.yml +++ b/test/integration/targets/copy/tasks/dest_in_non_existent_directories_remote_src.yml @@ -2,7 +2,7 @@ # checks that dest is created - name: Ensure that dest top directory doesn't exist file: - path: '{{ remote_dir }}/{{ item.dest.split("/")[0] }}' + path: '{{ remote_dir }}/{{ item.dest.split("/")[0] }}' state: absent - name: create subdir @@ -20,8 +20,8 @@ - name: Copy file, dest is a nonexistent target directory copy: - src: '{{ item.src }}' - dest: '{{ remote_dir }}/{{ item.dest }}' + src: '{{ item.src }}' + dest: '{{ remote_dir }}/{{ item.dest }}' remote_src: true register: copy_result diff --git a/test/integration/targets/copy/tasks/selinux.yml b/test/integration/targets/copy/tasks/selinux.yml index dddee6f..4a58706 100644 --- a/test/integration/targets/copy/tasks/selinux.yml +++ b/test/integration/targets/copy/tasks/selinux.yml @@ -2,7 +2,7 @@ # https://github.com/ansible/ansible/issues/70244 - block: - name: Install dosfstools - yum: + dnf: name: dosfstools state: present @@ -31,6 +31,6 @@ state: absent - name: Uninstall dosfstools - yum: + dnf: name: dosfstools state: absent diff --git a/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir.yml b/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir.yml index f4ab999..b7b77ba 100644 --- a/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir.yml +++ b/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir.yml @@ -1,6 +1,6 @@ - name: Ensure that dest top directory doesn't exist file: - path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' + path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' state: absent - name: Copy file, dest is a file in non-existing target directory @@ -17,7 +17,7 @@ - name: Stat dest path stat: - path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' + path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' register: stat_file_in_dir_result - name: assert that dest doesn't exist diff --git a/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir_remote_src.yml b/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir_remote_src.yml index 61d8796..2f51cb5 100644 --- a/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir_remote_src.yml +++ b/test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir_remote_src.yml @@ -1,6 +1,6 @@ - name: Ensure that dest top directory doesn't exist file: - path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' + path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' state: absent - name: create src file @@ -23,7 +23,7 @@ - name: Stat dest path stat: - path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' + path: '{{ remote_dir }}/{{ dest.split("/")[0] }}' register: stat_file_in_dir_result - name: assert that dest doesn't exist diff --git a/test/integration/targets/copy/tasks/tests.yml b/test/integration/targets/copy/tasks/tests.yml index 40ea9de..50a3465 100644 --- a/test/integration/targets/copy/tasks/tests.yml +++ b/test/integration/targets/copy/tasks/tests.yml @@ -92,6 +92,18 @@ - "stat_results.stat.issock == false" - "stat_results.stat.checksum == ('foo.txt\n'|hash('sha1'))" +- name: Test copying content with force=false when the dest already exists + copy: + content: other_data + dest: "{{ remote_file }}" + mode: 0444 + force: False + register: repeat_copy_result + +- name: Assert no changes are made + assert: + that: repeat_copy_result is not changed + - name: Overwrite the file via same means copy: src: foo.txt @@ -987,13 +999,13 @@ - name: Create a directory outside of the tree file: - path: '{{ local_temp_dir }}/source2' + path: '{{ local_temp_dir }}/source2' state: directory - name: Create a symlink to a directory outside of the tree file: path: '{{ local_temp_dir }}/source1/link' - src: '{{ local_temp_dir }}/source2' + src: '{{ local_temp_dir }}/source2' state: link - name: Create a circular link back to the tree @@ -1063,7 +1075,7 @@ - name: Create a file inside of the directory copy: content: "testing" - dest: '{{ local_temp_dir }}/source_recursive/file' + dest: '{{ local_temp_dir }}/source_recursive/file' - name: Create a directory to place the test output in file: @@ -1444,7 +1456,7 @@ block: - name: Create a test dir to copy file: - path: '{{ local_temp_dir }}/top_dir' + path: '{{ local_temp_dir }}/top_dir' state: directory - name: Create a test dir to symlink to @@ -1454,7 +1466,7 @@ - name: Create a file in the test dir copy: - dest: '{{ local_temp_dir }}/linked_dir/file1' + dest: '{{ local_temp_dir }}/linked_dir/file1' content: 'hello world' - name: Create a link to the test dir @@ -1477,7 +1489,7 @@ - name: Copy the directory's link copy: - src: '{{ local_temp_dir }}/top_dir' + src: '{{ local_temp_dir }}/top_dir' dest: '{{ remote_dir }}/new_dir' local_follow: True @@ -2044,7 +2056,7 @@ dest: '{{ remote_dir }}/testcase5_remote_src_subdirs_src' - name: Create a 2nd level subdirectory file: - path: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/subdir/subdir2/' + path: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/subdir/subdir2/' state: directory - name: execute - Copy the directory on remote copy: diff --git a/test/integration/targets/deb822_repository/tasks/test.yml b/test/integration/targets/deb822_repository/tasks/test.yml index 4911bb9..345ccb7 100644 --- a/test/integration/targets/deb822_repository/tasks/test.yml +++ b/test/integration/targets/deb822_repository/tasks/test.yml @@ -53,6 +53,19 @@ date_max_future: 10 register: deb822_create_1_idem +- name: Create deb822 repo (changed order of parameters) idempotency + deb822_repository: + uris: http://us.archive.ubuntu.com/ubuntu + name: ansible-test focal archive + date_max_future: 10 + components: + - main + - restricted + suites: + - focal + - focal-updates + register: deb822_create_2_idem + - name: Create deb822 repo - check_mode deb822_repository: name: ansible-test focal archive @@ -97,18 +110,19 @@ - deb822_create_1.repo|trim == focal_archive_expected - deb822_create_1_idem is not changed + - deb822_create_2_idem is not changed - deb822_create_1_mode is changed - deb822_create_1_stat_1.stat.mode == '0644' - deb822_create_1_stat_2.stat.mode == '0600' vars: focal_archive_expected: |- - X-Repolib-Name: ansible-test focal archive - URIs: http://us.archive.ubuntu.com/ubuntu - Suites: focal focal-updates Components: main restricted Date-Max-Future: 10 + X-Repolib-Name: ansible-test focal archive + Suites: focal focal-updates Types: deb + URIs: http://us.archive.ubuntu.com/ubuntu - name: Remove repos deb822_repository: @@ -177,11 +191,8 @@ 'BEGIN' not in signed_by_url.repo vars: signed_by_inline_expected: |- - X-Repolib-Name: ansible-test - Types: deb - URIs: https://deb.debian.org - Suites: stable Components: main contrib non-free + X-Repolib-Name: ansible-test Signed-By: -----BEGIN PGP PUBLIC KEY BLOCK----- . @@ -192,6 +203,9 @@ 3bHcln8DMpIJVXht78sL =IE0r -----END PGP PUBLIC KEY BLOCK----- + Suites: stable + Types: deb + URIs: https://deb.debian.org - name: remove ansible-test repo deb822_repository: diff --git a/test/integration/targets/debconf/tasks/main.yml b/test/integration/targets/debconf/tasks/main.yml index f923626..4021349 100644 --- a/test/integration/targets/debconf/tasks/main.yml +++ b/test/integration/targets/debconf/tasks/main.yml @@ -66,6 +66,86 @@ assert: that: - not debconf_test2.changed + + - name: Multiselect value + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - passwd + - group + - shadow + register: debconf_multiselect_test + + - name: validate results for multiselect test + assert: + that: + - debconf_multiselect_test.changed + + - name: Multiselect value again (idempotency) + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - passwd + - group + - shadow + register: debconf_multiselect_test_idem + + - name: validate results for multiselect test (idempotency) + assert: + that: + - not debconf_multiselect_test_idem.changed + + - name: Multiselect value to check if ordered value + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - group + - shadow + - passwd + register: debconf_multiselect_test_idem_2 + + - name: validate results for multiselect test for ordered value + assert: + that: + - not debconf_multiselect_test_idem_2.changed + + - name: Multiselect value to check backward compatibility + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: group, shadow, passwd + register: debconf_multiselect_test_idem_3 + + - name: validate results for multiselect test for backward compatibility + assert: + that: + - debconf_multiselect_test_idem_3.changed + + - name: Multiselect value to check if value contains invalid user input + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - group + - 1 + - passwd + register: debconf_multiselect_test_idem_4 + ignore_errors: yes + + - name: validate results for multiselect test for invalid value + assert: + that: + - not debconf_multiselect_test_idem_4.changed + - '"Invalid value provided" in debconf_multiselect_test_idem_4.msg' + always: - name: uninstall debconf-utils apt: diff --git a/test/integration/targets/debugger/test_run_once.py b/test/integration/targets/debugger/test_run_once.py index 237f9c2..0b65c42 100755 --- a/test/integration/targets/debugger/test_run_once.py +++ b/test/integration/targets/debugger/test_run_once.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import annotations import io import os diff --git a/test/integration/targets/delegate_to/connection_plugins/fakelocal.py b/test/integration/targets/delegate_to/connection_plugins/fakelocal.py index 59ddcf0..e0ecdfd 100644 --- a/test/integration/targets/delegate_to/connection_plugins/fakelocal.py +++ b/test/integration/targets/delegate_to/connection_plugins/fakelocal.py @@ -1,7 +1,6 @@ # 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 __future__ import annotations DOCUMENTATION = ''' connection: fakelocal diff --git a/test/integration/targets/delegate_to/library/detect_interpreter.py b/test/integration/targets/delegate_to/library/detect_interpreter.py index 1f40167..381ab7e 100644 --- a/test/integration/targets/delegate_to/library/detect_interpreter.py +++ b/test/integration/targets/delegate_to/library/detect_interpreter.py @@ -1,8 +1,7 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function +from __future__ import annotations -__metaclass__ = type import sys diff --git a/test/integration/targets/dict_transformations/library/convert_camelCase.py b/test/integration/targets/dict_transformations/library/convert_camelCase.py index 50ca34c..0bc267c 100644 --- a/test/integration/targets/dict_transformations/library/convert_camelCase.py +++ b/test/integration/targets/dict_transformations/library/convert_camelCase.py @@ -3,8 +3,7 @@ # 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 __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/dict_transformations/library/convert_snake_case.py b/test/integration/targets/dict_transformations/library/convert_snake_case.py index 4c13fbc..b645eb7 100644 --- a/test/integration/targets/dict_transformations/library/convert_snake_case.py +++ b/test/integration/targets/dict_transformations/library/convert_snake_case.py @@ -3,8 +3,7 @@ # 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 __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/dnf/filter_plugins/dnf_module_list.py b/test/integration/targets/dnf/filter_plugins/dnf_module_list.py new file mode 100644 index 0000000..3ef9874 --- /dev/null +++ b/test/integration/targets/dnf/filter_plugins/dnf_module_list.py @@ -0,0 +1,40 @@ +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +from collections import Counter + + +def parse_module_list(stdout): + lines = stdout.splitlines() + name_offset = 0 + empty_offset = -1 + modules = [] + for i, line in enumerate(lines): + if line.startswith('Name '): + name_offset = i + 1 + if not line.strip(): + empty_offset = i + for line in lines[name_offset:empty_offset]: + cols = line.split()[:3] + modules.append({ + 'name': cols[0], + 'version': cols[1], + 'profile': cols[2].rstrip(','), # Just the first profile + }) + return modules + + +def get_first_single_version_module(stdout): + modules = parse_module_list(stdout) + name = Counter([m['name'] for m in modules]).most_common()[-1][0] + module, = [m for m in modules if m['name'] == name] + return module + + +class FilterModule: + def filters(self): + return { + 'get_first_single_version_module': get_first_single_version_module, + } diff --git a/test/integration/targets/dnf/tasks/dnf.yml b/test/integration/targets/dnf/tasks/dnf.yml index c5f0173..4110d4b 100644 --- a/test/integration/targets/dnf/tasks/dnf.yml +++ b/test/integration/targets/dnf/tasks/dnf.yml @@ -120,6 +120,19 @@ that: - "not dnf_result.changed" +- name: install sos again with empty string enablerepo + dnf: + name: sos + state: present + enablerepo: "" + register: dnf_result + +- name: verify no change on third install with empty string enablerepo + assert: + that: + - "dnf_result is success" + - "not dnf_result is changed" + # Multiple packages - name: uninstall sos and dos2unix dnf: name=sos,dos2unix state=removed @@ -434,10 +447,6 @@ name: landsidescalping state: absent -# cleanup until https://github.com/ansible/ansible/issues/27377 is resolved -- shell: 'dnf -y group install "Custom Group" && dnf -y group remove "Custom Group"' - register: shell_dnf_result - - dnf: name: "@Custom Group" state: absent @@ -458,9 +467,6 @@ - dnf_result is changed - "'results' in dnf_result" -# cleanup until https://github.com/ansible/ansible/issues/27377 is resolved -- shell: dnf -y group install "Custom Group" && dnf -y group remove "Custom Group" - - dnf: name: "@Custom Group" state: absent @@ -515,6 +521,7 @@ that: - "dnf_result is failed" - "not dnf_result.changed" + - "'Failure downloading' in dnf_result.msg or 'Failed to download' in dnf_result.msg" - name: verify dnf module outputs assert: diff --git a/test/integration/targets/dnf/tasks/dnf_group_remove.yml b/test/integration/targets/dnf/tasks/dnf_group_remove.yml new file mode 100644 index 0000000..c6d4011 --- /dev/null +++ b/test/integration/targets/dnf/tasks/dnf_group_remove.yml @@ -0,0 +1,141 @@ +- name: install a group to test and dnf-utils + dnf: + name: "{{ pkgs }}" + state: present + vars: + pkgs: + - "@Custom Group" + - dnf-utils + +- name: check mode remove the group + dnf: + name: "@Custom Group" + state: absent + check_mode: yes + register: dnf_result + +- name: verify changed + assert: + that: + - "dnf_result.changed" + +- name: verify dnf module outputs + assert: + that: + - "'changed' in dnf_result" + - "'results' in dnf_result" + +- name: remove the group + dnf: + name: "@Custom Group" + state: absent + register: dnf_result + +- name: verify changed + assert: + that: + - "dnf_result.rc == 0" + - "dnf_result.changed" + +- name: verify dnf module outputs + assert: + that: + - "'changed' in dnf_result" + - "'msg' in dnf_result" + - "'results' in dnf_result" + +- name: remove the group again + dnf: + name: "@Custom Group" + state: absent + register: dnf_result + +- name: verify changed + assert: + that: + - "not dnf_result.changed" + +- name: verify dnf module outputs + assert: + that: + - "'changed' in dnf_result" + - "'msg' in dnf_result" + - "'results' in dnf_result" + +- name: check mode remove the group again + dnf: + name: "@Custom Group" + state: absent + check_mode: yes + register: dnf_result + +- name: verify changed + assert: + that: + - "not dnf_result.changed" + +- name: verify dnf module outputs + assert: + that: + - "'changed' in dnf_result" + - "'results' in dnf_result" + +- name: install a group and a package to test + dnf: + name: "@Custom Group,sos" + state: present + register: dnf_output + +- name: check mode remove the group along with the package + dnf: + name: "@Custom Group,sos" + state: absent + register: dnf_result + check_mode: yes + +- name: verify changed + assert: + that: + - "dnf_result.changed" + +- name: verify dnf module outputs + assert: + that: + - "'changed' in dnf_result" + - "'results' in dnf_result" + +- name: remove the group along with the package + dnf: + name: "@Custom Group,sos" + state: absent + register: dnf_result + +- name: verify changed + assert: + that: + - "dnf_result.changed" + +- name: verify dnf module outputs + assert: + that: + - "'changed' in dnf_result" + - "'msg' in dnf_result" + - "'results' in dnf_result" + +- name: check mode remove the group along with the package + dnf: + name: "@Custom Group,sos" + state: absent + register: dnf_result + check_mode: yes + +- name: verify not changed + assert: + that: + - "not dnf_result.changed" + +- name: verify dnf module outputs + assert: + that: + - "'changed' in dnf_result" + - "'results' in dnf_result" diff --git a/test/integration/targets/dnf/tasks/main.yml b/test/integration/targets/dnf/tasks/main.yml index 4941e2c..8d9bda4 100644 --- a/test/integration/targets/dnf/tasks/main.yml +++ b/test/integration/targets/dnf/tasks/main.yml @@ -47,6 +47,11 @@ 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', '>=')) +- include_tasks: dnf_group_remove.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', '>=')) + - include_tasks: dnfinstallroot.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', '>=')) @@ -57,13 +62,30 @@ - ansible_distribution == 'Fedora' - ansible_distribution_major_version is version('23', '>=') -- include_tasks: modularity.yml - when: - - (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('29', '>=')) or +- when: + - (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('39', '<')) or (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version is version('8', '>=')) - not dnf5|default(false) - tags: - - dnf_modularity + block: + # FUTURE - look at including AppStream support in our local repo + - name: list modules + command: dnf module list -q + register: module_list + + # A module that only has a single version + - name: Find a module that meets our testing needs + set_fact: + astream_name: '@{{ module.name }}:{{ module.version }}/{{ module.profile }}' + astream_name_no_stream: '@{{ module.name }}/{{ module.profile }}' + vars: + module: '{{ module_list.stdout|get_first_single_version_module }}' + + - include_tasks: modularity.yml + tags: + - dnf_modularity + rescue: + # Just in case something crazy happens when listing or parsing modules + - meta: noop - include_tasks: logging.yml when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('31', '>=')) or diff --git a/test/integration/targets/dnf/tasks/modularity.yml b/test/integration/targets/dnf/tasks/modularity.yml index 94f43a4..6a97bf6 100644 --- a/test/integration/targets/dnf/tasks/modularity.yml +++ b/test/integration/targets/dnf/tasks/modularity.yml @@ -1,12 +1,3 @@ -# FUTURE - look at including AppStream support in our local repo -- name: Include distribution specific variables - include_vars: "{{ item }}" - with_first_found: - - files: - - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml" - - "{{ ansible_facts.distribution }}.yml" - paths: ../vars - - name: install "{{ astream_name }}" module dnf: name: "{{ astream_name }}" diff --git a/test/integration/targets/dnf/tasks/repo.yml b/test/integration/targets/dnf/tasks/repo.yml index 4f82899..7e34aed 100644 --- a/test/integration/targets/dnf/tasks/repo.yml +++ b/test/integration/targets/dnf/tasks/repo.yml @@ -101,6 +101,30 @@ that: - "'results' in dnf_result" # ============================================================================ + - name: Install dinginessentail-1.0-1 from a file (higher version is already installed) + dnf: + name: "{{ repodir }}/dinginessentail-1.0-1.{{ ansible_architecture }}.rpm" + state: present + disable_gpg_check: True + register: dnf_result + + - name: Check dinginessentail with rpm + shell: rpm -q dinginessentail + register: rpm_result + + - name: Verify installation + assert: + that: + - "not dnf_result.changed" + - "rpm_result.stdout.startswith('dinginessentail-1.1-1')" + + - name: Verify dnf module outputs + assert: + that: + - "'msg' in dnf_result" + - "'rc' in dnf_result" + - "'results' in dnf_result" + # ============================================================================ - name: Install dinginessentail-1.0-1 from a file (downgrade) dnf: name: "{{ repodir }}/dinginessentail-1.0-1.{{ ansible_architecture }}.rpm" @@ -307,3 +331,192 @@ - dinginessentail-with-weak-dep - dinginessentail-weak-dep state: absent + +- block: + - dnf: + name: dinginessentail + state: present + + - dnf: + list: dinginessentail* + register: list_out + + - name: check that dnf returns nevra for backwards compat + assert: + that: + - '"envra" in list_out["results"][0]' + - '"nevra" in list_out["results"][0]' + + - 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 + dnf: + name: dinginessentail + state: absent + +- block: + - name: Install dinginessentail-1.0-2 + dnf: + name: "dinginessentail-1.0-2" + state: present + register: dnf_result + + - name: Check dinginessentail with rpm + shell: rpm -q dinginessentail + register: rpm_result + + - name: Verify installation + assert: + that: + - "dnf_result.changed" + - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" + + - name: Verify dnf module outputs + assert: + that: + - "'msg' in dnf_result" + - "'rc' in dnf_result" + - "'results' in dnf_result" + always: + - name: Clean up + dnf: + name: dinginessentail + state: absent + +- block: + - name: Install dinginessentail < 1.1 + dnf: + name: "dinginessentail < 1.1" + state: present + register: dnf_result + + - name: Check dinginessentail with rpm + shell: rpm -q dinginessentail + register: rpm_result + + - name: Verify installation + assert: + that: + - "dnf_result.changed" + - "rpm_result.stdout.startswith('dinginessentail-1.0')" + + - name: Install dinginessentail >= 1.1 + dnf: + name: "dinginessentail >= 1.1" + state: present + register: dnf_result + + - name: Check dinginessentail with rpm + shell: rpm -q dinginessentail + register: rpm_result + + - name: Verify installation + assert: + that: + - "dnf_result.changed" + - "rpm_result.stdout.startswith('dinginessentail-1.1')" + + - name: Verify dnf module outputs + assert: + that: + - "'msg' in dnf_result" + - "'rc' in dnf_result" + - "'results' in dnf_result" + always: + - name: Clean up + dnf: + name: dinginessentail + state: absent + +- name: > + test that when a package providing a file is installed then installing by specifying the file doesn't result in + installing a different package providing the same file + block: + - dnf: + name: provides_foo_b + state: "{{ item }}" + loop: + - absent + - present + + - dnf: + name: /foo.gif + state: present + register: dnf_result + + - command: rpm -q package_foo_a + ignore_errors: true + register: rpm_result + + - assert: + that: + - dnf_result is not changed + - rpm_result.rc == 1 + always: + - name: Clean up + dnf: + name: "{{ item }}" + state: absent + loop: + - provides_foo_b + +- name: ensure that a package named "$str-$number-$str" is parsed correctly + block: + - dnf: + name: number-11-name-11.0 + state: "{{ item }}" + loop: + - absent + - present + + - dnf: + name: number-11-name + state: present + register: dnf_result + + - assert: + that: + - dnf_result is not changed + + - dnf: + name: number-11-name + state: latest + update_only: true + register: dnf_result + + - assert: + that: + - dnf_result is changed + always: + - name: Clean up + dnf: + name: number-11-name + state: absent + +- name: test that epochs are handled the same way as via DNF on the command line + block: + - dnf: + name: "{{ item }}" + state: present + loop: + - "epochone-1.0-1.noarch" + - "epochone-1.1-1.noarch" + register: dnf_results + + - assert: + that: + - dnf_results["results"][0] is changed + - dnf_results["results"][1] is changed + always: + - name: Clean up + dnf: + name: epochone + state: absent diff --git a/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml b/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml index f54c0a8..3747966 100644 --- a/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml +++ b/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml @@ -264,6 +264,7 @@ name: - broken-a state: latest + best: true ignore_errors: true register: dnf_fail @@ -304,7 +305,26 @@ that: - res is not changed - # Case 7 is already tested quite extensively above in the earlier tests. + # Case 7 is already tested quite extensively above in the earlier tests. + # ###################################################################### + + - block: + - name: Test available package is installed while unavailable one is skipped due to skip_broken=true + dnf: + name: + - dinginessentail + - not-in-repo + skip_broken: true + register: res + + - assert: + that: + - res is changed + # There is a change in dnf5 that splits skip_broken into two options: + # skip_broken and skip_unavailable. + # TODO: for this test to pass on dnf5 the skip_unavailable option would have to be + # added to the dnf5 module and used here instead of skip_broken. + when: not dnf5|default(false) always: - name: Remove test yum repo @@ -313,7 +333,8 @@ state: absent - name: Remove all test packages installed - yum: + dnf: name: - broken-* + - dinginessentail state: absent diff --git a/test/integration/targets/dnf/vars/CentOS.yml b/test/integration/targets/dnf/vars/CentOS.yml deleted file mode 100644 index c70d853..0000000 --- a/test/integration/targets/dnf/vars/CentOS.yml +++ /dev/null @@ -1,2 +0,0 @@ -astream_name: '@php:7.2/minimal' -astream_name_no_stream: '@php/minimal' diff --git a/test/integration/targets/dnf/vars/Fedora.yml b/test/integration/targets/dnf/vars/Fedora.yml deleted file mode 100644 index fff6f4b..0000000 --- a/test/integration/targets/dnf/vars/Fedora.yml +++ /dev/null @@ -1,6 +0,0 @@ -astream_name: '@varnish:6.0/default' - -# For this to work, it needs to be that only shows once in `dnf module list`. -# Such packages, that exist on all the versions we test on, are hard to come by. -# TODO: This would be solved by using our own repo with modularity/streams. -astream_name_no_stream: '@varnish/default' diff --git a/test/integration/targets/dnf/vars/RedHat-9.yml b/test/integration/targets/dnf/vars/RedHat-9.yml deleted file mode 100644 index 680157d..0000000 --- a/test/integration/targets/dnf/vars/RedHat-9.yml +++ /dev/null @@ -1,2 +0,0 @@ -astream_name: '@php:8.1/minimal' -astream_name_no_stream: '@php/minimal' diff --git a/test/integration/targets/dnf/vars/RedHat.yml b/test/integration/targets/dnf/vars/RedHat.yml deleted file mode 100644 index c70d853..0000000 --- a/test/integration/targets/dnf/vars/RedHat.yml +++ /dev/null @@ -1,2 +0,0 @@ -astream_name: '@php:7.2/minimal' -astream_name_no_stream: '@php/minimal' diff --git a/test/integration/targets/dnf/vars/main.yml b/test/integration/targets/dnf/vars/main.yml index 3f7b43a..90b6856 100644 --- a/test/integration/targets/dnf/vars/main.yml +++ b/test/integration/targets/dnf/vars/main.yml @@ -3,4 +3,4 @@ dnf_log_files: - /var/log/dnf.rpm.log - /var/log/dnf.librepo.log -skip_broken_repo_baseurl: "https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/dnf/skip-broken/RPMS/" +skip_broken_repo_baseurl: "https://ci-files.testing.ansible.com/test/integration/targets/dnf/skip-broken/RPMS/" diff --git a/test/integration/targets/egg-info/lookup_plugins/import_pkg_resources.py b/test/integration/targets/egg-info/lookup_plugins/import_pkg_resources.py index 28227fc..cba386b 100644 --- a/test/integration/targets/egg-info/lookup_plugins/import_pkg_resources.py +++ b/test/integration/targets/egg-info/lookup_plugins/import_pkg_resources.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import pkg_resources # pylint: disable=unused-import diff --git a/test/integration/targets/entry_points/runme.sh b/test/integration/targets/entry_points/runme.sh index cabf153..f8d6fe5 100755 --- a/test/integration/targets/entry_points/runme.sh +++ b/test/integration/targets/entry_points/runme.sh @@ -4,7 +4,6 @@ set -eu -o pipefail source virtualenv.sh set +x unset PYTHONPATH -export SETUPTOOLS_USE_DISTUTILS=stdlib base_dir="$(dirname "$(dirname "$(dirname "$(dirname "${OUTPUT_DIR}")")")")" bin_dir="$(dirname "$(command -v pip)")" diff --git a/test/integration/targets/error_from_connection/connection_plugins/dummy.py b/test/integration/targets/error_from_connection/connection_plugins/dummy.py index d322fe0..8450b7b 100644 --- a/test/integration/targets/error_from_connection/connection_plugins/dummy.py +++ b/test/integration/targets/error_from_connection/connection_plugins/dummy.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = """ author: diff --git a/test/integration/targets/expect/files/test_command.py b/test/integration/targets/expect/files/test_command.py index 0e0e264..c723e7c 100644 --- a/test/integration/targets/expect/files/test_command.py +++ b/test/integration/targets/expect/files/test_command.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import sys diff --git a/test/integration/targets/fetch/injection/library/slurp.py b/test/integration/targets/fetch/injection/library/slurp.py index 7b78ba1..1fcd5c2 100644 --- a/test/integration/targets/fetch/injection/library/slurp.py +++ b/test/integration/targets/fetch/injection/library/slurp.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations DOCUMENTATION = """ diff --git a/test/integration/targets/file/tasks/state_link.yml b/test/integration/targets/file/tasks/state_link.yml index 6f96cdc..ab41b07 100644 --- a/test/integration/targets/file/tasks/state_link.yml +++ b/test/integration/targets/file/tasks/state_link.yml @@ -186,11 +186,11 @@ - name: Delete unprivileged user home and tempdir file: - path: "{{ item }}" + path: "{{ item }}" state: absent loop: - '{{ tempdir.path }}' - - '{{ user.home }}' + - '{{ user.home }}' - name: verify that link was created assert: @@ -199,7 +199,7 @@ - "missing_dst_no_follow_enable_force_use_mode2 is changed" - "missing_dst_no_follow_enable_force_use_mode3 is not changed" - "soft3_result['stat'].islnk" - - "soft3_result['stat'].lnk_target == user.home ~ '/nonexistent'" + - "soft3_result['stat'].lnk_target == user.home ~ '/nonexistent'" # # Test creating a link to a directory https://github.com/ansible/ansible/issues/1369 diff --git a/test/integration/targets/filter_core/aliases b/test/integration/targets/filter_core/aliases index 3005e4b..9f90774 100644 --- a/test/integration/targets/filter_core/aliases +++ b/test/integration/targets/filter_core/aliases @@ -1 +1,2 @@ shippable/posix/group4 +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/filter_core/meta/main.yml b/test/integration/targets/filter_core/meta/main.yml deleted file mode 100644 index e430ea6..0000000 --- a/test/integration/targets/filter_core/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: - - role: setup_passlib - when: ansible_facts.distribution == 'MacOSX' diff --git a/test/integration/targets/filter_core/tasks/main.yml b/test/integration/targets/filter_core/tasks/main.yml index 9d287a1..8b325a9 100644 --- a/test/integration/targets/filter_core/tasks/main.yml +++ b/test/integration/targets/filter_core/tasks/main.yml @@ -335,6 +335,27 @@ that: - '"hElLo there"|regex_replace("hello", "hi", ignorecase=True) == "hi there"' +- name: Verify regex_replace with count + assert: + that: + - '"foo=bar=baz"|regex_replace("=", ":", count=1) == "foo:bar=baz"' + +- name: Verify regex_replace with correct mandatory_count + assert: + that: + - '"foo=bar=baz"|regex_replace("=", ":", mandatory_count=2) == "foo:bar:baz"' + +- name: Verify regex_replace with incorrect mandatory_count + debug: + msg: "{{ 'foo=bar=baz'|regex_replace('=', ':', mandatory_count=1) }}" + ignore_errors: yes + register: incorrect_mandatory_count + +- assert: + that: + - "incorrect_mandatory_count is failed" + - "' times, but matches ' in incorrect_mandatory_count.msg" + - name: Verify case-insensitive regex_findall assert: that: @@ -454,38 +475,18 @@ - password_hash_2 is failed - "'not support' in password_hash_2.msg" -- name: install passlib if needed - pip: - name: passlib - state: present - register: installed_passlib - - name: test using passlib with an unsupported hash type set_fact: foo: '{{"hey"|password_hash("msdcc")}}' ignore_errors: yes register: unsupported_hash_type -- name: remove passlib if it was installed - pip: - name: passlib - state: absent - when: installed_passlib.changed - - assert: that: - unsupported_hash_type.msg == msg vars: msg: "msdcc is not in the list of supported passlib algorithms: md5, blowfish, sha256, sha512" -- name: test password_hash can work with bcrypt without passlib installed - debug: - msg: "{{ 'somestring'|password_hash('bcrypt') }}" - register: crypt_bcrypt - # Some implementations of crypt do not fail outright and return some short value. - failed_when: crypt_bcrypt is failed or (crypt_bcrypt.msg|length|int) != 60 - when: ansible_facts.os_family in ['RedHat', 'Debian'] - - name: Verify to_uuid throws on weird namespace set_fact: foo: '{{"hey"|to_uuid(namespace=22)}}' diff --git a/test/integration/targets/filter_encryption/aliases b/test/integration/targets/filter_encryption/aliases index 3005e4b..4d41cf4 100644 --- a/test/integration/targets/filter_encryption/aliases +++ b/test/integration/targets/filter_encryption/aliases @@ -1 +1,2 @@ shippable/posix/group4 +gather_facts/no diff --git a/test/integration/targets/filter_encryption/base.yml b/test/integration/targets/filter_encryption/base.yml deleted file mode 100644 index 1479f73..0000000 --- a/test/integration/targets/filter_encryption/base.yml +++ /dev/null @@ -1,49 +0,0 @@ -- hosts: localhost - gather_facts: true - vars: - data: secret - data2: 'foo: bar\n' - 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) }}' - # command line vaulted data2 - vaulted_id: !vault | - $ANSIBLE_VAULT;1.2;AES256;test1 - 36383733336533656264393332663131613335333332346439356164383935656234663631356430 - 3533353537343834333538356366376233326364613362640a623832636339363966336238393039 - 35316562626335306534356162623030613566306235623863373036626531346364626166656134 - 3063376436656635330a363636376131663362633731313964353061663661376638326461393736 - 3863 - vaulted_to_id: "{{data2|vault('test1@secret', vault_id='test1')}}" - - 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 - - vaulted_id|unvault('test1@secret', vault_id='test1') - - vaulted_to_id|unvault('test1@secret', vault_id='test1') diff --git a/test/integration/targets/filter_encryption/runme.sh b/test/integration/targets/filter_encryption/runme.sh deleted file mode 100755 index 41b30b1..0000000 --- a/test/integration/targets/filter_encryption/runme.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -ANSIBLE_GATHER_SUBSET='min' ansible-playbook base.yml "$@" diff --git a/test/integration/targets/filter_encryption/tasks/main.yml b/test/integration/targets/filter_encryption/tasks/main.yml new file mode 100644 index 0000000..4eb765d --- /dev/null +++ b/test/integration/targets/filter_encryption/tasks/main.yml @@ -0,0 +1,19 @@ +- name: check vaulting + assert: + that: + - data1_plaintext|vault(data1_password, salt=data1_salt) == data1_vaulted_string_with_id + - data1_plaintext|vault(data1_password, salt=data1_salt)|type_debug != 'AnsibleVaultEncryptedUnicode' + - data1_plaintext|vault(data1_password, salt=data1_salt, wrap_object=True)|type_debug == 'AnsibleVaultEncryptedUnicode' + +- name: check round-trip without salt + assert: + that: + - data2_plaintext|vault(data2_password, vault_id=data2_vault_id)|unvault(data2_password, vault_id=data2_vault_id) == data2_plaintext + +- name: check unvaulting + assert: + that: + - data1_vaulted_string_with_id|unvault(data1_password) == data1_plaintext + - data1_vaulted|unvault(data1_password) == data1_plaintext + - data2_vaulted_with_id|unvault(data2_password, vault_id=data2_vault_id) == data2_plaintext + - data2_vaulted_string_with_id|unvault(data2_password, vault_id=data2_vault_id) == data2_plaintext diff --git a/test/integration/targets/filter_encryption/vars/main.yml b/test/integration/targets/filter_encryption/vars/main.yml new file mode 100644 index 0000000..ca672f5 --- /dev/null +++ b/test/integration/targets/filter_encryption/vars/main.yml @@ -0,0 +1,38 @@ +data1_salt: 7 +data1_password: test +data1_plaintext: secret +# value from template: {{ data1_plaintext | vault(data1_password, vault_id='filter_default', salt=data1_salt) }} +data1_vaulted_string_with_id: | + $ANSIBLE_VAULT;1.2;AES256;filter_default + 33370a34333734353636633035656232613935353432656132646533346233326431346232616261 + 6133383034376566366261316365633931356133633337396363370a376664386236313834326561 + 6338373864623763613165366636633031303739 +data1_vaulted: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 33323332333033383335333533383338333333303339333733323339333833303334333133313339 + 33373339333133323331333833373335333933323338333633343338333133343334333733383334 + 33333335333433383337333133303339333433353332333333363339333733363335333233303330 + 3337333733353331333633313335333733373334333733320a373938666533366165653830313163 + 62386564343438653437333564383664646538653364343138303831613039313232636437336530 + 3438376662373764650a633366646563386335623161646262366137393635633464333265613938 + 6661 + +data2_vault_id: test1 +data2_password: test1@secret +data2_plaintext: 'foo: bar\n' +# value from template: {{ data2_plaintext | vault(data2_password, vault_id=data2_vault_id) }} +data2_vaulted_string_with_id: | + $ANSIBLE_VAULT;1.2;AES256;test1 + 65383166333033626133363239373635393635353232316433386430316265316639663234326638 + 6637623162613135623965386334313361383365326466340a316465653939333339393464623664 + 32303038646437326134363662393038666538643065613136316361306132636231336233333362 + 3665646531363138390a643530333038333936343262343638626535653564616537313635353633 + 3865 +# value from template: {{ data2_plaintext | vault(data2_password, vault_id=data2_vault_id) }} +data2_vaulted_with_id: !vault | + $ANSIBLE_VAULT;1.2;AES256;test1 + 65383166333033626133363239373635393635353232316433386430316265316639663234326638 + 6637623162613135623965386334313361383365326466340a316465653939333339393464623664 + 32303038646437326134363662393038666538643065613136316361306132636231336233333362 + 3665646531363138390a643530333038333936343262343638626535653564616537313635353633 + 3865 diff --git a/test/integration/targets/find/aliases b/test/integration/targets/find/aliases index cdd75ef..aa171eb 100644 --- a/test/integration/targets/find/aliases +++ b/test/integration/targets/find/aliases @@ -1,3 +1,4 @@ shippable/posix/group1 destructive -needs/root
\ No newline at end of file +needs/root +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/find/files/hello_world.gbk b/test/integration/targets/find/files/hello_world.gbk new file mode 100644 index 0000000..8e3d158 --- /dev/null +++ b/test/integration/targets/find/files/hello_world.gbk @@ -0,0 +1 @@ +ÄãºÃÊÀ½ç diff --git a/test/integration/targets/find/tasks/main.yml b/test/integration/targets/find/tasks/main.yml index c526dc7..c1198ca 100644 --- a/test/integration/targets/find/tasks/main.yml +++ b/test/integration/targets/find/tasks/main.yml @@ -124,6 +124,7 @@ with_items: - a.txt - log.txt + - hello_world.gbk - name: Ensure '$' only matches the true end of the file with read_whole_file, not a line find: @@ -195,6 +196,51 @@ that: - no_match_line_boundaries.matched == 0 +- name: read a gbk file by utf-8 + find: + paths: "{{ remote_tmp_dir_test }}" + patterns: "*.gbk" + contains: "ä½ å¥½ä¸–ç•Œ" + encoding: "utf-8" + register: fail_to_read_wrong_encoding_file + +- debug: var=fail_to_read_wrong_encoding_file + +- assert: + that: + - fail_to_read_wrong_encoding_file.msg == 'Not all paths examined, check warnings for details' + - >- + fail_to_read_wrong_encoding_file.skipped_paths[remote_tmp_dir_test] == + ("Failed to read the file %s/hello_world.gbk due to an encoding error. current encoding: utf-8" % (remote_tmp_dir_test)) + +- name: read a gbk file by gbk + find: + paths: "{{ remote_tmp_dir_test }}" + encoding: "gbk" + patterns: "*.gbk" + contains: "ä½ å¥½ä¸–ç•Œ" + register: success_to_read_right_encoding_file + +- debug: var=success_to_read_right_encoding_file + +- assert: + that: + - success_to_read_right_encoding_file.matched == 1 + +- name: read a gbk file by non-exists encoding + find: + paths: "{{ remote_tmp_dir_test }}" + encoding: "idontexist" + patterns: "*.gbk" + contains: "ä½ å¥½ä¸–ç•Œ" + register: fail_to_search_file_by_non_exists_encoding + +- debug: var=fail_to_search_file_by_non_exists_encoding + +- assert: + that: + - 'fail_to_search_file_by_non_exists_encoding.skipped_paths[remote_tmp_dir_test] == "unknown encoding: idontexist"' + - block: - set_fact: mypath: /idontexist{{lookup('pipe', 'mktemp')}} @@ -221,8 +267,8 @@ - assert: that: - - total_contents.matched == 18 - - total_contents.examined == 18 + - total_contents.matched == 19 + - total_contents.examined == 19 - name: Get files and directories with depth find: @@ -234,10 +280,10 @@ - assert: that: - - contents_with_depth.matched == 8 + - contents_with_depth.matched == 9 # dir contents are considered until the depth exceeds the requested depth # there are 8 files/directories in the requested depth and 4 that exceed it by 1 - - contents_with_depth.examined == 12 + - contents_with_depth.examined == 13 - name: Find files with depth find: @@ -248,10 +294,10 @@ - assert: that: - - files_with_depth.matched == 4 + - files_with_depth.matched == 5 # dir contents are considered until the depth exceeds the requested depth # there are 8 files/directories in the requested depth and 4 that exceed it by 1 - - files_with_depth.examined == 12 + - files_with_depth.examined == 13 - name: exclude with regex find: diff --git a/test/integration/targets/fork_safe_stdio/callback_plugins/spewstdio.py b/test/integration/targets/fork_safe_stdio/callback_plugins/spewstdio.py index 6ed6ef3..dba00a9 100644 --- a/test/integration/targets/fork_safe_stdio/callback_plugins/spewstdio.py +++ b/test/integration/targets/fork_safe_stdio/callback_plugins/spewstdio.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import atexit import os import sys diff --git a/test/integration/targets/fork_safe_stdio/run-with-pty.py b/test/integration/targets/fork_safe_stdio/run-with-pty.py index 4639152..b4ccb7b 100755 --- a/test/integration/targets/fork_safe_stdio/run-with-pty.py +++ b/test/integration/targets/fork_safe_stdio/run-with-pty.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Run a command using a PTY.""" +from __future__ import annotations import sys diff --git a/test/integration/targets/fork_safe_stdio/vendored_pty.py b/test/integration/targets/fork_safe_stdio/vendored_pty.py index bc70803..346bae3 100644 --- a/test/integration/targets/fork_safe_stdio/vendored_pty.py +++ b/test/integration/targets/fork_safe_stdio/vendored_pty.py @@ -7,6 +7,7 @@ # See: W. Richard Stevens. 1992. Advanced Programming in the # UNIX Environment. Chapter 19. # Author: Steen Lumholt -- with additions by Guido. +from __future__ import annotations from select import select import os diff --git a/test/integration/targets/gathering_facts/cache_plugins/none.py b/test/integration/targets/gathering_facts/cache_plugins/none.py index 5681dee..715f7ae 100644 --- a/test/integration/targets/gathering_facts/cache_plugins/none.py +++ b/test/integration/targets/gathering_facts/cache_plugins/none.py @@ -3,8 +3,7 @@ # 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 __future__ import annotations from ansible.plugins.cache import BaseCacheModule 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 index b79f794..8974181 100644 --- 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 @@ -1,4 +1,5 @@ #!/usr/bin/python +from __future__ import annotations DOCUMENTATION = """ --- diff --git a/test/integration/targets/gathering_facts/library/file_utils.py b/test/integration/targets/gathering_facts/library/file_utils.py index 38fa926..29da29b 100644 --- a/test/integration/targets/gathering_facts/library/file_utils.py +++ b/test/integration/targets/gathering_facts/library/file_utils.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.facts.utils import ( diff --git a/test/integration/targets/gathering_facts/test_run_once.yml b/test/integration/targets/gathering_facts/test_run_once.yml index 37023b2..35591f2 100644 --- a/test/integration/targets/gathering_facts/test_run_once.yml +++ b/test/integration/targets/gathering_facts/test_run_once.yml @@ -24,7 +24,7 @@ - name: "Check that run_once doesn't prevent fact gathering (#39453)" assert: that: 'hostvars.facthost1.ansible_local.uuid != hostvars.facthost2.ansible_local.uuid' - msg: "{{ 'Same value for ansible_local.uuid on both hosts: ' ~ hostvars.facthost1.ansible_local.uuid }}" + msg: "{{ 'Same value for ansible_local.uuid on both hosts: ' ~ hostvars.facthost1.ansible_local.uuid }}" always: - name: remove test local facts file: diff --git a/test/integration/targets/get_url/files/testserver.py b/test/integration/targets/get_url/files/testserver.py index 24967d4..3a83724 100644 --- a/test/integration/targets/get_url/files/testserver.py +++ b/test/integration/targets/get_url/files/testserver.py @@ -1,23 +1,15 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations +import http.server +import socketserver import sys if __name__ == '__main__': - if sys.version_info[0] >= 3: - import http.server - import socketserver - PORT = int(sys.argv[1]) + PORT = int(sys.argv[1]) - class Handler(http.server.SimpleHTTPRequestHandler): - pass + class Handler(http.server.SimpleHTTPRequestHandler): + pass - Handler.extensions_map['.json'] = 'application/json' - httpd = socketserver.TCPServer(("", PORT), Handler) - httpd.serve_forever() - else: - import mimetypes - mimetypes.init() - mimetypes.add_type('application/json', '.json') - import SimpleHTTPServer - SimpleHTTPServer.test() + Handler.extensions_map['.json'] = 'application/json' + httpd = socketserver.TCPServer(("", PORT), Handler) + httpd.serve_forever() diff --git a/test/integration/targets/get_url/tasks/hashlib.yml b/test/integration/targets/get_url/tasks/hashlib.yml index cc50ad7..e67555e 100644 --- a/test/integration/targets/get_url/tasks/hashlib.yml +++ b/test/integration/targets/get_url/tasks/hashlib.yml @@ -17,4 +17,3 @@ loop: "{{ algorithms.keys() }}" loop_control: loop_var: algorithm - when: ansible_python_version.startswith('3.') or not algorithm.startswith('sha3_') diff --git a/test/integration/targets/get_url/tasks/main.yml b/test/integration/targets/get_url/tasks/main.yml index c26cc08..ba1c933 100644 --- a/test/integration/targets/get_url/tasks/main.yml +++ b/test/integration/targets/get_url/tasks/main.yml @@ -667,6 +667,7 @@ environment: KRB5_CONFIG: '{{ krb5_config }}' KRB5CCNAME: FILE:{{ remote_tmp_dir }}/krb5.cc + OPENSSL_CONF: '{{ krb5_openssl_conf }}' when: krb5_config is defined - name: Test ciphers diff --git a/test/integration/targets/group/files/get_free_gid.py b/test/integration/targets/group/files/get_free_gid.py index 4c07b5e..155254d 100644 --- a/test/integration/targets/group/files/get_free_gid.py +++ b/test/integration/targets/group/files/get_free_gid.py @@ -1,6 +1,5 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import grp diff --git a/test/integration/targets/group/files/get_gid_for_group.py b/test/integration/targets/group/files/get_gid_for_group.py index 5a8cc41..ce35739 100644 --- a/test/integration/targets/group/files/get_gid_for_group.py +++ b/test/integration/targets/group/files/get_gid_for_group.py @@ -1,6 +1,5 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import grp import sys diff --git a/test/integration/targets/handlers/collections/ansible_collections/ns/col/roles/test_handlers_listen/handlers/main.yml b/test/integration/targets/handlers/collections/ansible_collections/ns/col/roles/test_handlers_listen/handlers/main.yml new file mode 100644 index 0000000..0658f7e --- /dev/null +++ b/test/integration/targets/handlers/collections/ansible_collections/ns/col/roles/test_handlers_listen/handlers/main.yml @@ -0,0 +1,4 @@ +- name: test notifying listen namespaced by collection + role + set_fact: + notify_listen_in_specific_collection_role: True + listen: notify_specific_collection_role_listen diff --git a/test/integration/targets/handlers/force_handlers_blocks_81533-1.yml b/test/integration/targets/handlers/force_handlers_blocks_81533-1.yml new file mode 100644 index 0000000..20605e4 --- /dev/null +++ b/test/integration/targets/handlers/force_handlers_blocks_81533-1.yml @@ -0,0 +1,16 @@ +- hosts: A,B + gather_facts: false + force_handlers: true + tasks: + - fail: + when: inventory_hostname == "A" + + - run_once: true + block: + - debug: + msg: task1 + - debug: + msg: task2 + + - debug: + msg: hosts_left diff --git a/test/integration/targets/handlers/force_handlers_blocks_81533-2.yml b/test/integration/targets/handlers/force_handlers_blocks_81533-2.yml new file mode 100644 index 0000000..4284a37 --- /dev/null +++ b/test/integration/targets/handlers/force_handlers_blocks_81533-2.yml @@ -0,0 +1,12 @@ +- hosts: A,B + gather_facts: false + force_handlers: true + tasks: + - fail: + when: inventory_hostname == "A" + + - meta: clear_host_errors + when: false + + - debug: + msg: hosts_left diff --git a/test/integration/targets/handlers/handlers_lockstep_82307.yml b/test/integration/targets/handlers/handlers_lockstep_82307.yml new file mode 100644 index 0000000..f7cf757 --- /dev/null +++ b/test/integration/targets/handlers/handlers_lockstep_82307.yml @@ -0,0 +1,25 @@ +- hosts: A,B + gather_facts: false + tasks: + - block: + - command: echo + notify: + - handler1 + - handler2 + + - fail: + when: inventory_hostname == "B" + + - meta: flush_handlers + always: + - name: always + debug: + msg: always + handlers: + - name: handler1 + debug: + msg: handler1 + + - name: handler2 + debug: + msg: handler2 diff --git a/test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml index 3bfd82a..d5cdbac 100644 --- a/test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml +++ b/test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml @@ -8,3 +8,8 @@ set_fact: notify_listen_in_role_4: True listen: notify_listen_in_role + +- name: test notifying listen namespaced by the role + set_fact: + notify_listen_in_specific_role: True + listen: notify_specific_role_listen diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh index 368ca44..9250fc8 100755 --- a/test/integration/targets/handlers/runme.sh +++ b/test/integration/targets/handlers/runme.sh @@ -202,9 +202,20 @@ ansible-playbook test_include_tasks_in_include_role.yml "$@" 2>&1 | tee out.txt ansible-playbook test_run_once.yml -i inventory.handlers "$@" 2>&1 | tee out.txt [ "$(grep out.txt -ce 'handler ran once')" = "1" ] -ansible-playbook 82241.yml -i inventory.handlers "$@" 2>&1 | tee out.txt -[ "$(grep out.txt -ce 'included_task_from_tasks_dir')" = "1" ] +ansible-playbook force_handlers_blocks_81533-1.yml -i inventory.handlers "$@" 2>&1 | tee out.txt +[ "$(grep out.txt -ce 'task1')" = "1" ] +[ "$(grep out.txt -ce 'task2')" = "1" ] +[ "$(grep out.txt -ce 'hosts_left')" = "1" ] + +ansible-playbook force_handlers_blocks_81533-2.yml -i inventory.handlers "$@" 2>&1 | tee out.txt +[ "$(grep out.txt -ce 'hosts_left')" = "1" ] ansible-playbook nested_flush_handlers_failure_force.yml -i inventory.handlers "$@" 2>&1 | tee out.txt [ "$(grep out.txt -ce 'flush_handlers_rescued')" = "1" ] [ "$(grep out.txt -ce 'flush_handlers_always')" = "2" ] + +ansible-playbook 82241.yml -i inventory.handlers "$@" 2>&1 | tee out.txt +[ "$(grep out.txt -ce 'included_task_from_tasks_dir')" = "1" ] + +ansible-playbook handlers_lockstep_82307.yml -i inventory.handlers "$@" 2>&1 | tee out.txt +[ "$(grep out.txt -ce 'TASK \[handler2\]')" = "0" ] diff --git a/test/integration/targets/handlers/test_handlers_listen.yml b/test/integration/targets/handlers/test_handlers_listen.yml index dd2cd87..16167a3 100644 --- a/test/integration/targets/handlers/test_handlers_listen.yml +++ b/test/integration/targets/handlers/test_handlers_listen.yml @@ -99,6 +99,7 @@ gather_facts: false roles: - role: test_handlers_listen + - role: ns.col.test_handlers_listen tasks: - name: test notify handlers listen in roles command: uptime @@ -113,6 +114,20 @@ - "notify_listen_ran_4_3 is defined" - "notify_listen_in_role_4 is defined" - "notify_listen_from_role_4 is defined" + - name: test notifying handlers using the role name prefix + command: uptime + notify: + - 'test_handlers_listen : notify_specific_role_listen' + - 'test_handlers_listen : notify_specific_collection_role_listen' + - meta: flush_handlers + - assert: + that: + - notify_listen_in_specific_collection_role is defined + - notify_listen_in_specific_role is defined + - name: test notifying the collection listener by the role's FQCN also works + command: uptime + notify: + - 'ns.col.test_handlers_listen : notify_specific_collection_role_listen' handlers: - name: notify_listen_ran_4_1 set_fact: diff --git a/test/integration/targets/ignore_unreachable/fake_connectors/bad_exec.py b/test/integration/targets/ignore_unreachable/fake_connectors/bad_exec.py index 0d8c385..0f350db 100644 --- a/test/integration/targets/ignore_unreachable/fake_connectors/bad_exec.py +++ b/test/integration/targets/ignore_unreachable/fake_connectors/bad_exec.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import ansible.plugins.connection.local as ansible_local from ansible.errors import AnsibleConnectionFailure diff --git a/test/integration/targets/ignore_unreachable/fake_connectors/bad_put_file.py b/test/integration/targets/ignore_unreachable/fake_connectors/bad_put_file.py index d4131f4..99a1c1b 100644 --- a/test/integration/targets/ignore_unreachable/fake_connectors/bad_put_file.py +++ b/test/integration/targets/ignore_unreachable/fake_connectors/bad_put_file.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import ansible.plugins.connection.local as ansible_local from ansible.errors import AnsibleConnectionFailure diff --git a/test/integration/targets/include_import/playbook/sub_playbook/library/helloworld.py b/test/integration/targets/include_import/playbook/sub_playbook/library/helloworld.py index 0ebe690..7fc1da9 100644 --- a/test/integration/targets/include_import/playbook/sub_playbook/library/helloworld.py +++ b/test/integration/targets/include_import/playbook/sub_playbook/library/helloworld.py @@ -14,8 +14,7 @@ # 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 __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/include_import/runme.sh b/test/integration/targets/include_import/runme.sh index d85b22d..12ee15b 100755 --- a/test/integration/targets/include_import/runme.sh +++ b/test/integration/targets/include_import/runme.sh @@ -127,7 +127,7 @@ test "$(ansible-playbook tasks/test_dynamic_allow_dup.yml --tags import | grep - # test templating public, allow_duplicates, and rolespec_validate ansible-playbook tasks/test_templating_IncludeRole_FA.yml 2>&1 | tee IncludeRole_FA_template.out -test "$(grep -c 'ok=4' IncludeRole_FA_template.out)" = 1 +test "$(grep -c 'ok=6' IncludeRole_FA_template.out)" = 1 test "$(grep -c 'failed=0' IncludeRole_FA_template.out)" = 1 # https://github.com/ansible/ansible/issues/66764 diff --git a/test/integration/targets/include_import/tasks/task_ansible_loop_index_var.yml b/test/integration/targets/include_import/tasks/task_ansible_loop_index_var.yml new file mode 100644 index 0000000..121227e --- /dev/null +++ b/test/integration/targets/include_import/tasks/task_ansible_loop_index_var.yml @@ -0,0 +1,5 @@ +- name: Assert ansible_loop_var and ansible_index_var are defined with correct values + assert: + that: + - ansible_loop_var is defined and ansible_index_var is defined + - ansible_loop_var == "should_show_up_loop" and ansible_index_var == "should_show_up_index" diff --git a/test/integration/targets/include_import/tasks/test_include_tasks.yml b/test/integration/targets/include_import/tasks/test_include_tasks.yml index ebe2273..e3ed4c0 100644 --- a/test/integration/targets/include_import/tasks/test_include_tasks.yml +++ b/test/integration/targets/include_import/tasks/test_include_tasks.yml @@ -42,3 +42,10 @@ - name: include_tasks + action action: include_tasks tasks1.yml + + - name: Test ansible_loop_var and ansible_index_var within included_tasks + include_tasks: task_ansible_loop_index_var.yml + loop: ['does not matter', 'dont care'] + loop_control: + loop_var: should_show_up_loop + index_var: should_show_up_index diff --git a/test/integration/targets/include_vars/tasks/main.yml b/test/integration/targets/include_vars/tasks/main.yml index 97636d9..edee91f 100644 --- a/test/integration/targets/include_vars/tasks/main.yml +++ b/test/integration/targets/include_vars/tasks/main.yml @@ -15,7 +15,7 @@ that: - "testing == 789" - "base_dir == 'environments/development'" - - "included_one_file.ansible_included_var_files | length == 1" + - "included_one_file.ansible_included_var_files | length == 1" - "'vars/environments/development/all.yml' in included_one_file.ansible_included_var_files[0]" - name: include the vars/environments/development/all.yml and save results in all @@ -67,7 +67,7 @@ - "testing == 456" - "base_dir == 'services'" - "webapp_containers == 10" - - "include_every_dir.ansible_included_var_files | length == 7" + - "include_every_dir.ansible_included_var_files | length == 7" - "'vars/all/all.yml' in include_every_dir.ansible_included_var_files[0]" - "'vars/environments/development/all.yml' in include_every_dir.ansible_included_var_files[1]" - "'vars/environments/development/services/webapp.yml' in include_every_dir.ansible_included_var_files[2]" @@ -88,7 +88,7 @@ that: - "testing == 789" - "base_dir == 'environments/development'" - - "include_without_webapp.ansible_included_var_files | length == 4" + - "include_without_webapp.ansible_included_var_files | length == 4" - "'webapp.yml' not in include_without_webapp.ansible_included_var_files | join(' ')" - "'file_without_extension' not in include_without_webapp.ansible_included_var_files | join(' ')" @@ -104,7 +104,7 @@ - "testing == 101112" - "base_dir == 'development/services'" - "webapp_containers == 20" - - "include_match_webapp.ansible_included_var_files | length == 1" + - "include_match_webapp.ansible_included_var_files | length == 1" - "'vars/environments/development/services/webapp.yml' in include_match_webapp.ansible_included_var_files[0]" - "'all.yml' not in include_match_webapp.ansible_included_var_files | join(' ')" diff --git a/test/integration/targets/infra/library/test.py b/test/integration/targets/infra/library/test.py index dbc4b61..ad8929b 100644 --- a/test/integration/targets/infra/library/test.py +++ b/test/integration/targets/infra/library/test.py @@ -1,8 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/interpreter_discovery_python/library/test_echo_module.py b/test/integration/targets/interpreter_discovery_python/library/test_echo_module.py index 7317921..b394f9d 100644 --- a/test/integration/targets/interpreter_discovery_python/library/test_echo_module.py +++ b/test/integration/targets/interpreter_discovery_python/library/test_echo_module.py @@ -5,8 +5,7 @@ # (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 +from __future__ import annotations import sys from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/interpreter_discovery_python/tasks/main.yml b/test/integration/targets/interpreter_discovery_python/tasks/main.yml index 7e9b2e8..13c11d9 100644 --- a/test/integration/targets/interpreter_discovery_python/tasks/main.yml +++ b/test/integration/targets/interpreter_discovery_python/tasks/main.yml @@ -141,8 +141,6 @@ - name: debian assertions assert: that: - # Debian 8 and older - - auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python' and distro_version is version('8', '<=') or distro_version is version('8', '>') # Debian 10 and newer - auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python3' and distro_version is version('10', '>=') or distro_version is version('10', '<') when: distro == 'debian' @@ -150,27 +148,21 @@ - name: fedora assertions assert: that: - - auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python3' + - "'/bin/python3' in auto_out.ansible_facts.discovered_interpreter_python" when: distro == 'fedora' and distro_version is version('23', '>=') - name: rhel assertions assert: that: - # rhel 6/7 - - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python' and distro_major_version is version('8','<')) or distro_major_version is version('8','>=') - # rhel 8 - - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/libexec/platform-python' and distro_major_version is version('8','==')) or distro_major_version is version('8','!=') # rhel 9 - - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python3' and distro_major_version is version('9','==')) or distro_major_version is version('9','!=') + - ('/bin/python3' in auto_out.ansible_facts.discovered_interpreter_python and distro_major_version is version('9','==')) or distro_major_version is version('9','!=') when: distro == 'redhat' - name: ubuntu assertions assert: that: - # ubuntu < 16 - - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python' and distro_version is version('16.04','<')) or distro_version is version('16.04','>=') # ubuntu >= 16 - - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python3' and distro_version is version('16.04','>=')) or distro_version is version('16.04','<') + - ('/bin/python3' in auto_out.ansible_facts.discovered_interpreter_python and distro_version is version('16.04','>=')) or distro_version is version('16.04','<') when: distro == 'ubuntu' - name: mac assertions diff --git a/test/integration/targets/inventory/inventory_plugins/contructed_with_hostvars.py b/test/integration/targets/inventory/inventory_plugins/contructed_with_hostvars.py index 43cad4f..8e179eb 100644 --- a/test/integration/targets/inventory/inventory_plugins/contructed_with_hostvars.py +++ b/test/integration/targets/inventory/inventory_plugins/contructed_with_hostvars.py @@ -1,8 +1,7 @@ # Copyright (c) 2022 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 +from __future__ import annotations DOCUMENTATION = ''' name: constructed_with_hostvars diff --git a/test/integration/targets/inventory_cache/plugins/inventory/cache_host.py b/test/integration/targets/inventory_cache/plugins/inventory/cache_host.py index 628aba1..6c93f03 100644 --- a/test/integration/targets/inventory_cache/plugins/inventory/cache_host.py +++ b/test/integration/targets/inventory_cache/plugins/inventory/cache_host.py @@ -1,8 +1,7 @@ # Copyright (c) 2021 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 +from __future__ import annotations DOCUMENTATION = ''' inventory: cache_host diff --git a/test/integration/targets/inventory_cache/plugins/inventory/exercise_cache.py b/test/integration/targets/inventory_cache/plugins/inventory/exercise_cache.py index cca2aa0..04afd0e 100644 --- a/test/integration/targets/inventory_cache/plugins/inventory/exercise_cache.py +++ b/test/integration/targets/inventory_cache/plugins/inventory/exercise_cache.py @@ -1,8 +1,7 @@ # Copyright (c) 2022 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 +from __future__ import annotations DOCUMENTATION = ''' inventory: exercise_cache 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 index 3666953..26af84b 100644 --- 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 @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class FilterModule: diff --git a/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter2.py b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter2.py index 96e726a..e039c8c 100644 --- a/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter2.py +++ b/test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter2.py @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class FilterModule: 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 index e2e7ffc..e43c984 100644 --- 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 @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class FilterModule: 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 index 9fce558..3c854ba 100644 --- 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 @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class TestModule: 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 index a4ca2ff..d13daca 100644 --- 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 @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class TestModule: diff --git a/test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py b/test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py index eebf39c..5dd653f 100644 --- a/test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py +++ b/test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class FilterModule: diff --git a/test/integration/targets/jinja_plugins/filter_plugins/good_filter.py b/test/integration/targets/jinja_plugins/filter_plugins/good_filter.py index e2e7ffc..e43c984 100644 --- a/test/integration/targets/jinja_plugins/filter_plugins/good_filter.py +++ b/test/integration/targets/jinja_plugins/filter_plugins/good_filter.py @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class FilterModule: diff --git a/test/integration/targets/jinja_plugins/test_plugins/bad_test.py b/test/integration/targets/jinja_plugins/test_plugins/bad_test.py index 0cc7a5a..251d5ef 100644 --- a/test/integration/targets/jinja_plugins/test_plugins/bad_test.py +++ b/test/integration/targets/jinja_plugins/test_plugins/bad_test.py @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class TestModule: diff --git a/test/integration/targets/jinja_plugins/test_plugins/good_test.py b/test/integration/targets/jinja_plugins/test_plugins/good_test.py index a4ca2ff..d13daca 100644 --- a/test/integration/targets/jinja_plugins/test_plugins/good_test.py +++ b/test/integration/targets/jinja_plugins/test_plugins/good_test.py @@ -1,9 +1,7 @@ # 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 +from __future__ import annotations class TestModule: diff --git a/test/integration/targets/keyword_inheritance/aliases b/test/integration/targets/keyword_inheritance/aliases index a6a3341..01741b9 100644 --- a/test/integration/targets/keyword_inheritance/aliases +++ b/test/integration/targets/keyword_inheritance/aliases @@ -1,3 +1,4 @@ shippable/posix/group4 context/controller needs/target/setup_test_user +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/known_hosts/defaults/main.yml b/test/integration/targets/known_hosts/defaults/main.yml index cd43843..849fb4b 100644 --- a/test/integration/targets/known_hosts/defaults/main.yml +++ b/test/integration/targets/known_hosts/defaults/main.yml @@ -1,6 +1,11 @@ --- example_org_rsa_key: > example.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAglyZmHHWskQ9wkh8LYbIqzvg99/oloneH7BaZ02ripJUy/2Zynv4tgUfm9fdXvAb1XXCEuTRnts9FBer87+voU0FPRgx3CfY9Sgr0FspUjnm4lqs53FIab1psddAaS7/F7lrnjl6VqBtPwMRQZG7qlml5uogGJwYJHxX0PGtsdoTJsM= - example_org_ed25519_key: > example.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIzlnSq5ESxLgW0avvPk3j7zLV59hcAPkxrMNdnZMKP2 +host_example_com_ed25519_key: > + host.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFp8VtD59XAcxkj1qbfCtB1in9nm5WiipORjtVJUBA6I +example_com_ed25519_ca: > + @cert-authority *.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPx6KAHnQhaWdYQoaclJMWfneZckvYOkZ32gUJO1zzJK +host_example_com_ed25519_signedhost: > + host.example.com ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIHgrfzePvYcPiRDh/3yKt2sJBk6mftlLGPpAlgveY8amAAAAIE/humEfyhaw5kawq/RC8tOoVJFgu6v+AYV2koz4bULNAAAAAAAAAAAAAAACAAAAFGhvc3QuZXhhbXBsZS5jb20ucHViAAAAFAAAABBob3N0LmV4YW1wbGUuY29tAAAAAAAAAAD//////////wAAAAAAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAg/HooAedCFpZ1hChpyUkxZ+d5lyS9g6RnfaBQk7XPMkoAAABTAAAAC3NzaC1lZDI1NTE5AAAAQPrSxFZ57dZvHy+ZqhudHBj5C1xU/aiAcMjbpyg3PwR/T/ym8B299uyhRj4g6wbby389xuTFkIYYgGlzh1vAkA0= diff --git a/test/integration/targets/known_hosts/files/existing_known_hosts b/test/integration/targets/known_hosts/files/existing_known_hosts index 2564f40..7aac98f 100644 --- a/test/integration/targets/known_hosts/files/existing_known_hosts +++ b/test/integration/targets/known_hosts/files/existing_known_hosts @@ -2,4 +2,5 @@ example.com ssh-dss AAAAB3NzaC1kc3MAAACBALT8YHxZ59d8yX4oQNPbpdK9AMPRQGKFY9X13S2f |1|d71/U7CbOH3Su+d2zxlbmiNfXtI=|g2YSPAVoK7bmg16FCOOPKTZe2BM= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== |1|L0TqxOhAVh6mLZ2lbHdTv3owun0=|vn0La5pbHNxin3XzQQdvaOulvVU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCNLCAA/SjVF3jkmlAlkgh+GtZdgxtusHaK66fcA7XSgCpQOdri1dGmND6pQDGwsxiKMy4Ou1GB2DR4N0G9T5E8= |1|WPo7yAOdlQKLSuRatNJCmDoga0k=|D/QybGglKokWuEQUe9Okpy5uSh0= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCNLCAA/SjVF3jkmlAlkgh+GtZdgxtusHaK66fcA7XSgCpQOdri1dGmND6pQDGwsxiKMy4Ou1GB2DR4N0G9T5E8= +@cert-authority *.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDXh1gk2xgS2MekPvo7ZEKiOT7HoyvOAzai2GqoLXGHO # example.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6OSqweGdPdQ/metQaf738AdN3P+itYp1AypOTgXkyj root@localhost diff --git a/test/integration/targets/known_hosts/tasks/main.yml b/test/integration/targets/known_hosts/tasks/main.yml index d5ffec4..2e5ecc7 100644 --- a/test/integration/targets/known_hosts/tasks/main.yml +++ b/test/integration/targets/known_hosts/tasks/main.yml @@ -57,7 +57,8 @@ that: - 'result is changed' - 'known_hosts.stdout_lines[0].startswith("example.com")' - - 'known_hosts.stdout_lines[4].startswith("# example.net")' + - 'known_hosts.stdout_lines[4].startswith("@cert-authority")' + - 'known_hosts.stdout_lines[5].startswith("# example.net")' - 'known_hosts.stdout_lines[-1].strip() == example_org_rsa_key.strip()' # test idempotence of addition @@ -222,7 +223,7 @@ that: - 'result is changed' - 'known_hosts_v5.stdout_lines[0].startswith("example.com")' - - 'known_hosts_v5.stdout_lines[4].startswith("# example.net")' + - 'known_hosts_v5.stdout_lines[5].startswith("# example.net")' - 'known_hosts_v5.stdout_lines[-1].strip().startswith("|1|")' - 'known_hosts_v5.stdout_lines[-1].strip().endswith(example_org_rsa_key.strip().split()[-1])' @@ -342,7 +343,7 @@ - name: assert the plaintext host is there assert: that: - - 'known_hosts_v10.stdout_lines[5].strip() == example_org_rsa_key.strip()' + - 'known_hosts_v10.stdout_lines[6].strip() == example_org_rsa_key.strip()' # ... and remove the host again for the next test @@ -378,6 +379,105 @@ that: - 'known_hosts_v11.stdout_lines[-1].strip().endswith("RANDOM=")' +- name: add the ed25519 host key + known_hosts: + name: host.example.com + key: "{{ host_example_com_ed25519_key }}" + state: present + path: "{{remote_tmp_dir}}/known_hosts" + register: result + +- name: get the file content + command: "cat {{remote_tmp_dir}}/known_hosts" + register: known_hosts_v12 + +- name: assert that the key was added and ordering preserved + assert: + that: + - 'result is changed' + - 'known_hosts_v12.stdout_lines[0].startswith("example.com")' + - 'known_hosts_v12.stdout_lines[4].startswith("@cert-authority")' + - 'known_hosts_v12.stdout_lines[5].startswith("# example.net")' + - 'known_hosts_v12.stdout_lines[-1].strip() == host_example_com_ed25519_key.strip()' + +- name: add the ed25519 ca key + known_hosts: + name: '*.example.com' + key: "{{ example_com_ed25519_ca }}" + state: present + path: "{{remote_tmp_dir}}/known_hosts" + register: result + +- name: get the file content + command: "cat {{remote_tmp_dir}}/known_hosts" + register: known_hosts_v13 + +- name: assert that the key was added and ordering preserved + assert: + that: + - 'result is changed' + - 'known_hosts_v13.stdout_lines[0].startswith("example.com")' + - 'known_hosts_v13.stdout_lines[4].startswith("@cert-authority")' + - 'known_hosts_v13.stdout_lines[5].startswith("# example.net")' + - 'known_hosts_v13.stdout_lines[-1].strip() == example_com_ed25519_ca.strip()' + +- name: Remove the ed25519 ca key + known_hosts: + name: '*.example.com' + key: "{{ example_com_ed25519_ca }}" + state: absent + path: "{{remote_tmp_dir}}/known_hosts" + register: result + +- name: get the file content + command: "cat {{remote_tmp_dir}}/known_hosts" + register: known_hosts_v14 + +- name: assert that the key was removed and ordering preserved + assert: + that: + - 'result is changed' + - 'known_hosts_v12.stdout == known_hosts_v14.stdout' + +- name: add the revoked ed25519 host key + known_hosts: + name: 'host.example.com' + key: "@revoked {{ host_example_com_ed25519_signedhost }}" + state: present + path: "{{remote_tmp_dir}}/known_hosts" + register: result + +- name: get the file content + command: "cat {{remote_tmp_dir}}/known_hosts" + register: known_hosts_v15 + +- name: assert that the key was added and ordering preserved + assert: + that: + - 'result is changed' + - 'known_hosts_v15.stdout_lines[0].startswith("example.com")' + - 'known_hosts_v15.stdout_lines[4].startswith("@cert-authority")' + - 'known_hosts_v15.stdout_lines[5].startswith("# example.net")' + - 'known_hosts_v15.stdout_lines[-1].strip() == "@revoked " ~ host_example_com_ed25519_signedhost.strip()' + +- name: remove the revoked ed25519 host key + known_hosts: + name: 'host.example.com' + key: "@revoked {{ host_example_com_ed25519_signedhost }}" + state: absent + path: "{{remote_tmp_dir}}/known_hosts" + register: result + +- name: get the file content + command: "cat {{remote_tmp_dir}}/known_hosts" + register: known_hosts_v16 + +- name: assert that the key was removed and ordering preserved + assert: + that: + - 'result is changed' + - 'known_hosts_v12.stdout == known_hosts_v16.stdout' + # test errors - name: Try using a comma separated list of hosts diff --git a/test/integration/targets/lineinfile/aliases b/test/integration/targets/lineinfile/aliases index 765b70d..ca7c912 100644 --- a/test/integration/targets/lineinfile/aliases +++ b/test/integration/targets/lineinfile/aliases @@ -1 +1,2 @@ shippable/posix/group2 +destructive diff --git a/test/integration/targets/lineinfile/tasks/acls.yml b/test/integration/targets/lineinfile/tasks/acls.yml new file mode 100644 index 0000000..1be6ecb --- /dev/null +++ b/test/integration/targets/lineinfile/tasks/acls.yml @@ -0,0 +1,54 @@ +- block: + - name: Install the acl package on Ubuntu + apt: + name: acl + when: ansible_distribution in ('Ubuntu') + register: setup_acl + + - name: Create file + copy: + content: "TEST" + mode: 0644 + dest: "~/test.txt" + + - shell: setfacl -m nobody:rwx ~/test.txt + + - shell: getfacl ~/test.txt + register: acls + + - name: Check that permissions match with the copy mode and setfacl command + assert: + that: + - "'user::rw-' in acls.stdout_lines" + - "'user:nobody:rwx' in acls.stdout_lines" + - "'group::r--' in acls.stdout_lines" + - "'other::r--' in acls.stdout_lines" + + - name: test atomic_move via lineinfile doesn't delete extended acls + lineinfile: + path: "~/test.txt" + regexp: "TEST" + line: "UPDATE" + + - shell: getfacl ~/test.txt + register: acls + + - name: Validate the acls are unmodified + assert: + that: + - "'user::rw-' in acls.stdout_lines" + - "'user:nobody:rwx' in acls.stdout_lines" + - "'group::r--' in acls.stdout_lines" + - "'other::r--' in acls.stdout_lines" + + always: + - name: Remove the acl package on Ubuntu + apt: + name: acl + state: absent + when: setup_acl is changed + + - name: Clean up + file: + path: "~/test.txt" + state: absent diff --git a/test/integration/targets/lineinfile/tasks/main.yml b/test/integration/targets/lineinfile/tasks/main.yml index 3d4678c..1914920 100644 --- a/test/integration/targets/lineinfile/tasks/main.yml +++ b/test/integration/targets/lineinfile/tasks/main.yml @@ -258,6 +258,27 @@ that: - "result.stat.checksum == 'd4eeb07bdebab2d1cdb3ec4a3635afa2618ad4ea'" +- name: try to remove the middle line again + lineinfile: + dest: "{{ remote_tmp_dir }}/test.txt" + state: absent + regexp: "^This is line 3$" + register: result + +- name: assert no change was made + assert: + that: result is not changed + +- name: use stat to verify no change was made + stat: + path: "{{ remote_tmp_dir }}/test.txt" + register: result + +- name: assert test checksum matches after the middle line was removed + assert: + that: + - "result.stat.checksum == 'd4eeb07bdebab2d1cdb3ec4a3635afa2618ad4ea'" + - name: run a validation script that succeeds lineinfile: dest: "{{ remote_tmp_dir }}/test.txt" @@ -944,9 +965,6 @@ The search string is an empty string, which will match every line in the file. This may have unintended consequences, such as replacing the last line in the file rather than appending. -- name: meta - meta: end_play - ################################################################### ## Issue #58923 ## Using firstmatch with insertafter and ensure multiple lines are not inserted @@ -1397,3 +1415,34 @@ - testend1 is changed - testend2 is changed - testend_file.stat.checksum == 'ef36116966836ce04f6b249fd1837706acae4e19' + +- name: Integration test for issue 76727 + block: + - name: Create a symbolic link for the test file + file: + src: "{{ remote_tmp_dir }}/test.txt" + dest: "{{ remote_tmp_dir }}/test-76727.txt" + state: link + + - name: Insert a line and back it up + lineinfile: + dest: "{{ remote_tmp_dir }}/test-76727.txt" + state: present + line: "#Line for issue 76727" + backup: yes + register: result1 + + - name: Stat the backup file + stat: + path: "{{ result1.backup }}" + register: result2 + + - name: Assert that the line was inserted and backup is created + assert: + that: + - result1 is changed + - result2.stat.exists + +- name: Integration test for issue 72929 + import_tasks: acls.yml + when: ansible_system == 'Linux' diff --git a/test/integration/targets/lookup_csvfile/tasks/main.yml b/test/integration/targets/lookup_csvfile/tasks/main.yml index 758da71..370dc05 100644 --- a/test/integration/targets/lookup_csvfile/tasks/main.yml +++ b/test/integration/targets/lookup_csvfile/tasks/main.yml @@ -41,6 +41,7 @@ assert: that: - lookup('csvfile', 'Smith', file='people.csv', delimiter=',', col=1) == "Jane" + - lookup('csvfile', 'Jane', file='people.csv', delimiter=',', col=0, keycol=1) == "Smith" - lookup('csvfile', 'German von Lastname file=people.csv delimiter=, col=1') == "Demo" - name: Check tab-separated file diff --git a/test/integration/targets/lookup_first_found/tasks/main.yml b/test/integration/targets/lookup_first_found/tasks/main.yml index ba248bd..cae4f84 100644 --- a/test/integration/targets/lookup_first_found/tasks/main.yml +++ b/test/integration/targets/lookup_first_found/tasks/main.yml @@ -147,3 +147,8 @@ - ishouldnotbefound.yml paths: - "{{role_path}}/vars" + +- name: Make sure skip works in 'mixed' argument passing + assert: + that: + - q('first_found', ['/nonexistant'], skip=True) == [] diff --git a/test/integration/targets/lookup_password/aliases b/test/integration/targets/lookup_password/aliases index b598321..cf6140f 100644 --- a/test/integration/targets/lookup_password/aliases +++ b/test/integration/targets/lookup_password/aliases @@ -1 +1,2 @@ shippable/posix/group3 +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/lookup_password/runme.sh b/test/integration/targets/lookup_password/runme.sh index a3637a7..d1a1293 100755 --- a/test/integration/targets/lookup_password/runme.sh +++ b/test/integration/targets/lookup_password/runme.sh @@ -4,8 +4,4 @@ set -eux source virtualenv.sh -# Requirements have to be installed prior to running ansible-playbook -# because plugins and requirements are loaded before the task runs -pip install passlib - ANSIBLE_ROLES_PATH=../ ansible-playbook runme.yml -e "output_dir=${OUTPUT_DIR}" "$@" diff --git a/test/integration/targets/lookup_sequence/tasks/main.yml b/test/integration/targets/lookup_sequence/tasks/main.yml index e64801d..3d74339 100644 --- a/test/integration/targets/lookup_sequence/tasks/main.yml +++ b/test/integration/targets/lookup_sequence/tasks/main.yml @@ -89,7 +89,7 @@ - assert: that: - ansible_failed_task.name == "EXPECTED FAILURE - test bad kv value" - - ansible_failed_result.msg == "can't parse start=A as integer" + - ansible_failed_result.msg.startswith("Invalid type for") - block: - name: EXPECTED FAILURE - test bad simple form start value @@ -102,7 +102,7 @@ - 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" + - ansible_failed_result.msg.startswith("Invalid type for") - block: - name: EXPECTED FAILURE - test bad simple form end value @@ -115,7 +115,7 @@ - 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" + - ansible_failed_result.msg.startswith("Invalid type for") - block: - name: EXPECTED FAILURE - test bad simple form stride value @@ -128,7 +128,7 @@ - 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" + - ansible_failed_result.msg.startswith("Invalid type for") - block: - name: EXPECTED FAILURE - test no count or end diff --git a/test/integration/targets/loop-connection/collections/ansible_collections/ns/name/plugins/connection/dummy.py b/test/integration/targets/loop-connection/collections/ansible_collections/ns/name/plugins/connection/dummy.py index cb14991..ca2ac25 100644 --- a/test/integration/targets/loop-connection/collections/ansible_collections/ns/name/plugins/connection/dummy.py +++ b/test/integration/targets/loop-connection/collections/ansible_collections/ns/name/plugins/connection/dummy.py @@ -1,4 +1,5 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import annotations DOCUMENTATION = ''' name: dummy diff --git a/test/integration/targets/missing_required_lib/library/missing_required_lib.py b/test/integration/targets/missing_required_lib/library/missing_required_lib.py index 8c7ba88..a5ba7c5 100644 --- a/test/integration/targets/missing_required_lib/library/missing_required_lib.py +++ b/test/integration/targets/missing_required_lib/library/missing_required_lib.py @@ -2,8 +2,7 @@ # Copyright: (c) 2020, Matt Martz <matt@sivel.net> # 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 __future__ import annotations from ansible.module_utils.basic import AnsibleModule, missing_required_lib diff --git a/test/integration/targets/module_defaults/action_plugins/debug.py b/test/integration/targets/module_defaults/action_plugins/debug.py index 0c43201..63c0779 100644 --- a/test/integration/targets/module_defaults/action_plugins/debug.py +++ b/test/integration/targets/module_defaults/action_plugins/debug.py @@ -15,8 +15,7 @@ # # 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 __future__ import annotations from ansible.errors import AnsibleUndefinedVariable from ansible.module_utils.six import string_types diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/action/other_echoaction.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/action/other_echoaction.py index f7777b8..dcbe089 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/action/other_echoaction.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/action/other_echoaction.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible_collections.testns.testcoll.plugins.action.echoaction import ActionModule as BaseAM diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/modules/other_echo1.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/modules/other_echo1.py index 771395f..6ca7b63 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/modules/other_echo1.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/modules/other_echo1.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible_collections.testns.testcoll.plugins.module_utils.echo_impl import do_echo 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 a8c2c8c..145941c 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 @@ -2,7 +2,7 @@ plugin_routing: action: # Backwards compat for modules-redirected-as-actions: # By default, each module_defaults entry is resolved as an action plugin, - # and if it does not exist, it is resolved a a module. + # and if it does not exist, it is resolved a module. # All modules that redirect to the same action will resolve to the same action. module_uses_action_defaults: redirect: testns.testcoll.eos diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/echoaction.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/echoaction.py index 2fa097b..88ec765 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/echoaction.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/echoaction.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/eos.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/eos.py index 174f372..627cbdd 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/eos.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/eos.py @@ -1,8 +1,7 @@ # Copyright: (c) 2022, 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 +from __future__ import annotations from ansible.plugins.action.normal import ActionModule as ActionBase diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/ios.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/ios.py index 7ba2434..1647816 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/ios.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/ios.py @@ -1,8 +1,7 @@ # Copyright: (c) 2022, 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 +from __future__ import annotations from ansible.plugins.action.normal import ActionModule as ActionBase diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/vyos.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/vyos.py index 67050fb..34732aa 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/vyos.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/vyos.py @@ -1,8 +1,7 @@ # Copyright: (c) 2022, 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 +from __future__ import annotations from ansible.plugins.action.normal import ActionModule as ActionBase diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/module_utils/echo_impl.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/module_utils/echo_impl.py index f5c5d73..2a880e2 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/module_utils/echo_impl.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/module_utils/echo_impl.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json from ansible.module_utils import basic diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo1.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo1.py index 771395f..6ca7b63 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo1.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo1.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible_collections.testns.testcoll.plugins.module_utils.echo_impl import do_echo diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo2.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo2.py index 771395f..6ca7b63 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo2.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo2.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible_collections.testns.testcoll.plugins.module_utils.echo_impl import do_echo diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/eosfacts.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/eosfacts.py index 8c73fe1..546205b 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/eosfacts.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/eosfacts.py @@ -3,8 +3,7 @@ # Copyright: (c) 2022, 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 +from __future__ import annotations DOCUMENTATION = r''' diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ios_facts.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ios_facts.py index e2ed598..2e230ec 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ios_facts.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ios_facts.py @@ -3,8 +3,7 @@ # Copyright: (c) 2022, 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 +from __future__ import annotations DOCUMENTATION = r''' 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 index 6a818fd..439b415 100644 --- 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 @@ -3,8 +3,7 @@ # 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 __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/module.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/module.py index b98a5f9..f7a1932 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/module.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/module.py @@ -3,8 +3,7 @@ # Copyright: (c) 2022, 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 +from __future__ import annotations DOCUMENTATION = r''' 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 index 2cb1fb2..b54b701 100644 --- 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 @@ -5,8 +5,7 @@ # (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 +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/vyosfacts.py b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/vyosfacts.py index 3a9abbc..7af1c6b 100644 --- a/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/vyosfacts.py +++ b/test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/vyosfacts.py @@ -3,8 +3,7 @@ # Copyright: (c) 2022, 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 +from __future__ import annotations DOCUMENTATION = r''' diff --git a/test/integration/targets/module_defaults/library/legacy_ping.py b/test/integration/targets/module_defaults/library/legacy_ping.py index 2cb1fb2..b54b701 100644 --- a/test/integration/targets/module_defaults/library/legacy_ping.py +++ b/test/integration/targets/module_defaults/library/legacy_ping.py @@ -5,8 +5,7 @@ # (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 +from __future__ import annotations DOCUMENTATION = ''' diff --git a/test/integration/targets/module_defaults/library/test_module_defaults.py b/test/integration/targets/module_defaults/library/test_module_defaults.py index ede8c99..3d7718d 100644 --- a/test/integration/targets/module_defaults/library/test_module_defaults.py +++ b/test/integration/targets/module_defaults/library/test_module_defaults.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/module_no_log/library/module_that_has_secret.py b/test/integration/targets/module_no_log/library/module_that_has_secret.py index 035228c..5bdfc85 100644 --- a/test/integration/targets/module_no_log/library/module_that_has_secret.py +++ b/test/integration/targets/module_no_log/library/module_that_has_secret.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/module_no_log/library/module_that_logs.py b/test/integration/targets/module_no_log/library/module_that_logs.py index 44b36ee..cb517f7 100644 --- a/test/integration/targets/module_no_log/library/module_that_logs.py +++ b/test/integration/targets/module_no_log/library/module_that_logs.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/module_precedence/lib_no_extension/ping b/test/integration/targets/module_precedence/lib_no_extension/ping index a28f469..ab4a989 100644 --- a/test/integration/targets/module_precedence/lib_no_extension/ping +++ b/test/integration/targets/module_precedence/lib_no_extension/ping @@ -19,8 +19,7 @@ # 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 __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], diff --git a/test/integration/targets/module_precedence/lib_with_extension/a.ini b/test/integration/targets/module_precedence/lib_with_extension/a.ini index 80278c9..4d0fe7b 100644 --- a/test/integration/targets/module_precedence/lib_with_extension/a.ini +++ b/test/integration/targets/module_precedence/lib_with_extension/a.ini @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/module_precedence/lib_with_extension/a.py b/test/integration/targets/module_precedence/lib_with_extension/a.py index 8eda141..dc537f0 100644 --- a/test/integration/targets/module_precedence/lib_with_extension/a.py +++ b/test/integration/targets/module_precedence/lib_with_extension/a.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/module_precedence/lib_with_extension/ping.ini b/test/integration/targets/module_precedence/lib_with_extension/ping.ini index 6f4b6a1..b8c9c94 100644 --- a/test/integration/targets/module_precedence/lib_with_extension/ping.ini +++ b/test/integration/targets/module_precedence/lib_with_extension/ping.ini @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/module_precedence/lib_with_extension/ping.py b/test/integration/targets/module_precedence/lib_with_extension/ping.py index a28f469..ab4a989 100644 --- a/test/integration/targets/module_precedence/lib_with_extension/ping.py +++ b/test/integration/targets/module_precedence/lib_with_extension/ping.py @@ -19,8 +19,7 @@ # 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 __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], diff --git a/test/integration/targets/module_precedence/multiple_roles/bar/library/ping.py b/test/integration/targets/module_precedence/multiple_roles/bar/library/ping.py index 98ef7b4..88fc595 100644 --- a/test/integration/targets/module_precedence/multiple_roles/bar/library/ping.py +++ b/test/integration/targets/module_precedence/multiple_roles/bar/library/ping.py @@ -19,8 +19,7 @@ # 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 __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], diff --git a/test/integration/targets/module_precedence/multiple_roles/foo/library/ping.py b/test/integration/targets/module_precedence/multiple_roles/foo/library/ping.py index 8860b7a..72c3cb8 100644 --- a/test/integration/targets/module_precedence/multiple_roles/foo/library/ping.py +++ b/test/integration/targets/module_precedence/multiple_roles/foo/library/ping.py @@ -19,8 +19,7 @@ # 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 __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], diff --git a/test/integration/targets/module_precedence/roles_no_extension/foo/library/ping b/test/integration/targets/module_precedence/roles_no_extension/foo/library/ping index 8860b7a..72c3cb8 100644 --- a/test/integration/targets/module_precedence/roles_no_extension/foo/library/ping +++ b/test/integration/targets/module_precedence/roles_no_extension/foo/library/ping @@ -19,8 +19,7 @@ # 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 __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], diff --git a/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.ini b/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.ini index 8b17029..8e3ae41 100644 --- a/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.ini +++ b/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.ini @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.py b/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.py index 4bc5906..cc66035 100644 --- a/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.py +++ b/test/integration/targets/module_precedence/roles_with_extension/foo/library/a.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.ini b/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.ini index f9c04f5..445ed9d 100644 --- a/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.ini +++ b/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.ini @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.py b/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.py index 8860b7a..72c3cb8 100644 --- a/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.py +++ b/test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.py @@ -19,8 +19,7 @@ # 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 __future__ import annotations ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], diff --git a/test/integration/targets/module_utils/aliases b/test/integration/targets/module_utils/aliases index a1fba96..8474c8a 100644 --- a/test/integration/targets/module_utils/aliases +++ b/test/integration/targets/module_utils/aliases @@ -4,3 +4,4 @@ needs/target/setup_test_user needs/target/setup_remote_tmp_dir context/target destructive +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/module_utils/callback/pure_json.py b/test/integration/targets/module_utils/callback/pure_json.py index 1723d7b..7a9b800 100644 --- a/test/integration/targets/module_utils/callback/pure_json.py +++ b/test/integration/targets/module_utils/callback/pure_json.py @@ -1,8 +1,7 @@ # (c) 2021 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 +from __future__ import annotations DOCUMENTATION = ''' name: pure_json diff --git a/test/integration/targets/module_utils/collections/ansible_collections/testns/testcoll/plugins/module_utils/legit.py b/test/integration/targets/module_utils/collections/ansible_collections/testns/testcoll/plugins/module_utils/legit.py index b9d6348..e12624d 100644 --- a/test/integration/targets/module_utils/collections/ansible_collections/testns/testcoll/plugins/module_utils/legit.py +++ b/test/integration/targets/module_utils/collections/ansible_collections/testns/testcoll/plugins/module_utils/legit.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations def importme(): diff --git a/test/integration/targets/module_utils/library/test.py b/test/integration/targets/module_utils/library/test.py index 857d3d8..71f9292 100644 --- a/test/integration/targets/module_utils/library/test.py +++ b/test/integration/targets/module_utils/library/test.py @@ -2,7 +2,7 @@ # Most of these names are only available via PluginLoader so pylint doesn't # know they exist # pylint: disable=no-name-in-module -__metaclass__ = type +from __future__ import annotations results = {} diff --git a/test/integration/targets/module_utils/library/test_alias_deprecation.py b/test/integration/targets/module_utils/library/test_alias_deprecation.py index dc36aba..7d7cfa3 100644 --- a/test/integration/targets/module_utils/library/test_alias_deprecation.py +++ b/test/integration/targets/module_utils/library/test_alias_deprecation.py @@ -1,7 +1,6 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule # overridden diff --git a/test/integration/targets/module_utils/library/test_cwd_missing.py b/test/integration/targets/module_utils/library/test_cwd_missing.py index cd1f9c7..489b0cc 100644 --- a/test/integration/targets/module_utils/library/test_cwd_missing.py +++ b/test/integration/targets/module_utils/library/test_cwd_missing.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations import os diff --git a/test/integration/targets/module_utils/library/test_cwd_unreadable.py b/test/integration/targets/module_utils/library/test_cwd_unreadable.py index d65f31a..9f973e5 100644 --- a/test/integration/targets/module_utils/library/test_cwd_unreadable.py +++ b/test/integration/targets/module_utils/library/test_cwd_unreadable.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations import os diff --git a/test/integration/targets/module_utils/library/test_datetime.py b/test/integration/targets/module_utils/library/test_datetime.py index 493a186..39eba25 100644 --- a/test/integration/targets/module_utils/library/test_datetime.py +++ b/test/integration/targets/module_utils/library/test_datetime.py @@ -2,8 +2,7 @@ # Most of these names are only available via PluginLoader so pylint doesn't # know they exist # pylint: disable=no-name-in-module -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule import datetime diff --git a/test/integration/targets/module_utils/library/test_env_override.py b/test/integration/targets/module_utils/library/test_env_override.py index ebfb5dd..041559b 100644 --- a/test/integration/targets/module_utils/library/test_env_override.py +++ b/test/integration/targets/module_utils/library/test_env_override.py @@ -2,8 +2,7 @@ # Most of these names are only available via PluginLoader so pylint doesn't # know they exist # pylint: disable=no-name-in-module -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.json_utils import data diff --git a/test/integration/targets/module_utils/library/test_failure.py b/test/integration/targets/module_utils/library/test_failure.py index ab80cea..ff8b477 100644 --- a/test/integration/targets/module_utils/library/test_failure.py +++ b/test/integration/targets/module_utils/library/test_failure.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations results = {} # Test that we are rooted correctly diff --git a/test/integration/targets/module_utils/library/test_heuristic_log_sanitize.py b/test/integration/targets/module_utils/library/test_heuristic_log_sanitize.py new file mode 100644 index 0000000..a30a622 --- /dev/null +++ b/test/integration/targets/module_utils/library/test_heuristic_log_sanitize.py @@ -0,0 +1,51 @@ +#!/usr/bin/python + +from __future__ import annotations + +from ansible.module_utils import basic +from ansible.module_utils.basic import AnsibleModule + +heuristic_log_sanitize = basic.heuristic_log_sanitize + + +def heuristic_log_sanitize_spy(*args, **kwargs): + heuristic_log_sanitize_spy.return_value = heuristic_log_sanitize(*args, **kwargs) + return heuristic_log_sanitize_spy.return_value + + +basic.heuristic_log_sanitize = heuristic_log_sanitize_spy + + +def main(): + + module = AnsibleModule( + argument_spec={ + 'data': { + 'type': 'str', + 'required': True, + } + }, + ) + + # This test module is testing that the data that will be used for logging + # to syslog is properly sanitized when it includes URLs that contain a password. + # + # As such, we build an expected sanitized string from the input, to + # compare it with the output from heuristic_log_sanitize. + # + # To test this in the same way that modules ultimately operate this test + # monkeypatches ansible.module_utils.basic to store the sanitized data + # for later inspection. + data = module.params['data'] + left = data.rindex(':') + 1 + right = data.rindex('@') + expected = data[:left] + '********' + data[right:] + + sanitized = heuristic_log_sanitize_spy.return_value + if sanitized != expected: + module.fail_json(msg='Invalid match', expected=expected, sanitized=sanitized) + module.exit_json(match=True) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/module_utils/library/test_network.py b/test/integration/targets/module_utils/library/test_network.py index c6a5390..c1abd94 100644 --- a/test/integration/targets/module_utils/library/test_network.py +++ b/test/integration/targets/module_utils/library/test_network.py @@ -3,8 +3,7 @@ # Copyright: (c) 2021, 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 +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.common.network import to_subnet diff --git a/test/integration/targets/module_utils/library/test_no_log.py b/test/integration/targets/module_utils/library/test_no_log.py index 770e0b3..6a8cd58 100644 --- a/test/integration/targets/module_utils/library/test_no_log.py +++ b/test/integration/targets/module_utils/library/test_no_log.py @@ -2,8 +2,7 @@ # (c) 2021 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 +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule, env_fallback diff --git a/test/integration/targets/module_utils/library/test_optional.py b/test/integration/targets/module_utils/library/test_optional.py index 4d0225d..019b25b 100644 --- a/test/integration/targets/module_utils/library/test_optional.py +++ b/test/integration/targets/module_utils/library/test_optional.py @@ -2,8 +2,7 @@ # Most of these names are only available via PluginLoader so pylint doesn't # know they exist # pylint: disable=no-name-in-module -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/module_utils/library/test_override.py b/test/integration/targets/module_utils/library/test_override.py index 7f6e7a5..4eef499 100644 --- a/test/integration/targets/module_utils/library/test_override.py +++ b/test/integration/targets/module_utils/library/test_override.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule # overridden diff --git a/test/integration/targets/module_utils/library/test_recursive_diff.py b/test/integration/targets/module_utils/library/test_recursive_diff.py index 0cf39d9..bb618ac 100644 --- a/test/integration/targets/module_utils/library/test_recursive_diff.py +++ b/test/integration/targets/module_utils/library/test_recursive_diff.py @@ -2,8 +2,7 @@ # Copyright: (c) 2020, Matt Martz <matt@sivel.net> # 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 __future__ import annotations from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.common.dict_transformations import recursive_diff diff --git a/test/integration/targets/module_utils/module_utils_test.yml b/test/integration/targets/module_utils/module_utils_test.yml index 352bc58..f2da776 100644 --- a/test/integration/targets/module_utils/module_utils_test.yml +++ b/test/integration/targets/module_utils/module_utils_test.yml @@ -119,3 +119,7 @@ that: - optionaltest is success - optionaltest.msg == 'all missing optional imports behaved as expected' + + - name: Test heuristic_log_sanitize + test_heuristic_log_sanitize: + data: https://user:pass@example.org/ diff --git a/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 b/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 index 9644df9..625cb21 100644 --- a/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 +++ b/test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1 @@ -155,6 +155,7 @@ $tests = @{ "_ansible_shell_executable": "ignored", "_ansible_socket": "ignored", "_ansible_syslog_facility": "ignored", + "_ansible_target_log_info": "ignored", "_ansible_tmpdir": "$($m_tmpdir -replace "\\", "\\")", "_ansible_verbosity": 3, "_ansible_version": "2.8.0" @@ -2253,6 +2254,34 @@ test_no_log - Invoked with: $actual.invocation | Assert-DictionaryEqual -Expected @{module_args = $complex_args } } + "Unsupported options with ignore" = { + $spec = @{ + options = @{ + option_key = @{ + type = "str" + } + } + } + Set-Variable -Name complex_args -Scope Global -Value @{ + option_key = "abc" + invalid_key = "def" + another_key = "ghi" + _ansible_ignore_unknown_opts = $true + } + + $m = [Ansible.Basic.AnsibleModule]::Create(@(), $spec) + $m.Params | Assert-DictionaryEqual -Expected @{ option_key = "abc"; invalid_key = "def"; another_key = "ghi" } + try { + $m.ExitJson() + } + catch [System.Management.Automation.RuntimeException] { + $output = [Ansible.Basic.AnsibleModule]::FromJson($_.Exception.InnerException.Output) + } + $output.Keys.Count | Assert-Equal -Expected 2 + $output.changed | Assert-Equal -Expected $false + $output.invocation | Assert-DictionaryEqual -Expected @{module_args = @{option_key = "abc"; invalid_key = "def"; another_key = "ghi" } } + } + "Check mode and module doesn't support check mode" = { $spec = @{ options = @{ diff --git a/test/integration/targets/module_utils_ansible_release/library/ansible_release.py b/test/integration/targets/module_utils_ansible_release/library/ansible_release.py index 528465d..8e15b85 100644 --- a/test/integration/targets/module_utils_ansible_release/library/ansible_release.py +++ b/test/integration/targets/module_utils_ansible_release/library/ansible_release.py @@ -2,8 +2,7 @@ # Copyright: (c) 2021, 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 +from __future__ import annotations DOCUMENTATION = r''' --- diff --git a/test/integration/targets/module_utils_common.respawn/library/respawnme.py b/test/integration/targets/module_utils_common.respawn/library/respawnme.py index 6471dba..1dd1739 100644 --- a/test/integration/targets/module_utils_common.respawn/library/respawnme.py +++ b/test/integration/targets/module_utils_common.respawn/library/respawnme.py @@ -3,8 +3,7 @@ # Copyright: (c) 2021, 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 +from __future__ import annotations import os import sys diff --git a/test/integration/targets/module_utils_urls/library/test_peercert.py b/test/integration/targets/module_utils_urls/library/test_peercert.py index ecb7d20..7bac222 100644 --- a/test/integration/targets/module_utils_urls/library/test_peercert.py +++ b/test/integration/targets/module_utils_urls/library/test_peercert.py @@ -2,8 +2,7 @@ # Copyright: (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 +from __future__ import annotations DOCUMENTATION = r''' --- diff --git a/test/integration/targets/no_log/library/module.py b/test/integration/targets/no_log/library/module.py index d4f3c56..61c2908 100644 --- a/test/integration/targets/no_log/library/module.py +++ b/test/integration/targets/no_log/library/module.py @@ -3,8 +3,7 @@ # Copyright (c) 2019 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 +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule 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 index 23c7789..805cdba 100644 --- 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 @@ -1,8 +1,7 @@ # (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 +from __future__ import annotations DOCUMENTATION = ''' cache: configurable_redis diff --git a/test/integration/targets/old_style_cache_plugins/plugins/cache/legacy_redis.py b/test/integration/targets/old_style_cache_plugins/plugins/cache/legacy_redis.py index 9879dec..98bd188 100644 --- a/test/integration/targets/old_style_cache_plugins/plugins/cache/legacy_redis.py +++ b/test/integration/targets/old_style_cache_plugins/plugins/cache/legacy_redis.py @@ -1,8 +1,7 @@ # (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 +from __future__ import annotations DOCUMENTATION = ''' cache: redis diff --git a/test/integration/targets/old_style_cache_plugins/plugins/inventory/test.py b/test/integration/targets/old_style_cache_plugins/plugins/inventory/test.py index 7e59195..6dd450f 100644 --- a/test/integration/targets/old_style_cache_plugins/plugins/inventory/test.py +++ b/test/integration/targets/old_style_cache_plugins/plugins/inventory/test.py @@ -1,8 +1,7 @@ # Copyright (c) 2019 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 +from __future__ import annotations DOCUMENTATION = ''' name: test diff --git a/test/integration/targets/old_style_vars_plugins/deprecation_warning/v2_vars_plugin.py b/test/integration/targets/old_style_vars_plugins/deprecation_warning/v2_vars_plugin.py index f342b69..723e0a4 100644 --- a/test/integration/targets/old_style_vars_plugins/deprecation_warning/v2_vars_plugin.py +++ b/test/integration/targets/old_style_vars_plugins/deprecation_warning/v2_vars_plugin.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + class VarsModule: def get_host_vars(self, entity): return {} diff --git a/test/integration/targets/old_style_vars_plugins/deprecation_warning/vars.py b/test/integration/targets/old_style_vars_plugins/deprecation_warning/vars.py index f554be0..22fb451 100644 --- a/test/integration/targets/old_style_vars_plugins/deprecation_warning/vars.py +++ b/test/integration/targets/old_style_vars_plugins/deprecation_warning/vars.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.plugins.vars import BaseVarsPlugin diff --git a/test/integration/targets/old_style_vars_plugins/vars_plugins/auto_enabled.py b/test/integration/targets/old_style_vars_plugins/vars_plugins/auto_enabled.py index a91d94d..c933f56 100644 --- a/test/integration/targets/old_style_vars_plugins/vars_plugins/auto_enabled.py +++ b/test/integration/targets/old_style_vars_plugins/vars_plugins/auto_enabled.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.plugins.vars import BaseVarsPlugin diff --git a/test/integration/targets/old_style_vars_plugins/vars_plugins/implicitly_auto_enabled.py b/test/integration/targets/old_style_vars_plugins/vars_plugins/implicitly_auto_enabled.py index 4f407b4..5dff8ad 100644 --- a/test/integration/targets/old_style_vars_plugins/vars_plugins/implicitly_auto_enabled.py +++ b/test/integration/targets/old_style_vars_plugins/vars_plugins/implicitly_auto_enabled.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.plugins.vars import BaseVarsPlugin diff --git a/test/integration/targets/old_style_vars_plugins/vars_plugins/require_enabled.py b/test/integration/targets/old_style_vars_plugins/vars_plugins/require_enabled.py index a251447..302b6cc 100644 --- a/test/integration/targets/old_style_vars_plugins/vars_plugins/require_enabled.py +++ b/test/integration/targets/old_style_vars_plugins/vars_plugins/require_enabled.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.plugins.vars import BaseVarsPlugin diff --git a/test/integration/targets/omit/aliases b/test/integration/targets/omit/aliases index 1bff31c..fea0458 100644 --- a/test/integration/targets/omit/aliases +++ b/test/integration/targets/omit/aliases @@ -1,3 +1,4 @@ shippable/posix/group5 needs/target/setup_test_user context/controller +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/package/tasks/main.yml b/test/integration/targets/package/tasks/main.yml index 37267aa..119474a 100644 --- a/test/integration/targets/package/tasks/main.yml +++ b/test/integration/targets/package/tasks/main.yml @@ -149,17 +149,17 @@ when: ansible_distribution in package_distros ## -## yum +## dnf ## -#Validation for new parameter 'use' in yum action plugin which aliases to 'use_backend' +#Validation for new parameter 'use' in dnf 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: + dnf: name: at state: present - use_backend: yum - use: yum + use_backend: dnf + use: dnf ignore_errors: yes register: result @@ -170,7 +170,7 @@ - "not result is changed" - name: verify if package installation is successful using 'use' parameter - yum: + dnf: name: at state: present use: dnf @@ -182,7 +182,7 @@ - "result is changed" - name: remove at package - yum: + dnf: name: at state: absent use: dnf @@ -194,7 +194,7 @@ - "result is changed" - name: verify if package installation is successful using 'use_backend' parameter - yum: + dnf: name: at state: present use_backend: dnf @@ -206,7 +206,7 @@ - "result is changed" - name: remove at package - yum: + dnf: name: at state: absent use_backend: dnf @@ -218,7 +218,7 @@ - "result is changed" - name: verify if package installation is successful without using 'use_backend' and 'use' parameters - yum: + dnf: name: at state: present register: result @@ -229,7 +229,7 @@ - "result is changed" - name: remove at package - yum: + dnf: name: at state: absent register: result @@ -240,3 +240,19 @@ - "result is changed" when: ansible_distribution == "Fedora" + + +- name: test ansible_package_use + block: + - name: test with var + package: + name: doesnotmatter + vars: + ansible_package_use: lola + ignore_errors: true + register: use_to_use + + - assert: + that: + - use_to_use is failed + - "'Could not find a matching action' in use_to_use['msg']" diff --git a/test/integration/targets/packaging_cli-doc/verify.py b/test/integration/targets/packaging_cli-doc/verify.py index 7793fa8..7fe9d1d 100755 --- a/test/integration/targets/packaging_cli-doc/verify.py +++ b/test/integration/targets/packaging_cli-doc/verify.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import annotations import os import pathlib diff --git a/test/integration/targets/pause/test-pause.py b/test/integration/targets/pause/test-pause.py index ab771fa..1aebfbb 100755 --- a/test/integration/targets/pause/test-pause.py +++ b/test/integration/targets/pause/test-pause.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import os import pexpect diff --git a/test/integration/targets/pip/aliases b/test/integration/targets/pip/aliases index aa159d9..9ad637e 100644 --- a/test/integration/targets/pip/aliases +++ b/test/integration/targets/pip/aliases @@ -1,2 +1,3 @@ destructive shippable/posix/group2 +needs/root diff --git a/test/integration/targets/pip/files/ansible_test_pip_chdir/__init__.py b/test/integration/targets/pip/files/ansible_test_pip_chdir/__init__.py index 5d1f9ae..a039849 100644 --- a/test/integration/targets/pip/files/ansible_test_pip_chdir/__init__.py +++ b/test/integration/targets/pip/files/ansible_test_pip_chdir/__init__.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def main(): diff --git a/test/integration/targets/pip/files/sample-project/pyproject.toml b/test/integration/targets/pip/files/sample-project/pyproject.toml new file mode 100644 index 0000000..d1ea3b1 --- /dev/null +++ b/test/integration/targets/pip/files/sample-project/pyproject.toml @@ -0,0 +1,7 @@ +[project] +name = "sample-project" +version = "1.0.0" + +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" diff --git a/test/integration/targets/pip/files/sample-project/src/sample_project/__init__.py b/test/integration/targets/pip/files/sample-project/src/sample_project/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/integration/targets/pip/files/sample-project/src/sample_project/__init__.py diff --git a/test/integration/targets/pip/files/setup.py b/test/integration/targets/pip/files/setup.py index aaf2187..7d7240f 100755 --- a/test/integration/targets/pip/files/setup.py +++ b/test/integration/targets/pip/files/setup.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from setuptools import setup, find_packages diff --git a/test/integration/targets/pip/tasks/break_system_packages.yml b/test/integration/targets/pip/tasks/break_system_packages.yml new file mode 100644 index 0000000..3683720 --- /dev/null +++ b/test/integration/targets/pip/tasks/break_system_packages.yml @@ -0,0 +1,59 @@ +- name: Get the pip version + command: "{{ ansible_python_interpreter }} -c 'import pip; print(pip.__version__)'" + register: pip_version + +- when: pip_version.stdout is version("23.0.1", ">=") + block: + - name: Locate the Python externally-managed marker file + command: | + {{ ansible_python_interpreter }} -c 'import sys, sysconfig; print(f"""{sysconfig.get_path("stdlib", sysconfig.get_default_scheme() + if sys.version_info >= (3, 10) else sysconfig._get_default_scheme())}/EXTERNALLY-MANAGED""")' + register: externally_managed_marker + + - name: Detect if Python is externally-managed + stat: + path: "{{ externally_managed_marker.stdout }}" + register: externally_managed + + - name: Mark Python as externally managed + file: + path: "{{ externally_managed_marker.stdout }}" + state: touch + when: not externally_managed.stat.exists + + - block: + - name: Copy the sample project to the target + copy: + src: sample-project/ + dest: "{{ remote_sample_project }}" + + - name: Attempt to pip install the sample project without a venv + pip: + name: "{{ remote_sample_project }}" + register: pip_install + failed_when: pip_install is success + + - name: Attempt to pip install the sample project without a venv using break_system_packages + pip: + name: "{{ remote_sample_project }}" + break_system_packages: true + + - name: Remove the sample project without using break_system_packages + pip: + name: sample-project + state: absent + register: pip_uninstall + failed_when: pip_uninstall is success + + - name: Remove the sample project using break_system_packages + pip: + name: sample-project + state: absent + break_system_packages: true + + always: + - name: Unmark Python as externally managed + file: + path: "{{ externally_managed_marker.stdout }}" + state: absent + when: not externally_managed.stat.exists diff --git a/test/integration/targets/pip/tasks/main.yml b/test/integration/targets/pip/tasks/main.yml index a377070..b05b04f 100644 --- a/test/integration/targets/pip/tasks/main.yml +++ b/test/integration/targets/pip/tasks/main.yml @@ -1,6 +1,9 @@ # Current pip unconditionally uses md5. # We can re-enable if pip switches to a different hash or allows us to not check md5. +- include_tasks: + file: break_system_packages.yml + - name: Python 2 when: ansible_python.version.major == 2 block: diff --git a/test/integration/targets/pip/vars/main.yml b/test/integration/targets/pip/vars/main.yml index 2e87abc..34d481b 100644 --- a/test/integration/targets/pip/vars/main.yml +++ b/test/integration/targets/pip/vars/main.yml @@ -11,3 +11,4 @@ pip_test_pkg_ver_unsatisfied: pip_test_modules: - sample - jiphy +remote_sample_project: "{{ remote_tmp_dir }}/sample-project" diff --git a/test/integration/targets/pkg_resources/lookup_plugins/check_pkg_resources.py b/test/integration/targets/pkg_resources/lookup_plugins/check_pkg_resources.py index 44412f2..8f0b4b2 100644 --- a/test/integration/targets/pkg_resources/lookup_plugins/check_pkg_resources.py +++ b/test/integration/targets/pkg_resources/lookup_plugins/check_pkg_resources.py @@ -6,8 +6,7 @@ If pkg_resources is installed but is unable to function, this test will fail. One known failure case this test can detect is when ansible declares a __requires__ and then tests are run without an egg-info directory. """ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations # noinspection PyUnresolvedReferences try: diff --git a/test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py b/test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py index 62a91c8..771b418 100644 --- a/test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py +++ b/test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py @@ -3,8 +3,7 @@ # 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 __future__ import annotations from ansible.plugins.cache import BaseCacheModule diff --git a/test/integration/targets/plugin_config_for_inventory/test_inventory.py b/test/integration/targets/plugin_config_for_inventory/test_inventory.py index f937c03..ad39efc 100644 --- a/test/integration/targets/plugin_config_for_inventory/test_inventory.py +++ b/test/integration/targets/plugin_config_for_inventory/test_inventory.py @@ -1,6 +1,5 @@ -from __future__ import (absolute_import, division, print_function) +from __future__ import annotations -__metaclass__ = type DOCUMENTATION = ''' name: test_inventory diff --git a/test/integration/targets/plugin_loader/collections/ansible_collections/n/c/plugins/action/a.py b/test/integration/targets/plugin_loader/collections/ansible_collections/n/c/plugins/action/a.py index 685b159..19cf56d 100644 --- a/test/integration/targets/plugin_loader/collections/ansible_collections/n/c/plugins/action/a.py +++ b/test/integration/targets/plugin_loader/collections/ansible_collections/n/c/plugins/action/a.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/plugin_loader/normal/action_plugins/self_referential.py b/test/integration/targets/plugin_loader/normal/action_plugins/self_referential.py index b4c8957..33905f8 100644 --- a/test/integration/targets/plugin_loader/normal/action_plugins/self_referential.py +++ b/test/integration/targets/plugin_loader/normal/action_plugins/self_referential.py @@ -1,7 +1,6 @@ # Copyright: Contributors to the 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 +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/plugin_loader/normal/library/_underscore.py b/test/integration/targets/plugin_loader/normal/library/_underscore.py index 7a416a6..d770577 100644 --- a/test/integration/targets/plugin_loader/normal/library/_underscore.py +++ b/test/integration/targets/plugin_loader/normal/library/_underscore.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/integration/targets/plugin_loader/override/filter_plugins/core.py b/test/integration/targets/plugin_loader/override/filter_plugins/core.py index f283dc3..8924637 100644 --- a/test/integration/targets/plugin_loader/override/filter_plugins/core.py +++ b/test/integration/targets/plugin_loader/override/filter_plugins/core.py @@ -1,6 +1,4 @@ -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def do_flag(myval): diff --git a/test/integration/targets/plugin_loader/runme.sh b/test/integration/targets/plugin_loader/runme.sh index e68f06a..a313778 100755 --- a/test/integration/targets/plugin_loader/runme.sh +++ b/test/integration/targets/plugin_loader/runme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -ux +set -eux cleanup() { unlink normal/library/_symlink.py diff --git a/test/integration/targets/plugin_namespace/filter_plugins/test_filter.py b/test/integration/targets/plugin_namespace/filter_plugins/test_filter.py index dca094b..aea1bba 100644 --- a/test/integration/targets/plugin_namespace/filter_plugins/test_filter.py +++ b/test/integration/targets/plugin_namespace/filter_plugins/test_filter.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def filter_name(a): diff --git a/test/integration/targets/plugin_namespace/lookup_plugins/lookup_name.py b/test/integration/targets/plugin_namespace/lookup_plugins/lookup_name.py index d0af703..4a8d042 100644 --- a/test/integration/targets/plugin_namespace/lookup_plugins/lookup_name.py +++ b/test/integration/targets/plugin_namespace/lookup_plugins/lookup_name.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.plugins.lookup import LookupBase diff --git a/test/integration/targets/plugin_namespace/test_plugins/test_test.py b/test/integration/targets/plugin_namespace/test_plugins/test_test.py index 2a9d6ee..fd949e4 100644 --- a/test/integration/targets/plugin_namespace/test_plugins/test_test.py +++ b/test/integration/targets/plugin_namespace/test_plugins/test_test.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import re diff --git a/test/integration/targets/prepare_http_tests/files/openssl_legacy.cnf b/test/integration/targets/prepare_http_tests/files/openssl_legacy.cnf new file mode 100644 index 0000000..adfa225 --- /dev/null +++ b/test/integration/targets/prepare_http_tests/files/openssl_legacy.cnf @@ -0,0 +1,14 @@ +openssl_conf = openssl_init + +[openssl_init] +providers = provider_sect + +[provider_sect] +default = default_sect +legacy = legacy_sect + +[default_sect] +activate = 1 + +[legacy_sect] +activate = 1 diff --git a/test/integration/targets/prepare_http_tests/library/httptester_kinit.py b/test/integration/targets/prepare_http_tests/library/httptester_kinit.py index 4f7b7ad..a84e3fb 100644 --- a/test/integration/targets/prepare_http_tests/library/httptester_kinit.py +++ b/test/integration/targets/prepare_http_tests/library/httptester_kinit.py @@ -2,8 +2,7 @@ # Copyright: (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 +from __future__ import annotations DOCUMENTATION = r''' --- diff --git a/test/integration/targets/prepare_http_tests/tasks/kerberos.yml b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml index 2678b46..4b3d488 100644 --- a/test/integration/targets/prepare_http_tests/tasks/kerberos.yml +++ b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml @@ -2,6 +2,17 @@ krb5_config: '{{ remote_tmp_dir }}/krb5.conf' krb5_realm: '{{ httpbin_host.split(".")[1:] | join(".") | upper }}' krb5_provider: '{{ (ansible_facts.os_family == "FreeBSD" or ansible_facts.distribution == "MacOSX") | ternary("Heimdal", "MIT") }}' + # FreeBSD needs to enable the OpenSSL legacy providers for RC4 support. + # While RC4 isn't used Heimdal is currently requiring it as part of a + # runtime test, until that is removed we need this hack. + # https://github.com/heimdal/heimdal/issues/1224 + krb5_openssl_conf: >- + {{ + (ansible_facts.os_family == "FreeBSD" and ansible_facts.distribution_major_version == "14") | ternary( + remote_tmp_dir ~ "/openssl_legacy.cnf", + "" + ) + }} - set_fact: krb5_username: admin@{{ krb5_realm }} @@ -11,6 +22,12 @@ src: krb5.conf.j2 dest: '{{ krb5_config }}' +- name: Create openssl.cnf to enable Legacy providers + copy: + src: openssl_legacy.cnf + dest: '{{ krb5_openssl_conf }}' + when: krb5_openssl_conf | default(False, True) + - name: Include distribution specific variables include_vars: '{{ lookup("first_found", params) }}' vars: @@ -37,11 +54,7 @@ - name: Install python gssapi pip: - name: - - 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' + name: gssapi state: present extra_args: '-c {{ remote_constraints }}' environment: @@ -58,6 +71,7 @@ environment: KRB5_CONFIG: '{{ krb5_config }}' KRB5CCNAME: FILE:{{ remote_tmp_dir }}/krb5.cc + OPENSSL_CONF: '{{ krb5_openssl_conf }}' - name: remove test credential cache file: diff --git a/test/integration/targets/rel_plugin_loading/subdir/inventory_plugins/notyaml.py b/test/integration/targets/rel_plugin_loading/subdir/inventory_plugins/notyaml.py index 41a76d9..4242e2e 100644 --- a/test/integration/targets/rel_plugin_loading/subdir/inventory_plugins/notyaml.py +++ b/test/integration/targets/rel_plugin_loading/subdir/inventory_plugins/notyaml.py @@ -1,8 +1,7 @@ # Copyright (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 +from __future__ import annotations DOCUMENTATION = ''' inventory: yaml @@ -16,7 +15,7 @@ DOCUMENTATION = ''' - File MUST have a valid extension, defined in configuration. notes: - If you want to set vars for the C(all) group inside the inventory file, the C(all) group must be the first entry in the file. - - Whitelisted in configuration by default. + - Enabled in configuration by default. options: yaml_extensions: description: list of 'valid' extensions for files containing YAML @@ -94,7 +93,7 @@ class InventoryModule(BaseFileInventoryPlugin): self.set_options() try: - data = self.loader.load_from_file(path, cache=False) + data = self.loader.load_from_file(path, cache='none') except Exception as e: raise AnsibleParserError(e) diff --git a/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py b/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py index e8d712a..c55cfc3 100644 --- a/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py +++ b/test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py @@ -2,8 +2,7 @@ # Copyright: Contributors to the 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 +from __future__ import annotations from ansible.plugins.action import ActionBase from jinja2 import Undefined diff --git a/test/integration/targets/roles/no_outside_import.yml b/test/integration/targets/roles/no_outside_import.yml new file mode 100644 index 0000000..c9e0d13 --- /dev/null +++ b/test/integration/targets/roles/no_outside_import.yml @@ -0,0 +1,6 @@ +- hosts: testhost + gather_facts: false + tasks: + - import_role: + name: a + tasks_from: subdir/../../../../no_outside.yml diff --git a/test/integration/targets/roles/privacy.yml b/test/integration/targets/roles/privacy.yml index 2f671c0..60d5198 100644 --- a/test/integration/targets/roles/privacy.yml +++ b/test/integration/targets/roles/privacy.yml @@ -27,6 +27,28 @@ - not is_default or is_default and privacy is defined - hosts: localhost + name: test public no always overrides global on import_role + gather_facts: false + tasks: + - import_role: name=a public=no + + - name: role is private, var should be undefined + assert: + that: + - privacy is undefined + +- hosts: localhost + name: test public yes always overrides global on import_role + gather_facts: false + tasks: + - import_role: name=a public=yes + + - name: role is private, var should be undefined + assert: + that: + - privacy is defined + +- hosts: localhost name: test global privacy setting on includes gather_facts: false tasks: diff --git a/test/integration/targets/roles/roles/a/tasks/subdir/entrypoint.yml b/test/integration/targets/roles/roles/a/tasks/subdir/entrypoint.yml new file mode 100644 index 0000000..331ec94 --- /dev/null +++ b/test/integration/targets/roles/roles/a/tasks/subdir/entrypoint.yml @@ -0,0 +1 @@ +- debug: msg=subdir diff --git a/test/integration/targets/roles/runme.sh b/test/integration/targets/roles/runme.sh index bf3aaf5..5227e42 100755 --- a/test/integration/targets/roles/runme.sh +++ b/test/integration/targets/roles/runme.sh @@ -26,13 +26,19 @@ ansible-playbook role_complete.yml -i ../../inventory -i fake, --tags unreachabl ansible-playbook data_integrity.yml -i ../../inventory "$@" # ensure role fails when trying to load 'non role' in _from -ansible-playbook no_outside.yml -i ../../inventory > role_outside_output.log 2>&1 || true -if grep "as it is not inside the expected role path" role_outside_output.log >/dev/null; then - echo "Test passed (playbook failed with expected output, output not shown)." -else - echo "Test failed, expected output from playbook failure is missing, output not shown)." - exit 1 -fi +test_no_outside=("no_outside.yml" "no_outside_import.yml") +for file in "${test_no_outside[@]}"; do + ansible-playbook "$file" -i ../../inventory > "${file}_output.log" 2>&1 || true + if grep "as it is not inside the expected role path" "${file}_output.log" >/dev/null; then + echo "Test passed for $file (playbook failed with expected output, output not shown)." + else + echo "Test failed for $file, expected output from playbook failure is missing, output not shown)." + exit 1 + fi +done + +# ensure subdir contained to role in tasks_from is valid +ansible-playbook test_subdirs.yml -i ../../inventory "$@" # ensure vars scope is correct ansible-playbook vars_scope.yml -i ../../inventory "$@" diff --git a/test/integration/targets/roles/test_subdirs.yml b/test/integration/targets/roles/test_subdirs.yml new file mode 100644 index 0000000..503239d --- /dev/null +++ b/test/integration/targets/roles/test_subdirs.yml @@ -0,0 +1,10 @@ +--- +- hosts: testhost + gather_facts: false + tasks: + - import_role: + name: a + tasks_from: subdir/entrypoint.yml + - include_role: + name: a + tasks_from: subdir/entrypoint.yml diff --git a/test/integration/targets/run_modules/library/test.py b/test/integration/targets/run_modules/library/test.py index 15a92e9..fed83ec 100644 --- a/test/integration/targets/run_modules/library/test.py +++ b/test/integration/targets/run_modules/library/test.py @@ -1,7 +1,6 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/script/files/no_shebang.py b/test/integration/targets/script/files/no_shebang.py index f2d386a..7a2e3e6 100644 --- a/test/integration/targets/script/files/no_shebang.py +++ b/test/integration/targets/script/files/no_shebang.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import sys diff --git a/test/integration/targets/script/tasks/main.yml b/test/integration/targets/script/tasks/main.yml index 668ec48..d6f77fd 100644 --- a/test/integration/targets/script/tasks/main.yml +++ b/test/integration/targets/script/tasks/main.yml @@ -162,7 +162,7 @@ assert: that: - script_result3 is failed - - script_result3.msg == "async is not supported for this task." + - script_result3.msg == "This action (script) does not support async." # check mode diff --git a/test/integration/targets/service/files/ansible_test_service.py b/test/integration/targets/service/files/ansible_test_service.py index 6292272..6bf404c 100644 --- a/test/integration/targets/service/files/ansible_test_service.py +++ b/test/integration/targets/service/files/ansible_test_service.py @@ -3,8 +3,7 @@ # this is mostly based off of the code found here: # http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import os import resource diff --git a/test/integration/targets/service/tasks/main.yml b/test/integration/targets/service/tasks/main.yml index 4fc2ddf..7a4ecda 100644 --- a/test/integration/targets/service/tasks/main.yml +++ b/test/integration/targets/service/tasks/main.yml @@ -46,7 +46,7 @@ msg: 'ansible_service_mgr: {{ ansible_service_mgr }}' - name: setup test service script - include_tasks: '{{ service_type }}_setup.yml' + include_tasks: '{{ service_type }}_setup.yml' - name: execute tests import_tasks: tests.yml diff --git a/test/integration/targets/service/tasks/upstart_cleanup.yml b/test/integration/targets/service/tasks/upstart_cleanup.yml index 683fb10..fa418fe 100644 --- a/test/integration/targets/service/tasks/upstart_cleanup.yml +++ b/test/integration/targets/service/tasks/upstart_cleanup.yml @@ -11,7 +11,7 @@ loop: '{{ upstart_files }}' - name: assert that upstart init files were removed - raw: 'test -e {{ item }}' + raw: 'test -e {{ item }}' loop: '{{ upstart_files }}' register: file_exists failed_when: file_exists is not failed diff --git a/test/integration/targets/service_facts/files/ansible_test_service.py b/test/integration/targets/service_facts/files/ansible_test_service.py index 19f1e29..6bf404c 100644 --- a/test/integration/targets/service_facts/files/ansible_test_service.py +++ b/test/integration/targets/service_facts/files/ansible_test_service.py @@ -3,8 +3,7 @@ # this is mostly based off of the code found here: # http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations import os import resource diff --git a/test/integration/targets/set_fact/runme.sh b/test/integration/targets/set_fact/runme.sh index 9309359..7fd548c 100755 --- a/test/integration/targets/set_fact/runme.sh +++ b/test/integration/targets/set_fact/runme.sh @@ -34,3 +34,6 @@ 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 + +ansible-playbook -i inventory "$@" set_fact_ansible_vars.yml 2>&1 | tee test_set_fact_ansible_vars.out +test "$(grep -E -c 'is reserved for internal use only.' test_set_fact_ansible_vars.out)" = 1 diff --git a/test/integration/targets/set_fact/set_fact_ansible_vars.yml b/test/integration/targets/set_fact/set_fact_ansible_vars.yml new file mode 100644 index 0000000..53ed535 --- /dev/null +++ b/test/integration/targets/set_fact/set_fact_ansible_vars.yml @@ -0,0 +1,9 @@ +- name: Test set_fact with key starting with reserved keyword '_ansible_' + hosts: testhost + gather_facts: no + tasks: + - name: Define fact with key starting with reserved keyword '_ansible_' + set_fact: + _ansible_foo: bar + ignore_errors: yes + register: r diff --git a/test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0 b/test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0 new file mode 100644 index 0000000..1e5d0a4 --- /dev/null +++ b/test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0 @@ -0,0 +1,11 @@ +Section: misc +Priority: optional +Standards-Version: 2.3.3 + +Package: baz +Version: 1.0.0 +Section: system +Maintainer: John Doe <john@doe.com> +Architecture: all +Description: Dummy package +Recommends: rolldice diff --git a/test/integration/targets/setup_epel/tasks/main.yml b/test/integration/targets/setup_epel/tasks/main.yml deleted file mode 100644 index a8593bb..0000000 --- a/test/integration/targets/setup_epel/tasks/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -- name: Enable RHEL7 extras - # EPEL 7 depends on RHEL 7 extras, which is not enabled by default on RHEL. - # See: https://docs.fedoraproject.org/en-US/epel/epel-policy/#_policy - command: yum-config-manager --enable rhel-7-server-rhui-extras-rpms - when: ansible_facts.distribution == 'RedHat' and ansible_facts.distribution_major_version == '7' -- name: Install EPEL - yum: - name: https://ci-files.testing.ansible.com/test/integration/targets/setup_epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm - disable_gpg_check: true - when: ansible_facts.distribution in ['RedHat', 'CentOS'] diff --git a/test/integration/targets/setup_paramiko/constraints.txt b/test/integration/targets/setup_paramiko/constraints.txt index c502ba0..e69de29 100644 --- a/test/integration/targets/setup_paramiko/constraints.txt +++ b/test/integration/targets/setup_paramiko/constraints.txt @@ -1 +0,0 @@ -cryptography >= 2.5, < 3.4 diff --git a/test/integration/targets/setup_paramiko/library/detect_paramiko.py b/test/integration/targets/setup_paramiko/library/detect_paramiko.py index e3a8158..15905b8 100644 --- a/test/integration/targets/setup_paramiko/library/detect_paramiko.py +++ b/test/integration/targets/setup_paramiko/library/detect_paramiko.py @@ -1,9 +1,8 @@ #!/usr/bin/python """Ansible module to detect the presence of both the normal and Ansible-specific versions of Paramiko.""" -from __future__ import absolute_import, division, print_function +from __future__ import annotations -__metaclass__ = type from ansible.module_utils.basic import AnsibleModule diff --git a/test/integration/targets/setup_passlib_controller/runme.sh b/test/integration/targets/setup_passlib_controller/runme.sh new file mode 100755 index 0000000..c9f13e7 --- /dev/null +++ b/test/integration/targets/setup_passlib_controller/runme.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -eux + +# Temporary hack for PEP 668 on newer systems. +# Remove once ansible-test can provide targets their own virtual environment. +# Tests which can manage their own virtual environment should not use this approach. +export PIP_BREAK_SYSTEM_PACKAGES=1 + +# Requirements have to be installed prior to running ansible-playbook +# because plugins and requirements are loaded before the task runs +python -m pip install passlib diff --git a/test/integration/targets/setup_pexpect/files/constraints.txt b/test/integration/targets/setup_pexpect/files/constraints.txt index c78ecda..930ee5c 100644 --- a/test/integration/targets/setup_pexpect/files/constraints.txt +++ b/test/integration/targets/setup_pexpect/files/constraints.txt @@ -1,2 +1 @@ pexpect == 4.8.0 -ptyprocess < 0.7.0 ; python_version < '2.7' # ptyprocess >= 0.7.0 not compatible with Python 2.6 diff --git a/test/integration/targets/setup_rpm_repo/aliases b/test/integration/targets/setup_rpm_repo/aliases deleted file mode 100644 index 65e8315..0000000 --- a/test/integration/targets/setup_rpm_repo/aliases +++ /dev/null @@ -1 +0,0 @@ -needs/target/setup_epel diff --git a/test/integration/targets/setup_rpm_repo/library/create_repo.py b/test/integration/targets/setup_rpm_repo/library/create_repo.py index e6a61ba..7424ea5 100644 --- a/test/integration/targets/setup_rpm_repo/library/create_repo.py +++ b/test/integration/targets/setup_rpm_repo/library/create_repo.py @@ -1,10 +1,7 @@ #!/usr/bin/python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations -import subprocess -import sys import tempfile from collections import namedtuple @@ -15,10 +12,12 @@ from ansible.module_utils.common.respawn import has_respawned, probe_interpreter HAS_RPMFLUFF = True can_use_rpm_weak_deps = None try: - from rpmfluff import SimpleRpmBuild + from rpmfluff import SimpleRpmBuild, GeneratedSourceFile, make_gif from rpmfluff import YumRepoBuild except ImportError: try: + from rpmfluff.make import make_gif + from rpmfluff.sourcefile import GeneratedSourceFile from rpmfluff.rpmbuild import SimpleRpmBuild from rpmfluff.yumrepobuild import YumRepoBuild except ImportError: @@ -35,20 +34,25 @@ if HAS_RPMFLUFF: pass -RPM = namedtuple('RPM', ['name', 'version', 'release', 'epoch', 'recommends', 'arch']) - +RPM = namedtuple('RPM', ['name', 'version', 'release', 'epoch', 'recommends', 'file', 'arch']) SPECS = [ - RPM('dinginessentail', '1.0', '1', None, None, None), - RPM('dinginessentail', '1.0', '2', '1', None, None), - RPM('dinginessentail', '1.1', '1', '1', None, None), - RPM('dinginessentail-olive', '1.0', '1', None, None, None), - RPM('dinginessentail-olive', '1.1', '1', None, None, None), - RPM('landsidescalping', '1.0', '1', None, None, None), - RPM('landsidescalping', '1.1', '1', None, None, None), - RPM('dinginessentail-with-weak-dep', '1.0', '1', None, ['dinginessentail-weak-dep'], None), - RPM('dinginessentail-weak-dep', '1.0', '1', None, None, None), - RPM('noarchfake', '1.0', '1', None, None, 'noarch'), + RPM('dinginessentail', '1.0', '1', None, None, None, None), + RPM('dinginessentail', '1.0', '2', '1', None, None, None), + RPM('dinginessentail', '1.1', '1', '1', None, None, None), + RPM('dinginessentail-olive', '1.0', '1', None, None, None, None), + RPM('dinginessentail-olive', '1.1', '1', None, None, None, None), + RPM('landsidescalping', '1.0', '1', None, None, None, None), + RPM('landsidescalping', '1.1', '1', None, None, None, None), + RPM('dinginessentail-with-weak-dep', '1.0', '1', None, ['dinginessentail-weak-dep'], None, None), + RPM('dinginessentail-weak-dep', '1.0', '1', None, None, None, None), + RPM('noarchfake', '1.0', '1', None, None, None, 'noarch'), + RPM('provides_foo_a', '1.0', '1', None, None, 'foo.gif', 'noarch'), + RPM('provides_foo_b', '1.0', '1', None, None, 'foo.gif', 'noarch'), + RPM('number-11-name', '11.0', '1', None, None, None, None), + RPM('number-11-name', '11.1', '1', None, None, None, None), + RPM('epochone', '1.0', '1', '1', None, None, "noarch"), + RPM('epochone', '1.1', '1', '1', None, None, "noarch"), ] @@ -66,21 +70,18 @@ def create_repo(arch='x86_64'): for recommend in spec.recommends: pkg.add_recommends(recommend) - pkgs.append(pkg) - - # HACK: EPEL6 version of rpmfluff can't do multi-arch packaging, so we'll just build separately and copy - # the noarch stuff in, since we don't currently care about the repodata for noarch - if sys.version_info[0:2] == (2, 6): - noarch_repo = YumRepoBuild([p for p in pkgs if 'noarch' in p.get_build_archs()]) - noarch_repo.make('noarch') + if spec.file: + pkg.add_installed_file( + "/" + spec.file, + GeneratedSourceFile( + spec.file, make_gif() + ) + ) - repo = YumRepoBuild([p for p in pkgs if arch in p.get_build_archs()]) - repo.make(arch) + pkgs.append(pkg) - subprocess.call("cp {0}/*.rpm {1}".format(noarch_repo.repoDir, repo.repoDir), shell=True) - else: - repo = YumRepoBuild(pkgs) - repo.make(arch, 'noarch') + repo = YumRepoBuild(pkgs) + repo.make(arch, 'noarch') for pkg in pkgs: pkg.clean() diff --git a/test/integration/targets/setup_rpm_repo/tasks/main.yml b/test/integration/targets/setup_rpm_repo/tasks/main.yml index bf5af10..8104190 100644 --- a/test/integration/targets/setup_rpm_repo/tasks/main.yml +++ b/test/integration/targets/setup_rpm_repo/tasks/main.yml @@ -1,11 +1,4 @@ - block: - - name: Install epel repo which is missing on rhel-7 and is needed for rpmfluff - include_role: - name: setup_epel - when: - - ansible_distribution in ['RedHat', 'CentOS'] - - ansible_distribution_major_version is version('7', '==') - - name: Include distribution specific variables include_vars: "{{ lookup('first_found', params) }}" vars: diff --git a/test/integration/targets/shell/action_plugins/test_shell.py b/test/integration/targets/shell/action_plugins/test_shell.py index 6e66ed0..17fa4d9 100644 --- a/test/integration/targets/shell/action_plugins/test_shell.py +++ b/test/integration/targets/shell/action_plugins/test_shell.py @@ -3,9 +3,7 @@ # Copyright (c) 2019 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 +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/shell/connection_plugins/test_connection_default.py b/test/integration/targets/shell/connection_plugins/test_connection_default.py index 60feedd..6f13102 100644 --- a/test/integration/targets/shell/connection_plugins/test_connection_default.py +++ b/test/integration/targets/shell/connection_plugins/test_connection_default.py @@ -1,8 +1,7 @@ # Copyright (c) 2019 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 +from __future__ import annotations DOCUMENTATION = ''' connection: test_connection_default diff --git a/test/integration/targets/shell/connection_plugins/test_connection_override.py b/test/integration/targets/shell/connection_plugins/test_connection_override.py index d26d2b5..b962dfa 100644 --- a/test/integration/targets/shell/connection_plugins/test_connection_override.py +++ b/test/integration/targets/shell/connection_plugins/test_connection_override.py @@ -1,8 +1,7 @@ # Copyright (c) 2019 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 +from __future__ import annotations DOCUMENTATION = ''' connection: test_connection_override diff --git a/test/integration/targets/slurp/aliases b/test/integration/targets/slurp/aliases index 6eae8bd..069c660 100644 --- a/test/integration/targets/slurp/aliases +++ b/test/integration/targets/slurp/aliases @@ -1,2 +1,3 @@ shippable/posix/group1 destructive +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/subversion/roles/subversion/defaults/main.yml b/test/integration/targets/subversion/roles/subversion/defaults/main.yml index 02ecd1e..5feda8c 100644 --- a/test/integration/targets/subversion/roles/subversion/defaults/main.yml +++ b/test/integration/targets/subversion/roles/subversion/defaults/main.yml @@ -3,7 +3,9 @@ apache_port: 11386 # cannot use 80 as httptester overrides this 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: https://localhost:{{ apache_port }}/svn/{{ subversion_repo_name }} # svn can't verify TLS certificates against IP addresses -subversion_repo_auth_url: https://localhost:{{ apache_port }}/svnauth/{{ subversion_repo_name }} +# default to explicit IPv4; svn doesn't handle IPv4 fallback if eg "localhost" -> [::1, 127.0.0.1] and ::1 doesn't answer +subversion_repo_ip: 127.0.0.1 +subversion_repo_url: https://{{ subversion_repo_ip }}:{{ apache_port }}/svn/{{ subversion_repo_name }} +subversion_repo_auth_url: https://{{ subversion_repo_ip }}:{{ apache_port }}/svnauth/{{ subversion_repo_name }} subversion_username: subsvn_user''' subversion_password: Password123! diff --git a/test/integration/targets/subversion/roles/subversion/tasks/setup.yml b/test/integration/targets/subversion/roles/subversion/tasks/setup.yml index 880c295..52729d5 100644 --- a/test/integration/targets/subversion/roles/subversion/tasks/setup.yml +++ b/test/integration/targets/subversion/roles/subversion/tasks/setup.yml @@ -29,10 +29,6 @@ path: '{{ subversion_server_dir }}' state: directory -- name: setup selinux when enabled - include_tasks: setup_selinux.yml - when: ansible_selinux.status == "enabled" - - name: Generate CA and TLS certificates via trustme vars: venv_path: >- @@ -42,21 +38,8 @@ block: - name: trustme -- provision a venv command: >- - {{ ansible_python_interpreter }} - -{% if ansible_python.version.major != 2 %}I{% endif %}m - {% if ansible_python.version.major != 2 %}venv{% - else %}virtualenv{% endif %} - + {{ ansible_python_interpreter }} -Im venv {{ venv_path }} - - name: trustme -- upgrade pip in venv | RHEL 7.9 & 8.8+py36 - when: >- # these don't know how to notice `cryptography` wheels - ansible_distribution == 'RedHat' - and ansible_distribution_major_version | int < 9 - pip: - name: pip - state: latest - virtualenv: >- - {{ venv_path }} - name: trustme -- install tool pip: name: trustme @@ -67,18 +50,18 @@ argv: - >- {{ venv_python }} - - -{%- if ansible_python.version.major != 2 -%}I{%- endif -%}m + - -Im - trustme - --dir={{ subversion_server_dir }} + - --identities={{ subversion_repo_ip }} + - --common-name={{ subversion_repo_ip }} - name: symlink trustme certificates into apache config dir - Red Hat when: ansible_os_family in ['RedHat'] - # when: ansible_distribution in ['Fedora', 'RedHat'] file: src: /tmp/ansible-svn/server.{{ item.trustme_filetype }} dest: /etc/pki/tls/{{ item.apache_target_path }} state: link - force: yes # Othewise Apache on CentOS 7 uses its own fake certificate loop: - apache_target_path: certs/localhost.crt trustme_filetype: pem diff --git a/test/integration/targets/subversion/roles/subversion/tasks/setup_selinux.yml b/test/integration/targets/subversion/roles/subversion/tasks/setup_selinux.yml deleted file mode 100644 index a9ffa71..0000000 --- a/test/integration/targets/subversion/roles/subversion/tasks/setup_selinux.yml +++ /dev/null @@ -1,11 +0,0 @@ -- name: set SELinux security context for SVN folder - sefcontext: - target: '{{ subversion_server_dir }}(/.*)?' - setype: '{{ item }}' - state: present - with_items: - - httpd_sys_content_t - - httpd_sys_rw_content_t - -- name: apply new SELinux context to filesystem - command: restorecon -irv {{ subversion_server_dir | quote }} diff --git a/test/integration/targets/subversion/roles/subversion/templates/subversion.conf.j2 b/test/integration/targets/subversion/roles/subversion/templates/subversion.conf.j2 index 133c70c..74d7cc1 100644 --- a/test/integration/targets/subversion/roles/subversion/templates/subversion.conf.j2 +++ b/test/integration/targets/subversion/roles/subversion/templates/subversion.conf.j2 @@ -39,6 +39,7 @@ LoadModule dav_svn_module libexec/apache24/mod_dav_svn.so LoadModule authz_svn_module libexec/apache24/mod_authz_svn.so {% elif ansible_os_family == "Suse" %} Include /etc/apache2/httpd.conf +Include mods-available/ssl.load LoadModule dav_module /usr/lib64/apache2/mod_dav.so LoadModule dav_svn_module /usr/lib64/apache2/mod_dav_svn.so {% elif ansible_os_family == "Alpine" %} @@ -50,10 +51,7 @@ Include /etc/httpd/conf/httpd.conf {% endif %} PidFile {{ subversion_server_dir }}/apache.pid -Listen 127.0.0.1:{{ apache_port }} https -{% if ansible_distribution not in ["Alpine", "CentOS", "Fedora", "openSUSE Leap", "Ubuntu"] %} -Listen [::1]:{{ apache_port }} https -{% endif %} +Listen {{ subversion_repo_ip }}:{{ apache_port }} https SSLEngine on SSLCertificateFile {{ subversion_server_dir }}/server.pem SSLCertificateKeyFile {{ subversion_server_dir }}/server.key diff --git a/test/integration/targets/support-callback_plugins/callback_plugins/callback_debug.py b/test/integration/targets/support-callback_plugins/callback_plugins/callback_debug.py index 2462c1f..7d7df62 100644 --- a/test/integration/targets/support-callback_plugins/callback_plugins/callback_debug.py +++ b/test/integration/targets/support-callback_plugins/callback_plugins/callback_debug.py @@ -1,8 +1,9 @@ # (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 +from __future__ import annotations + +import functools from ansible.plugins.callback import CallbackBase @@ -16,9 +17,8 @@ class CallbackModule(CallbackBase): super(CallbackModule, self).__init__(*args, **kwargs) self._display.display('__init__') - for cb in [x for x in dir(CallbackBase) if x.startswith('v2_')]: - delattr(CallbackBase, cb) + for name in (cb for cb in dir(self) if cb.startswith('v2_')): + setattr(self, name, functools.partial(self.handle_v2, name)) - def __getattr__(self, name): - if name.startswith('v2_'): - return lambda *args, **kwargs: self._display.display(name) + def handle_v2(self, name, *args, **kwargs): + self._display.display(name) diff --git a/test/integration/targets/template/ansible_managed.yml b/test/integration/targets/template/ansible_managed.yml index 2bd7c2c..a94e57e 100644 --- a/test/integration/targets/template/ansible_managed.yml +++ b/test/integration/targets/template/ansible_managed.yml @@ -2,13 +2,51 @@ - hosts: testhost gather_facts: False tasks: - - set_fact: + - name: set output_dir + set_fact: output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}" - - file: - path: '{{ output_dir }}/café.txt' - state: 'absent' - # Smoketest that ansible_managed with non-ascii chars works: - # https://github.com/ansible/ansible/issues/27262 - - template: - src: 'templates/café.j2' - dest: '{{ output_dir }}/café.txt' + tags: ['always'] + + - name: Smoketest that ansible_managed with non-ascii chars works, https://github.com/ansible/ansible/issues/27262 + tags: ['27262'] + block: + - name: ensure output file does not exist + file: + path: '{{ output_dir }}/café.txt' + state: 'absent' + + - name: test templating with unicode in template name + template: + src: 'templates/café.j2' + dest: '{{ output_dir }}/café.txt' + + always: + - name: clean up! + file: + path: '{{ output_dir }}/café.txt' + state: 'absent' + + - name: check strftime resolution in ansible_managed, https://github.com/ansible/ansible/pull/79129 + tags: ['79129'] + block: + - template: + src: "templates/%necho Onii-chan help Im stuck;exit 1%n.j2" + dest: "{{ output_dir }}/strftime.sh" + mode: '0755' + + - shell: "exec {{ output_dir | quote }}/strftime.sh" + + - name: Avoid templating 'injections' via file names + template: + src: !unsafe "templates/completely{{ 1 % 0 }} safe template.j2" + dest: "{{ output_dir }}/jinja.sh" + mode: '0755' + + - shell: "exec {{ output_dir | quote }}/jinja.sh" + register: result + + - assert: + that: + - "'Hello' in result.stdout" + - "'uname' not in lookup('file', output_dir ~ '/strftime.sh')" + - "'uname' not in lookup('file', output_dir ~ '/jinja.sh')" diff --git a/test/integration/targets/template/ansible_managed_79129.yml b/test/integration/targets/template/ansible_managed_79129.yml deleted file mode 100644 index e00ada8..0000000 --- a/test/integration/targets/template/ansible_managed_79129.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -- hosts: testhost - gather_facts: false - tasks: - - set_fact: - output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}" - - - name: check strftime - block: - - template: - src: "templates/%necho Onii-chan help Im stuck;exit 1%n.j2" - dest: "{{ output_dir }}/79129-strftime.sh" - mode: '0755' - - - shell: "exec {{ output_dir | quote }}/79129-strftime.sh" - - - name: check jinja template - block: - - template: - src: !unsafe "templates/completely{{ 1 % 0 }} safe template.j2" - dest: "{{ output_dir }}/79129-jinja.sh" - mode: '0755' - - - shell: "exec {{ output_dir | quote }}/79129-jinja.sh" - register: result - - - assert: - that: - - "'Hello' in result.stdout" diff --git a/test/integration/targets/template/ansible_managed_templated.cfg b/test/integration/targets/template/ansible_managed_templated.cfg new file mode 100644 index 0000000..4840045 --- /dev/null +++ b/test/integration/targets/template/ansible_managed_templated.cfg @@ -0,0 +1,2 @@ +[defaults] +ansible_managed=ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}({{{{q('pipe', 'uname -a')}}}}) diff --git a/test/integration/targets/template/role_filter/filter_plugins/myplugin.py b/test/integration/targets/template/role_filter/filter_plugins/myplugin.py index b0a8889..6043fdf 100644 --- a/test/integration/targets/template/role_filter/filter_plugins/myplugin.py +++ b/test/integration/targets/template/role_filter/filter_plugins/myplugin.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations class FilterModule(object): diff --git a/test/integration/targets/template/runme.sh b/test/integration/targets/template/runme.sh index d3913d9..e814110 100755 --- a/test/integration/targets/template/runme.sh +++ b/test/integration/targets/template/runme.sh @@ -7,11 +7,11 @@ ANSIBLE_ROLES_PATH=../ ansible-playbook template.yml -i ../../inventory -v "$@" # 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_managed tests ANSIBLE_CONFIG=ansible_managed.cfg ansible-playbook ansible_managed.yml -i ../../inventory -v "$@" -# Test for https://github.com/ansible/ansible/pull/79129 -ANSIBLE_CONFIG=ansible_managed.cfg ansible-playbook ansible_managed_79129.yml -i ../../inventory -v "$@" +# same as above but with ansible_managed j2 template +ANSIBLE_CONFIG=ansible_managed_templated.cfg ansible-playbook ansible_managed.yml -i ../../inventory -v "$@" # Test for #42585 ANSIBLE_ROLES_PATH=../ ansible-playbook custom_template.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/template/tasks/main.yml b/test/integration/targets/template/tasks/main.yml index 34e8828..d96941f 100644 --- a/test/integration/targets/template/tasks/main.yml +++ b/test/integration/targets/template/tasks/main.yml @@ -714,7 +714,7 @@ - name: check that proper error message is emitted when in operator is used assert: - that: "\"'y' is undefined\" in error.msg" + that: "\"The error was: 'y' is undefined\n\n\" in error.msg" - template: src: template_import_macro_globals.j2 diff --git a/test/integration/targets/templating_lookups/template_lookups/mock_lookup_plugins/77788.py b/test/integration/targets/templating_lookups/template_lookups/mock_lookup_plugins/77788.py index 436ceaf..99a44ad 100644 --- a/test/integration/targets/templating_lookups/template_lookups/mock_lookup_plugins/77788.py +++ b/test/integration/targets/templating_lookups/template_lookups/mock_lookup_plugins/77788.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.plugins.lookup import LookupBase diff --git a/test/integration/targets/test_utils/scripts/timeout.py b/test/integration/targets/test_utils/scripts/timeout.py index f88f3e4..9960712 100755 --- a/test/integration/targets/test_utils/scripts/timeout.py +++ b/test/integration/targets/test_utils/scripts/timeout.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import annotations import argparse import subprocess diff --git a/test/integration/targets/throttle/test_throttle.py b/test/integration/targets/throttle/test_throttle.py index 1a5bdd3..95bb217 100755 --- a/test/integration/targets/throttle/test_throttle.py +++ b/test/integration/targets/throttle/test_throttle.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import os import sys diff --git a/test/integration/targets/unarchive/aliases b/test/integration/targets/unarchive/aliases index 961b205..62ef2f7 100644 --- a/test/integration/targets/unarchive/aliases +++ b/test/integration/targets/unarchive/aliases @@ -1,3 +1,4 @@ needs/root shippable/posix/group2 destructive +setup/always/setup_passlib_controller # required for setup_test_user diff --git a/test/integration/targets/unarchive/tasks/prepare_tests.yml b/test/integration/targets/unarchive/tasks/prepare_tests.yml index 98a8ba1..fa8de52 100644 --- a/test/integration/targets/unarchive/tasks/prepare_tests.yml +++ b/test/integration/targets/unarchive/tasks/prepare_tests.yml @@ -5,7 +5,7 @@ - name: Ensure required binaries are present package: name: "{{ unarchive_packages }}" - when: ansible_pkg_mgr in ('yum', 'dnf', 'apt', 'pkgng') + when: ansible_pkg_mgr in ('dnf', 'apt', 'pkgng') - name: prep our file copy: diff --git a/test/integration/targets/unarchive/tasks/test_download.yml b/test/integration/targets/unarchive/tasks/test_download.yml index 241f11b..a133bf5 100644 --- a/test/integration/targets/unarchive/tasks/test_download.yml +++ b/test/integration/targets/unarchive/tasks/test_download.yml @@ -6,19 +6,9 @@ - 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" + src: "https://ci-files.testing.ansible.com/test/integration/targets/apt/echo-hello-source.tar.gz" dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz" mode: "0700" remote_src: yes @@ -28,16 +18,6 @@ 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' diff --git a/test/integration/targets/unarchive/tasks/test_missing_binaries.yml b/test/integration/targets/unarchive/tasks/test_missing_binaries.yml index 49f862b..6d6a80f 100644 --- a/test/integration/targets/unarchive/tasks/test_missing_binaries.yml +++ b/test/integration/targets/unarchive/tasks/test_missing_binaries.yml @@ -1,5 +1,5 @@ - name: Test missing binaries - when: ansible_pkg_mgr in ('yum', 'dnf', 'apt', 'pkgng') + when: ansible_pkg_mgr in ('dnf', 'apt', 'pkgng') block: - name: Remove zip binaries package: @@ -39,7 +39,7 @@ environment: PATH: "{{ ENV_PATH }}" vars: - ENV_PATH: "{{ lookup('env', 'PATH') | regex_replace(re, '') }}" + ENV_PATH: "{{ ansible_env['PATH']| regex_replace(re, '') }}" re: "[^A-Za-z](\/usr\/bin:?)" - name: Ensure tasks worked as expected diff --git a/test/integration/targets/unarchive/tasks/test_symlink.yml b/test/integration/targets/unarchive/tasks/test_symlink.yml index fcb7282..a511ddd 100644 --- a/test/integration/targets/unarchive/tasks/test_symlink.yml +++ b/test/integration/targets/unarchive/tasks/test_symlink.yml @@ -62,3 +62,65 @@ file: path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz' state: absent + +- name: Create a destination dir + file: + path: "{{ remote_tmp_dir }}/test-symlink" + state: directory + +- name: Create files + file: + path: "{{ remote_tmp_dir }}/test-symlink/{{ item }}" + state: touch + loop: + - file1 + - file2 + +- name: Create a symlink to the file + file: + path: "{{ remote_tmp_dir }}/test-symlink/link1" + src: "{{ remote_tmp_dir }}/test-symlink/file1" + state: link + +- name: Create archive of symlink + shell: tar czvf {{ remote_tmp_dir }}/link1.tar.gz link1 chdir={{ remote_tmp_dir }}/test-symlink + +- name: Change target of symlink + file: + path: "{{ remote_tmp_dir }}/test-symlink/link1" + src: "{{ remote_tmp_dir }}/test-symlink/file2" + state: link + +- name: Unarchive when symlink differs + unarchive: + src: "{{ remote_tmp_dir }}/link1.tar.gz" + dest: "{{ remote_tmp_dir }}/test-symlink" + remote_src: yes + register: unarchive_13 + +- name: Assert that unarchive was performed + assert: + that: + - unarchive_13.changed == true + +- name: Unarchive when symlink is the same + unarchive: + src: "{{ remote_tmp_dir }}/link1.tar.gz" + dest: "{{ remote_tmp_dir }}/test-symlink" + remote_src: yes + register: unarchive_13 + +- name: Assert that unarchive was not performed + assert: + that: + - "unarchive_13.changed == false" + +- name: Remove files + file: + path: "{{ remote_tmp_dir }}/test-symlink/{{ item }}" + state: absent + with_items: + - file1 + - file2 + - link1 + - link1.tar.gz diff --git a/test/integration/targets/unexpected_executor_exception/action_plugins/unexpected.py b/test/integration/targets/unexpected_executor_exception/action_plugins/unexpected.py index 77fe58f..358ff34 100644 --- a/test/integration/targets/unexpected_executor_exception/action_plugins/unexpected.py +++ b/test/integration/targets/unexpected_executor_exception/action_plugins/unexpected.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/until/action_plugins/shell_no_failed.py b/test/integration/targets/until/action_plugins/shell_no_failed.py index 594c014..5072b47 100644 --- a/test/integration/targets/until/action_plugins/shell_no_failed.py +++ b/test/integration/targets/until/action_plugins/shell_no_failed.py @@ -1,8 +1,7 @@ # Copyright: (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 +from __future__ import annotations from ansible.plugins.action import ActionBase diff --git a/test/integration/targets/uri/files/testserver.py b/test/integration/targets/uri/files/testserver.py index 24967d4..3a83724 100644 --- a/test/integration/targets/uri/files/testserver.py +++ b/test/integration/targets/uri/files/testserver.py @@ -1,23 +1,15 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations +import http.server +import socketserver import sys if __name__ == '__main__': - if sys.version_info[0] >= 3: - import http.server - import socketserver - PORT = int(sys.argv[1]) + PORT = int(sys.argv[1]) - class Handler(http.server.SimpleHTTPRequestHandler): - pass + class Handler(http.server.SimpleHTTPRequestHandler): + pass - Handler.extensions_map['.json'] = 'application/json' - httpd = socketserver.TCPServer(("", PORT), Handler) - httpd.serve_forever() - else: - import mimetypes - mimetypes.init() - mimetypes.add_type('application/json', '.json') - import SimpleHTTPServer - SimpleHTTPServer.test() + Handler.extensions_map['.json'] = 'application/json' + httpd = socketserver.TCPServer(("", PORT), Handler) + httpd.serve_forever() diff --git a/test/integration/targets/uri/tasks/install-socat-and-test-unix-socket.yml b/test/integration/targets/uri/tasks/install-socat-and-test-unix-socket.yml new file mode 100644 index 0000000..92c0a90 --- /dev/null +++ b/test/integration/targets/uri/tasks/install-socat-and-test-unix-socket.yml @@ -0,0 +1,25 @@ +- when: ansible_facts.distribution not in ['MacOSX'] + block: + - name: install socat + package: + name: socat + state: present + register: socat_install_package + when: ansible_facts.distribution not in ['Alpine'] + + - name: install socat for alpine + command: apk add --virtual .socat socat + register: socat_install_alpine + when: ansible_facts.distribution == 'Alpine' + + - include_tasks: unix-socket.yml + always: + - name: uninstall socat + package: + name: socat + state: absent + when: socat_install_package|default({}) is changed + + - name: uninstall socat for alpine + command: apk del .socat + when: socat_install_alpine|default({}) is changed and 'Installing socat' in socat_install_alpine.stdout diff --git a/test/integration/targets/uri/tasks/main.yml b/test/integration/targets/uri/tasks/main.yml index ddae83a..a818107 100644 --- a/test/integration/targets/uri/tasks/main.yml +++ b/test/integration/targets/uri/tasks/main.yml @@ -54,6 +54,18 @@ register: pass_checksum with_sequence: start=0 end=4 format=pass%d + +- name: test basic auth with urlencoded + register: result + uri: + url: 'https://foo%40example.com:test%40@{{ httpbin_host }}/basic-auth/foo%40example.com/test%40' + +- name: Ensure basic auth credentials where URL-decoded + assert: + that: + - result.json.authenticated + - result.json.user == 'foo@example.com' + - name: fetch pass_json uri: return_content=yes url=http://localhost:{{ http_port }}/{{ item }}.json register: fetch_pass_json @@ -321,12 +333,6 @@ url: 'https://{{ httpbin_host }}/get' use_proxy: no -# Ubuntu12.04 doesn't have python-urllib3, this makes handling required dependencies a pain across all variations -# We'll use this to just skip 12.04 on those tests. We should be sufficiently covered with other OSes and versions -- name: Set fact if running on Ubuntu 12.04 - set_fact: - is_ubuntu_precise: "{{ ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'precise' }}" - - name: Test that SNI succeeds on python versions that have SNI uri: url: 'https://{{ sni_host }}/' @@ -341,128 +347,6 @@ - 'sni_host in result.content' when: ansible_python.has_sslcontext -- name: Verify SNI verification fails on old python without urllib3 contrib - uri: - url: 'https://{{ sni_host }}' - ignore_errors: true - when: not ansible_python.has_sslcontext - register: result - -- name: Assert SNI verification fails on old python - assert: - that: - - result is failed - when: result is not skipped - -- name: check if urllib3 is installed as an OS package - package: - name: "{{ uri_os_packages[ansible_os_family].urllib3 }}" - check_mode: yes - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool and uri_os_packages[ansible_os_family].urllib3|default - register: urllib3 - -- name: uninstall conflicting urllib3 pip package - pip: - name: urllib3 - state: absent - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool and uri_os_packages[ansible_os_family].urllib3|default and urllib3.changed - -- name: install OS packages that are needed for SNI on old python - package: - name: "{{ item }}" - with_items: "{{ uri_os_packages[ansible_os_family].step1 | default([]) }}" - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - -- name: install python modules for Older Python SNI verification - pip: - name: "{{ item }}" - with_items: - - ndg-httpsclient - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - -- name: Verify SNI verification succeeds on old python with urllib3 contrib - uri: - url: 'https://{{ sni_host }}' - return_content: true - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - register: result - -- name: Assert SNI verification succeeds on old python - assert: - that: - - result is successful - - 'sni_host in result.content' - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - -- name: Uninstall ndg-httpsclient - pip: - name: "{{ item }}" - state: absent - with_items: - - ndg-httpsclient - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - -- name: uninstall OS packages that are needed for SNI on old python - package: - name: "{{ item }}" - state: absent - with_items: "{{ uri_os_packages[ansible_os_family].step1 | default([]) }}" - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - -- name: install OS packages that are needed for building cryptography - package: - name: "{{ item }}" - 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 }}" - extra_args: "-c {{ remote_constraints }}" - with_items: - - urllib3 - - PyOpenSSL - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - -- name: Verify SNI verification succeeds on old python with pip urllib3 contrib - uri: - url: 'https://{{ sni_host }}' - return_content: true - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - register: result - -- name: Assert SNI verification succeeds on old python with pip urllib3 contrib - assert: - that: - - result is successful - - 'sni_host in result.content' - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - -- name: Uninstall urllib3 and PyOpenSSL - pip: - name: "{{ item }}" - state: absent - with_items: - - urllib3 - - PyOpenSSL - when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool - - name: validate the status_codes are correct uri: url: "https://{{ httpbin_host }}/status/202" @@ -761,6 +645,22 @@ that: - "'content' in file_out.stdout" +- name: Test downloading cached file + uri: + url: "https://{{ httpbin_host }}/cache" + +- name: Test downloading cached file to existing file results in "304 Not Modified" + uri: + url: "https://{{ httpbin_host }}/cache" + dest: "{{ remote_tmp_dir }}/output" + status_code: [304] + +- name: Test downloading cached file to existing file with "force" + uri: + url: "https://{{ httpbin_host }}/cache" + dest: "{{ remote_tmp_dir }}/output" + force: true + - name: Clean up file: dest: "{{ remote_tmp_dir }}/output" @@ -815,6 +715,7 @@ environment: KRB5_CONFIG: '{{ krb5_config }}' KRB5CCNAME: FILE:{{ remote_tmp_dir }}/krb5.cc + OPENSSL_CONF: '{{ krb5_openssl_conf }}' when: krb5_config is defined - name: Test ciphers @@ -822,3 +723,17 @@ - name: Test use_netrc.yml import_tasks: use_netrc.yml + +- name: Test unix socket + import_tasks: install-socat-and-test-unix-socket.yml + +- name: ensure skip action + uri: + url: http://example.com + check_mode: True + register: uri_check + +- name: check that we skipped at action + assert: + that: + - uri_check.msg == "This action (uri) does not support check mode." diff --git a/test/integration/targets/uri/tasks/unix-socket.yml b/test/integration/targets/uri/tasks/unix-socket.yml new file mode 100644 index 0000000..6e6cf83 --- /dev/null +++ b/test/integration/targets/uri/tasks/unix-socket.yml @@ -0,0 +1,36 @@ +- name: Bind socat to socket + command: socat UNIX-LISTEN:{{ remote_tmp_dir }}/{{ item.name }}.sock,fork,reuseaddr TCP4:{{ httpbin_host }}:{{ item.port }} + loop: + - port: 80 + name: http + - port: 443 + name: https + async: 10 + poll: 0 + +- name: Test http connection to unix socket + uri: + url: http://localhost/get + unix_socket: '{{ remote_tmp_dir }}/http.sock' + register: unix_socket_http + +- name: Test https connection to unix socket with valdiate_certs=false + uri: + url: https://localhost/get + unix_socket: '{{ remote_tmp_dir }}/https.sock' + # Ignore ssl verification since we list the host as localhost + # to ensure we really are connecting over the socket + validate_certs: false + register: unix_socket_https_no_validate + +- name: Test https connection to unix socket + uri: + url: https://{{ httpbin_host }}/get + unix_socket: '{{ remote_tmp_dir }}/https.sock' + register: unix_socket_https + +- assert: + that: + - unix_socket_http.json is defined + - unix_socket_https_no_validate.json is defined + - unix_socket_https.json is defined diff --git a/test/integration/targets/uri/tasks/use_netrc.yml b/test/integration/targets/uri/tasks/use_netrc.yml index 521f8eb..1559f36 100644 --- a/test/integration/targets/uri/tasks/use_netrc.yml +++ b/test/integration/targets/uri/tasks/use_netrc.yml @@ -25,7 +25,7 @@ fail_msg: "Was expecting 'foo:bar' in base64, but received: {{ response_failed }}" success_msg: "Expected to fail because netrc is using Basic authentication by default" -- name: Test Bearer authorization is successfull with use_netrc=False +- name: Test Bearer authorization is successful with use_netrc=False uri: url: https://{{ httpbin_host }}/bearer use_netrc: false @@ -36,14 +36,14 @@ NETRC: "{{ remote_tmp_dir }}/netrc" register: response -- name: assert Test Bearer authorization is successfull with use_netrc=False +- name: assert Test Bearer authorization is successful with use_netrc=False assert: that: - response.status == 200 - response.json.token == 'foobar' - response.url == 'https://{{ httpbin_host }}/bearer' fail_msg: "Was expecting successful Bearer authentication, but received: {{ response }}" - success_msg: "Bearer authentication successfull when netrc is ignored." + success_msg: "Bearer authentication successful when netrc is ignored." - name: Clean up file: diff --git a/test/integration/targets/uri/vars/main.yml b/test/integration/targets/uri/vars/main.yml deleted file mode 100644 index 83a740b..0000000 --- a/test/integration/targets/uri/vars/main.yml +++ /dev/null @@ -1,20 +0,0 @@ -uri_os_packages: - RedHat: - urllib3: python-urllib3 - step1: - - python-pyasn1 - - pyOpenSSL - - python-urllib3 - step2: - - libffi-devel - - openssl-devel - - python-devel - Debian: - step1: - - python-pyasn1 - - python-openssl - - python-urllib3 - step2: - - libffi-dev - - libssl-dev - - python-dev diff --git a/test/integration/targets/user/tasks/test_create_user_password.yml b/test/integration/targets/user/tasks/test_create_user_password.yml index 02aae00..f22ef6b 100644 --- a/test/integration/targets/user/tasks/test_create_user_password.yml +++ b/test/integration/targets/user/tasks/test_create_user_password.yml @@ -1,5 +1,5 @@ # test user add with password -- name: add an encrypted password for user +- name: add an sha512 password for user user: name: ansibulluser password: "$6$rounds=656000$TT4O7jz2M57npccl$33LF6FcUMSW11qrESXL1HX0BS.bsiT6aenFLLiVpsQh6hDtI9pJh5iY7x8J7ePkN4fP8hmElidHXaeD51pbGS." @@ -88,3 +88,15 @@ - "'warnings' not in test_user_encrypt3" - "'warnings' not in test_user_encrypt4" - "'warnings' not in test_user_encrypt5" + +- name: add an yescrypt password for user + user: + name: ansibulluser + password: "$y$jCT$ZiF3ZV39/maUl9Lzt2Hk80$Ih6bI4OXU52OnWWqt3T1BAmVn8eH.4qlcP.8/NOjGN5" #gitleaks:allow + state: present + update_password: always + register: test_user_encrypt6 + +- name: there should not be warnings + assert: + that: "'warnings' not in test_user_encrypt6" diff --git a/test/integration/targets/user/tasks/test_local.yml b/test/integration/targets/user/tasks/test_local.yml index 217d476..c49ab0c 100644 --- a/test/integration/targets/user/tasks/test_local.yml +++ b/test/integration/targets/user/tasks/test_local.yml @@ -224,8 +224,6 @@ - name: Ensure warnings were displayed properly assert: that: - - local_user_test_1['warnings'] | length > 0 - - local_user_test_1['warnings'] | first is search('The local user account may already exist') - local_user_test_5['warnings'] is search("'append' is set, but no 'groups' are specified. Use 'groups'") - local_existing['warnings'] is not defined when: ansible_facts.system in ['Linux'] diff --git a/test/integration/targets/var_precedence/ansible-var-precedence-check.py b/test/integration/targets/var_precedence/ansible-var-precedence-check.py index b03c87b..6511169 100755 --- a/test/integration/targets/var_precedence/ansible-var-precedence-check.py +++ b/test/integration/targets/var_precedence/ansible-var-precedence-check.py @@ -3,8 +3,7 @@ # A tool to check the order of precedence for ansible variables # https://github.com/ansible/ansible/blob/devel/test/integration/test_var_precedence.yml -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import os diff --git a/test/integration/targets/wait_for/files/testserver.py b/test/integration/targets/wait_for/files/testserver.py index 2b728b6..452a045 100644 --- a/test/integration/targets/wait_for/files/testserver.py +++ b/test/integration/targets/wait_for/files/testserver.py @@ -1,19 +1,11 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations +import http.server +import socketserver import sys if __name__ == '__main__': - if sys.version_info[0] >= 3: - import http.server - import socketserver - PORT = int(sys.argv[1]) - Handler = http.server.SimpleHTTPRequestHandler - httpd = socketserver.TCPServer(("", PORT), Handler) - httpd.serve_forever() - else: - import mimetypes - mimetypes.init() - mimetypes.add_type('application/json', '.json') - import SimpleHTTPServer - SimpleHTTPServer.test() + PORT = int(sys.argv[1]) + Handler = http.server.SimpleHTTPRequestHandler + httpd = socketserver.TCPServer(("", PORT), Handler) + httpd.serve_forever() diff --git a/test/integration/targets/wait_for/files/write_utf16.py b/test/integration/targets/wait_for/files/write_utf16.py index 6079ed3..fca04ca 100644 --- a/test/integration/targets/wait_for/files/write_utf16.py +++ b/test/integration/targets/wait_for/files/write_utf16.py @@ -1,5 +1,4 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import sys diff --git a/test/integration/targets/wait_for/files/zombie.py b/test/integration/targets/wait_for/files/zombie.py index 913074e..19437ea 100644 --- a/test/integration/targets/wait_for/files/zombie.py +++ b/test/integration/targets/wait_for/files/zombie.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations import os import sys diff --git a/test/integration/targets/wait_for/tasks/main.yml b/test/integration/targets/wait_for/tasks/main.yml index 74b8e9a..fd63c34 100644 --- a/test/integration/targets/wait_for/tasks/main.yml +++ b/test/integration/targets/wait_for/tasks/main.yml @@ -114,14 +114,12 @@ path: "{{remote_tmp_dir}}/utf16.txt" search_regex: completed -- name: test non mmapable file +- name: test non mmapable file, skip OSs w/o /sys wait_for: path: "/sys/class/net/lo/carrier" search_regex: "1" timeout: 30 - when: - - ansible_facts['os_family'] not in ['FreeBSD', 'Darwin'] - - not (ansible_facts['os_family'] in ['RedHat', 'CentOS'] and ansible_facts['distribution_major_version'] is version('7', '<=')) + when: ansible_os_family not in ['FreeBSD', 'Darwin'] - name: test wait for port timeout wait_for: @@ -167,9 +165,9 @@ - waitfor is not changed - "waitfor.port == http_port" -- name: install psutil using pip (non-Linux only) +- name: install psutil using pip (non-Linux) pip: - name: psutil==5.8.0 + name: psutil==5.9.8 when: ansible_system != 'Linux' - name: Copy zombie.py diff --git a/test/integration/targets/want_json_modules_posix/library/helloworld.py b/test/integration/targets/want_json_modules_posix/library/helloworld.py index 80f8761..e32a203 100644 --- a/test/integration/targets/want_json_modules_posix/library/helloworld.py +++ b/test/integration/targets/want_json_modules_posix/library/helloworld.py @@ -16,8 +16,7 @@ # WANT_JSON -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import sys diff --git a/test/integration/targets/win_exec_wrapper/action_plugins/test_rc_1.py b/test/integration/targets/win_exec_wrapper/action_plugins/test_rc_1.py index 60cffde..1cc92b8 100644 --- a/test/integration/targets/win_exec_wrapper/action_plugins/test_rc_1.py +++ b/test/integration/targets/win_exec_wrapper/action_plugins/test_rc_1.py @@ -1,5 +1,6 @@ # Copyright: (c) 2023, Ansible Project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import annotations import json diff --git a/test/integration/targets/yum/aliases b/test/integration/targets/yum/aliases deleted file mode 100644 index b12f354..0000000 --- a/test/integration/targets/yum/aliases +++ /dev/null @@ -1,4 +0,0 @@ -destructive -shippable/posix/group1 -skip/freebsd -skip/macos diff --git a/test/integration/targets/yum/files/yum.conf b/test/integration/targets/yum/files/yum.conf deleted file mode 100644 index 5a5fca6..0000000 --- a/test/integration/targets/yum/files/yum.conf +++ /dev/null @@ -1,5 +0,0 @@ -[main] -gpgcheck=1 -installonly_limit=3 -clean_requirements_on_remove=True -tsflags=nodocs 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 deleted file mode 100644 index 306ccd9..0000000 --- a/test/integration/targets/yum/filter_plugins/filter_list_of_tuples_by_first_param.py +++ /dev/null @@ -1,23 +0,0 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - - -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/meta/main.yml b/test/integration/targets/yum/meta/main.yml deleted file mode 100644 index 34d8126..0000000 --- a/test/integration/targets/yum/meta/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -dependencies: - - prepare_tests - - setup_rpm_repo - - setup_remote_tmp_dir diff --git a/test/integration/targets/yum/tasks/cacheonly.yml b/test/integration/targets/yum/tasks/cacheonly.yml deleted file mode 100644 index 03cbd0e..0000000 --- a/test/integration/targets/yum/tasks/cacheonly.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- 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/check_mode_consistency.yml b/test/integration/targets/yum/tasks/check_mode_consistency.yml deleted file mode 100644 index e2a99d9..0000000 --- a/test/integration/targets/yum/tasks/check_mode_consistency.yml +++ /dev/null @@ -1,61 +0,0 @@ -- name: install htop in check mode to verify changes dict returned - yum: - name: htop - state: present - check_mode: yes - register: yum_changes_check_mode_result - -- name: install verify changes dict returned in check mode - assert: - that: - - "yum_changes_check_mode_result is success" - - "yum_changes_check_mode_result is changed" - - "'changes' in yum_changes_check_mode_result" - - "'installed' in yum_changes_check_mode_result['changes']" - - "'htop' in yum_changes_check_mode_result['changes']['installed']" - -- name: install htop to verify changes dict returned - yum: - name: htop - state: present - register: yum_changes_result - -- name: install verify changes dict returned - assert: - that: - - "yum_changes_result is success" - - "yum_changes_result is changed" - - "'changes' in yum_changes_result" - - "'installed' in yum_changes_result['changes']" - - "'htop' in yum_changes_result['changes']['installed']" - -- name: remove htop in check mode to verify changes dict returned - yum: - name: htop - state: absent - check_mode: yes - register: yum_changes_check_mode_result - -- name: remove verify changes dict returned in check mode - assert: - that: - - "yum_changes_check_mode_result is success" - - "yum_changes_check_mode_result is changed" - - "'changes' in yum_changes_check_mode_result" - - "'removed' in yum_changes_check_mode_result['changes']" - - "'htop' in yum_changes_check_mode_result['changes']['removed']" - -- name: remove htop to verify changes dict returned - yum: - name: htop - state: absent - register: yum_changes_result - -- name: remove verify changes dict returned - assert: - that: - - "yum_changes_result is success" - - "yum_changes_result is changed" - - "'changes' in yum_changes_result" - - "'removed' in yum_changes_result['changes']" - - "'htop' in yum_changes_result['changes']['removed']" diff --git a/test/integration/targets/yum/tasks/lock.yml b/test/integration/targets/yum/tasks/lock.yml deleted file mode 100644 index 3f585c1..0000000 --- a/test/integration/targets/yum/tasks/lock.yml +++ /dev/null @@ -1,28 +0,0 @@ -- block: - - name: Make sure testing package is not installed - yum: - name: sos - state: absent - - - name: Create bogus lock file - copy: - content: bogus content for this lock file - dest: /var/run/yum.pid - - - name: Install a package, lock file should be deleted by the module - yum: - name: sos - state: present - register: yum_result - - - assert: - that: - - yum_result is success - - always: - - name: Clean up - yum: - name: sos - state: absent - - when: ansible_pkg_mgr == 'yum' diff --git a/test/integration/targets/yum/tasks/main.yml b/test/integration/targets/yum/tasks/main.yml deleted file mode 100644 index 157124a..0000000 --- a/test/integration/targets/yum/tasks/main.yml +++ /dev/null @@ -1,82 +0,0 @@ -# (c) 2014, James Tanner <tanner.jc@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Note: We install the yum package onto Fedora so that this will work on dnf systems -# We want to test that for people who don't want to upgrade their systems. - -- block: - - name: ensure test packages are removed before starting - yum: - name: - - sos - state: absent - - - import_tasks: yum.yml - always: - - name: remove installed packages - yum: - name: - - sos - state: absent - - - name: remove installed group - yum: - name: "@Custom Group" - state: absent - - - name: On Fedora 28 the above won't remove the group which results in a failure in repo.yml below - yum: - name: dinginessentail - state: absent - when: - - ansible_distribution in ['Fedora'] - - when: - - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux', 'Fedora'] - - -- block: - - import_tasks: repo.yml - - import_tasks: yum_group_remove.yml - when: - - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] - always: - - yum_repository: - name: "{{ item }}" - state: absent - loop: "{{ repos }}" - - - command: yum clean metadata - when: - - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux', 'Fedora'] - - -- import_tasks: yuminstallroot.yml - when: - - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux', 'Fedora'] - - -- import_tasks: proxy.yml - when: - - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux', 'Fedora'] - - -- import_tasks: check_mode_consistency.yml - when: - - (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ansible_distribution_major_version|int == 7) - - -- 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 deleted file mode 100644 index bced634..0000000 --- a/test/integration/targets/yum/tasks/multiarch.yml +++ /dev/null @@ -1,154 +0,0 @@ -- 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/proxy.yml b/test/integration/targets/yum/tasks/proxy.yml deleted file mode 100644 index b011d11..0000000 --- a/test/integration/targets/yum/tasks/proxy.yml +++ /dev/null @@ -1,186 +0,0 @@ -- name: test yum proxy settings - block: - - name: install tinyproxy - yum: - name: 'https://ci-files.testing.ansible.com/test/integration/targets/yum/tinyproxy-1.10.0-3.el7.x86_64.rpm' - state: installed - - # systemd doesn't play nice with this in a container for some reason - - name: start tinyproxy (systemd with tiny proxy does not work in container) - shell: tinyproxy - changed_when: false - - # test proxy without auth - - name: set unauthenticated proxy in yum.conf - lineinfile: - path: /etc/yum.conf - line: "proxy=http://127.0.0.1:8888" - state: present - - - name: clear proxy logs - shell: ': > /var/log/tinyproxy/tinyproxy.log' - changed_when: false - args: - executable: /usr/bin/bash - - - name: install ninvaders with unauthenticated proxy - yum: - name: 'https://ci-files.testing.ansible.com/test/integration/targets/yum/ninvaders-0.1.1-18.el7.x86_64.rpm' - state: installed - register: yum_proxy_result - - - assert: - that: - - "yum_proxy_result.changed" - - "'msg' in yum_proxy_result" - - "'rc' in yum_proxy_result" - - - name: check that it install via unauthenticated proxy - command: grep -q Request /var/log/tinyproxy/tinyproxy.log - - - name: uninstall ninvaders with unauthenticated proxy - yum: - name: ninvaders - state: absent - register: yum_proxy_result - - - assert: - that: - - "yum_proxy_result.changed" - - "'msg' in yum_proxy_result" - - "'rc' in yum_proxy_result" - - - name: unset unauthenticated proxy in yum.conf - lineinfile: - path: /etc/yum.conf - line: "proxy=http://127.0.0.1:8888" - state: absent - - # test proxy with auth - - name: set authenticated proxy config in tinyproxy.conf - lineinfile: - path: /etc/tinyproxy/tinyproxy.conf - line: "BasicAuth 1testuser 1testpassword" - state: present - - # systemd doesn't play nice with this in a container for some reason - - name: SIGHUP tinyproxy to reload config (workaround because of systemd+tinyproxy in container) - shell: kill -HUP $(ps -ef | grep tinyproxy | grep -v grep | awk '{print $2}') - changed_when: false - args: - executable: /usr/bin/bash - - - name: set authenticated proxy config in yum.conf - lineinfile: - path: /etc/yum.conf - line: "proxy=http://1testuser:1testpassword@127.0.0.1:8888" - state: present - - - name: clear proxy logs - shell: ': > /var/log/tinyproxy/tinyproxy.log' - changed_when: false - args: - executable: /usr/bin/bash - - - name: install ninvaders with authenticated proxy - yum: - name: 'https://ci-files.testing.ansible.com/test/integration/targets/yum/ninvaders-0.1.1-18.el7.x86_64.rpm' - state: installed - register: yum_proxy_result - - - assert: - that: - - "yum_proxy_result.changed" - - "'msg' in yum_proxy_result" - - "'rc' in yum_proxy_result" - - - name: check that it install via authenticated proxy - command: grep -q Request /var/log/tinyproxy/tinyproxy.log - - - name: uninstall ninvaders with authenticated proxy - yum: - name: ninvaders - state: absent - - - name: unset authenticated proxy config in yum.conf - lineinfile: - path: /etc/yum.conf - line: "proxy=http://1testuser:1testpassword@127.0.0.1:8888" - state: absent - - - name: set proxy config in yum.conf - lineinfile: - path: /etc/yum.conf - line: "proxy=http://127.0.0.1:8888" - state: present - - - name: set proxy_username config in yum.conf - lineinfile: - path: /etc/yum.conf - line: "proxy_username=1testuser" - state: present - - - name: set proxy_password config in yum.conf - lineinfile: - path: /etc/yum.conf - line: "proxy_password=1testpassword" - state: present - - - name: clear proxy logs - shell: ': > /var/log/tinyproxy/tinyproxy.log' - changed_when: false - args: - executable: /usr/bin/bash - - - name: install ninvaders with proxy, proxy_username, and proxy_password config in yum.conf - yum: - name: 'https://ci-files.testing.ansible.com/test/integration/targets/yum/ninvaders-0.1.1-18.el7.x86_64.rpm' - state: installed - register: yum_proxy_result - - - assert: - that: - - "yum_proxy_result.changed" - - "'msg' in yum_proxy_result" - - "'rc' in yum_proxy_result" - - - name: check that it install via proxy with proxy_username, proxy_password config in yum.conf - command: grep -q Request /var/log/tinyproxy/tinyproxy.log - - always: - #cleanup - - name: uninstall tinyproxy - yum: - name: tinyproxy - state: absent - - - name: uninstall ninvaders - yum: - name: ninvaders - state: absent - - - name: ensure unset authenticated proxy - lineinfile: - path: /etc/yum.conf - line: "proxy=http://1testuser:1testpassword@127.0.0.1:8888" - state: absent - - - name: ensure unset proxy - lineinfile: - path: /etc/yum.conf - line: "proxy=http://127.0.0.1:8888" - state: absent - - - name: ensure unset proxy_username - lineinfile: - path: /etc/yum.conf - line: "proxy_username=1testuser" - state: absent - - - name: ensure unset proxy_password - lineinfile: - path: /etc/yum.conf - line: "proxy_password=1testpassword" - state: absent - when: - - (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ansible_distribution_major_version|int == 7 and ansible_architecture in ['x86_64']) diff --git a/test/integration/targets/yum/tasks/repo.yml b/test/integration/targets/yum/tasks/repo.yml deleted file mode 100644 index f312b1c..0000000 --- a/test/integration/targets/yum/tasks/repo.yml +++ /dev/null @@ -1,729 +0,0 @@ -- block: - - name: Install dinginessentail-1.0-1 - yum: - name: dinginessentail-1.0-1 - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Install dinginessentail-1.0-1 again - yum: - name: dinginessentail-1.0-1 - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "not yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Install dinginessentail-1:1.0-2 - yum: - name: "dinginessentail-1:1.0-2.{{ ansible_architecture }}" - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - - - name: Remove dinginessentail - yum: - name: dinginessentail - state: absent - # ============================================================================ - - name: Downgrade dinginessentail - yum: - name: dinginessentail-1.0-1 - state: present - allow_downgrade: yes - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Update to the latest dinginessentail - yum: - name: dinginessentail - state: latest - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.1-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Install dinginessentail-1.0-1 from a file (higher version is already installed) - yum: - name: "{{ repodir }}/dinginessentail-1.0-1.{{ ansible_architecture }}.rpm" - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "not yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.1-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - - - name: Remove dinginessentail - yum: - name: dinginessentail - state: absent - # ============================================================================ - - name: Install dinginessentail-1.0-1 from a file - yum: - name: "{{ repodir }}/dinginessentail-1.0-1.{{ ansible_architecture }}.rpm" - state: present - disable_gpg_check: true - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Install dinginessentail-1.0-1 from a file again - yum: - name: "{{ repodir }}/dinginessentail-1.0-1.{{ ansible_architecture }}.rpm" - state: present - disable_gpg_check: true - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "not yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Install dinginessentail-1.0-2 from a file - yum: - name: "{{ repodir }}/dinginessentail-1.0-2.{{ ansible_architecture }}.rpm" - state: present - disable_gpg_check: true - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Install dinginessentail-1.0-2 from a file again - yum: - name: "{{ repodir }}/dinginessentail-1.0-2.{{ ansible_architecture }}.rpm" - state: present - disable_gpg_check: true - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "not yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Try to downgrade dinginessentail without allow_downgrade being set - yum: - name: dinginessentail-1.0-1 - state: present - allow_downgrade: no - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "not yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Update dinginessentail with update_only set - yum: - name: dinginessentail - state: latest - update_only: yes - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.1-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - - - name: Remove dinginessentail - yum: - name: dinginessentail - state: absent - # ============================================================================ - - name: Try to update dinginessentail which is not installed, update_only is set - yum: - name: dinginessentail - state: latest - update_only: yes - register: yum_result - ignore_errors: yes - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - ignore_errors: yes - - - name: Verify installation - assert: - that: - - "rpm_result.rc == 1" - - "yum_result.rc == 0" - - "not yum_result.changed" - - "not yum_result is failed" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Try to install incompatible arch - yum: - name: "{{ repodir_ppc64 }}/dinginessentail-1.0-1.ppc64.rpm" - state: present - register: yum_result - ignore_errors: yes - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - ignore_errors: yes - - - name: Verify installation - assert: - that: - - "rpm_result.rc == 1" - - "yum_result.rc == 1" - - "not yum_result.changed" - - "yum_result is failed" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - name: Make sure latest dinginessentail is installed - yum: - name: dinginessentail - state: latest - - - name: Downgrade dinginessentail using rpm file - yum: - name: "{{ repodir }}/dinginessentail-1.0-1.{{ ansible_architecture }}.rpm" - state: present - allow_downgrade: yes - disable_gpg_check: yes - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - # ============================================================================ - - block: - - name: make sure dinginessentail is not installed - yum: - name: dinginessentail - state: absent - - - name: install dinginessentail both archs - yum: - name: "{{ pkgs }}" - state: present - disable_gpg_check: true - vars: - pkgs: - - "{{ repodir }}/dinginessentail-1.1-1.x86_64.rpm" - - "{{ repodir_i686 }}/dinginessentail-1.1-1.i686.rpm" - - - name: try to install lower version of dinginessentail from rpm file, without allow_downgrade, just one arch - yum: - name: "{{ repodir_i686 }}/dinginessentail-1.0-1.i686.rpm" - state: present - register: yum_result - - - name: check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: verify installation - assert: - that: - - "not yum_result.changed" - - "rpm_result.stdout_lines[0].startswith('dinginessentail-1.1-1')" - - "rpm_result.stdout_lines[1].startswith('dinginessentail-1.1-1')" - - - name: verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - when: ansible_architecture == "x86_64" - # ============================================================================ - - block: - - name: make sure dinginessentail is not installed - yum: - name: dinginessentail - state: absent - - - name: install dinginessentail both archs - yum: - name: "{{ pkgs }}" - state: present - disable_gpg_check: true - vars: - pkgs: - - "{{ repodir }}/dinginessentail-1.0-1.x86_64.rpm" - - "{{ repodir_i686 }}/dinginessentail-1.0-1.i686.rpm" - - - name: Update both arch in one task using rpm files - yum: - name: "{{ repodir }}/dinginessentail-1.1-1.x86_64.rpm,{{ repodir_i686 }}/dinginessentail-1.1-1.i686.rpm" - state: present - disable_gpg_check: yes - register: yum_result - - - name: check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout_lines[0].startswith('dinginessentail-1.1-1')" - - "rpm_result.stdout_lines[1].startswith('dinginessentail-1.1-1')" - - - name: verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - when: ansible_architecture == "x86_64" - # ============================================================================ - always: - - name: Clean up - yum: - name: dinginessentail - state: absent - -# FIXME: dnf currently doesn't support epoch as part of it's pkg_spec for -# finding install candidates -# https://bugzilla.redhat.com/show_bug.cgi?id=1619687 -- block: - - name: Install 1:dinginessentail-1.0-2 - yum: - name: "1:dinginessentail-1.0-2.{{ ansible_architecture }}" - state: present - disable_gpg_check: true - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - always: - - name: Clean up - yum: - name: dinginessentail - state: absent - - when: ansible_pkg_mgr == 'yum' - -# DNF1 (Fedora < 26) had some issues: -# - did not accept architecture tag as valid component of a package spec unless -# installing a file (i.e. can't search the repo) -# - doesn't handle downgrade transactions via the API properly, marks it as a -# conflict -# -# NOTE: Both DNF1 and Fedora < 26 have long been EOL'd by their respective -# upstreams -- block: - # ============================================================================ - - name: Install dinginessentail-1.0-2 - yum: - name: "dinginessentail-1.0-2.{{ ansible_architecture }}" - state: present - disable_gpg_check: true - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - - - name: Install dinginessentail-1.0-2 again - yum: - name: dinginessentail-1.0-2 - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "not yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-2')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - always: - - name: Clean up - yum: - name: dinginessentail - state: absent - when: not (ansible_distribution == "Fedora" and ansible_distribution_major_version|int < 26) - -# https://github.com/ansible/ansible/issues/47689 -- block: - - name: Install dinginessentail == 1.0 - yum: - name: "dinginessentail == 1.0" - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - always: - - name: Clean up - yum: - name: dinginessentail - state: absent - - when: ansible_pkg_mgr == 'yum' - - -# https://github.com/ansible/ansible/pull/54603 -- block: - - name: Install dinginessentail < 1.1 - yum: - name: "dinginessentail < 1.1" - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.0')" - - - name: Install dinginessentail >= 1.1 - yum: - name: "dinginessentail >= 1.1" - state: present - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify installation - assert: - that: - - "yum_result.changed" - - "rpm_result.stdout.startswith('dinginessentail-1.1')" - - - name: Verify yum module outputs - assert: - that: - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - - always: - - name: Clean up - yum: - name: dinginessentail - state: absent - - when: ansible_pkg_mgr == 'yum' - -# https://github.com/ansible/ansible/issues/45250 -- block: - - name: Install dinginessentail-1.0, dinginessentail-olive-1.0, landsidescalping-1.0 - yum: - name: "dinginessentail-1.0,dinginessentail-olive-1.0,landsidescalping-1.0" - state: present - - - name: Upgrade dinginessentail* - yum: - name: dinginessentail* - state: latest - register: yum_result - - - name: Check dinginessentail with rpm - shell: rpm -q dinginessentail - register: rpm_result - - - name: Verify update of dinginessentail - assert: - that: - - "rpm_result.stdout.startswith('dinginessentail-1.1-1')" - - - name: Check dinginessentail-olive with rpm - shell: rpm -q dinginessentail-olive - register: rpm_result - - - name: Verify update of dinginessentail-olive - assert: - that: - - "rpm_result.stdout.startswith('dinginessentail-olive-1.1-1')" - - - name: Check landsidescalping with rpm - shell: rpm -q landsidescalping - register: rpm_result - - - name: Verify landsidescalping did NOT get updated - assert: - that: - - "rpm_result.stdout.startswith('landsidescalping-1.0-1')" - - - name: Verify yum module outputs - assert: - that: - - "yum_result is changed" - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - always: - - name: Clean up - 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 deleted file mode 100644 index 511c577..0000000 --- a/test/integration/targets/yum/tasks/yum.yml +++ /dev/null @@ -1,884 +0,0 @@ -# Setup by setup_rpm_repo -- set_fact: - package1: dinginessentail - package2: dinginessentail-olive - -# UNINSTALL -- name: uninstall {{ package1 }} - yum: name={{ package1 }} state=removed - register: yum_result - -- name: check {{ package1 }} with rpm - shell: rpm -q {{ package1 }} - ignore_errors: True - register: rpm_result - -- name: verify uninstallation of {{ package1 }} - assert: - that: - - "yum_result is success" - - "rpm_result is failed" - -# UNINSTALL AGAIN -- name: uninstall {{ package1 }} again in check mode - yum: name={{ package1 }} state=removed - check_mode: true - register: yum_result - -- name: verify no change on re-uninstall in check mode - assert: - that: - - "not yum_result is changed" - -- name: uninstall {{ package1 }} again - yum: name={{ package1 }} state=removed - register: yum_result - -- name: verify no change on re-uninstall - assert: - that: - - "not yum_result is changed" - -# INSTALL -- name: install {{ package1 }} in check mode - yum: name={{ package1 }} state=present - check_mode: true - register: yum_result - -- name: verify installation of {{ package1 }} in check mode - assert: - that: - - "yum_result is changed" - -- name: install {{ package1 }} - yum: name={{ package1 }} state=present - register: yum_result - -- name: verify installation of {{ package1 }} - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: check {{ package1 }} with rpm - shell: rpm -q {{ package1 }} - -# INSTALL AGAIN -- name: install {{ package1 }} again in check mode - yum: name={{ package1 }} state=present - check_mode: true - register: yum_result -- name: verify no change on second install in check mode - assert: - that: - - "not yum_result is changed" - -- name: install {{ package1 }} again - yum: name={{ package1 }} state=present - register: yum_result -- name: verify no change on second install - assert: - that: - - "not yum_result is changed" - -- name: install {{ package1 }} again with empty string enablerepo - yum: name={{ package1 }} state=present enablerepo="" - register: yum_result -- name: verify no change on third install with empty string enablerepo - assert: - that: - - "yum_result is success" - - "not yum_result is changed" - -# This test case is unfortunately distro specific because we have to specify -# repo names which are not the same across Fedora/RHEL/CentOS for base/updates -- name: install {{ package1 }} again with missing repo enablerepo - yum: - name: '{{ package1 }}' - state: present - enablerepo: '{{ repos + ["thisrepodoesnotexist"] }}' - disablerepo: "*" - register: yum_result - when: ansible_distribution == 'CentOS' -- name: verify no change on fourth install with missing repo enablerepo (yum) - assert: - that: - - "yum_result is success" - - "yum_result is not changed" - when: ansible_distribution == 'CentOS' - -# This test case is unfortunately distro specific because we have to specify -# repo names which are not the same across Fedora/RHEL/CentOS for base/updates -- name: install repos again with disable all and enable select repo(s) - yum: - name: '{{ package1 }}' - state: present - enablerepo: '{{ repos }}' - disablerepo: "*" - register: yum_result - when: ansible_distribution == 'CentOS' -- name: verify no change on fourth install with missing repo enablerepo (yum) - assert: - that: - - "yum_result is success" - - "yum_result is not changed" - when: ansible_distribution == 'CentOS' - -- name: install {{ package1 }} again with only missing repo enablerepo - yum: - name: '{{ package1 }}' - state: present - enablerepo: "thisrepodoesnotexist" - ignore_errors: true - register: yum_result -- name: verify no change on fifth install with only missing repo enablerepo (yum) - assert: - that: - - "yum_result is not success" - when: ansible_pkg_mgr == 'yum' -- name: verify no change on fifth install with only missing repo enablerepo (dnf) - assert: - that: - - "yum_result is success" - when: ansible_pkg_mgr == 'dnf' - -# INSTALL AGAIN WITH LATEST -- name: install {{ package1 }} again with state latest in check mode - yum: name={{ package1 }} state=latest - check_mode: true - register: yum_result -- name: verify install {{ package1 }} again with state latest in check mode - assert: - that: - - "not yum_result is changed" - -- name: install {{ package1 }} again with state latest idempotence - yum: name={{ package1 }} state=latest - register: yum_result -- name: verify install {{ package1 }} again with state latest idempotence - assert: - that: - - "not yum_result is changed" - -# INSTALL WITH LATEST -- name: uninstall {{ package1 }} - yum: name={{ package1 }} state=removed - register: yum_result -- name: verify uninstall {{ package1 }} - assert: - that: - - "yum_result is successful" - -- name: copy yum.conf file in case it is missing - copy: - src: yum.conf - dest: /etc/yum.conf - force: False - register: yum_conf_copy - -- block: - - name: install {{ package1 }} with state latest in check mode with config file param - yum: name={{ package1 }} state=latest conf_file=/etc/yum.conf - check_mode: true - register: yum_result - - name: verify install {{ package1 }} with state latest in check mode with config file param - assert: - that: - - "yum_result is changed" - - always: - - name: remove tmp yum.conf file if we created it - file: - path: /etc/yum.conf - state: absent - when: yum_conf_copy is changed - -- name: install {{ package1 }} with state latest in check mode - yum: name={{ package1 }} state=latest - check_mode: true - register: yum_result -- name: verify install {{ package1 }} with state latest in check mode - assert: - that: - - "yum_result is changed" - -- name: install {{ package1 }} with state latest - yum: name={{ package1 }} state=latest - register: yum_result -- name: verify install {{ package1 }} with state latest - assert: - that: - - "yum_result is changed" - -- name: install {{ package1 }} with state latest idempotence - yum: name={{ package1 }} state=latest - register: yum_result -- name: verify install {{ package1 }} with state latest idempotence - assert: - that: - - "not yum_result is changed" - -- name: install {{ package1 }} with state latest idempotence with config file param - yum: name={{ package1 }} state=latest - register: yum_result -- name: verify install {{ package1 }} with state latest idempotence with config file param - assert: - that: - - "not yum_result is changed" - - -# Multiple packages -- name: uninstall {{ package1 }} and {{ package2 }} - yum: name={{ package1 }},{{ package2 }} state=removed - -- name: check {{ package1 }} with rpm - shell: rpm -q {{ package1 }} - ignore_errors: True - register: rpm_package1_result - -- name: check {{ package2 }} with rpm - shell: rpm -q {{ package2 }} - ignore_errors: True - register: rpm_package2_result - -- name: verify packages installed - assert: - that: - - "rpm_package1_result is failed" - - "rpm_package2_result is failed" - -- name: install {{ package1 }} and {{ package2 }} as comma separated - yum: name={{ package1 }},{{ package2 }} state=present - register: yum_result - -- name: verify packages installed - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: check {{ package1 }} with rpm - shell: rpm -q {{ package1 }} - -- name: check {{ package2 }} with rpm - shell: rpm -q {{ package2 }} - -- name: uninstall {{ package1 }} and {{ package2 }} - yum: name={{ package1 }},{{ package2 }} state=removed - register: yum_result - -- name: install {{ package1 }} and {{ package2 }} as list - yum: - name: - - '{{ package1 }}' - - '{{ package2 }}' - state: present - register: yum_result - -- name: verify packages installed - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: check {{ package1 }} with rpm - shell: rpm -q {{ package1 }} - -- name: check {{ package2 }} with rpm - shell: rpm -q {{ package2 }} - -- name: uninstall {{ package1 }} and {{ package2 }} - yum: name={{ package1 }},{{ package2 }} state=removed - register: yum_result - -- name: install {{ package1 }} and {{ package2 }} as comma separated with spaces - yum: - name: "{{ package1 }}, {{ package2 }}" - state: present - register: yum_result - -- name: verify packages installed - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: check {{ package1 }} with rpm - shell: rpm -q {{ package1 }} - -- name: check {{ package2 }} with rpm - shell: rpm -q {{ package2 }} - -- name: uninstall {{ package1 }} and {{ package2 }} - yum: name={{ package1 }},{{ package2 }} state=removed - -- name: install non-existent rpm - yum: - name: does-not-exist - register: non_existent_rpm - ignore_errors: True - -- name: check non-existent rpm install failed - assert: - that: - - non_existent_rpm is failed - -# Install in installroot='/' -- name: install {{ package1 }} - yum: name={{ package1 }} state=present installroot='/' - register: yum_result - -- name: verify installation of {{ package1 }} - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: check {{ package1 }} with rpm - shell: rpm -q {{ package1 }} --root=/ - -- name: uninstall {{ package1 }} - yum: - name: '{{ package1 }}' - installroot: '/' - state: removed - register: yum_result - -# Seems like some yum versions won't download a package from local file repository, continue to use sos for this test. -# https://stackoverflow.com/questions/58295660/yum-downloadonly-ignores-packages-in-local-repo -- name: Test download_only - yum: - name: sos - state: latest - download_only: true - register: yum_result - -- name: verify download of sos (part 1 -- yum "install" succeeded) - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: uninstall sos (noop) - yum: - name: sos - state: removed - register: yum_result - -- name: verify download of sos (part 2 -- nothing removed during uninstall) - assert: - that: - - "yum_result is success" - - "not yum_result is changed" - -- name: uninstall sos for downloadonly/downloaddir test - yum: - name: sos - state: absent - -- name: Test download_only/download_dir - yum: - name: sos - state: latest - download_only: true - download_dir: "/var/tmp/packages" - register: yum_result - -- name: verify yum output - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- command: "ls /var/tmp/packages" - register: ls_out - -- name: Verify specified download_dir was used - assert: - that: - - "'sos' in ls_out.stdout" - -- name: install group - yum: - name: "@Custom Group" - state: present - register: yum_result - -- name: verify installation of the group - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: install the group again - yum: - name: "@Custom Group" - state: present - register: yum_result - -- name: verify nothing changed - assert: - that: - - "yum_result is success" - - "not yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: install the group again but also with a package that is not yet installed - yum: - name: - - "@Custom Group" - - '{{ package2 }}' - state: present - register: yum_result - -- name: verify {{ package3 }} is installed - assert: - that: - - "yum_result is success" - - "yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: try to install the group again, with --check to check 'changed' - yum: - name: "@Custom Group" - state: present - check_mode: yes - register: yum_result - -- name: verify nothing changed - assert: - that: - - "not yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: try to install non existing group - yum: - name: "@non-existing-group" - state: present - register: yum_result - ignore_errors: True - -- name: verify installation of the non existing group failed - assert: - that: - - "yum_result is failed" - - "not yum_result is changed" - - "yum_result is failed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: try to install non existing file - yum: - name: /tmp/non-existing-1.0.0.fc26.noarch.rpm - state: present - register: yum_result - ignore_errors: yes - -- name: verify installation failed - assert: - that: - - "yum_result is failed" - - "not yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - -- name: try to install from non existing url - yum: - name: https://ci-files.testing.ansible.com/test/integration/targets/yum/non-existing-1.0.0.fc26.noarch.rpm - state: present - register: yum_result - ignore_errors: yes - -- name: verify installation failed - assert: - that: - - "yum_result is failed" - - "not yum_result is changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - -- name: use latest to install httpd - yum: - name: httpd - state: latest - register: yum_result - -- name: verify httpd was installed - assert: - that: - - "'changed' in yum_result" - -- name: uninstall httpd - yum: - name: httpd - state: removed - -- name: update httpd only if it exists - yum: - name: httpd - state: latest - update_only: yes - register: yum_result - -- name: verify httpd not installed - assert: - that: - - "not yum_result is changed" - - "'Packages providing httpd not installed due to update_only specified' in yum_result.results" - -- name: try to install uncompatible arch rpm on non-ppc64le, should fail - yum: - name: https://ci-files.testing.ansible.com/test/integration/targets/yum/banner-1.3.4-3.el7.ppc64le.rpm - state: present - register: yum_result - ignore_errors: True - when: - - ansible_architecture not in ['ppc64le'] - -- name: verify that yum failed on non-ppc64le - assert: - that: - - "not yum_result is changed" - - "yum_result is failed" - when: - - ansible_architecture not in ['ppc64le'] - -- name: try to install uncompatible arch rpm on ppc64le, should fail - yum: - name: https://ci-files.testing.ansible.com/test/integration/targets/yum/tinyproxy-1.10.0-3.el7.x86_64.rpm - state: present - register: yum_result - ignore_errors: True - when: - - ansible_architecture in ['ppc64le'] - -- name: verify that yum failed on ppc64le - assert: - that: - - "not yum_result is changed" - - "yum_result is failed" - when: - - ansible_architecture in ['ppc64le'] - -# setup for testing installing an RPM from url - -- set_fact: - pkg_name: noarchfake - pkg_path: '{{ repodir }}/noarchfake-1.0-1.noarch.rpm' - -- name: cleanup - yum: - name: "{{ pkg_name }}" - state: absent - -# setup end - -- name: install a local noarch rpm from file - yum: - name: "{{ pkg_path }}" - state: present - disable_gpg_check: true - register: yum_result - -- name: verify installation - assert: - that: - - "yum_result is success" - - "yum_result is changed" - - "yum_result is not failed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: install the downloaded rpm again - yum: - name: "{{ pkg_path }}" - state: present - register: yum_result - -- name: verify installation - assert: - that: - - "yum_result is success" - - "not yum_result is changed" - - "yum_result is not failed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: clean up - yum: - name: "{{ pkg_name }}" - state: absent - -- name: install from url - yum: - name: "file://{{ pkg_path }}" - state: present - disable_gpg_check: true - register: yum_result - -- name: verify installation - assert: - that: - - "yum_result is success" - - "yum_result is changed" - - "yum_result is not failed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: Create a temp RPM file which does not contain nevra information - file: - name: "/tmp/non_existent_pkg.rpm" - state: touch - -- name: Try installing RPM file which does not contain nevra information - yum: - name: "/tmp/non_existent_pkg.rpm" - state: present - register: no_nevra_info_result - ignore_errors: yes - -- name: Verify RPM failed to install - assert: - that: - - "'changed' in no_nevra_info_result" - - "'msg' in no_nevra_info_result" - -- name: Delete a temp RPM file - file: - name: "/tmp/non_existent_pkg.rpm" - state: absent - -- name: get yum version - yum: - list: yum - register: yum_version - -- name: set yum_version of installed version - set_fact: - yum_version: "{%- if item.yumstate == 'installed' -%}{{ item.version }}{%- else -%}{{ yum_version }}{%- endif -%}" - with_items: "{{ yum_version.results }}" - -- name: Ensure double uninstall of wildcard globs works - block: - - name: "Install lohit-*-fonts" - yum: - name: "lohit-*-fonts" - state: present - - - name: "Remove lohit-*-fonts (1st time)" - yum: - name: "lohit-*-fonts" - state: absent - register: remove_lohit_fonts_1 - - - name: "Verify lohit-*-fonts (1st time)" - assert: - that: - - "remove_lohit_fonts_1 is changed" - - "'msg' in remove_lohit_fonts_1" - - "'results' in remove_lohit_fonts_1" - - - name: "Remove lohit-*-fonts (2nd time)" - yum: - name: "lohit-*-fonts" - state: absent - register: remove_lohit_fonts_2 - - - name: "Verify lohit-*-fonts (2nd time)" - assert: - that: - - "remove_lohit_fonts_2 is not changed" - - "'msg' in remove_lohit_fonts_2" - - "'results' in remove_lohit_fonts_2" - - "'lohit-*-fonts is not installed' in remove_lohit_fonts_2['results']" - -- block: - - name: uninstall {{ package2 }} - yum: name={{ package2 }} state=removed - - - name: check {{ package2 }} with rpm - shell: rpm -q {{ package2 }} - ignore_errors: True - register: rpm_package2_result - - - name: verify {{ package2 }} is uninstalled - assert: - that: - - "rpm_package2_result is failed" - - - name: exclude {{ package2 }} (yum backend) - lineinfile: - dest: /etc/yum.conf - regexp: (^exclude=)(.)* - line: "exclude={{ package2 }}*" - state: present - when: ansible_pkg_mgr == 'yum' - - - name: exclude {{ package2 }} (dnf backend) - lineinfile: - dest: /etc/dnf/dnf.conf - regexp: (^excludepkgs=)(.)* - line: "excludepkgs={{ package2 }}*" - state: present - when: ansible_pkg_mgr == 'dnf' - - # begin test case where disable_excludes is supported - - name: Try install {{ package2 }} without disable_excludes - yum: name={{ package2 }} state=latest - register: yum_package2_result - ignore_errors: True - - - name: verify {{ package2 }} did not install because it is in exclude list - assert: - that: - - "yum_package2_result is failed" - - - name: install {{ package2 }} with disable_excludes - yum: name={{ package2 }} state=latest disable_excludes=all - register: yum_package2_result_using_excludes - - - name: verify {{ package2 }} did install using disable_excludes=all - assert: - that: - - "yum_package2_result_using_excludes is success" - - "yum_package2_result_using_excludes is changed" - - "yum_package2_result_using_excludes is not failed" - - - name: remove exclude {{ package2 }} (cleanup yum.conf) - lineinfile: - dest: /etc/yum.conf - regexp: (^exclude={{ package2 }}*) - line: "exclude=" - state: present - when: ansible_pkg_mgr == 'yum' - - - name: remove exclude {{ package2 }} (cleanup dnf.conf) - lineinfile: - dest: /etc/dnf/dnf.conf - regexp: (^excludepkgs={{ package2 }}*) - line: "excludepkgs=" - state: present - when: ansible_pkg_mgr == 'dnf' - - # Fedora < 26 has a bug in dnf where package excludes in dnf.conf aren't - # actually honored and those releases are EOL'd so we have no expectation they - # will ever be fixed - when: not ((ansible_distribution == "Fedora") and (ansible_distribution_major_version|int < 26)) - -- name: Check that packages with Provides are handled correctly in state=absent - block: - - name: Install test packages - yum: - name: - - https://ci-files.testing.ansible.com/test/integration/targets/yum/test-package-that-provides-toaster-1.3.3.7-1.el7.noarch.rpm - - https://ci-files.testing.ansible.com/test/integration/targets/yum/toaster-1.2.3.4-1.el7.noarch.rpm - disable_gpg_check: true - register: install - - - name: Remove toaster - yum: - name: toaster - state: absent - register: remove - - - name: rpm -qa - command: rpm -qa - register: rpmqa - - - assert: - that: - - install is successful - - install is changed - - remove is successful - - remove is changed - - "'toaster-1.2.3.4' not in rpmqa.stdout" - - "'test-package-that-provides-toaster' in rpmqa.stdout" - always: - - name: Remove test packages - yum: - name: - - 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/tasks/yum_group_remove.yml b/test/integration/targets/yum/tasks/yum_group_remove.yml deleted file mode 100644 index 22c6dcb..0000000 --- a/test/integration/targets/yum/tasks/yum_group_remove.yml +++ /dev/null @@ -1,152 +0,0 @@ -- name: install a group to test and yum-utils - yum: - name: "{{ pkgs }}" - state: present - vars: - pkgs: - - "@Custom Group" - - yum-utils - when: ansible_pkg_mgr == "yum" - -- name: install a group to test and dnf-utils - yum: - name: "{{ pkgs }}" - state: present - vars: - pkgs: - - "@Custom Group" - - dnf-utils - when: ansible_pkg_mgr == "dnf" - -- name: check mode remove the group - yum: - name: "@Custom Group" - state: absent - check_mode: yes - register: yum_result - -- name: verify changed - assert: - that: - - "yum_result.changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'results' in yum_result" - -- name: remove the group - yum: - name: "@Custom Group" - state: absent - register: yum_result - -- name: verify changed - assert: - that: - - "yum_result.rc == 0" - - "yum_result.changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: remove the group again - yum: - name: "@Custom Group" - state: absent - register: yum_result - -- name: verify changed - assert: - that: - - "not yum_result.changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: check mode remove the group again - yum: - name: "@Custom Group" - state: absent - check_mode: yes - register: yum_result - -- name: verify changed - assert: - that: - - "not yum_result.changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'results' in yum_result" - -- name: install a group and a package to test - yum: - name: "@Custom Group,sos" - state: present - register: yum_output - -- name: check mode remove the group along with the package - yum: - name: "@Custom Group,sos" - state: absent - register: yum_result - check_mode: yes - -- name: verify changed - assert: - that: - - "yum_result.changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'results' in yum_result" - -- name: remove the group along with the package - yum: - name: "@Custom Group,sos" - state: absent - register: yum_result - -- name: verify changed - assert: - that: - - "yum_result.changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'results' in yum_result" - -- name: check mode remove the group along with the package - yum: - name: "@Custom Group,sos" - state: absent - register: yum_result - check_mode: yes - -- name: verify not changed - assert: - that: - - "not yum_result.changed" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'results' in yum_result" diff --git a/test/integration/targets/yum/tasks/yuminstallroot.yml b/test/integration/targets/yum/tasks/yuminstallroot.yml deleted file mode 100644 index 028e805..0000000 --- a/test/integration/targets/yum/tasks/yuminstallroot.yml +++ /dev/null @@ -1,132 +0,0 @@ -# make a installroot -- name: Create installroot - command: mktemp -d "{{ remote_tmp_dir }}/ansible.test.XXXXXX" - register: yumroot - -#- name: Populate directory -# file: -# path: "/{{ yumroot.stdout }}/etc/" -# state: directory -# mode: 0755 -# -#- name: Populate directory2 -# copy: -# content: "[main]\ndistropkgver={{ ansible_distribution_version }}\n" -# dest: "/{{ yumroot.stdout }}/etc/yum.conf" - -- name: Make a necessary directory - file: - path: "{{ yumroot.stdout }}/etc/yum/vars/" - state: directory - mode: 0755 - -- name: get yum releasever - command: "{{ ansible_python_interpreter }} -c 'import yum; yb = yum.YumBase(); print(yb.conf.yumvar[\"releasever\"])'" - register: releasever - ignore_errors: yes - -- name: Populate directory - copy: - content: "{{ releasever.stdout_lines[-1] }}\n" - dest: "/{{ yumroot.stdout }}/etc/yum/vars/releasever" - when: releasever is successful - -# This will drag in > 200 MB. -- name: attempt installroot - yum: name=zlib installroot="{{ yumroot.stdout }}/" disable_gpg_check=yes - register: yum_result - -- name: check sos with rpm in installroot - shell: rpm -q zlib --root="{{ yumroot.stdout }}/" - failed_when: False - register: rpm_result - -- name: verify installation of sos - assert: - that: - - "yum_result.rc == 0" - - "yum_result.changed" - - "rpm_result.rc == 0" - -- name: verify yum module outputs - assert: - that: - - "'changed' in yum_result" - - "'msg' in yum_result" - - "'rc' in yum_result" - - "'results' in yum_result" - -- name: cleanup installroot - file: - path: "{{ yumroot.stdout }}/" - state: absent - -# Test for releasever working correctly -# -# Bugfix: https://github.com/ansible/ansible/issues/67050 -# -# This test case is based on a reproducer originally reported on Reddit: -# https://www.reddit.com/r/ansible/comments/g2ps32/ansible_yum_module_throws_up_an_error_when/ -# -# NOTE: For the Ansible upstream CI we can only run this for RHEL7 because the -# containerized runtimes in shippable don't allow the nested mounting of -# buildah container volumes. -- name: perform yuminstallroot in a buildah mount with releasever - when: - - ansible_facts["distribution_major_version"] == "7" - - ansible_facts["distribution"] == "RedHat" - block: - - name: install required packages for buildah test - yum: - state: present - name: - - buildah - - name: create buildah container from scratch - command: "buildah --name yum_installroot_releasever_test from scratch" - - name: mount the buildah container - command: "buildah mount yum_installroot_releasever_test" - register: buildah_mount - - name: figure out yum value of $releasever - shell: python -c 'import yum; yb = yum.YumBase(); print(yb.conf.yumvar["releasever"])' | tail -1 - register: buildah_host_releasever - - name: test yum install of python using releasever - yum: - name: 'python' - state: present - installroot: "{{ buildah_mount.stdout }}" - releasever: "{{ buildah_host_releasever.stdout }}" - register: yum_result - - name: verify installation of python - assert: - that: - - "yum_result.rc == 0" - - "yum_result.changed" - - "rpm_result.rc == 0" - - name: remove python before another test - yum: - name: 'python' - state: absent - installroot: "{{ buildah_mount.stdout }}" - releasever: "{{ buildah_host_releasever.stdout }}" - - name: test yum install of python using releasever with latest - yum: - name: 'python' - state: latest - installroot: "{{ buildah_mount.stdout }}" - releasever: "{{ buildah_host_releasever.stdout }}" - register: yum_result - - name: verify installation of python - assert: - that: - - "yum_result.rc == 0" - - "yum_result.changed" - - "rpm_result.rc == 0" - always: - - name: remove buildah container - command: "buildah rm yum_installroot_releasever_test" - ignore_errors: yes - - name: remove buildah from CI system - yum: - state: absent - name: - - buildah diff --git a/test/integration/targets/yum/vars/main.yml b/test/integration/targets/yum/vars/main.yml deleted file mode 100644 index a2a073f..0000000 --- a/test/integration/targets/yum/vars/main.yml +++ /dev/null @@ -1 +0,0 @@ -multiarch_repo_baseurl: https://ci-files.testing.ansible.com/test/integration/targets/yum/multiarch-test-repo/RPMS/ |