Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ansible-test - Allow multiple documents in the YAML stream for EXAMPLES #82355

Merged
merged 3 commits into from Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelogs/fragments/82353-ansible-sanity-examples.yml
@@ -0,0 +1,4 @@
---
minor_changes:
- ansible-test - sanity test allows ``EXAMPLES`` to be multi-document YAML (https://github.com/ansible/ansible/issues/82353).
- ansible-test - document block name now included in error message for YAML parsing errors (https://github.com/ansible/ansible/issues/82353).
4 changes: 4 additions & 0 deletions test/integration/targets/ansible-test-sanity-yamllint/aliases
@@ -0,0 +1,4 @@
shippable/posix/group3 # runs in the distro test containers
shippable/generic/group1 # runs in the default test container
context/controller
needs/target/collection
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-

# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import annotations

DOCUMENTATION = r"""
---
module: module2
short_description: Hello test module
description: Hello test module.
options:
plugin:
required: true
description: name of the plugin (cache_host)
author:
- Ansible Core Team
"""

EXAMPLES = r"""
---

first_doc:
some_key:

---

second_doc:
some_key:

"""

RETURN = r"""
---
---
"""

from ansible.plugins.inventory import BaseInventoryPlugin


class InventoryModule(BaseInventoryPlugin):

NAME = 'inventory1'
@@ -0,0 +1,40 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import annotations

DOCUMENTATION = r"""
module: module1
short_description: Hello test module
description: Hello test module.
options: {}
author:
- Ansible Core Team
short_description: Duplicate short description
"""

EXAMPLES = r"""
- minimal:
"""

RETURN = r"""
invalid_yaml:
bad_indent:
usual_indent:
"""

from ansible.module_utils.basic import AnsibleModule


def main():
module = AnsibleModule(
argument_spec={},
)

module.exit_json()


if __name__ == "__main__":
main()
@@ -0,0 +1,4 @@
plugins/inventory/inventory1.py:34:1: multiple-yaml-documents: RETURN: expected a single document in the stream
plugins/modules/module1.py:15:1: key-duplicates: DOCUMENTATION: duplication of key "short_description" in mapping
plugins/modules/module1.py:25:3: error: RETURN: syntax error: expected <block end>, but found '<block mapping start>' (syntax)
plugins/modules/module1.py:25:3: unparsable-with-libyaml: RETURN: while parsing a block mapping - did not find expected key
11 changes: 11 additions & 0 deletions test/integration/targets/ansible-test-sanity-yamllint/runme.sh
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

set -eu

source ../collection/setup.sh

set -x

ansible-test sanity --test yamllint --color --lint --failure-ok "${@}" > actual.txt

diff -u "${TEST_DIR}/expected.txt" actual.txt
Expand Up @@ -126,19 +126,31 @@ def check_module(self, conf, path, contents): # type: (YamlLintConfig, str, str
yaml_data = yaml_data[1:]
lineno += 1

self.check_parsable(path, yaml_data, lineno)
multiple_docs_allowed = [
"EXAMPLES",
]
self.check_parsable(path, yaml_data, lineno, (key in multiple_docs_allowed), key)

messages = list(linter.run(yaml_data, conf, path))

self.messages += [self.result_to_message(r, path, lineno - 1, key) for r in messages]

def check_parsable(self, path, contents, lineno=1): # type: (str, str, int) -> None
def check_parsable(self, path, contents, lineno=1, allow_multiple=False, prefix=""): # type: (str, str, int, bool) -> None
"""Check the given contents to verify they can be parsed as YAML."""
prefix = f"{prefix}: " if prefix else ""
try:
yaml.load(contents, Loader=TestLoader)
documents = len(list(yaml.load_all(contents, Loader=TestLoader)))
if documents > 1 and not allow_multiple:
self.messages += [{'code': 'multiple-yaml-documents',
'message': f'{prefix}expected a single document in the stream',
'path': path,
'line': lineno,
'column': 1,
'level': 'error',
}]
except MarkedYAMLError as ex:
self.messages += [{'code': 'unparsable-with-libyaml',
'message': '%s - %s' % (ex.args[0], ex.args[2]),
'message': f'{prefix}{ex.args[0]} - {ex.args[2]}',
'path': path,
'line': ex.problem_mark.line + lineno,
'column': ex.problem_mark.column + 1,
Expand Down