summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/collections/posix.yml
diff options
context:
space:
mode:
Diffstat (limited to 'test/integration/targets/collections/posix.yml')
-rw-r--r--test/integration/targets/collections/posix.yml443
1 files changed, 443 insertions, 0 deletions
diff --git a/test/integration/targets/collections/posix.yml b/test/integration/targets/collections/posix.yml
new file mode 100644
index 00000000..903fb4ff
--- /dev/null
+++ b/test/integration/targets/collections/posix.yml
@@ -0,0 +1,443 @@
+- hosts: testhost
+ tasks:
+ # basic test of FQ module lookup and that we got the right one (user-dir hosted)
+ - name: exec FQ module in a user-dir testns collection
+ testns.testcoll.testmodule:
+ register: testmodule_out
+
+ # verifies that distributed collection subpackages are visible under a multi-location namespace (testns exists in user and sys locations)
+ - name: exec FQ module in a sys-dir testns collection
+ testns.coll_in_sys.systestmodule:
+ register: systestmodule_out
+
+ # verifies that content-adjacent collections were automatically added to the installed content roots
+ - name: exec FQ module from content-adjacent collection
+ testns.content_adj.contentadjmodule:
+ register: contentadjmodule_out
+
+ # content should only be loaded from the first visible instance of a collection
+ - name: attempt to look up FQ module in a masked collection
+ testns.testcoll.plugin_lookup:
+ type: module
+ name: testns.testcoll.maskedmodule
+ register: maskedmodule_out
+
+ # ensure the ansible ns can have real collections added to it
+ - name: call an external module in the ansible namespace
+ ansible.bullcoll.bullmodule:
+ register: bullmodule_out
+
+ # ensure the ansible ns cannot override ansible.builtin externally
+ - name: call an external module in the ansible.builtin collection (should use the built in module)
+ ansible.builtin.ping:
+ register: builtin_ping_out
+
+ # action in a collection subdir
+ - name: test subdir action FQ
+ testns.testcoll.action_subdir.subdir_ping_action:
+ register: subdir_ping_action_out
+
+ # module in a collection subdir
+ - name: test subdir module FQ
+ testns.testcoll.module_subdir.subdir_ping_module:
+ register: subdir_ping_module_out
+
+ # module with a granular module_utils import (from (this collection).module_utils.leaf import thingtocall)
+ - name: exec module with granular module utils import from this collection
+ testns.testcoll.uses_leaf_mu_granular_import:
+ register: granular_out
+
+ # module with a granular nested module_utils import (from (this collection).module_utils.base import thingtocall,
+ # where base imports secondary from the same collection's module_utils)
+ - name: exec module with nested module utils from this collection
+ testns.testcoll.uses_base_mu_granular_nested_import:
+ register: granular_nested_out
+
+ # module with a flat module_utils import (import (this collection).module_utils.leaf)
+ - name: exec module with flat module_utils import from this collection
+ testns.testcoll.uses_leaf_mu_flat_import:
+ register: flat_out
+
+ # module with a full-module module_utils import using 'from' (from (this collection).module_utils import leaf)
+ - name: exec module with full-module module_utils import using 'from' from this collection
+ testns.testcoll.uses_leaf_mu_module_import_from:
+ register: from_out
+
+ # module with multiple levels of the same nested package name and imported as a function
+ - name: exec module with multiple levels of the same nested package name imported as a function
+ testns.testcoll.uses_nested_same_as_func:
+ register: from_nested_func
+
+ # module with multiple levels of the same nested package name and imported as a module
+ - name: exec module with multiple levels of the same nested package name imported as a module
+ testns.testcoll.uses_nested_same_as_module:
+ register: from_nested_module
+
+ # module using a bunch of collection-level redirected module_utils
+ - name: exec module using a bunch of collection-level redirected module_utils
+ testns.testcoll.uses_collection_redirected_mu:
+ register: from_redirected_mu
+
+ # module with bogus MU
+ - name: exec module with bogus MU
+ testns.testcoll.uses_mu_missing:
+ ignore_errors: true
+ register: from_missing_mu
+
+ # module with redirected MU, redirect collection not found
+ - name: exec module with a missing redirect target collection
+ testns.testcoll.uses_mu_missing_redirect_collection:
+ ignore_errors: true
+ register: from_missing_redir_collection
+
+ # module with redirected MU, redirect module not found
+ - name: exec module with a missing redirect target module
+ testns.testcoll.uses_mu_missing_redirect_module:
+ ignore_errors: true
+ register: from_missing_redir_module
+
+ - assert:
+ that:
+ - testmodule_out.source == 'user'
+ - systestmodule_out.source == 'sys'
+ - contentadjmodule_out.source == 'content_adj'
+ - not maskedmodule_out.plugin_path
+ - bullmodule_out.source == 'user_ansible_bullcoll'
+ - builtin_ping_out.source is not defined
+ - builtin_ping_out.ping == 'pong'
+ - subdir_ping_action_out is not changed
+ - subdir_ping_module_out is not changed
+ - granular_out.mu_result == 'thingtocall in leaf'
+ - granular_nested_out.mu_result == 'thingtocall in base called thingtocall in secondary'
+ - flat_out.mu_result == 'thingtocall in leaf'
+ - from_out.mu_result == 'thingtocall in leaf'
+ - from_out.mu2_result == 'thingtocall in secondary'
+ - from_out.mu3_result == 'thingtocall in subpkg.submod'
+ - from_out.mu4_result == 'thingtocall in subpkg_with_init'
+ - from_out.mu5_result == 'thingtocall in mod_in_subpkg_with_init'
+ - from_out.mu6_result == 'thingtocall in subpkg.submod'
+ - from_nested_func.mu_result == 'hello from nested_same'
+ - from_nested_module.mu_result == 'hello from nested_same'
+ - from_redirected_mu.mu_result == 'hello from ansible_collections.testns.content_adj.plugins.module_utils.sub1.foomodule'
+ - from_redirected_mu.mu_result2 == 'hello from testns.othercoll.formerly_testcoll_pkg.thing'
+ - from_redirected_mu.mu_result3 == 'hello from formerly_testcoll_pkg.submod.thing'
+ - from_missing_mu is failed
+ - "'Could not find imported module support' in from_missing_mu.msg"
+ - from_missing_redir_collection is failed
+ - "'unable to locate collection bogusns.boguscoll' in from_missing_redir_collection.msg"
+ - from_missing_redir_module is failed
+ - "'Could not find imported module support code for ansible_collections.testns.testcoll.plugins.modules.uses_mu_missing_redirect_module' in from_missing_redir_module.msg"
+
+
+- hosts: testhost
+ tasks:
+ - name: exercise filters/tests/lookups
+ assert:
+ that:
+ - "'data' | testns.testcoll.testfilter == 'data_via_testfilter_from_userdir'"
+ - "'data' | testns.testcoll.testfilter2 == 'data_via_testfilter2_from_userdir'"
+ - "'data' | testns.testcoll.filter_subdir.test_subdir_filter == 'data_via_testfilter_from_subdir'"
+ - "'from_user' is testns.testcoll.testtest"
+ - "'from_user2' is testns.testcoll.testtest2"
+ - "'subdir_from_user' is testns.testcoll.test_subdir.subdir_test"
+ - lookup('testns.testcoll.mylookup') == 'mylookup_from_user_dir'
+ - lookup('testns.testcoll.mylookup2') == 'mylookup2_from_user_dir'
+ - lookup('testns.testcoll.lookup_subdir.my_subdir_lookup') == 'subdir_lookup_from_user_dir'
+
+ - debug:
+ msg: "{{ 'foo'|testns.testbroken.broken }}"
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - |
+ 'This is a broken filter plugin.' in result.msg
+
+ - debug:
+ msg: "{{ 'foo'|missing.collection.filter }}"
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+
+# ensure that the synthetic ansible.builtin collection limits to builtin plugins, that ansible.legacy loads overrides
+# from legacy plugin dirs, and that a same-named plugin loaded from a real collection is not masked by the others
+- hosts: testhost
+ tasks:
+ - name: test unqualified ping from library dir
+ ping:
+ register: unqualified_ping_out
+
+ - name: test legacy-qualified ping from library dir
+ ansible.legacy.ping:
+ register: legacy_ping_out
+
+ - name: test builtin ping
+ ansible.builtin.ping:
+ register: builtin_ping_out
+
+ - name: test collection-based ping
+ testns.testcoll.ping:
+ register: collection_ping_out
+
+ - assert:
+ that:
+ - unqualified_ping_out.source == 'legacy_library_dir'
+ - legacy_ping_out.source == 'legacy_library_dir'
+ - builtin_ping_out.ping == 'pong'
+ - collection_ping_out.source == 'user'
+
+# verify the default value for the collections list is empty
+- hosts: testhost
+ tasks:
+ - name: sample default collections value
+ testns.testcoll.plugin_lookup:
+ register: coll_default_out
+
+ - assert:
+ that:
+ # in original release, collections defaults to empty, which is mostly equivalent to ansible.legacy
+ - not coll_default_out.collection_list
+
+
+# ensure that inheritance/masking works as expected, that the proper default values are injected when missing,
+# and that the order is preserved if one of the magic values is explicitly specified
+- name: verify collections keyword play/block/task inheritance and magic values
+ hosts: testhost
+ collections:
+ - bogus.fromplay
+ tasks:
+ - name: sample play collections value
+ testns.testcoll.plugin_lookup:
+ register: coll_play_out
+
+ - name: collections override block-level
+ collections:
+ - bogus.fromblock
+ block:
+ - name: sample block collections value
+ testns.testcoll.plugin_lookup:
+ register: coll_block_out
+
+ - name: sample task collections value
+ collections:
+ - bogus.fromtask
+ testns.testcoll.plugin_lookup:
+ register: coll_task_out
+
+ - name: sample task with explicit core
+ collections:
+ - ansible.builtin
+ - bogus.fromtaskexplicitcore
+ testns.testcoll.plugin_lookup:
+ register: coll_task_core
+
+ - name: sample task with explicit legacy
+ collections:
+ - ansible.legacy
+ - bogus.fromtaskexplicitlegacy
+ testns.testcoll.plugin_lookup:
+ register: coll_task_legacy
+
+ - assert:
+ that:
+ # ensure that parent value inheritance is masked properly by explicit setting
+ - coll_play_out.collection_list == ['bogus.fromplay', 'ansible.legacy']
+ - coll_block_out.collection_list == ['bogus.fromblock', 'ansible.legacy']
+ - coll_task_out.collection_list == ['bogus.fromtask', 'ansible.legacy']
+ - coll_task_core.collection_list == ['ansible.builtin', 'bogus.fromtaskexplicitcore']
+ - coll_task_legacy.collection_list == ['ansible.legacy', 'bogus.fromtaskexplicitlegacy']
+
+- name: verify unqualified plugin resolution behavior
+ hosts: testhost
+ collections:
+ - testns.testcoll
+ - testns.coll_in_sys
+ - testns.contentadj
+ tasks:
+ # basic test of unqualified module lookup and that we got the right one (user-dir hosted, there's another copy of
+ # this one in the same-named collection in sys dir that should be masked
+ - name: exec unqualified module in a user-dir testns collection
+ testmodule:
+ register: testmodule_out
+
+ # use another collection to verify that we're looking in all collections listed on the play
+ - name: exec unqualified module in a sys-dir testns collection
+ systestmodule:
+ register: systestmodule_out
+
+ - assert:
+ that:
+ - testmodule_out.source == 'user'
+ - systestmodule_out.source == 'sys'
+
+# test keyword-static execution of a FQ collection-backed role with "tasks/main.yaml"
+- name: verify collection-backed role execution (keyword static)
+ hosts: testhost
+ collections:
+ # set to ansible.builtin only to ensure that roles function properly without inheriting the play's collections config
+ - ansible.builtin
+ vars:
+ test_role_input: keyword static
+ roles:
+ - role: testns.testcoll.testrole_main_yaml
+ tasks:
+ - name: ensure role executed
+ assert:
+ that:
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'collection'
+
+
+# test dynamic execution of a FQ collection-backed role
+- name: verify collection-backed role execution (dynamic)
+ hosts: testhost
+ collections:
+ # set to ansible.builtin only to ensure that roles function properly without inheriting the play's collections config
+ - ansible.builtin
+ vars:
+ test_role_input: dynamic
+ tasks:
+ - include_role:
+ name: testns.testcoll.testrole
+ - name: ensure role executed
+ assert:
+ that:
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'collection'
+
+# test task-static execution of a FQ collection-backed role
+- name: verify collection-backed role execution (task static)
+ hosts: testhost
+ collections:
+ - ansible.builtin
+ vars:
+ test_role_input: task static
+ tasks:
+ - import_role:
+ name: testns.testcoll.testrole
+ - name: ensure role executed
+ assert:
+ that:
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'collection'
+
+
+# test a legacy playbook-adjacent role, ensure that play collections config is not inherited
+- name: verify legacy playbook-adjacent role behavior
+ hosts: testhost
+ collections:
+ - bogus.bogus
+ vars:
+ test_role_input: legacy playbook-adjacent
+ roles:
+ - testrole
+# FIXME: this should technically work to look up a playbook-adjacent role
+# - ansible.legacy.testrole
+ tasks:
+ - name: ensure role executed
+ assert:
+ that:
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'legacy roles dir'
+
+
+# test dynamic execution of a FQ collection-backed role
+- name: verify collection-backed role execution in subdir (include)
+ hosts: testhost
+ vars:
+ test_role_input: dynamic (subdir)
+ tasks:
+ - include_role:
+ name: testns.testcoll.role_subdir.subdir_testrole
+ - name: ensure role executed
+ assert:
+ that:
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'collection'
+
+
+# test collection-relative role deps (keyword static)
+- name: verify collection-relative role deps
+ hosts: testhost
+ vars:
+ outer_role_input: keyword static outer
+ test_role_input: keyword static inner
+ roles:
+ - testns.testcoll.calls_intra_collection_dep_role_unqualified
+ tasks:
+ - assert:
+ that:
+ - outer_role_output.msg == outer_role_input
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'collection'
+
+# test collection-relative role deps (task static)
+- name: verify collection-relative role deps
+ hosts: testhost
+ vars:
+ outer_role_input: task static outer
+ test_role_input: task static inner
+ tasks:
+ - import_role:
+ name: testns.testcoll.calls_intra_collection_dep_role_unqualified
+ - assert:
+ that:
+ - outer_role_output.msg == outer_role_input
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'collection'
+
+# test collection-relative role deps (task dynamic)
+- name: verify collection-relative role deps
+ hosts: testhost
+ vars:
+ outer_role_input: task dynamic outer
+ test_role_input: task dynamic inner
+ tasks:
+ - include_role:
+ name: testns.testcoll.calls_intra_collection_dep_role_unqualified
+ - assert:
+ that:
+ - outer_role_output.msg == outer_role_input
+ - test_role_output.msg == test_role_input
+ - testrole_source == 'collection'
+
+
+- name: validate static task include behavior
+ hosts: testhost
+ collections:
+ - bogus.bogus
+ tasks:
+ - import_tasks: includeme.yml
+
+
+- name: validate dynamic task include behavior
+ hosts: testhost
+ collections:
+ - bogus.bogus
+ tasks:
+ - include_tasks: includeme.yml
+
+
+- import_playbook: test_collection_meta.yml
+- name: Test FQCN handlers
+ hosts: testhost
+ vars:
+ handler_counter: 0
+ roles:
+ - testns.testcoll.test_fqcn_handlers
+
+- name: Ensure a collection role can call a standalone role
+ hosts: testhost
+ roles:
+ - testns.testcoll.call_standalone
+
+# Issue https://github.com/ansible/ansible/issues/69054
+- name: Test collection as string
+ hosts: testhost
+ collections: foo
+ tasks:
+ - debug: msg="Test"