summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-25 02:51:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-25 02:51:10 +0000
commiteee9982be19a16d860b7e9dde05850e7f8c2276a (patch)
tree21d77352ca156d2d5671ffcdc88a65d4f7fb97b0 /test
parentReleasing progress-linux version 2.16.5-1~progress7.99u1. (diff)
downloadansible-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')
-rw-r--r--test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/_module3.py32
-rw-r--r--test/integration/targets/async/check_task_test.yml8
-rw-r--r--test/integration/targets/async/tasks/main.yml12
-rw-r--r--test/integration/targets/blockinfile/tasks/create_file.yml14
-rwxr-xr-xtest/integration/targets/config/runme.sh3
-rw-r--r--test/integration/targets/connection_local/connection_plugins/network_noop.py95
-rwxr-xr-xtest/integration/targets/connection_local/runme.sh7
-rw-r--r--test/integration/targets/connection_local/test_network_connection.inventory2
-rw-r--r--test/integration/targets/connection_windows_ssh/tests.yml12
-rw-r--r--test/integration/targets/connection_winrm/tests.yml12
-rw-r--r--test/integration/targets/dnf/tasks/dnf.yml11
-rw-r--r--test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml24
-rw-r--r--test/integration/targets/find/aliases2
-rw-r--r--test/integration/targets/find/meta/main.yml1
-rw-r--r--test/integration/targets/find/tasks/main.yml56
-rwxr-xr-xtest/integration/targets/include_import/runme.sh4
-rw-r--r--test/integration/targets/include_import/tasks/test_dynamic_allow_dup.yml30
-rw-r--r--test/lib/ansible_test/_internal/commands/sanity/ansible_doc.py2
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])