def test_get_warning_messages(warning_messages): for w in warning_messages: warn(w) accessor_warnings = get_warning_messages() assert isinstance(accessor_warnings, tuple) assert len(accessor_warnings) == 3
def validate(self, parameters): result = super(ModuleArgumentSpecValidator, self).validate(parameters) for d in result._deprecations: deprecate( "Alias '{name}' is deprecated. See the module docs for more information" .format(name=d['name']), version=d.get('version'), date=d.get('date'), collection_name=d.get('collection_name')) for w in result._warnings: warn('Both option {option} and its alias {alias} are set.'.format( option=w['option'], alias=w['alias'])) return result
def _validate_sub_spec(argument_spec, parameters, prefix='', options_context=None, errors=None, no_log_values=None, unsupported_parameters=None): """Validate sub argument spec. This function is recursive. """ if options_context is None: options_context = [] if errors is None: errors = AnsibleValidationErrorMultiple() if no_log_values is None: no_log_values = set() if unsupported_parameters is None: unsupported_parameters = set() for param, value in argument_spec.items(): wanted = value.get('type') if wanted == 'dict' or (wanted == 'list' and value.get('elements', '') == 'dict'): sub_spec = value.get('options') if value.get('apply_defaults', False): if sub_spec is not None: if parameters.get(param) is None: parameters[param] = {} else: continue elif sub_spec is None or param not in parameters or parameters[ param] is None: continue # Keep track of context for warning messages options_context.append(param) # Make sure we can iterate over the elements if not isinstance(parameters[param], Sequence) or isinstance( parameters[param], string_types): elements = [parameters[param]] else: elements = parameters[param] for idx, sub_parameters in enumerate(elements): no_log_values.update(set_fallbacks(sub_spec, sub_parameters)) if not isinstance(sub_parameters, dict): errors.append( SubParameterTypeError( "value of '%s' must be of type dict or list of dicts" % param)) continue # Set prefix for warning messages new_prefix = prefix + param if wanted == 'list': new_prefix += '[%d]' % idx new_prefix += '.' alias_warnings = [] alias_deprecations = [] try: options_aliases = _handle_aliases(sub_spec, sub_parameters, alias_warnings, alias_deprecations) except (TypeError, ValueError) as e: options_aliases = {} errors.append(AliasError(to_native(e))) for option, alias in alias_warnings: warn('Both option %s and its alias %s are set.' % (option, alias)) try: no_log_values.update( _list_no_log_values(sub_spec, sub_parameters)) except TypeError as te: errors.append(NoLogError(to_native(te))) legal_inputs = _get_legal_inputs(sub_spec, sub_parameters, options_aliases) unsupported_parameters.update( _get_unsupported_parameters(sub_spec, sub_parameters, legal_inputs, options_context)) try: check_mutually_exclusive(value.get('mutually_exclusive'), sub_parameters, options_context) except TypeError as e: errors.append(MutuallyExclusiveError(to_native(e))) no_log_values.update( _set_defaults(sub_spec, sub_parameters, False)) try: check_required_arguments(sub_spec, sub_parameters, options_context) except TypeError as e: errors.append(RequiredError(to_native(e))) _validate_argument_types(sub_spec, sub_parameters, new_prefix, options_context, errors=errors) _validate_argument_values(sub_spec, sub_parameters, options_context, errors=errors) for check in _ADDITIONAL_CHECKS: try: check['func'](value.get(check['attr']), sub_parameters, options_context) except TypeError as e: errors.append(check['err'](to_native(e))) no_log_values.update(_set_defaults(sub_spec, sub_parameters)) # Handle nested specs _validate_sub_spec(sub_spec, sub_parameters, new_prefix, options_context, errors, no_log_values, unsupported_parameters) options_context.pop()
def validate_sub_spec(argument_spec, parameters, prefix='', options_context=None, errors=None, no_log_values=None, unsupported_parameters=None): """Validate sub argument spec. This function is recursive.""" if options_context is None: options_context = [] if errors is None: errors = [] if no_log_values is None: no_log_values = set() if unsupported_parameters is None: unsupported_parameters = set() for param, value in argument_spec.items(): wanted = value.get('type') if wanted == 'dict' or (wanted == 'list' and value.get('elements', '') == dict): sub_spec = value.get('options') if value.get('apply_defaults', False): if sub_spec is not None: if parameters.get(value) is None: parameters[param] = {} else: continue elif sub_spec is None or param not in parameters or parameters[param] is None: continue # Keep track of context for warning messages options_context.append(param) # Make sure we can iterate over the elements if isinstance(parameters[param], dict): elements = [parameters[param]] else: elements = parameters[param] for idx, sub_parameters in enumerate(elements): if not isinstance(sub_parameters, dict): errors.append("value of '%s' must be of type dict or list of dicts" % param) # Set prefix for warning messages new_prefix = prefix + param if wanted == 'list': new_prefix += '[%d]' % idx new_prefix += '.' no_log_values.update(set_fallbacks(sub_spec, sub_parameters)) alias_warnings = [] try: options_aliases, legal_inputs = handle_aliases(sub_spec, sub_parameters, alias_warnings) except (TypeError, ValueError) as e: options_aliases = {} legal_inputs = None errors.append(to_native(e)) for option, alias in alias_warnings: warn('Both option %s and its alias %s are set.' % (option, alias)) no_log_values.update(list_no_log_values(sub_spec, sub_parameters)) if legal_inputs is None: legal_inputs = list(options_aliases.keys()) + list(sub_spec.keys()) unsupported_parameters.update(get_unsupported_parameters(sub_spec, sub_parameters, legal_inputs)) try: check_mutually_exclusive(value.get('mutually_exclusive'), sub_parameters) except TypeError as e: errors.append(to_native(e)) no_log_values.update(set_defaults(sub_spec, sub_parameters, False)) try: check_required_arguments(sub_spec, sub_parameters) except TypeError as e: errors.append(to_native(e)) validate_argument_types(sub_spec, sub_parameters, new_prefix, options_context, errors=errors) validate_argument_values(sub_spec, sub_parameters, options_context, errors=errors) checks = [ (check_required_together, 'required_together'), (check_required_one_of, 'required_one_of'), (check_required_if, 'required_if'), (check_required_by, 'required_by'), ] for check in checks: try: check[0](value.get(check[1]), parameters) except TypeError as e: errors.append(to_native(e)) no_log_values.update(set_defaults(sub_spec, sub_parameters)) # Handle nested specs validate_sub_spec(sub_spec, sub_parameters, new_prefix, options_context, errors, no_log_values, unsupported_parameters) options_context.pop()
def test_warn_failure(test_case): with pytest.raises(TypeError, match='warn requires a string not a %s' % type(test_case)): warn(test_case)
def test_multiple_warningss(warning_messages): for w in warning_messages: warn(w) assert warning_messages == warnings._global_warnings
def test_warn(): warn('Warning message') assert warnings._global_warnings == ['Warning message']
def validate(self, *args, **kwargs): """Validate module parameters against argument spec. :Example: validator = ArgumentSpecValidator(argument_spec, parameters) passeded = validator.validate() :param argument_spec: Specification of parameters, type, and valid values :type argument_spec: dict :param parameters: Parameters provided to the role :type parameters: dict :returns: True if no errors were encountered, False if any errors were encountered. :rtype: bool """ self._no_log_values.update(set_fallbacks(self.argument_spec, self._validated_parameters)) alias_warnings = [] alias_deprecations = [] try: alias_results, legal_inputs = handle_aliases(self.argument_spec, self._validated_parameters, alias_warnings, alias_deprecations) except (TypeError, ValueError) as e: alias_results = {} legal_inputs = None self._add_error(to_native(e)) for option, alias in alias_warnings: warn('Both option %s and its alias %s are set.' % (option, alias)) for deprecation in alias_deprecations: deprecate("Alias '%s' is deprecated. See the module docs for more information" % deprecation['name'], version=deprecation.get('version'), date=deprecation.get('date'), collection_name=deprecation.get('collection_name')) self._no_log_values.update(list_no_log_values(self.argument_spec, self._validated_parameters)) if legal_inputs is None: legal_inputs = list(alias_results.keys()) + list(self.argument_spec.keys()) self._unsupported_parameters.update(get_unsupported_parameters(self.argument_spec, self._validated_parameters, legal_inputs)) self._no_log_values.update(set_defaults(self.argument_spec, self._validated_parameters, False)) try: check_required_arguments(self.argument_spec, self._validated_parameters) except TypeError as e: self._add_error(to_native(e)) validate_argument_types(self.argument_spec, self._validated_parameters, errors=self._error_messages) validate_argument_values(self.argument_spec, self._validated_parameters, errors=self._error_messages) self._no_log_values.update(set_defaults(self.argument_spec, self._validated_parameters)) validate_sub_spec(self.argument_spec, self._validated_parameters, errors=self._error_messages, no_log_values=self._no_log_values, unsupported_parameters=self._unsupported_parameters) if self._unsupported_parameters: self._add_error('Unsupported parameters: %s' % ', '.join(sorted(list(self._unsupported_parameters)))) self._sanitize_error_messages() if self.error_messages: return False else: return True