diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-25 02:51:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-25 02:51:10 +0000 |
commit | eee9982be19a16d860b7e9dde05850e7f8c2276a (patch) | |
tree | 21d77352ca156d2d5671ffcdc88a65d4f7fb97b0 /test | |
parent | Releasing progress-linux version 2.16.5-1~progress7.99u1. (diff) | |
download | ansible-core-eee9982be19a16d860b7e9dde05850e7f8c2276a.tar.xz ansible-core-eee9982be19a16d860b7e9dde05850e7f8c2276a.zip |
Merging upstream version 2.16.6.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test')
18 files changed, 326 insertions, 1 deletions
diff --git a/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/_module3.py b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/_module3.py new file mode 100644 index 0000000..41784ae --- /dev/null +++ b/test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/_module3.py @@ -0,0 +1,32 @@ +#!/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: _module3 +short_description: Another test module +description: This is a test module that has not been deprecated. +author: + - Ansible Core Team +''' + +EXAMPLES = ''' +- minimal: +''' + +RETURN = '''''' + +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/async/check_task_test.yml b/test/integration/targets/async/check_task_test.yml new file mode 100644 index 0000000..f875640 --- /dev/null +++ b/test/integration/targets/async/check_task_test.yml @@ -0,0 +1,8 @@ +- hosts: localhost + gather_facts: false + tasks: + - name: Async in check mode task disabled test + command: sleep 5 + async: 6 + poll: 1 + check_mode: False diff --git a/test/integration/targets/async/tasks/main.yml b/test/integration/targets/async/tasks/main.yml index f5e5c99..491be96 100644 --- a/test/integration/targets/async/tasks/main.yml +++ b/test/integration/targets/async/tasks/main.yml @@ -298,3 +298,15 @@ - assert: that: - '"ASYNC POLL on localhost" in callback_output.stdout' + +- name: run playbook in --check with task disabling check mode + command: ansible-playbook {{ role_path }}/check_task_test.yml --check + register: check_task_disabled_output + delegate_to: localhost + environment: + ANSIBLE_NOCOLOR: 'true' + ANSIBLE_FORCE_COLOR: 'false' + +- assert: + that: + - '"ASYNC OK on localhost" in check_task_disabled_output.stdout' diff --git a/test/integration/targets/blockinfile/tasks/create_file.yml b/test/integration/targets/blockinfile/tasks/create_file.yml index c8ded30..9a5cf05 100644 --- a/test/integration/targets/blockinfile/tasks/create_file.yml +++ b/test/integration/targets/blockinfile/tasks/create_file.yml @@ -30,3 +30,17 @@ - empty_test_2 is changed - "'Block removed' in empty_test_2.msg" - empty_test_stat.stat.size == 0 + +- block: + - name: Create file in current directory + blockinfile: + path: "empty.txt" + block: Hello. + state: present + create: yes + + always: + - name: Remove file + file: + path: "empty.txt" + state: absent diff --git a/test/integration/targets/config/runme.sh b/test/integration/targets/config/runme.sh index 122e15d..5b999e3 100755 --- a/test/integration/targets/config/runme.sh +++ b/test/integration/targets/config/runme.sh @@ -41,3 +41,6 @@ do ANSIBLE_LOOKUP_PLUGINS=./ ansible-config init types -t lookup -f "${format}" > "files/types.new.${format}" diff -u "files/types.${format}" "files/types.new.${format}" done + +# ensure we don't show default templates, but templated defaults +[ "$(ansible-config init |grep '={{' -c )" -eq 0 ] diff --git a/test/integration/targets/connection_local/connection_plugins/network_noop.py b/test/integration/targets/connection_local/connection_plugins/network_noop.py new file mode 100644 index 0000000..5b0c584 --- /dev/null +++ b/test/integration/targets/connection_local/connection_plugins/network_noop.py @@ -0,0 +1,95 @@ +# (c) 2024 Red Hat Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +DOCUMENTATION = """ +connection: network_noop +author: ansible-core +short_description: legacy-ish connection plugin with only minimal config +description: + - A wrapper around NetworkConnectionBase to test that the default attributes don't cause internal errors in TE. +options: + persistent_log_messages: + type: boolean + description: + - This flag will enable logging the command executed and response received from + target device in the ansible log file. For this option to work 'log_path' ansible + configuration option is required to be set to a file path with write access. + - Be sure to fully understand the security implications of enabling this + option as it could create a security vulnerability by logging sensitive information in log file. + default: False + ini: + - section: persistent_connection + key: log_messages + env: + - name: ANSIBLE_PERSISTENT_LOG_MESSAGES + vars: + - name: ansible_persistent_log_messages + persistent_command_timeout: + type: int + description: + - Configures, in seconds, the amount of time to wait for a command to + return from the remote device. If this timer is exceeded before the + command returns, the connection plugin will raise an exception and + close. + default: 30 + ini: + - section: persistent_connection + key: command_timeout + env: + - name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT + vars: + - name: ansible_command_timeout + persistent_connect_timeout: + type: int + description: + - Configures, in seconds, the amount of time to wait when trying to + initially establish a persistent connection. If this value expires + before the connection to the remote device is completed, the connection + will fail. + default: 30 + ini: + - section: persistent_connection + key: connect_timeout + env: + - name: ANSIBLE_PERSISTENT_CONNECT_TIMEOUT + vars: +extends_documentation_fragment: + - connection_pipelining +""" + +from ansible.plugins.connection import NetworkConnectionBase, ensure_connect +from ansible.utils.display import Display + +display = Display() + + +class Connection(NetworkConnectionBase): + transport = 'network_noop' + has_pipelining = True + + def __init__(self, play_context, new_stdin, *args, **kwargs): + super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs) + + @ensure_connect + def exec_command(self, *args, **kwargs): + return super(Connection, self).exec_command(*args, **kwargs) + + @ensure_connect + def put_file(self, *args, **kwargs): + return super(Connection, self).put_file(*args, **kwargs) + + @ensure_connect + def fetch_file(self, *args, **kwargs): + return super(Connection, self).fetch_file(*args, **kwargs) + + def _connect(self): + if not self.connected: + self._connected = True + display.vvv("ESTABLISH NEW CONNECTION") + + def close(self): + if self.connected: + display.vvv("CLOSING CONNECTION") + super(Connection, self).close() diff --git a/test/integration/targets/connection_local/runme.sh b/test/integration/targets/connection_local/runme.sh index a2c32ad..42b2b82 100755 --- a/test/integration/targets/connection_local/runme.sh +++ b/test/integration/targets/connection_local/runme.sh @@ -12,3 +12,10 @@ INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \ -e local_tmp=/tmp/ansible-local \ -e remote_tmp=/tmp/ansible-remote \ "$@" + +ANSIBLE_CONNECTION_PLUGINS="../connection_${group}/connection_plugins" INVENTORY="../connection_${group}/test_network_connection.inventory" ./test.sh \ + -e target_hosts="${group}" \ + -e action_prefix= \ + -e local_tmp=/tmp/ansible-local \ + -e remote_tmp=/tmp/ansible-remote \ + "$@" diff --git a/test/integration/targets/connection_local/test_network_connection.inventory b/test/integration/targets/connection_local/test_network_connection.inventory new file mode 100644 index 0000000..8114023 --- /dev/null +++ b/test/integration/targets/connection_local/test_network_connection.inventory @@ -0,0 +1,2 @@ +[all] +local ansible_host=127.0.0.1 ansible_connection=network_noop diff --git a/test/integration/targets/connection_windows_ssh/tests.yml b/test/integration/targets/connection_windows_ssh/tests.yml index e9b538b..3b09f62 100644 --- a/test/integration/targets/connection_windows_ssh/tests.yml +++ b/test/integration/targets/connection_windows_ssh/tests.yml @@ -30,3 +30,15 @@ - win_ssh_async.rc == 0 - win_ssh_async.stdout == "café\n" - win_ssh_async.stderr == "" + + # Ensures the connection plugin can handle a timeout + # without raising another error. + - name: run command with timeout + win_shell: Start-Sleep -Seconds 10 + timeout: 5 + register: timeout_cmd + ignore_errors: true + + - assert: + that: + - timeout_cmd.msg == 'The win_shell action failed to execute in the expected time frame (5) and was terminated' diff --git a/test/integration/targets/connection_winrm/tests.yml b/test/integration/targets/connection_winrm/tests.yml index b086a3a..cf109a8 100644 --- a/test/integration/targets/connection_winrm/tests.yml +++ b/test/integration/targets/connection_winrm/tests.yml @@ -29,3 +29,15 @@ that: - winrm_copy_empty is changed - winrm_copy_empty_actual.stat.size == 0 + + # Ensures the connection plugin can handle a timeout + # without raising another error. + - name: run command with timeout + win_shell: Start-Sleep -Seconds 10 + timeout: 5 + register: timeout_cmd + ignore_errors: true + + - assert: + that: + - timeout_cmd.msg == 'The win_shell action failed to execute in the expected time frame (5) and was terminated' diff --git a/test/integration/targets/dnf/tasks/dnf.yml b/test/integration/targets/dnf/tasks/dnf.yml index 9845f3d..c5f0173 100644 --- a/test/integration/targets/dnf/tasks/dnf.yml +++ b/test/integration/targets/dnf/tasks/dnf.yml @@ -67,6 +67,17 @@ update_cache: True register: dnf_result +- find: + paths: /var/cache/dnf + patterns: "*.rpm" + recurse: true + register: r + +- name: verify that RPM cache is cleared after installation as keepcache is off by default + assert: + that: + - r.matched == 0 + - name: check sos with rpm shell: rpm -q sos failed_when: False diff --git a/test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml b/test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml index d0bf9bd..94941ed 100644 --- a/test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml +++ b/test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml @@ -28,6 +28,28 @@ register: failed_fetch_dest_dir ignore_errors: true +- block: + - name: create local dir for test + file: + path: "{{ output_dir }}/test dir/orig" + state: directory + delegate_to: localhost + + - name: Dest is a path that is calculated as an existing directory, should fail + fetch: + src: "{{ remote_tmp_dir }}/orig" + dest: "{{ output_dir }}/test dir/" + flat: true + register: failed_detch_dest_calc_dir + ignore_errors: true + + always: + - name: remote local dir for test + file: + path: "{{ output_dir }}/test dir" + state: absent + delegate_to: localhost + - name: Test unreachable fetch: src: "{{ remote_tmp_dir }}/orig" @@ -48,4 +70,6 @@ - failed_fetch_no_access.msg is search('file is not readable') - failed_fetch_dest_dir is failed - failed_fetch_dest_dir.msg is search('dest is an existing directory') + - failed_detch_dest_calc_dir is failed + - failed_detch_dest_calc_dir.msg is search("calculated dest '" ~ output_dir ~ "/test dir/orig' is an existing directory") - unreachable_fetch is unreachable diff --git a/test/integration/targets/find/aliases b/test/integration/targets/find/aliases index a6dafcf..cdd75ef 100644 --- a/test/integration/targets/find/aliases +++ b/test/integration/targets/find/aliases @@ -1 +1,3 @@ shippable/posix/group1 +destructive +needs/root
\ No newline at end of file diff --git a/test/integration/targets/find/meta/main.yml b/test/integration/targets/find/meta/main.yml index cb6005d..c384e11 100644 --- a/test/integration/targets/find/meta/main.yml +++ b/test/integration/targets/find/meta/main.yml @@ -1,3 +1,4 @@ dependencies: - prepare_tests + - setup_test_user - setup_remote_tmp_dir diff --git a/test/integration/targets/find/tasks/main.yml b/test/integration/targets/find/tasks/main.yml index 9c4a960..c526dc7 100644 --- a/test/integration/targets/find/tasks/main.yml +++ b/test/integration/targets/find/tasks/main.yml @@ -375,5 +375,61 @@ - 'remote_tmp_dir_test ~ "/astest/.hidden.txt" in astest_list' - '"checksum" in result.files[0]' +# Test permission error is correctly handled by find module +- vars: + test_dir: /tmp/permission_test + block: + - name: Set up content + file: + path: "{{ test_dir }}/{{ item.name }}" + state: "{{ item.state }}" + mode: "{{ item.mode }}" + owner: "{{ item.owner | default(omit) }}" + group: "{{ item.group | default(omit) }}" + loop: + - name: readable + state: directory + owner: "{{ test_user_name }}" + mode: "1711" + - name: readable/1-unreadable + state: directory + mode: "0700" + - name: readable/2-readable + state: touch + owner: "{{ test_user_name }}" + mode: "0777" + + - name: Find a file in readable directory + find: + paths: "{{ test_dir }}/readable/" + patterns: "*" + recurse: true + register: permission_issue + become_user: "{{ test_user_name }}" + + - name: Find a file in readable directory + find: + paths: "{{ test_dir }}/readable/" + patterns: "*" + recurse: true + register: permission_issue + become_user: "{{ test_user_name }}" + become: yes + + - name: Check if the skipped_paths are populated correctly with permission error + assert: + that: + - permission_issue is success + - not permission_issue.changed + - permission_issue.skipped_paths|length == 1 + - "'{{ test_dir }}/readable/1-unreadable' in permission_issue.skipped_paths" + - "'Permission denied' in permission_issue.skipped_paths['{{ test_dir }}/readable/1-unreadable']" + - permission_issue.matched == 1 + always: + - name: cleanup test directory + file: + dest: "{{ test_dir }}" + state: absent + - name: Run mode tests import_tasks: mode.yml diff --git a/test/integration/targets/include_import/runme.sh b/test/integration/targets/include_import/runme.sh index 078f080..d85b22d 100755 --- a/test/integration/targets/include_import/runme.sh +++ b/test/integration/targets/include_import/runme.sh @@ -121,6 +121,10 @@ ansible-playbook valid_include_keywords/playbook.yml "$@" ansible-playbook tasks/test_allow_single_role_dup.yml 2>&1 | tee test_allow_single_role_dup.out test "$(grep -c 'ok=3' test_allow_single_role_dup.out)" = 1 +# Test allow_duplicate with include_role and import_role +test "$(ansible-playbook tasks/test_dynamic_allow_dup.yml --tags include | grep -c 'Tasks file inside role')" = 2 +test "$(ansible-playbook tasks/test_dynamic_allow_dup.yml --tags import | grep -c 'Tasks file inside role')" = 2 + # 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 diff --git a/test/integration/targets/include_import/tasks/test_dynamic_allow_dup.yml b/test/integration/targets/include_import/tasks/test_dynamic_allow_dup.yml new file mode 100644 index 0000000..82e08b3 --- /dev/null +++ b/test/integration/targets/include_import/tasks/test_dynamic_allow_dup.yml @@ -0,0 +1,30 @@ +--- +- name: test for allow_duplicates with include_role + hosts: localhost + gather_facts: false + tags: + - include + tasks: + - include_role: + name: dup_allowed_role + allow_duplicates: false + - include_role: + name: dup_allowed_role + - include_role: + name: dup_allowed_role + allow_duplicates: false + +- name: test for allow_duplicates with import_role + hosts: localhost + gather_facts: false + tags: + - import + tasks: + - import_role: + name: dup_allowed_role + allow_duplicates: false + - import_role: + name: dup_allowed_role + - import_role: + name: dup_allowed_role + allow_duplicates: false diff --git a/test/lib/ansible_test/_internal/commands/sanity/ansible_doc.py b/test/lib/ansible_test/_internal/commands/sanity/ansible_doc.py index ff035ef..1b3b402 100644 --- a/test/lib/ansible_test/_internal/commands/sanity/ansible_doc.py +++ b/test/lib/ansible_test/_internal/commands/sanity/ansible_doc.py @@ -79,7 +79,7 @@ class AnsibleDocTest(SanitySingleVersion): plugin_parts = os.path.relpath(plugin_file_path, plugin_path).split(os.path.sep) plugin_name = os.path.splitext(plugin_parts[-1])[0] - if plugin_name.startswith('_'): + if plugin_name.startswith('_') and not data_context().content.collection: plugin_name = plugin_name[1:] plugin_fqcn = data_context().content.prefix + '.'.join(plugin_parts[:-1] + [plugin_name]) |