summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/ansible-doc
diff options
context:
space:
mode:
Diffstat (limited to 'test/integration/targets/ansible-doc')
-rw-r--r--test/integration/targets/ansible-doc/aliases2
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/MANIFEST.json30
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py70
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py36
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py45
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py28
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py13
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py96
-rw-r--r--test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py30
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/MANIFEST.json30
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py69
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/filter_subdir/in_subdir.py23
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/grouped.py28
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/ultimatequestion.yml21
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py35
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py45
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/database/database_type/subdir_module.py37
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py27
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py13
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py95
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/test_test.py16
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/yolo.yml18
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py29
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml26
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole_with_no_argspecs/meta/empty0
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/MANIFEST.json30
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/deprecation.py16
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/module.py21
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/plugin.py47
-rw-r--r--test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/version_added.py13
-rw-r--r--test/integration/targets/ansible-doc/fakecollrole.output15
-rw-r--r--test/integration/targets/ansible-doc/fakemodule.output16
-rw-r--r--test/integration/targets/ansible-doc/fakerole.output32
-rw-r--r--test/integration/targets/ansible-doc/filter_plugins/donothing.yml21
-rw-r--r--test/integration/targets/ansible-doc/filter_plugins/other.py25
-rw-r--r--test/integration/targets/ansible-doc/filter_plugins/split.yml21
-rw-r--r--test/integration/targets/ansible-doc/inventory1
-rw-r--r--test/integration/targets/ansible-doc/library/double_doc.py19
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs.py39
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_missing_description.py40
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_no_metadata.py35
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_no_status.py38
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_non_iterable_status.py39
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_removed_precedence.py40
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_removed_status.py39
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_returns.py56
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_returns_broken.py40
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_suboptions.py70
-rw-r--r--test/integration/targets/ansible-doc/library/test_docs_yaml_anchors.py71
-rw-r--r--test/integration/targets/ansible-doc/library/test_empty.py0
-rw-r--r--test/integration/targets/ansible-doc/library/test_no_docs.py23
-rw-r--r--test/integration/targets/ansible-doc/library/test_no_docs_no_metadata.py18
-rw-r--r--test/integration/targets/ansible-doc/library/test_no_docs_no_status.py22
-rw-r--r--test/integration/targets/ansible-doc/library/test_no_docs_non_iterable_status.py23
-rw-r--r--test/integration/targets/ansible-doc/library/test_win_module.ps121
-rw-r--r--test/integration/targets/ansible-doc/library/test_win_module.yml9
-rw-r--r--test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_adj_docs.py5
-rw-r--r--test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_docs.py26
-rw-r--r--test/integration/targets/ansible-doc/lookup_plugins/deprecated_with_adj_docs.yml16
-rw-r--r--test/integration/targets/ansible-doc/noop.output32
-rw-r--r--test/integration/targets/ansible-doc/noop_vars_plugin.output42
-rw-r--r--test/integration/targets/ansible-doc/notjsonfile.output157
-rw-r--r--test/integration/targets/ansible-doc/randommodule-text.output101
-rw-r--r--test/integration/targets/ansible-doc/randommodule.output115
-rw-r--r--test/integration/targets/ansible-doc/roles/test_role1/meta/argument_specs.yml34
-rw-r--r--test/integration/targets/ansible-doc/roles/test_role1/meta/main.yml13
-rw-r--r--test/integration/targets/ansible-doc/roles/test_role2/meta/empty0
-rw-r--r--test/integration/targets/ansible-doc/roles/test_role3/meta/main.yml0
-rwxr-xr-xtest/integration/targets/ansible-doc/runme.sh214
-rw-r--r--test/integration/targets/ansible-doc/test.yml172
-rw-r--r--test/integration/targets/ansible-doc/test_docs_returns.output33
-rw-r--r--test/integration/targets/ansible-doc/test_docs_suboptions.output42
-rw-r--r--test/integration/targets/ansible-doc/test_docs_yaml_anchors.output46
-rw-r--r--test/integration/targets/ansible-doc/test_role1/README.txt3
-rw-r--r--test/integration/targets/ansible-doc/test_role1/meta/main.yml8
75 files changed, 2821 insertions, 0 deletions
diff --git a/test/integration/targets/ansible-doc/aliases b/test/integration/targets/ansible-doc/aliases
new file mode 100644
index 0000000..1d28bdb
--- /dev/null
+++ b/test/integration/targets/ansible-doc/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group5
+context/controller
diff --git a/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/MANIFEST.json b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/MANIFEST.json
new file mode 100644
index 0000000..243a5e4
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/MANIFEST.json
@@ -0,0 +1,30 @@
+{
+ "collection_info": {
+ "description": null,
+ "repository": "",
+ "tags": [],
+ "dependencies": {},
+ "authors": [
+ "Ansible (https://ansible.com)"
+ ],
+ "issues": "",
+ "name": "testcol",
+ "license": [
+ "GPL-3.0-or-later"
+ ],
+ "documentation": "",
+ "namespace": "testns",
+ "version": "0.1.1231",
+ "readme": "README.md",
+ "license_file": "COPYING",
+ "homepage": "",
+ },
+ "file_manifest_file": {
+ "format": 1,
+ "ftype": "file",
+ "chksum_sha256": "4c15a867ceba8ba1eaf2f4a58844bb5dbb82fec00645fc7eb74a3d31964900f6",
+ "name": "FILES.json",
+ "chksum_type": "sha256"
+ },
+ "format": 1
+}
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
new file mode 100644
index 0000000..9fa25b4
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py
@@ -0,0 +1,70 @@
+# (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
+
+DOCUMENTATION = '''
+ cache: notjsonfile
+ broken:
+ short_description: JSON formatted files.
+ description:
+ - This cache uses JSON formatted, per host, files saved to the filesystem.
+ author: Ansible Core (@ansible-core)
+ version_added: 0.7.0
+ options:
+ _uri:
+ required: True
+ description:
+ - Path in which the cache plugin will save the JSON files
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_CONNECTION
+ version_added: 1.2.0
+ ini:
+ - key: fact_caching_connection
+ section: defaults
+ deprecated:
+ alternative: none
+ why: Test deprecation
+ version: '2.0.0'
+ _prefix:
+ description: User defined prefix to use when creating the JSON files
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_PREFIX
+ version_added: 1.1.0
+ ini:
+ - key: fact_caching_prefix
+ section: defaults
+ deprecated:
+ alternative: none
+ why: Another test deprecation
+ removed_at_date: '2050-01-01'
+ _timeout:
+ default: 86400
+ description: Expiration timeout for the cache plugin data
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_TIMEOUT
+ ini:
+ - key: fact_caching_timeout
+ section: defaults
+ vars:
+ - name: notsjonfile_fact_caching_timeout
+ version_added: 1.5.0
+ deprecated:
+ alternative: do not use a variable
+ why: Test deprecation
+ version: '3.0.0'
+ type: integer
+ extends_documentation_fragment:
+ - testns.testcol2.plugin
+'''
+
+from ansible.plugins.cache import BaseFileCacheModule
+
+
+class CacheModule(BaseFileCacheModule):
+ """
+ A caching module backed by json files.
+ """
+ pass
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
new file mode 100644
index 0000000..caec2ed
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py
@@ -0,0 +1,36 @@
+# 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
+
+DOCUMENTATION = '''
+ inventory: statichost
+ broken:
+ short_description: Add a single host
+ description: Add a single host
+ extends_documentation_fragment:
+ - inventory_cache
+ options:
+ plugin:
+ description: plugin name (must be statichost)
+ required: true
+ hostname:
+ description: Toggle display of stderr even when script was successful
+ required: True
+'''
+
+from ansible.errors import AnsibleParserError
+from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable
+
+
+class InventoryModule(BaseInventoryPlugin, Cacheable):
+
+ NAME = 'testns.content_adj.statichost'
+
+ def verify_file(self, path):
+ pass
+
+ def parse(self, inventory, loader, path, cache=None):
+
+ pass
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
new file mode 100644
index 0000000..d456986
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py
@@ -0,0 +1,45 @@
+# (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
+
+DOCUMENTATION = """
+ lookup: noop
+ broken:
+ author: Ansible core team
+ short_description: returns input
+ description:
+ - this is a noop
+ deprecated:
+ alternative: Use some other lookup
+ why: Test deprecation
+ removed_in: '3.0.0'
+ extends_documentation_fragment:
+ - testns.testcol2.version_added
+"""
+
+EXAMPLES = """
+- name: do nothing
+ debug: msg="{{ lookup('testns.testcol.noop', [1,2,3,4] }}"
+"""
+
+RETURN = """
+ _list:
+ description: input given
+ version_added: 1.0.0
+"""
+
+from ansible.module_utils.common._collections_compat import Sequence
+from ansible.plugins.lookup import LookupBase
+from ansible.errors import AnsibleError
+
+
+class LookupModule(LookupBase):
+
+ def run(self, terms, **kwargs):
+ if not isinstance(terms, Sequence):
+ raise AnsibleError("testns.testcol.noop expects a list")
+ return terms
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
new file mode 100644
index 0000000..a1caeb1
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+ module: fakemodule
+ broken:
+ short_desciption: fake module
+ description:
+ - this is a fake module
+ version_added: 1.0.0
+ options:
+ _notreal:
+ description: really not a real option
+ author:
+ - me
+"""
+
+import json
+
+
+def main():
+ print(json.dumps(dict(changed=False, source='testns.testcol.fakemodule')))
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..4479f23
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import json
+
+
+def main():
+ print(json.dumps(dict(changed=False, source='testns.testcol.notrealmodule')))
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..fb0e319
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: randommodule
+short_description: A random module
+description:
+ - A random module.
+author:
+ - Ansible Core Team
+version_added: 1.0.0
+deprecated:
+ alternative: Use some other module
+ why: Test deprecation
+ removed_in: '3.0.0'
+options:
+ test:
+ description: Some text.
+ type: str
+ version_added: 1.2.0
+ sub:
+ description: Suboptions.
+ type: dict
+ suboptions:
+ subtest:
+ description: A suboption.
+ type: int
+ version_added: 1.1.0
+ # The following is the wrong syntax, and should not get processed
+ # by add_collection_to_versions_and_dates()
+ options:
+ subtest2:
+ description: Another suboption.
+ type: float
+ version_added: 1.1.0
+ # The following is not supported in modules, and should not get processed
+ # by add_collection_to_versions_and_dates()
+ env:
+ - name: TEST_ENV
+ version_added: 1.0.0
+ deprecated:
+ alternative: none
+ why: Test deprecation
+ removed_in: '2.0.0'
+ version: '2.0.0'
+extends_documentation_fragment:
+ - testns.testcol2.module
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+z_last:
+ description: A last result.
+ broken:
+ type: str
+ returned: success
+ version_added: 1.3.0
+
+m_middle:
+ description:
+ - This should be in the middle.
+ - Has some more data
+ type: dict
+ returned: success and 1st of month
+ contains:
+ suboption:
+ description: A suboption.
+ type: str
+ choices: [ARF, BARN, c_without_capital_first_letter]
+ version_added: 1.4.0
+
+a_first:
+ description: A first result.
+ type: str
+ returned: success
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..ae0f75e
--- /dev/null
+++ b/test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py
@@ -0,0 +1,30 @@
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+ vars: noop_vars_plugin
+ broken:
+ short_description: Do NOT load host and group vars
+ description: don't test loading host and group vars from a collection
+ options:
+ stage:
+ default: all
+ choices: ['all', 'inventory', 'task']
+ type: str
+ ini:
+ - key: stage
+ section: testns.testcol.noop_vars_plugin
+ env:
+ - name: ANSIBLE_VARS_PLUGIN_STAGE
+ extends_documentation_fragment:
+ - testns.testcol2.deprecation
+'''
+
+from ansible.plugins.vars import BaseVarsPlugin
+
+
+class VarsModule(BaseVarsPlugin):
+
+ def get_vars(self, loader, path, entities, cache=True):
+ super(VarsModule, self).get_vars(loader, path, entities)
+ return {'collection': 'yes', 'notreal': 'value'}
diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/MANIFEST.json b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/MANIFEST.json
new file mode 100644
index 0000000..243a5e4
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/MANIFEST.json
@@ -0,0 +1,30 @@
+{
+ "collection_info": {
+ "description": null,
+ "repository": "",
+ "tags": [],
+ "dependencies": {},
+ "authors": [
+ "Ansible (https://ansible.com)"
+ ],
+ "issues": "",
+ "name": "testcol",
+ "license": [
+ "GPL-3.0-or-later"
+ ],
+ "documentation": "",
+ "namespace": "testns",
+ "version": "0.1.1231",
+ "readme": "README.md",
+ "license_file": "COPYING",
+ "homepage": "",
+ },
+ "file_manifest_file": {
+ "format": 1,
+ "ftype": "file",
+ "chksum_sha256": "4c15a867ceba8ba1eaf2f4a58844bb5dbb82fec00645fc7eb74a3d31964900f6",
+ "name": "FILES.json",
+ "chksum_type": "sha256"
+ },
+ "format": 1
+}
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
new file mode 100644
index 0000000..ea4a722
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py
@@ -0,0 +1,69 @@
+# (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
+
+DOCUMENTATION = '''
+ cache: notjsonfile
+ short_description: JSON formatted files.
+ description:
+ - This cache uses JSON formatted, per host, files saved to the filesystem.
+ author: Ansible Core (@ansible-core)
+ version_added: 0.7.0
+ options:
+ _uri:
+ required: True
+ description:
+ - Path in which the cache plugin will save the JSON files
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_CONNECTION
+ version_added: 1.2.0
+ ini:
+ - key: fact_caching_connection
+ section: defaults
+ deprecated:
+ alternative: none
+ why: Test deprecation
+ version: '2.0.0'
+ _prefix:
+ description: User defined prefix to use when creating the JSON files
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_PREFIX
+ version_added: 1.1.0
+ ini:
+ - key: fact_caching_prefix
+ section: defaults
+ deprecated:
+ alternative: none
+ why: Another test deprecation
+ removed_at_date: '2050-01-01'
+ _timeout:
+ default: 86400
+ description: Expiration timeout for the cache plugin data
+ env:
+ - name: ANSIBLE_CACHE_PLUGIN_TIMEOUT
+ ini:
+ - key: fact_caching_timeout
+ section: defaults
+ vars:
+ - name: notsjonfile_fact_caching_timeout
+ version_added: 1.5.0
+ deprecated:
+ alternative: do not use a variable
+ why: Test deprecation
+ version: '3.0.0'
+ type: integer
+ extends_documentation_fragment:
+ - testns.testcol2.plugin
+'''
+
+from ansible.plugins.cache import BaseFileCacheModule
+
+
+class CacheModule(BaseFileCacheModule):
+ """
+ A caching module backed by json files.
+ """
+ pass
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
new file mode 100644
index 0000000..a8924e1
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/filter_subdir/in_subdir.py
@@ -0,0 +1,23 @@
+# 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 ansible.utils.display import Display
+
+display = Display()
+
+
+def nochange(a):
+ return a
+
+
+class FilterModule(object):
+ ''' Ansible core jinja2 filters '''
+
+ def filters(self):
+ return {
+ 'noop': nochange,
+ 'nested': nochange,
+ }
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
new file mode 100644
index 0000000..a10c7aa
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/grouped.py
@@ -0,0 +1,28 @@
+# 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 ansible.utils.display import Display
+
+display = Display()
+
+
+def nochange(a):
+ return a
+
+
+def meaningoflife(a):
+ return 42
+
+
+class FilterModule(object):
+ ''' Ansible core jinja2 filters '''
+
+ def filters(self):
+ return {
+ 'noop': nochange,
+ 'ultimatequestion': meaningoflife,
+ 'b64decode': nochange, # here to colide with basename of builtin
+ }
diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/ultimatequestion.yml b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/ultimatequestion.yml
new file mode 100644
index 0000000..a67654d
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/ultimatequestion.yml
@@ -0,0 +1,21 @@
+DOCUMENTATION:
+ name: ultimatequestion
+ author: Terry Prachet
+ version_added: 'histerical'
+ short_description: Ask any question but it will only respond with the answer to the ulitmate one
+ description:
+ - read the book
+ options:
+ _input:
+ description: Anything you want, goign to ignore it anywayss ...
+ type: raw
+ required: true
+
+EXAMPLES: |
+ # set first 10 volumes rw, rest as dp
+ meaning: "{{ (stuff|ulmtimatequestion }}"
+
+RETURN:
+ _value:
+ description: guess
+ type: int
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
new file mode 100644
index 0000000..cbb8f0f
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py
@@ -0,0 +1,35 @@
+# 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
+
+DOCUMENTATION = '''
+ inventory: statichost
+ short_description: Add a single host
+ description: Add a single host
+ extends_documentation_fragment:
+ - inventory_cache
+ options:
+ plugin:
+ description: plugin name (must be statichost)
+ required: true
+ hostname:
+ description: Toggle display of stderr even when script was successful
+ required: True
+'''
+
+from ansible.errors import AnsibleParserError
+from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable
+
+
+class InventoryModule(BaseInventoryPlugin, Cacheable):
+
+ NAME = 'testns.content_adj.statichost'
+
+ def verify_file(self, path):
+ pass
+
+ def parse(self, inventory, loader, path, cache=None):
+
+ pass
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
new file mode 100644
index 0000000..7a64a5d
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py
@@ -0,0 +1,45 @@
+# (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
+
+DOCUMENTATION = """
+ lookup: noop
+ author: Ansible core team
+ short_description: returns input
+ description:
+ - this is a noop
+ deprecated:
+ alternative: Use some other lookup
+ why: Test deprecation
+ removed_in: '3.0.0'
+ extends_documentation_fragment:
+ - testns.testcol2.version_added
+"""
+
+EXAMPLES = """
+- name: do nothing
+ debug: msg="{{ lookup('testns.testcol.noop', [1,2,3,4] }}"
+"""
+
+RETURN = """
+ _list:
+ description: input given
+ version_added: 1.0.0
+"""
+
+from collections.abc import Sequence
+
+from ansible.plugins.lookup import LookupBase
+from ansible.errors import AnsibleError
+
+
+class LookupModule(LookupBase):
+
+ def run(self, terms, **kwargs):
+ if not isinstance(terms, Sequence):
+ raise AnsibleError("testns.testcol.noop expects a list")
+ return terms
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
new file mode 100644
index 0000000..dd41305
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/database/database_type/subdir_module.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: subdir_module
+short_description: A module in multiple subdirectories
+description:
+ - A module in multiple subdirectories
+author:
+ - Ansible Core Team
+version_added: 1.0.0
+options: {}
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..6d18c08
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+ module: fakemodule
+ short_desciption: fake module
+ description:
+ - this is a fake module
+ version_added: 1.0.0
+ options:
+ _notreal:
+ description: really not a real option
+ author:
+ - me
+"""
+
+import json
+
+
+def main():
+ print(json.dumps(dict(changed=False, source='testns.testcol.fakemodule')))
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..4479f23
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import json
+
+
+def main():
+ print(json.dumps(dict(changed=False, source='testns.testcol.notrealmodule')))
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..f251a69
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py
@@ -0,0 +1,95 @@
+#!/usr/bin/python
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: randommodule
+short_description: A random module
+description:
+ - A random module.
+author:
+ - Ansible Core Team
+version_added: 1.0.0
+deprecated:
+ alternative: Use some other module
+ why: Test deprecation
+ removed_in: '3.0.0'
+options:
+ test:
+ description: Some text.
+ type: str
+ version_added: 1.2.0
+ sub:
+ description: Suboptions.
+ type: dict
+ suboptions:
+ subtest:
+ description: A suboption.
+ type: int
+ version_added: 1.1.0
+ # The following is the wrong syntax, and should not get processed
+ # by add_collection_to_versions_and_dates()
+ options:
+ subtest2:
+ description: Another suboption.
+ type: float
+ version_added: 1.1.0
+ # The following is not supported in modules, and should not get processed
+ # by add_collection_to_versions_and_dates()
+ env:
+ - name: TEST_ENV
+ version_added: 1.0.0
+ deprecated:
+ alternative: none
+ why: Test deprecation
+ removed_in: '2.0.0'
+ version: '2.0.0'
+extends_documentation_fragment:
+ - testns.testcol2.module
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+z_last:
+ description: A last result.
+ type: str
+ returned: success
+ version_added: 1.3.0
+
+m_middle:
+ description:
+ - This should be in the middle.
+ - Has some more data
+ type: dict
+ returned: success and 1st of month
+ contains:
+ suboption:
+ description: A suboption.
+ type: str
+ choices: [ARF, BARN, c_without_capital_first_letter]
+ version_added: 1.4.0
+
+a_first:
+ description: A first result.
+ type: str
+ returned: success
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..f1c2b3a
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/test_test.py
@@ -0,0 +1,16 @@
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+def yolo(value):
+ return True
+
+
+class TestModule(object):
+ ''' Ansible core jinja2 tests '''
+
+ def tests(self):
+ return {
+ # failure testing
+ 'yolo': yolo,
+ }
diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/yolo.yml b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/yolo.yml
new file mode 100644
index 0000000..cc60945
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/yolo.yml
@@ -0,0 +1,18 @@
+DOCUMENTATION:
+ name: yolo
+ short_description: you only live once
+ description:
+ - This is always true
+ options:
+ _input:
+ description: does not matter
+ type: raw
+ required: true
+
+EXAMPLES: |
+ {{ 'anything' is yolo }}
+
+RETURN:
+ output:
+ type: boolean
+ description: always true
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
new file mode 100644
index 0000000..94e7feb
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py
@@ -0,0 +1,29 @@
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+ vars: noop_vars_plugin
+ short_description: Do NOT load host and group vars
+ description: don't test loading host and group vars from a collection
+ options:
+ stage:
+ default: all
+ choices: ['all', 'inventory', 'task']
+ type: str
+ ini:
+ - key: stage
+ section: testns.testcol.noop_vars_plugin
+ env:
+ - name: ANSIBLE_VARS_PLUGIN_STAGE
+ extends_documentation_fragment:
+ - testns.testcol2.deprecation
+'''
+
+from ansible.plugins.vars import BaseVarsPlugin
+
+
+class VarsModule(BaseVarsPlugin):
+
+ def get_vars(self, loader, path, entities, cache=True):
+ super(VarsModule, self).get_vars(loader, path, entities)
+ return {'collection': 'yes', 'notreal': 'value'}
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
new file mode 100644
index 0000000..bc6af69
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml
@@ -0,0 +1,26 @@
+---
+dependencies:
+galaxy_info:
+
+argument_specs:
+ main:
+ short_description: testns.testcol.testrole short description for main entry point
+ description:
+ - Longer description for testns.testcol.testrole main entry point.
+ author: Ansible Core (@ansible)
+ options:
+ opt1:
+ description: opt1 description
+ type: "str"
+ required: true
+
+ alternate:
+ short_description: testns.testcol.testrole short description for alternate entry point
+ description:
+ - Longer description for testns.testcol.testrole alternate entry point.
+ author: Ansible Core (@ansible)
+ options:
+ altopt1:
+ description: altopt1 description
+ type: "int"
+ required: true
diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole_with_no_argspecs/meta/empty b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole_with_no_argspecs/meta/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole_with_no_argspecs/meta/empty
diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/MANIFEST.json b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/MANIFEST.json
new file mode 100644
index 0000000..02ec289
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/MANIFEST.json
@@ -0,0 +1,30 @@
+{
+ "collection_info": {
+ "description": null,
+ "repository": "",
+ "tags": [],
+ "dependencies": {},
+ "authors": [
+ "Ansible (https://ansible.com)"
+ ],
+ "issues": "",
+ "name": "testcol2",
+ "license": [
+ "GPL-3.0-or-later"
+ ],
+ "documentation": "",
+ "namespace": "testns",
+ "version": "1.2.0",
+ "readme": "README.md",
+ "license_file": "COPYING",
+ "homepage": "",
+ },
+ "file_manifest_file": {
+ "format": 1,
+ "ftype": "file",
+ "chksum_sha256": "4c15a867ceba8ba1eaf2f4a58844bb5dbb82fec00645fc7eb74a3d31964900f6",
+ "name": "FILES.json",
+ "chksum_type": "sha256"
+ },
+ "format": 1
+}
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
new file mode 100644
index 0000000..3942d72
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/deprecation.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class ModuleDocFragment(object):
+ DOCUMENTATION = r'''
+options: {}
+deprecated:
+ alternative: Use some other module
+ why: Test deprecation
+ removed_in: '3.0.0'
+'''
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
new file mode 100644
index 0000000..a572363
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/module.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class ModuleDocFragment(object):
+ DOCUMENTATION = r'''
+options:
+ testcol2option:
+ description:
+ - An option taken from testcol2
+ type: str
+ version_added: 1.0.0
+ testcol2option2:
+ description:
+ - Another option taken from testcol2
+ type: str
+'''
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
new file mode 100644
index 0000000..2fe4e4a
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/plugin.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class ModuleDocFragment(object):
+ DOCUMENTATION = r'''
+options:
+ testcol2option:
+ description:
+ - A plugin option taken from testcol2
+ type: str
+ version_added: 1.0.0
+ ini:
+ - key: foo
+ section: bar
+ version_added: 1.1.0
+ deprecated:
+ alternative: none
+ why: Test deprecation
+ version: '3.0.0'
+ env:
+ - name: FOO_BAR
+ version_added: 1.2.0
+ deprecated:
+ alternative: none
+ why: Test deprecation
+ removed_at_date: 2020-01-31
+ vars:
+ - name: foobar
+ version_added: 1.3.0
+ deprecated:
+ alternative: none
+ why: Test deprecation
+ removed_at_date: 2040-12-31
+ testcol2depr:
+ description:
+ - A plugin option taken from testcol2 that is deprecated
+ type: str
+ deprecated:
+ alternative: none
+ why: Test option deprecation
+ version: '2.0.0'
+'''
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
new file mode 100644
index 0000000..73e5f2f
--- /dev/null
+++ b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/version_added.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class ModuleDocFragment(object):
+ DOCUMENTATION = r'''
+options: {}
+version_added: 1.0.0
+'''
diff --git a/test/integration/targets/ansible-doc/fakecollrole.output b/test/integration/targets/ansible-doc/fakecollrole.output
new file mode 100644
index 0000000..3ae9077
--- /dev/null
+++ b/test/integration/targets/ansible-doc/fakecollrole.output
@@ -0,0 +1,15 @@
+> TESTNS.TESTCOL.TESTROLE (/ansible/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol)
+
+ENTRY POINT: alternate - testns.testcol.testrole short description for alternate entry point
+
+ Longer description for testns.testcol.testrole alternate entry
+ point.
+
+OPTIONS (= is mandatory):
+
+= altopt1
+ altopt1 description
+ type: int
+
+
+AUTHOR: Ansible Core (@ansible)
diff --git a/test/integration/targets/ansible-doc/fakemodule.output b/test/integration/targets/ansible-doc/fakemodule.output
new file mode 100644
index 0000000..4fb0776
--- /dev/null
+++ b/test/integration/targets/ansible-doc/fakemodule.output
@@ -0,0 +1,16 @@
+> TESTNS.TESTCOL.FAKEMODULE (./collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py)
+
+ this is a fake module
+
+ADDED IN: version 1.0.0 of testns.testcol
+
+OPTIONS (= is mandatory):
+
+- _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
new file mode 100644
index 0000000..bcb53dc
--- /dev/null
+++ b/test/integration/targets/ansible-doc/fakerole.output
@@ -0,0 +1,32 @@
+> TEST_ROLE1 (/ansible/test/integration/targets/ansible-doc/roles/normal_role1)
+
+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.
+
+OPTIONS (= is mandatory):
+
+= myopt1
+ First option.
+ type: str
+
+- myopt2
+ Second option
+ default: 8000
+ type: int
+
+- myopt3
+ Third option.
+ choices: [choice1, choice2]
+ default: null
+ type: str
+
+
+AUTHOR: John Doe (@john), Jane Doe (@jane)
diff --git a/test/integration/targets/ansible-doc/filter_plugins/donothing.yml b/test/integration/targets/ansible-doc/filter_plugins/donothing.yml
new file mode 100644
index 0000000..87fe2f9
--- /dev/null
+++ b/test/integration/targets/ansible-doc/filter_plugins/donothing.yml
@@ -0,0 +1,21 @@
+DOCUMENTATION:
+ name: donothing
+ author: lazy
+ version_added: 'histerical'
+ short_description: noop
+ description:
+ - don't do anything
+ options:
+ _input:
+ description: Anything you want to get back
+ type: raw
+ required: true
+
+EXAMPLES: |
+ # set first 10 volumes rw, rest as dp
+ meaning: "{{ (stuff|donothing}}"
+
+RETURN:
+ _value:
+ description: guess
+ type: raw
diff --git a/test/integration/targets/ansible-doc/filter_plugins/other.py b/test/integration/targets/ansible-doc/filter_plugins/other.py
new file mode 100644
index 0000000..1bc2e17
--- /dev/null
+++ b/test/integration/targets/ansible-doc/filter_plugins/other.py
@@ -0,0 +1,25 @@
+# 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 ansible.utils.display import Display
+
+display = Display()
+
+
+def donothing(a):
+ return a
+
+
+class FilterModule(object):
+ ''' Ansible core jinja2 filters '''
+
+ def filters(self):
+ return {
+ 'donothing': donothing,
+ 'nodocs': donothing,
+ 'split': donothing,
+ 'b64decode': donothing,
+ }
diff --git a/test/integration/targets/ansible-doc/filter_plugins/split.yml b/test/integration/targets/ansible-doc/filter_plugins/split.yml
new file mode 100644
index 0000000..87fe2f9
--- /dev/null
+++ b/test/integration/targets/ansible-doc/filter_plugins/split.yml
@@ -0,0 +1,21 @@
+DOCUMENTATION:
+ name: donothing
+ author: lazy
+ version_added: 'histerical'
+ short_description: noop
+ description:
+ - don't do anything
+ options:
+ _input:
+ description: Anything you want to get back
+ type: raw
+ required: true
+
+EXAMPLES: |
+ # set first 10 volumes rw, rest as dp
+ meaning: "{{ (stuff|donothing}}"
+
+RETURN:
+ _value:
+ description: guess
+ type: raw
diff --git a/test/integration/targets/ansible-doc/inventory b/test/integration/targets/ansible-doc/inventory
new file mode 100644
index 0000000..ab9b62c
--- /dev/null
+++ b/test/integration/targets/ansible-doc/inventory
@@ -0,0 +1 @@
+not_empty # avoid empty empty hosts list warning without defining explicit localhost
diff --git a/test/integration/targets/ansible-doc/library/double_doc.py b/test/integration/targets/ansible-doc/library/double_doc.py
new file mode 100644
index 0000000..6f0412a
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/double_doc.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r'''
+name: double_doc
+description:
+ - module also uses 'DOCUMENTATION' in class
+'''
+
+
+class Foo:
+
+ # 2nd ref to documentation string, used to trip up tokinzer doc reader
+ DOCUMENTATION = None
+
+ def __init__(self):
+ pass
diff --git a/test/integration/targets/ansible-doc/library/test_docs.py b/test/integration/targets/ansible-doc/library/test_docs.py
new file mode 100644
index 0000000..39ae372
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['stableinterface'],
+ 'supported_by': 'core'}
+
+DOCUMENTATION = '''
+---
+module: test_docs
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..6ed4183
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_missing_description.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: test_docs_returns
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+options:
+ test:
+ type: str
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ test=dict(type='str'),
+ ),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..4ea86f0
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_no_metadata.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: test_docs_no_metadata
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..1b0db4e
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_no_status.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'supported_by': 'core'}
+
+DOCUMENTATION = '''
+---
+module: test_docs_no_status
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..63d080f
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_non_iterable_status.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': 1,
+ 'supported_by': 'core'}
+
+DOCUMENTATION = '''
+---
+module: test_docs_non_iterable_status
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..3de1c69
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_removed_precedence.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: test_docs_removed_precedence
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+deprecated:
+ alternative: new_module
+ why: Updated module released with more functionality
+ removed_at_date: '2022-06-01'
+ removed_in: '2.14'
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..cb48c16
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_removed_status.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['removed'],
+ 'supported_by': 'core'}
+
+DOCUMENTATION = '''
+---
+module: test_docs_removed_status
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/ansible-doc/library/test_docs_returns.py b/test/integration/targets/ansible-doc/library/test_docs_returns.py
new file mode 100644
index 0000000..77c1376
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_returns.py
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: test_docs_returns
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+z_last:
+ description: A last result.
+ type: str
+ returned: success
+
+m_middle:
+ description:
+ - This should be in the middle.
+ - Has some more data
+ type: dict
+ returned: success and 1st of month
+ contains:
+ suboption:
+ description: A suboption.
+ type: str
+ choices: [ARF, BARN, c_without_capital_first_letter]
+
+a_first:
+ description: A first result.
+ type: str
+ returned: success
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..d6d6264
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_returns_broken.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: test_docs_returns_broken
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+test:
+ description: A test return value.
+ type: str
+
+broken_key: [
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/ansible-doc/library/test_docs_suboptions.py b/test/integration/targets/ansible-doc/library/test_docs_suboptions.py
new file mode 100644
index 0000000..c922d1d
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_suboptions.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: test_docs_suboptions
+short_description: Test module
+description:
+ - Test module
+author:
+ - Ansible Core Team
+options:
+ with_suboptions:
+ description:
+ - An option with suboptions.
+ - Use with care.
+ type: dict
+ suboptions:
+ z_last:
+ description: The last suboption.
+ type: str
+ m_middle:
+ description:
+ - The suboption in the middle.
+ - Has its own suboptions.
+ suboptions:
+ a_suboption:
+ description: A sub-suboption.
+ type: str
+ a_first:
+ description: The first suboption.
+ type: str
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ test_docs_suboptions=dict(
+ type='dict',
+ options=dict(
+ a_first=dict(type='str'),
+ m_middle=dict(
+ type='dict',
+ options=dict(
+ a_suboption=dict(type='str')
+ ),
+ ),
+ z_last=dict(type='str'),
+ ),
+ ),
+ ),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..bec0292
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_docs_yaml_anchors.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: test_docs_yaml_anchors
+short_description: Test module with YAML anchors in docs
+description:
+ - Test module
+author:
+ - Ansible Core Team
+options:
+ at_the_top: &toplevel_anchor
+ description:
+ - Short desc
+ default: some string
+ type: str
+
+ last_one: *toplevel_anchor
+
+ egress:
+ description:
+ - Egress firewall rules
+ type: list
+ elements: dict
+ suboptions: &sub_anchor
+ port:
+ description:
+ - Rule port
+ type: int
+ required: true
+
+ ingress:
+ description:
+ - Ingress firewall rules
+ type: list
+ elements: dict
+ suboptions: *sub_anchor
+'''
+
+EXAMPLES = '''
+'''
+
+RETURN = '''
+'''
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ at_the_top=dict(type='str', default='some string'),
+ last_one=dict(type='str', default='some string'),
+ egress=dict(type='list', elements='dict', options=dict(
+ port=dict(type='int', required=True),
+ )),
+ ingress=dict(type='list', elements='dict', options=dict(
+ port=dict(type='int', required=True),
+ )),
+ ),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/ansible-doc/library/test_empty.py b/test/integration/targets/ansible-doc/library/test_empty.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_empty.py
diff --git a/test/integration/targets/ansible-doc/library/test_no_docs.py b/test/integration/targets/ansible-doc/library/test_no_docs.py
new file mode 100644
index 0000000..5503aed
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_no_docs.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['stableinterface'],
+ 'supported_by': 'core'}
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..4887268
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_no_docs_no_metadata.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..f90c5c7
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_no_docs_no_status.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'supported_by': 'core'}
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 0000000..44fbede
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_no_docs_non_iterable_status.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': 1,
+ 'supported_by': 'core'}
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(),
+ )
+
+ module.exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/ansible-doc/library/test_win_module.ps1 b/test/integration/targets/ansible-doc/library/test_win_module.ps1
new file mode 100644
index 0000000..5653c8b
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_win_module.ps1
@@ -0,0 +1,21 @@
+#!powershell
+# Copyright: (c) Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#AnsibleRequires -CSharpUtil Ansible.Basic
+
+$spec = @{
+ options = @{
+ hello = @{ type = 'str'; required = $true }
+ }
+ supports_check_mode = $true
+}
+
+$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
+
+$hello = $module.Params.hello
+
+$module.Result.msg = $hello
+$module.Result.changed = $false
+
+$module.ExitJson()
diff --git a/test/integration/targets/ansible-doc/library/test_win_module.yml b/test/integration/targets/ansible-doc/library/test_win_module.yml
new file mode 100644
index 0000000..0547c70
--- /dev/null
+++ b/test/integration/targets/ansible-doc/library/test_win_module.yml
@@ -0,0 +1,9 @@
+DOCUMENTATION:
+ module: test_win_module
+ short_description: Test win module
+ description:
+ - Test win module with sidecar docs
+ author:
+ - Ansible Core Team
+EXAMPLES: ''
+RETURN: ''
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
new file mode 100644
index 0000000..81d401d
--- /dev/null
+++ b/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_adj_docs.py
@@ -0,0 +1,5 @@
+# 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
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
new file mode 100644
index 0000000..4fd63aa
--- /dev/null
+++ b/test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_docs.py
@@ -0,0 +1,26 @@
+# 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
+
+
+DOCUMENTATION = '''
+ name: deprecated_with_docs
+ short_description: test lookup
+ description: test lookup
+ author: Ansible Core Team
+ version_added: "2.14"
+ deprecated:
+ why: reasons
+ alternative: other thing
+ removed_in: "2.16"
+ removed_from_collection: "ansible.legacy"
+ options: {}
+'''
+
+EXAMPLE = '''
+'''
+
+RETURN = '''
+'''
diff --git a/test/integration/targets/ansible-doc/lookup_plugins/deprecated_with_adj_docs.yml b/test/integration/targets/ansible-doc/lookup_plugins/deprecated_with_adj_docs.yml
new file mode 100644
index 0000000..6349c39
--- /dev/null
+++ b/test/integration/targets/ansible-doc/lookup_plugins/deprecated_with_adj_docs.yml
@@ -0,0 +1,16 @@
+DOCUMENTATION:
+ name: deprecated_with_adj_docs
+ short_description: test lookup
+ description: test lookup
+ author: Ansible Core Team
+ version_added: "2.14"
+ deprecated:
+ why: reasons
+ alternative: use other thing
+ removed_in: "2.16"
+ removed_from_collection: "ansible.legacy"
+ options: {}
+
+EXAMPLE: ""
+
+RETURN: {}
diff --git a/test/integration/targets/ansible-doc/noop.output b/test/integration/targets/ansible-doc/noop.output
new file mode 100644
index 0000000..567150a
--- /dev/null
+++ b/test/integration/targets/ansible-doc/noop.output
@@ -0,0 +1,32 @@
+{
+ "testns.testcol.noop": {
+ "doc": {
+ "author": "Ansible core team",
+ "collection": "testns.testcol",
+ "deprecated": {
+ "alternative": "Use some other lookup",
+ "removed_from_collection": "testns.testcol",
+ "removed_in": "3.0.0",
+ "why": "Test deprecation"
+ },
+ "description": [
+ "this is a noop"
+ ],
+ "filename": "./collections/ansible_collections/testns/testcol/plugins/lookup/noop.py",
+ "lookup": "noop",
+ "options": {},
+ "short_description": "returns input",
+ "version_added": "1.0.0",
+ "version_added_collection": "testns.testcol2"
+ },
+ "examples": "\n- name: do nothing\n debug: msg=\"{{ lookup('testns.testcol.noop', [1,2,3,4] }}\"\n",
+ "metadata": null,
+ "return": {
+ "_list": {
+ "description": "input given",
+ "version_added": "1.0.0",
+ "version_added_collection": "testns.testcol"
+ }
+ }
+ }
+}
diff --git a/test/integration/targets/ansible-doc/noop_vars_plugin.output b/test/integration/targets/ansible-doc/noop_vars_plugin.output
new file mode 100644
index 0000000..5c42af3
--- /dev/null
+++ b/test/integration/targets/ansible-doc/noop_vars_plugin.output
@@ -0,0 +1,42 @@
+{
+ "testns.testcol.noop_vars_plugin": {
+ "doc": {
+ "collection": "testns.testcol",
+ "deprecated": {
+ "alternative": "Use some other module",
+ "removed_from_collection": "testns.testcol2",
+ "removed_in": "3.0.0",
+ "why": "Test deprecation"
+ },
+ "description": "don't test loading host and group vars from a collection",
+ "filename": "./collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py",
+ "options": {
+ "stage": {
+ "choices": [
+ "all",
+ "inventory",
+ "task"
+ ],
+ "default": "all",
+ "env": [
+ {
+ "name": "ANSIBLE_VARS_PLUGIN_STAGE"
+ }
+ ],
+ "ini": [
+ {
+ "key": "stage",
+ "section": "testns.testcol.noop_vars_plugin"
+ }
+ ],
+ "type": "str"
+ }
+ },
+ "short_description": "Do NOT load host and group vars",
+ "vars": "noop_vars_plugin"
+ },
+ "examples": null,
+ "metadata": null,
+ "return": null
+ }
+}
diff --git a/test/integration/targets/ansible-doc/notjsonfile.output b/test/integration/targets/ansible-doc/notjsonfile.output
new file mode 100644
index 0000000..a73b1a9
--- /dev/null
+++ b/test/integration/targets/ansible-doc/notjsonfile.output
@@ -0,0 +1,157 @@
+{
+ "testns.testcol.notjsonfile": {
+ "doc": {
+ "author": "Ansible Core (@ansible-core)",
+ "cache": "notjsonfile",
+ "collection": "testns.testcol",
+ "description": [
+ "This cache uses JSON formatted, per host, files saved to the filesystem."
+ ],
+ "filename": "./collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py",
+ "options": {
+ "_prefix": {
+ "deprecated": {
+ "alternative": "none",
+ "collection_name": "testns.testcol",
+ "removed_at_date": "2050-01-01",
+ "why": "Another test deprecation"
+ },
+ "description": "User defined prefix to use when creating the JSON files",
+ "env": [
+ {
+ "name": "ANSIBLE_CACHE_PLUGIN_PREFIX",
+ "version_added": "1.1.0",
+ "version_added_collection": "testns.testcol"
+ }
+ ],
+ "ini": [
+ {
+ "key": "fact_caching_prefix",
+ "section": "defaults"
+ }
+ ]
+ },
+ "_timeout": {
+ "default": 86400,
+ "description": "Expiration timeout for the cache plugin data",
+ "env": [
+ {
+ "name": "ANSIBLE_CACHE_PLUGIN_TIMEOUT"
+ }
+ ],
+ "ini": [
+ {
+ "key": "fact_caching_timeout",
+ "section": "defaults"
+ }
+ ],
+ "type": "integer",
+ "vars": [
+ {
+ "deprecated": {
+ "alternative": "do not use a variable",
+ "collection_name": "testns.testcol",
+ "version": "3.0.0",
+ "why": "Test deprecation"
+ },
+ "name": "notsjonfile_fact_caching_timeout",
+ "version_added": "1.5.0",
+ "version_added_collection": "testns.testcol"
+ }
+ ]
+ },
+ "_uri": {
+ "description": [
+ "Path in which the cache plugin will save the JSON files"
+ ],
+ "env": [
+ {
+ "name": "ANSIBLE_CACHE_PLUGIN_CONNECTION",
+ "version_added": "1.2.0",
+ "version_added_collection": "testns.testcol"
+ }
+ ],
+ "ini": [
+ {
+ "deprecated": {
+ "alternative": "none",
+ "collection_name": "testns.testcol",
+ "version": "2.0.0",
+ "why": "Test deprecation"
+ },
+ "key": "fact_caching_connection",
+ "section": "defaults"
+ }
+ ],
+ "required": true
+ },
+ "testcol2depr": {
+ "deprecated": {
+ "alternative": "none",
+ "collection_name": "testns.testcol2",
+ "version": "2.0.0",
+ "why": "Test option deprecation"
+ },
+ "description": [
+ "A plugin option taken from testcol2 that is deprecated"
+ ],
+ "type": "str"
+ },
+ "testcol2option": {
+ "description": [
+ "A plugin option taken from testcol2"
+ ],
+ "env": [
+ {
+ "deprecated": {
+ "alternative": "none",
+ "collection_name": "testns.testcol2",
+ "removed_at_date": "2020-01-31",
+ "why": "Test deprecation"
+ },
+ "name": "FOO_BAR",
+ "version_added": "1.2.0",
+ "version_added_collection": "testns.testcol2"
+ }
+ ],
+ "ini": [
+ {
+ "deprecated": {
+ "alternative": "none",
+ "collection_name": "testns.testcol2",
+ "version": "3.0.0",
+ "why": "Test deprecation"
+ },
+ "key": "foo",
+ "section": "bar",
+ "version_added": "1.1.0",
+ "version_added_collection": "testns.testcol2"
+ }
+ ],
+ "type": "str",
+ "vars": [
+ {
+ "deprecated": {
+ "alternative": "none",
+ "collection_name": "testns.testcol2",
+ "removed_at_date": "2040-12-31",
+ "why": "Test deprecation"
+ },
+ "name": "foobar",
+ "version_added": "1.3.0",
+ "version_added_collection": "testns.testcol2"
+ }
+ ],
+ "version_added": "1.0.0",
+ "version_added_collection": "testns.testcol2"
+ }
+ },
+ "short_description": "JSON formatted files.",
+ "version_added": "0.7.0",
+ "version_added_collection": "testns.testcol"
+ },
+ "examples": null,
+ "metadata": null,
+ "return": null
+ }
+}
diff --git a/test/integration/targets/ansible-doc/randommodule-text.output b/test/integration/targets/ansible-doc/randommodule-text.output
new file mode 100644
index 0000000..51d7930
--- /dev/null
+++ b/test/integration/targets/ansible-doc/randommodule-text.output
@@ -0,0 +1,101 @@
+> TESTNS.TESTCOL.RANDOMMODULE (./collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py)
+
+ A random module.
+
+ADDED IN: version 1.0.0 of testns.testcol
+
+DEPRECATED:
+
+ Reason: Test deprecation
+ Will be removed in: Ansible 3.0.0
+ Alternatives: Use some other module
+
+
+OPTIONS (= is mandatory):
+
+- sub
+ Suboptions.
+ set_via:
+ env:
+ - 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
+
+
+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.output b/test/integration/targets/ansible-doc/randommodule.output
new file mode 100644
index 0000000..25f46c3
--- /dev/null
+++ b/test/integration/targets/ansible-doc/randommodule.output
@@ -0,0 +1,115 @@
+{
+ "testns.testcol.randommodule": {
+ "doc": {
+ "author": [
+ "Ansible Core Team"
+ ],
+ "collection": "testns.testcol",
+ "deprecated": {
+ "alternative": "Use some other module",
+ "removed_from_collection": "testns.testcol",
+ "removed_in": "3.0.0",
+ "why": "Test deprecation"
+ },
+ "description": [
+ "A random module."
+ ],
+ "filename": "./collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py",
+ "has_action": false,
+ "module": "randommodule",
+ "options": {
+ "sub": {
+ "description": "Suboptions.",
+ "env": [
+ {
+ "deprecated": {
+ "alternative": "none",
+ "removed_in": "2.0.0",
+ "version": "2.0.0",
+ "why": "Test deprecation"
+ },
+ "name": "TEST_ENV",
+ "version_added": "1.0.0"
+ }
+ ],
+ "options": {
+ "subtest2": {
+ "description": "Another suboption.",
+ "type": "float",
+ "version_added": "1.1.0"
+ }
+ },
+ "suboptions": {
+ "subtest": {
+ "description": "A suboption.",
+ "type": "int",
+ "version_added": "1.1.0",
+ "version_added_collection": "testns.testcol"
+ }
+ },
+ "type": "dict"
+ },
+ "test": {
+ "description": "Some text.",
+ "type": "str",
+ "version_added": "1.2.0",
+ "version_added_collection": "testns.testcol"
+ },
+ "testcol2option": {
+ "description": [
+ "An option taken from testcol2"
+ ],
+ "type": "str",
+ "version_added": "1.0.0",
+ "version_added_collection": "testns.testcol2"
+ },
+ "testcol2option2": {
+ "description": [
+ "Another option taken from testcol2"
+ ],
+ "type": "str"
+ }
+ },
+ "short_description": "A random module",
+ "version_added": "1.0.0",
+ "version_added_collection": "testns.testcol"
+ },
+ "examples": "\n",
+ "metadata": null,
+ "return": {
+ "a_first": {
+ "description": "A first result.",
+ "returned": "success",
+ "type": "str"
+ },
+ "m_middle": {
+ "contains": {
+ "suboption": {
+ "choices": [
+ "ARF",
+ "BARN",
+ "c_without_capital_first_letter"
+ ],
+ "description": "A suboption.",
+ "type": "str",
+ "version_added": "1.4.0",
+ "version_added_collection": "testns.testcol"
+ }
+ },
+ "description": [
+ "This should be in the middle.",
+ "Has some more data"
+ ],
+ "returned": "success and 1st of month",
+ "type": "dict"
+ },
+ "z_last": {
+ "description": "A last result.",
+ "returned": "success",
+ "type": "str",
+ "version_added": "1.3.0",
+ "version_added_collection": "testns.testcol"
+ }
+ }
+ }
+}
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
new file mode 100644
index 0000000..0315a1f
--- /dev/null
+++ b/test/integration/targets/ansible-doc/roles/test_role1/meta/argument_specs.yml
@@ -0,0 +1,34 @@
+---
+argument_specs:
+ main:
+ short_description: test_role1 from roles subdir
+ description:
+ - In to am attended desirous raptures B(declared) diverted confined at. Collected instantly remaining
+ up certainly to C(necessary) as. Over walk dull into son boy door went new.
+ - At or happiness commanded daughters as. Is I(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.
+ author:
+ - John Doe (@john)
+ - Jane Doe (@jane)
+
+ options:
+ myopt1:
+ description:
+ - First option.
+ type: "str"
+ required: true
+
+ myopt2:
+ description:
+ - Second option
+ type: "int"
+ default: 8000
+
+ myopt3:
+ description:
+ - Third option.
+ type: "str"
+ choices:
+ - choice1
+ - choice2
diff --git a/test/integration/targets/ansible-doc/roles/test_role1/meta/main.yml b/test/integration/targets/ansible-doc/roles/test_role1/meta/main.yml
new file mode 100644
index 0000000..19f6162
--- /dev/null
+++ b/test/integration/targets/ansible-doc/roles/test_role1/meta/main.yml
@@ -0,0 +1,13 @@
+# This meta/main.yml exists to test that it is NOT read, with preference being
+# given to the meta/argument_specs.yml file. This spec contains additional
+# entry points (groot, foo) that the argument_specs.yml does not. If this file
+# were read, the additional entrypoints would show up in --list output, breaking
+# tests.
+---
+argument_specs:
+ main:
+ short_description: test_role1 from roles subdir
+ groot:
+ short_description: I am Groot
+ foo:
+ short_description: I am Foo
diff --git a/test/integration/targets/ansible-doc/roles/test_role2/meta/empty b/test/integration/targets/ansible-doc/roles/test_role2/meta/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/integration/targets/ansible-doc/roles/test_role2/meta/empty
diff --git a/test/integration/targets/ansible-doc/roles/test_role3/meta/main.yml b/test/integration/targets/ansible-doc/roles/test_role3/meta/main.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/integration/targets/ansible-doc/roles/test_role3/meta/main.yml
diff --git a/test/integration/targets/ansible-doc/runme.sh b/test/integration/targets/ansible-doc/runme.sh
new file mode 100755
index 0000000..887d3c4
--- /dev/null
+++ b/test/integration/targets/ansible-doc/runme.sh
@@ -0,0 +1,214 @@
+#!/usr/bin/env bash
+
+set -eux
+ansible-playbook test.yml -i inventory "$@"
+
+# test keyword docs
+ansible-doc -t keyword -l | grep 'vars_prompt: list of variables to prompt for.'
+ansible-doc -t keyword vars_prompt | grep 'description: list of variables to prompt for.'
+ansible-doc -t keyword asldkfjaslidfhals 2>&1 | grep 'Skipping Invalid keyword'
+
+# collections testing
+(
+unset ANSIBLE_PLAYBOOK_DIR
+cd "$(dirname "$0")"
+
+# test module 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)"
+test "$current_out" == "$expected_out"
+
+# we use sed to strip the module path from the first line
+current_out="$(ansible-doc --playbook-dir ./ testns.testcol.randommodule | sed '1 s/\(^> TESTNS\.TESTCOL\.RANDOMMODULE\).*(.*)$/\1/')"
+expected_out="$(sed '1 s/\(^> TESTNS\.TESTCOL\.RANDOMMODULE\).*(.*)$/\1/' randommodule-text.output)"
+test "$current_out" == "$expected_out"
+
+# ensure we do work with valid collection name for list
+ansible-doc --list testns.testcol --playbook-dir ./ 2>&1 | grep -v "Invalid collection name"
+
+# ensure we dont break on invalid collection name for list
+ansible-doc --list testns.testcol.fakemodule --playbook-dir ./ 2>&1 | grep "Invalid collection name"
+
+# test listing diff plugin types from collection
+for ptype in cache inventory lookup vars filter module
+do
+ # each plugin type adds 1 from collection
+ # FIXME pre=$(ansible-doc -l -t ${ptype}|wc -l)
+ # FIXME post=$(ansible-doc -l -t ${ptype} --playbook-dir ./|wc -l)
+ # FIXME test "$pre" -eq $((post - 1))
+ if [ "${ptype}" == "filter" ]; then
+ expected=5
+ expected_names=("b64decode" "filter_subdir.nested" "filter_subdir.noop" "noop" "ultimatequestion")
+ elif [ "${ptype}" == "module" ]; then
+ expected=4
+ expected_names=("fakemodule" "notrealmodule" "randommodule" "database.database_type.subdir_module")
+ else
+ expected=1
+ if [ "${ptype}" == "cache" ]; then expected_names=("notjsonfile");
+ elif [ "${ptype}" == "inventory" ]; then expected_names=("statichost");
+ elif [ "${ptype}" == "lookup" ]; then expected_names=("noop");
+ elif [ "${ptype}" == "vars" ]; then expected_names=("noop_vars_plugin"); fi
+ fi
+ # ensure we ONLY list from the collection
+ justcol=$(ansible-doc -l -t ${ptype} --playbook-dir ./ testns.testcol|wc -l)
+ test "$justcol" -eq "$expected"
+
+ # ensure the right names are displayed
+ 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 "testns.testcol.${name}"
+ echo "${metadata_result}" | grep "testns.testcol.${name}"
+ done
+
+ # ensure we get error if passinginvalid collection, much less any plugins
+ ansible-doc -l -t ${ptype} testns.testcol 2>&1 | grep "unable to locate collection"
+
+ # TODO: do we want per namespace?
+ # ensure we get 1 plugins when restricting namespace
+ #justcol=$(ansible-doc -l -t ${ptype} --playbook-dir ./ testns|wc -l)
+ #test "$justcol" -eq 1
+done
+
+#### test role functionality
+
+# Test 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)"
+test "$current_role_out" == "$expected_role_out"
+
+# 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
+
+# Include normal roles (no collection filter)
+output=$(ansible-doc -t role -l --playbook-dir . | wc -l)
+test "$output" -eq 3
+
+# Test that a role in the playbook dir with the same name as a role in the
+# 'roles' subdir of the playbook dir does not appear (lower precedence).
+output=$(ansible-doc -t role -l --playbook-dir . | grep -c "test_role1 from roles subdir")
+test "$output" -eq 1
+output=$(ansible-doc -t role -l --playbook-dir . | grep -c "test_role1 from playbook dir" || true)
+test "$output" -eq 0
+
+# Test entry point 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)"
+test "$current_role_out" == "$expected_role_out"
+
+)
+
+#### test add_collection_to_versions_and_dates()
+
+current_out="$(ansible-doc --json --playbook-dir ./ testns.testcol.randommodule | sed 's/ *$//' | sed 's/ *"filename": "[^"]*",$//')"
+expected_out="$(sed 's/ *"filename": "[^"]*",$//' randommodule.output)"
+test "$current_out" == "$expected_out"
+
+current_out="$(ansible-doc --json --playbook-dir ./ -t cache testns.testcol.notjsonfile | sed 's/ *$//' | sed 's/ *"filename": "[^"]*",$//')"
+expected_out="$(sed 's/ *"filename": "[^"]*",$//' notjsonfile.output)"
+test "$current_out" == "$expected_out"
+
+current_out="$(ansible-doc --json --playbook-dir ./ -t lookup testns.testcol.noop | sed 's/ *$//' | sed 's/ *"filename": "[^"]*",$//')"
+expected_out="$(sed 's/ *"filename": "[^"]*",$//' noop.output)"
+test "$current_out" == "$expected_out"
+
+current_out="$(ansible-doc --json --playbook-dir ./ -t vars testns.testcol.noop_vars_plugin | sed 's/ *$//' | sed 's/ *"filename": "[^"]*",$//')"
+expected_out="$(sed 's/ *"filename": "[^"]*",$//' noop_vars_plugin.output)"
+test "$current_out" == "$expected_out"
+
+# just ensure it runs
+ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --playbook-dir /dev/null >/dev/null
+
+# create broken role argument spec
+mkdir -p broken-docs/collections/ansible_collections/testns/testcol/roles/testrole/meta
+cat <<EOF > broken-docs/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml
+---
+dependencies:
+galaxy_info:
+
+argument_specs:
+ main:
+ short_description: testns.testcol.testrole short description for main entry point
+ description:
+ - Longer description for testns.testcol.testrole main entry point.
+ author: Ansible Core (@ansible)
+ options:
+ opt1:
+ description: opt1 description
+ broken:
+ type: "str"
+ required: true
+EOF
+
+# ensure that --metadata-dump does not fail when --no-fail-on-errors is supplied
+ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --no-fail-on-errors --playbook-dir broken-docs testns.testcol >/dev/null
+
+# ensure that --metadata-dump does fail when --no-fail-on-errors is not supplied
+output=$(ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --playbook-dir broken-docs testns.testcol 2>&1 | grep -c 'ERROR!' || true)
+test "${output}" -eq 1
+
+# ensure we list the 'legacy plugins'
+[ "$(ansible-doc -M ./library -l ansible.legacy |wc -l)" -gt "0" ]
+
+# playbook dir should work the same
+[ "$(ansible-doc -l ansible.legacy --playbook-dir ./|wc -l)" -gt "0" ]
+
+# see that we show undocumented when missing docs
+[ "$(ansible-doc -M ./library -l ansible.legacy |grep -c UNDOCUMENTED)" == "6" ]
+
+# ensure filtering works and does not include any 'test_' modules
+[ "$(ansible-doc -M ./library -l ansible.builtin |grep -c test_)" == 0 ]
+[ "$(ansible-doc --playbook-dir ./ -l ansible.builtin |grep -c test_)" == 0 ]
+
+# ensure filtering still shows modules
+count=$(ANSIBLE_LIBRARY='./nolibrary' ansible-doc -l ansible.builtin |wc -l)
+[ "${count}" -gt "0" ]
+[ "$(ansible-doc -M ./library -l ansible.builtin |wc -l)" == "${count}" ]
+[ "$(ansible-doc --playbook-dir ./ -l ansible.builtin |wc -l)" == "${count}" ]
+
+
+# produce 'sidecar' docs for test
+[ "$(ansible-doc -t test --playbook-dir ./ testns.testcol.yolo| wc -l)" -gt "0" ]
+[ "$(ansible-doc -t filter --playbook-dir ./ donothing| wc -l)" -gt "0" ]
+[ "$(ansible-doc -t filter --playbook-dir ./ ansible.legacy.donothing| wc -l)" -gt "0" ]
+
+# no docs and no sidecar
+ansible-doc -t filter --playbook-dir ./ nodocs 2>&1| grep -c 'missing documentation' || true
+
+# produce 'sidecar' docs for module
+[ "$(ansible-doc -M ./library test_win_module| wc -l)" -gt "0" ]
+[ "$(ansible-doc --playbook-dir ./ test_win_module| wc -l)" -gt "0" ]
+
+# test 'double DOCUMENTATION' use
+[ "$(ansible-doc --playbook-dir ./ double_doc| wc -l)" -gt "0" ]
+
+# don't break on module dir
+ansible-doc --list --module-path ./modules > /dev/null
+
+# ensure we dedupe by fqcn and not base name
+[ "$(ansible-doc -l -t filter --playbook-dir ./ |grep -c 'b64decode')" -eq "3" ]
+
+# ensure we don't show duplicates for plugins that only exist in ansible.builtin when listing ansible.legacy plugins
+[ "$(ansible-doc -l -t filter --playbook-dir ./ |grep -c 'b64encode')" -eq "1" ]
+
+# with playbook dir, legacy should override
+ansible-doc -t filter split --playbook-dir ./ |grep histerical
+
+pyc_src="$(pwd)/filter_plugins/other.py"
+pyc_1="$(pwd)/filter_plugins/split.pyc"
+pyc_2="$(pwd)/library/notaplugin.pyc"
+trap 'rm -rf "$pyc_1" "$pyc_2"' EXIT
+
+# test 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 histerical
+
+# test 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
+
+# without playbook dir, builtin should return
+ansible-doc -t filter split |grep -v histerical
diff --git a/test/integration/targets/ansible-doc/test.yml b/test/integration/targets/ansible-doc/test.yml
new file mode 100644
index 0000000..a8c992e
--- /dev/null
+++ b/test/integration/targets/ansible-doc/test.yml
@@ -0,0 +1,172 @@
+- hosts: localhost
+ gather_facts: no
+ environment:
+ ANSIBLE_LIBRARY: "{{ playbook_dir }}/library"
+ tasks:
+ - name: module with missing description return docs
+ command: ansible-doc test_docs_missing_description
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+ - |
+ "ERROR! Unable to retrieve documentation from 'test_docs_missing_description' due to: All (sub-)options and return values must have a 'description' field"
+ in result.stderr
+
+ - name: module with suboptions (avoid first line as it has full path)
+ shell: ansible-doc test_docs_suboptions| tail -n +2
+ register: result
+ ignore_errors: true
+
+ - set_fact:
+ actual_output: >-
+ {{ result.stdout | regex_replace('^(> [A-Z_]+ +\().+library/([a-z_]+.py)\)$', '\1library/\2)', multiline=true) }}
+ expected_output: "{{ lookup('file', 'test_docs_suboptions.output') }}"
+
+ - assert:
+ that:
+ - result is succeeded
+ - actual_output == expected_output
+
+ - name: module with return docs
+ shell: ansible-doc test_docs_returns| tail -n +2
+ register: result
+ ignore_errors: true
+
+ - set_fact:
+ actual_output: >-
+ {{ result.stdout | regex_replace('^(> [A-Z_]+ +\().+library/([a-z_]+.py)\)$', '\1library/\2)', multiline=true) }}
+ expected_output: "{{ lookup('file', 'test_docs_returns.output') }}"
+
+ - assert:
+ that:
+ - result is succeeded
+ - actual_output == expected_output
+
+ - name: module with broken return docs
+ command: ansible-doc test_docs_returns_broken
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+ - '"module test_docs_returns_broken missing documentation (or could not parse documentation)" in result.stderr'
+
+ - name: non-existent module
+ command: ansible-doc test_does_not_exist
+ register: result
+ - assert:
+ that:
+ - '"test_does_not_exist was not found" in result.stderr'
+
+ - name: documented module
+ command: ansible-doc test_docs
+ register: result
+ - assert:
+ that:
+ - '"WARNING" not in result.stderr'
+ - '"TEST_DOCS " in result.stdout'
+ - '"AUTHOR: Ansible Core Team" in result.stdout'
+
+ - name: documented module without metadata
+ command: ansible-doc test_docs_no_metadata
+ register: result
+ - assert:
+ that:
+ - '"WARNING" not in result.stderr'
+ - '"TEST_DOCS_NO_METADATA " in result.stdout'
+ - '"AUTHOR: Ansible Core Team" in result.stdout'
+
+ - name: documented module with no status in metadata
+ command: ansible-doc test_docs_no_status
+ register: result
+ - assert:
+ that:
+ - '"WARNING" not in result.stderr'
+ - '"TEST_DOCS_NO_STATUS " in result.stdout'
+ - '"AUTHOR: Ansible Core Team" in result.stdout'
+
+ - name: documented module with non-iterable status in metadata
+ command: ansible-doc test_docs_non_iterable_status
+ register: result
+ - assert:
+ that:
+ - '"WARNING" not in result.stderr'
+ - '"TEST_DOCS_NON_ITERABLE_STATUS " in result.stdout'
+ - '"AUTHOR: Ansible Core Team" in result.stdout'
+
+ - name: documented module with removed status
+ command: ansible-doc test_docs_removed_status
+ register: result
+
+ - assert:
+ that:
+ - '"WARNING" not in result.stderr'
+ - '"TEST_DOCS_REMOVED_STATUS " in result.stdout'
+ - '"AUTHOR: Ansible Core Team" in result.stdout'
+
+ - name: empty module
+ command: ansible-doc test_empty
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+
+ - name: module with no documentation
+ command: ansible-doc test_no_docs
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+
+ - name: deprecated module with both removed date and version (date should get precedence)
+ command: ansible-doc test_docs_removed_precedence
+ register: result
+
+ - assert:
+ that:
+ - '"DEPRECATED" in result.stdout'
+ - '"Reason: Updated module released with more functionality" in result.stdout'
+ - '"Will be removed in a release after 2022-06-01" in result.stdout'
+ - '"Alternatives: new_module" in result.stdout'
+
+ - name: documented module with YAML anchors
+ shell: ansible-doc test_docs_yaml_anchors |tail -n +2
+ 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
+
+ - name: ensure 'donothing' adjacent filter is loaded
+ assert:
+ that:
+ - "'x' == ('x'|donothing)"
+
+ - name: docs for deprecated plugin
+ command: ansible-doc deprecated_with_docs -t lookup
+ register: result
+ - assert:
+ that:
+ - '"WARNING" not 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
+ register: result
+ - assert:
+ that:
+ - '"WARNING" not 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
new file mode 100644
index 0000000..3e23645
--- /dev/null
+++ b/test/integration/targets/ansible-doc/test_docs_returns.output
@@ -0,0 +1,33 @@
+
+ Test module
+
+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
+
+- 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
new file mode 100644
index 0000000..350f90f
--- /dev/null
+++ b/test/integration/targets/ansible-doc/test_docs_suboptions.output
@@ -0,0 +1,42 @@
+
+ Test module
+
+OPTIONS (= is mandatory):
+
+- with_suboptions
+ An option with suboptions.
+ Use with care.
+ default: null
+ type: dict
+
+ 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_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
new file mode 100644
index 0000000..5eb2eee
--- /dev/null
+++ b/test/integration/targets/ansible-doc/test_docs_yaml_anchors.output
@@ -0,0 +1,46 @@
+
+ Test module
+
+OPTIONS (= is mandatory):
+
+- at_the_top
+ Short desc
+ default: some string
+ type: str
+
+- egress
+ Egress firewall rules
+ default: null
+ elements: dict
+ type: list
+
+ SUBOPTIONS:
+
+ = port
+ Rule port
+ type: int
+
+- ingress
+ Ingress firewall rules
+ default: null
+ elements: dict
+ type: list
+
+ SUBOPTIONS:
+
+ = port
+ Rule port
+ type: int
+
+- last_one
+ Short desc
+ default: some string
+ type: str
+
+
+AUTHOR: Ansible Core Team
+
+EXAMPLES:
+
+
+
diff --git a/test/integration/targets/ansible-doc/test_role1/README.txt b/test/integration/targets/ansible-doc/test_role1/README.txt
new file mode 100644
index 0000000..98983c8
--- /dev/null
+++ b/test/integration/targets/ansible-doc/test_role1/README.txt
@@ -0,0 +1,3 @@
+Test role that exists in the playbook directory so we can validate
+that a role of the same name that exists in the 'roles' subdirectory
+will take precedence over this one.
diff --git a/test/integration/targets/ansible-doc/test_role1/meta/main.yml b/test/integration/targets/ansible-doc/test_role1/meta/main.yml
new file mode 100644
index 0000000..4f7abcc
--- /dev/null
+++ b/test/integration/targets/ansible-doc/test_role1/meta/main.yml
@@ -0,0 +1,8 @@
+---
+dependencies:
+galaxy_info:
+
+argument_specs:
+ main:
+ short_description: test_role1 from playbook dir
+ description: This should not appear in `ansible-doc --list` output.