Add several new doc<->arg_spec checks (#36247)

* Add several new doc<->arg_spec checks. See #18183

* Update ignore.txt for validate-modules
This commit is contained in:
Matt Martz 2018-02-15 14:34:40 -06:00 committed by John R Barker
parent 77fa41795e
commit 50adc5409b
4 changed files with 2958 additions and 7 deletions

View file

@ -110,6 +110,9 @@ Errors
321 ``Exception`` attempting to import module for ``argument_spec`` introspection
322 argument is listed in the argument_spec, but not documented in the module
323 argument is listed in DOCUMENTATION.options, but not accepted by the module
324 Value for "default" from the argument_spec does not match the documentation
325 argument_spec defines type="bool" but documentation does not
326 Value for "choices" from the argument_spec does not match the documentation
..
--------- -------------------
**4xx** **Syntax**

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,7 @@ from module_args import AnsibleModuleImportError, get_argument_spec
from schema import doc_schema, metadata_1_1_schema, return_schema
from utils import CaptureStd, parse_yaml
from utils import CaptureStd, compare_unordered_lists, maybe_convert_bool, parse_yaml
from voluptuous.humanize import humanize_error
from ansible.module_utils.six import PY3, with_metaclass
@ -1058,6 +1058,34 @@ class ModuleValidator(Validator):
'should not be marked as required' % arg)
)
doc_default = docs.get('options', {}).get(arg, {}).get('default', None)
if data.get('type') == 'bool':
doc_default = maybe_convert_bool(doc_default)
if 'default' in data and data['default'] != doc_default:
self.reporter.error(
path=self.object_path,
code=324,
msg=('Value for "default" from the argument_spec (%r) for "%s" does not match the '
'documentation (%r)' % (data['default'], arg, doc_default))
)
doc_type = docs.get('options', {}).get(arg, {}).get('type', 'str')
if 'type' in data and data['type'] == 'bool' and doc_type != 'bool':
self.reporter.error(
path=self.object_path,
code=325,
msg='argument_spec for "%s" defines type="bool" but documentation does not' % (arg,)
)
doc_choices = docs.get('options', {}).get(arg, {}).get('choices', [])
if not compare_unordered_lists(data.get('choices', []), doc_choices):
self.reporter.error(
path=self.object_path,
code=326,
msg=('Value for "choices" from the argument_spec (%r) for "%s" does not match the '
'documentation (%r)' % (data.get('choices', []), arg, doc_choices))
)
if docs:
try:
add_fragments(docs, self.object_path, fragment_loader=fragment_loader)

View file

@ -25,6 +25,7 @@ import yaml
import yaml.reader
from ansible.module_utils._text import to_text
from ansible.module_utils.parsing.convert_bool import boolean
class AnsibleTextIOWrapper(TextIOWrapper):
@ -114,3 +115,24 @@ def parse_yaml(value, lineno, module, name, load_all=False):
})
return data, errors, traces
def maybe_convert_bool(value):
"""Safe conversion to boolean, catching TypeError and returning the original result
Only used in doc<->arg_spec comparisons
"""
try:
return boolean(value)
except TypeError:
return value
def compare_unordered_lists(a, b):
"""Safe list comparisons
Supports:
- unordered lists
- unhashable elements
"""
return len(a) == len(b) and all(x in b for x in a)