"Fossies" - the Fresh Open Source Software Archive

Member "keystone-18.0.0/keystone/tests/unit/test_validation.py" (14 Oct 2020, 139339 Bytes) of package /linux/misc/openstack/keystone-18.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_validation.py": 17.0.0_vs_18.0.0.

    1 # -*- coding: utf-8 -*-
    2 # Licensed under the Apache License, Version 2.0 (the "License"); you may
    3 # not use this file except in compliance with the License. You may obtain
    4 # a copy of the License at
    5 #
    6 # http://www.apache.org/licenses/LICENSE-2.0
    7 #
    8 # Unless required by applicable law or agreed to in writing, software
    9 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   10 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   11 # License for the specific language governing permissions and limitations
   12 # under the License.
   13 
   14 import copy
   15 import uuid
   16 
   17 from keystone.application_credential import schema as app_cred_schema
   18 from keystone.assignment import schema as assignment_schema
   19 from keystone.catalog import schema as catalog_schema
   20 from keystone.common import validation
   21 from keystone.common.validation import parameter_types
   22 from keystone.common.validation import validators
   23 from keystone.credential import schema as credential_schema
   24 from keystone import exception
   25 from keystone.federation import schema as federation_schema
   26 from keystone.identity.backends import resource_options as ro
   27 from keystone.identity import schema as identity_schema
   28 from keystone.limit import schema as limit_schema
   29 from keystone.oauth1 import schema as oauth1_schema
   30 from keystone.policy import schema as policy_schema
   31 from keystone.resource import schema as resource_schema
   32 from keystone.tests import unit
   33 from keystone.trust import schema as trust_schema
   34 
   35 """Example model to validate create requests against. Assume that this is
   36 the only backend for the create and validate schemas. This is just an
   37 example to show how a backend can be used to construct a schema. In
   38 Keystone, schemas are built according to the Identity API and the backends
   39 available in Keystone. This example does not mean that all schema in
   40 Keystone were strictly based on the SQL backends.
   41 
   42 class Entity(sql.ModelBase):
   43     __tablename__ = 'entity'
   44     attributes = ['id', 'name', 'domain_id', 'description']
   45     id = sql.Column(sql.String(64), primary_key=True)
   46     name = sql.Column(sql.String(255), nullable=False)
   47     description = sql.Column(sql.Text(), nullable=True)
   48     enabled = sql.Column(sql.Boolean, default=True, nullable=False)
   49     url = sql.Column(sql.String(225), nullable=True)
   50     email = sql.Column(sql.String(64), nullable=True)
   51 """
   52 
   53 # Test schema to validate create requests against
   54 
   55 _entity_properties = {
   56     'name': parameter_types.name,
   57     'description': validation.nullable(parameter_types.description),
   58     'enabled': parameter_types.boolean,
   59     'url': validation.nullable(parameter_types.url),
   60     'email': validation.nullable(parameter_types.email),
   61     'id_string': validation.nullable(parameter_types.id_string)
   62 }
   63 
   64 entity_create = {
   65     'type': 'object',
   66     'properties': _entity_properties,
   67     'required': ['name'],
   68     'additionalProperties': True,
   69 }
   70 
   71 entity_create_optional_body = {
   72     'type': 'object',
   73     'properties': _entity_properties,
   74     'additionalProperties': True,
   75 }
   76 
   77 entity_update = {
   78     'type': 'object',
   79     'properties': _entity_properties,
   80     'minProperties': 1,
   81     'additionalProperties': True,
   82 }
   83 
   84 _VALID_ENABLED_FORMATS = [True, False]
   85 
   86 _INVALID_ENABLED_FORMATS = ['some string', 1, 0, 'True', 'False']
   87 
   88 _INVALID_DESC_FORMATS = [False, 1, 2.0]
   89 
   90 _VALID_URLS = ['https://example.com', 'http://EXAMPLE.com/v3',
   91                'http://localhost', 'http://127.0.0.1:5000',
   92                'http://1.1.1.1', 'http://255.255.255.255',
   93                'http://[::1]', 'http://[::1]:35357',
   94                'http://[1::8]', 'http://[fe80::8%25eth0]',
   95                'http://[::1.2.3.4]', 'http://[2001:DB8::1.2.3.4]',
   96                'http://[::a:1.2.3.4]', 'http://[a::b:1.2.3.4]',
   97                'http://[1:2:3:4:5:6:7:8]', 'http://[1:2:3:4:5:6:1.2.3.4]',
   98                'http://[abcd:efAB:CDEF:1111:9999::]']
   99 
  100 _INVALID_URLS = [False, 'this is not a URL', 1234, 'www.example.com',
  101                  'localhost', 'http//something.com',
  102                  'https//something.com', ' http://example.com']
  103 
  104 _VALID_FILTERS = [{'interface': 'admin'},
  105                   {'region': 'US-WEST',
  106                    'interface': 'internal'}]
  107 
  108 _INVALID_FILTERS = ['some string', 1, 0, True, False]
  109 
  110 _INVALID_NAMES = [True, 24, ' ', '', 'a' * 256, None]
  111 
  112 
  113 class CommonValidationTestCase(unit.BaseTestCase):
  114 
  115     def test_nullable_type_only(self):
  116         bool_without_enum = copy.deepcopy(parameter_types.boolean)
  117         bool_without_enum.pop('enum')
  118         schema_type_only = {
  119             'type': 'object',
  120             'properties': {'test': validation.nullable(bool_without_enum)},
  121             'additionalProperties': False,
  122             'required': ['test']}
  123 
  124         # Null should be in the types
  125         self.assertIn('null', schema_type_only['properties']['test']['type'])
  126         # No Enum, and nullable should not have added it.
  127         self.assertNotIn('enum', schema_type_only['properties']['test'].keys())
  128         validator = validators.SchemaValidator(schema_type_only)
  129         reqs_to_validate = [{'test': val} for val in [True, False, None]]
  130         for req in reqs_to_validate:
  131             validator.validate(req)
  132 
  133     def test_nullable_with_enum(self):
  134         schema_with_enum = {
  135             'type': 'object',
  136             'properties': {
  137                 'test': validation.nullable(parameter_types.boolean)},
  138             'additionalProperties': False,
  139             'required': ['test']}
  140 
  141         # Null should be in enum and type
  142         self.assertIn('null', schema_with_enum['properties']['test']['type'])
  143         self.assertIn(None, schema_with_enum['properties']['test']['enum'])
  144         validator = validators.SchemaValidator(schema_with_enum)
  145         reqs_to_validate = [{'test': val} for val in [True, False, None]]
  146         for req in reqs_to_validate:
  147             validator.validate(req)
  148 
  149 
  150 class EntityValidationTestCase(unit.BaseTestCase):
  151 
  152     def setUp(self):
  153         super(EntityValidationTestCase, self).setUp()
  154         self.resource_name = 'some resource name'
  155         self.description = 'Some valid description'
  156         self.valid_enabled = True
  157         self.valid_url = 'http://example.com'
  158         self.valid_email = 'joe@example.com'
  159         self.create_schema_validator = validators.SchemaValidator(
  160             entity_create)
  161         self.update_schema_validator = validators.SchemaValidator(
  162             entity_update)
  163 
  164     def test_create_entity_with_all_valid_parameters_validates(self):
  165         """Validate all parameter values against test schema."""
  166         request_to_validate = {'name': self.resource_name,
  167                                'description': self.description,
  168                                'enabled': self.valid_enabled,
  169                                'url': self.valid_url,
  170                                'email': self.valid_email}
  171         self.create_schema_validator.validate(request_to_validate)
  172 
  173     def test_create_entity_with_only_required_valid_parameters_validates(self):
  174         """Validate correct for only parameters values against test schema."""
  175         request_to_validate = {'name': self.resource_name}
  176         self.create_schema_validator.validate(request_to_validate)
  177 
  178     def test_create_entity_with_name_too_long_raises_exception(self):
  179         """Validate long names.
  180 
  181         Validate that an exception is raised when validating a string of 255+
  182         characters passed in as a name.
  183         """
  184         invalid_name = 'a' * 256
  185         request_to_validate = {'name': invalid_name}
  186         self.assertRaises(exception.SchemaValidationError,
  187                           self.create_schema_validator.validate,
  188                           request_to_validate)
  189 
  190     def test_create_entity_with_name_too_short_raises_exception(self):
  191         """Validate short names.
  192 
  193         Test that an exception is raised when passing a string of length
  194         zero as a name parameter.
  195         """
  196         request_to_validate = {'name': ''}
  197         self.assertRaises(exception.SchemaValidationError,
  198                           self.create_schema_validator.validate,
  199                           request_to_validate)
  200 
  201     def test_create_entity_with_unicode_name_validates(self):
  202         """Test that we successfully validate a unicode string."""
  203         request_to_validate = {'name': u'αβγδ'}
  204         self.create_schema_validator.validate(request_to_validate)
  205 
  206     def test_create_entity_with_invalid_enabled_format_raises_exception(self):
  207         """Validate invalid enabled formats.
  208 
  209         Test that an exception is raised when passing invalid boolean-like
  210         values as `enabled`.
  211         """
  212         for format in _INVALID_ENABLED_FORMATS:
  213             request_to_validate = {'name': self.resource_name,
  214                                    'enabled': format}
  215             self.assertRaises(exception.SchemaValidationError,
  216                               self.create_schema_validator.validate,
  217                               request_to_validate)
  218 
  219     def test_create_entity_with_valid_enabled_formats_validates(self):
  220         """Validate valid enabled formats.
  221 
  222         Test that we have successful validation on boolean values for
  223         `enabled`.
  224         """
  225         for valid_enabled in _VALID_ENABLED_FORMATS:
  226             request_to_validate = {'name': self.resource_name,
  227                                    'enabled': valid_enabled}
  228             # Make sure validation doesn't raise a validation exception
  229             self.create_schema_validator.validate(request_to_validate)
  230 
  231     def test_create_entity_with_valid_urls_validates(self):
  232         """Test that proper urls are successfully validated."""
  233         for valid_url in _VALID_URLS:
  234             request_to_validate = {'name': self.resource_name,
  235                                    'url': valid_url}
  236             self.create_schema_validator.validate(request_to_validate)
  237 
  238     def test_create_entity_with_invalid_urls_fails(self):
  239         """Test that an exception is raised when validating improper urls."""
  240         for invalid_url in _INVALID_URLS:
  241             request_to_validate = {'name': self.resource_name,
  242                                    'url': invalid_url}
  243             self.assertRaises(exception.SchemaValidationError,
  244                               self.create_schema_validator.validate,
  245                               request_to_validate)
  246 
  247     def test_create_entity_with_valid_email_validates(self):
  248         """Validate email address.
  249 
  250         Test that we successfully validate properly formatted email
  251         addresses.
  252         """
  253         request_to_validate = {'name': self.resource_name,
  254                                'email': self.valid_email}
  255         self.create_schema_validator.validate(request_to_validate)
  256 
  257     def test_create_entity_with_invalid_email_fails(self):
  258         """Validate invalid email address.
  259 
  260         Test that an exception is raised when validating improperly
  261         formatted email addresses.
  262         """
  263         request_to_validate = {'name': self.resource_name,
  264                                'email': 'some invalid email value'}
  265         self.assertRaises(exception.SchemaValidationError,
  266                           self.create_schema_validator.validate,
  267                           request_to_validate)
  268 
  269     def test_create_entity_with_valid_id_strings(self):
  270         """Validate acceptable id strings."""
  271         valid_id_strings = [str(uuid.uuid4()), uuid.uuid4().hex, 'default']
  272         for valid_id in valid_id_strings:
  273             request_to_validate = {'name': self.resource_name,
  274                                    'id_string': valid_id}
  275             self.create_schema_validator.validate(request_to_validate)
  276 
  277     def test_create_entity_with_invalid_id_strings(self):
  278         """Exception raised when using invalid id strings."""
  279         long_string = 'A' * 65
  280         invalid_id_strings = ['', long_string]
  281         for invalid_id in invalid_id_strings:
  282             request_to_validate = {'name': self.resource_name,
  283                                    'id_string': invalid_id}
  284             self.assertRaises(exception.SchemaValidationError,
  285                               self.create_schema_validator.validate,
  286                               request_to_validate)
  287 
  288     def test_create_entity_with_null_id_string(self):
  289         """Validate that None is an acceptable optional string type."""
  290         request_to_validate = {'name': self.resource_name,
  291                                'id_string': None}
  292         self.create_schema_validator.validate(request_to_validate)
  293 
  294     def test_create_entity_with_null_string_succeeds(self):
  295         """Exception raised when passing None on required id strings."""
  296         request_to_validate = {'name': self.resource_name,
  297                                'id_string': None}
  298         self.create_schema_validator.validate(request_to_validate)
  299 
  300     def test_update_entity_with_no_parameters_fails(self):
  301         """At least one parameter needs to be present for an update."""
  302         request_to_validate = {}
  303         self.assertRaises(exception.SchemaValidationError,
  304                           self.update_schema_validator.validate,
  305                           request_to_validate)
  306 
  307     def test_update_entity_with_all_parameters_valid_validates(self):
  308         """Simulate updating an entity by ID."""
  309         request_to_validate = {'name': self.resource_name,
  310                                'description': self.description,
  311                                'enabled': self.valid_enabled,
  312                                'url': self.valid_url,
  313                                'email': self.valid_email}
  314         self.update_schema_validator.validate(request_to_validate)
  315 
  316     def test_update_entity_with_a_valid_required_parameter_validates(self):
  317         """Succeed if a valid required parameter is provided."""
  318         request_to_validate = {'name': self.resource_name}
  319         self.update_schema_validator.validate(request_to_validate)
  320 
  321     def test_update_entity_with_invalid_required_parameter_fails(self):
  322         """Fail if a provided required parameter is invalid."""
  323         request_to_validate = {'name': 'a' * 256}
  324         self.assertRaises(exception.SchemaValidationError,
  325                           self.update_schema_validator.validate,
  326                           request_to_validate)
  327 
  328     def test_update_entity_with_a_null_optional_parameter_validates(self):
  329         """Optional parameters can be null to removed the value."""
  330         request_to_validate = {'email': None}
  331         self.update_schema_validator.validate(request_to_validate)
  332 
  333     def test_update_entity_with_a_required_null_parameter_fails(self):
  334         """The `name` parameter can't be null."""
  335         request_to_validate = {'name': None}
  336         self.assertRaises(exception.SchemaValidationError,
  337                           self.update_schema_validator.validate,
  338                           request_to_validate)
  339 
  340     def test_update_entity_with_a_valid_optional_parameter_validates(self):
  341         """Succeed with only a single valid optional parameter."""
  342         request_to_validate = {'email': self.valid_email}
  343         self.update_schema_validator.validate(request_to_validate)
  344 
  345     def test_update_entity_with_invalid_optional_parameter_fails(self):
  346         """Fail when an optional parameter is invalid."""
  347         request_to_validate = {'email': 0}
  348         self.assertRaises(exception.SchemaValidationError,
  349                           self.update_schema_validator.validate,
  350                           request_to_validate)
  351 
  352 
  353 class ProjectValidationTestCase(unit.BaseTestCase):
  354     """Test for V3 Project API validation."""
  355 
  356     def setUp(self):
  357         super(ProjectValidationTestCase, self).setUp()
  358 
  359         self.project_name = 'My Project'
  360 
  361         create = resource_schema.project_create
  362         update = resource_schema.project_update
  363         self.create_project_validator = validators.SchemaValidator(create)
  364         self.update_project_validator = validators.SchemaValidator(update)
  365 
  366     def test_validate_project_request(self):
  367         """Test that we validate a project with `name` in request."""
  368         request_to_validate = {'name': self.project_name}
  369         self.create_project_validator.validate(request_to_validate)
  370 
  371     def test_validate_project_request_without_name_fails(self):
  372         """Validate project request fails without name."""
  373         request_to_validate = {'enabled': True}
  374         self.assertRaises(exception.SchemaValidationError,
  375                           self.create_project_validator.validate,
  376                           request_to_validate)
  377 
  378     def test_validate_project_request_with_enabled(self):
  379         """Validate `enabled` as boolean-like values for projects."""
  380         for valid_enabled in _VALID_ENABLED_FORMATS:
  381             request_to_validate = {'name': self.project_name,
  382                                    'enabled': valid_enabled}
  383             self.create_project_validator.validate(request_to_validate)
  384 
  385     def test_validate_project_request_with_invalid_enabled_fails(self):
  386         """Exception is raised when `enabled` isn't a boolean-like value."""
  387         for invalid_enabled in _INVALID_ENABLED_FORMATS:
  388             request_to_validate = {'name': self.project_name,
  389                                    'enabled': invalid_enabled}
  390             self.assertRaises(exception.SchemaValidationError,
  391                               self.create_project_validator.validate,
  392                               request_to_validate)
  393 
  394     def test_validate_project_request_with_valid_description(self):
  395         """Test that we validate `description` in create project requests."""
  396         request_to_validate = {'name': self.project_name,
  397                                'description': 'My Project'}
  398         self.create_project_validator.validate(request_to_validate)
  399 
  400     def test_validate_project_request_with_invalid_description_fails(self):
  401         """Exception is raised when `description` as a non-string value."""
  402         request_to_validate = {'name': self.project_name,
  403                                'description': False}
  404         self.assertRaises(exception.SchemaValidationError,
  405                           self.create_project_validator.validate,
  406                           request_to_validate)
  407 
  408     def test_validate_project_request_with_name_too_long(self):
  409         """Exception is raised when `name` is too long."""
  410         long_project_name = 'a' * 65
  411         request_to_validate = {'name': long_project_name}
  412         self.assertRaises(exception.SchemaValidationError,
  413                           self.create_project_validator.validate,
  414                           request_to_validate)
  415 
  416     def test_validate_project_create_fails_with_invalid_name(self):
  417         """Exception when validating a create request with invalid `name`."""
  418         for invalid_name in _INVALID_NAMES + ['a' * 65]:
  419             request_to_validate = {'name': invalid_name}
  420             self.assertRaises(exception.SchemaValidationError,
  421                               self.create_project_validator.validate,
  422                               request_to_validate)
  423 
  424     def test_validate_project_create_with_tags(self):
  425         request_to_validate = {'name': uuid.uuid4().hex,
  426                                'tags': ['foo', 'bar']}
  427         self.create_project_validator.validate(request_to_validate)
  428 
  429     def test_validate_project_create_with_tags_invalid_char(self):
  430         invalid_chars = [',', '/', ',foo', 'foo/bar']
  431         for char in invalid_chars:
  432             tag = uuid.uuid4().hex + char
  433             request_to_validate = {'name': uuid.uuid4().hex,
  434                                    'tags': ['foo', tag]}
  435             self.assertRaises(exception.SchemaValidationError,
  436                               self.create_project_validator.validate,
  437                               request_to_validate)
  438 
  439     def test_validate_project_create_with_tag_name_too_long(self):
  440         invalid_name = 'a' * 256
  441         request_to_validate = {'name': uuid.uuid4().hex,
  442                                'tags': ['foo', invalid_name]}
  443         self.assertRaises(exception.SchemaValidationError,
  444                           self.create_project_validator.validate,
  445                           request_to_validate)
  446 
  447     def test_validate_project_create_with_too_many_tags(self):
  448         tags = [uuid.uuid4().hex for _ in range(81)]
  449         request_to_validate = {'name': uuid.uuid4().hex,
  450                                'tags': tags}
  451         self.assertRaises(exception.SchemaValidationError,
  452                           self.create_project_validator.validate,
  453                           request_to_validate)
  454 
  455     def test_validate_project_request_with_valid_parent_id(self):
  456         """Test that we validate `parent_id` in create project requests."""
  457         # parent_id is nullable
  458         request_to_validate = {'name': self.project_name,
  459                                'parent_id': None}
  460         self.create_project_validator.validate(request_to_validate)
  461         request_to_validate = {'name': self.project_name,
  462                                'parent_id': uuid.uuid4().hex}
  463         self.create_project_validator.validate(request_to_validate)
  464 
  465     def test_validate_project_request_with_invalid_parent_id_fails(self):
  466         """Exception is raised when `parent_id` as a non-id value."""
  467         request_to_validate = {'name': self.project_name,
  468                                'parent_id': False}
  469         self.assertRaises(exception.SchemaValidationError,
  470                           self.create_project_validator.validate,
  471                           request_to_validate)
  472         request_to_validate = {'name': self.project_name,
  473                                'parent_id': 'fake project'}
  474         self.assertRaises(exception.SchemaValidationError,
  475                           self.create_project_validator.validate,
  476                           request_to_validate)
  477 
  478     def test_validate_project_update_request(self):
  479         """Test that we validate a project update request."""
  480         request_to_validate = {'domain_id': uuid.uuid4().hex}
  481         self.update_project_validator.validate(request_to_validate)
  482 
  483     def test_validate_project_update_request_with_no_parameters_fails(self):
  484         """Exception is raised when updating project without parameters."""
  485         request_to_validate = {}
  486         self.assertRaises(exception.SchemaValidationError,
  487                           self.update_project_validator.validate,
  488                           request_to_validate)
  489 
  490     def test_validate_project_update_request_with_name_too_long_fails(self):
  491         """Exception raised when updating a project with `name` too long."""
  492         long_project_name = 'a' * 65
  493         request_to_validate = {'name': long_project_name}
  494         self.assertRaises(exception.SchemaValidationError,
  495                           self.update_project_validator.validate,
  496                           request_to_validate)
  497 
  498     def test_validate_project_update_fails_with_invalid_name(self):
  499         """Exception when validating an update request with invalid `name`."""
  500         for invalid_name in _INVALID_NAMES:
  501             request_to_validate = {'name': invalid_name}
  502             self.assertRaises(exception.SchemaValidationError,
  503                               self.update_project_validator.validate,
  504                               request_to_validate)
  505 
  506     def test_validate_project_update_with_tags(self):
  507         request_to_validate = {'name': uuid.uuid4().hex,
  508                                'tags': ['foo', 'bar']}
  509         self.update_project_validator.validate(request_to_validate)
  510 
  511     def test_validate_project_update_with_tags_invalid_char(self):
  512         invalid_chars = [',', '/']
  513         for char in invalid_chars:
  514             tag = uuid.uuid4().hex + char
  515             request_to_validate = {'name': uuid.uuid4().hex,
  516                                    'tags': ['foo', tag]}
  517             self.assertRaises(exception.SchemaValidationError,
  518                               self.update_project_validator.validate,
  519                               request_to_validate)
  520 
  521     def test_validate_project_update_with_tag_name_too_long(self):
  522         invalid_name = 'a' * 256
  523         request_to_validate = {'name': uuid.uuid4().hex,
  524                                'tags': ['foo', invalid_name]}
  525         self.assertRaises(exception.SchemaValidationError,
  526                           self.update_project_validator.validate,
  527                           request_to_validate)
  528 
  529     def test_validate_project_update_with_too_many_tags(self):
  530         tags = [uuid.uuid4().hex for _ in range(81)]
  531         request_to_validate = {'name': uuid.uuid4().hex,
  532                                'tags': tags}
  533         self.assertRaises(exception.SchemaValidationError,
  534                           self.update_project_validator.validate,
  535                           request_to_validate)
  536 
  537     def test_validate_project_create_request_with_valid_domain_id(self):
  538         """Test that we validate `domain_id` in create project requests."""
  539         # domain_id is nullable
  540         for domain_id in [None, uuid.uuid4().hex]:
  541             request_to_validate = {'name': self.project_name,
  542                                    'domain_id': domain_id}
  543             self.create_project_validator.validate(request_to_validate)
  544 
  545     def test_validate_project_request_with_invalid_domain_id_fails(self):
  546         """Exception is raised when `domain_id` is a non-id value."""
  547         for domain_id in [False, 'fake_project']:
  548             request_to_validate = {'name': self.project_name,
  549                                    'domain_id': domain_id}
  550             self.assertRaises(exception.SchemaValidationError,
  551                               self.create_project_validator.validate,
  552                               request_to_validate)
  553 
  554 
  555 class DomainValidationTestCase(unit.BaseTestCase):
  556     """Test for V3 Domain API validation."""
  557 
  558     def setUp(self):
  559         super(DomainValidationTestCase, self).setUp()
  560 
  561         self.domain_name = 'My Domain'
  562 
  563         create = resource_schema.domain_create
  564         update = resource_schema.domain_update
  565         self.create_domain_validator = validators.SchemaValidator(create)
  566         self.update_domain_validator = validators.SchemaValidator(update)
  567 
  568     def test_validate_domain_request(self):
  569         """Make sure we successfully validate a create domain request."""
  570         request_to_validate = {'name': self.domain_name}
  571         self.create_domain_validator.validate(request_to_validate)
  572 
  573     def test_validate_domain_request_without_name_fails(self):
  574         """Make sure we raise an exception when `name` isn't included."""
  575         request_to_validate = {'enabled': True}
  576         self.assertRaises(exception.SchemaValidationError,
  577                           self.create_domain_validator.validate,
  578                           request_to_validate)
  579 
  580     def test_validate_domain_request_with_enabled(self):
  581         """Validate `enabled` as boolean-like values for domains."""
  582         for valid_enabled in _VALID_ENABLED_FORMATS:
  583             request_to_validate = {'name': self.domain_name,
  584                                    'enabled': valid_enabled}
  585             self.create_domain_validator.validate(request_to_validate)
  586 
  587     def test_validate_domain_request_with_invalid_enabled_fails(self):
  588         """Exception is raised when `enabled` isn't a boolean-like value."""
  589         for invalid_enabled in _INVALID_ENABLED_FORMATS:
  590             request_to_validate = {'name': self.domain_name,
  591                                    'enabled': invalid_enabled}
  592             self.assertRaises(exception.SchemaValidationError,
  593                               self.create_domain_validator.validate,
  594                               request_to_validate)
  595 
  596     def test_validate_domain_request_with_valid_description(self):
  597         """Test that we validate `description` in create domain requests."""
  598         request_to_validate = {'name': self.domain_name,
  599                                'description': 'My Domain'}
  600         self.create_domain_validator.validate(request_to_validate)
  601 
  602     def test_validate_domain_request_with_invalid_description_fails(self):
  603         """Exception is raised when `description` is a non-string value."""
  604         request_to_validate = {'name': self.domain_name,
  605                                'description': False}
  606         self.assertRaises(exception.SchemaValidationError,
  607                           self.create_domain_validator.validate,
  608                           request_to_validate)
  609 
  610     def test_validate_domain_request_with_name_too_long(self):
  611         """Exception is raised when `name` is too long."""
  612         long_domain_name = 'a' * 65
  613         request_to_validate = {'name': long_domain_name}
  614         self.assertRaises(exception.SchemaValidationError,
  615                           self.create_domain_validator.validate,
  616                           request_to_validate)
  617 
  618     def test_validate_domain_create_fails_with_invalid_name(self):
  619         """Exception when validating a create request with invalid `name`."""
  620         for invalid_name in _INVALID_NAMES:
  621             request_to_validate = {'name': invalid_name}
  622             self.assertRaises(exception.SchemaValidationError,
  623                               self.create_domain_validator.validate,
  624                               request_to_validate)
  625 
  626     def test_validate_domain_create_with_tags(self):
  627         request_to_validate = {'name': uuid.uuid4().hex,
  628                                'tags': ['foo', 'bar']}
  629         self.create_domain_validator.validate(request_to_validate)
  630 
  631     def test_validate_domain_create_with_tags_invalid_char(self):
  632         invalid_chars = [',', '/']
  633         for char in invalid_chars:
  634             tag = uuid.uuid4().hex + char
  635             request_to_validate = {'name': uuid.uuid4().hex,
  636                                    'tags': ['foo', tag]}
  637             self.assertRaises(exception.SchemaValidationError,
  638                               self.create_domain_validator.validate,
  639                               request_to_validate)
  640 
  641     def test_validate_domain_create_with_tag_name_too_long(self):
  642         invalid_name = 'a' * 256
  643         request_to_validate = {'name': uuid.uuid4().hex,
  644                                'tags': ['foo', invalid_name]}
  645         self.assertRaises(exception.SchemaValidationError,
  646                           self.create_domain_validator.validate,
  647                           request_to_validate)
  648 
  649     def test_validate_domain_create_with_too_many_tags(self):
  650         tags = [uuid.uuid4().hex for _ in range(81)]
  651         request_to_validate = {'name': uuid.uuid4().hex,
  652                                'tags': tags}
  653         self.assertRaises(exception.SchemaValidationError,
  654                           self.create_domain_validator.validate,
  655                           request_to_validate)
  656 
  657     def test_validate_domain_update_request(self):
  658         """Test that we validate a domain update request."""
  659         request_to_validate = {'domain_id': uuid.uuid4().hex}
  660         self.update_domain_validator.validate(request_to_validate)
  661 
  662     def test_validate_domain_update_request_with_no_parameters_fails(self):
  663         """Exception is raised when updating a domain without parameters."""
  664         request_to_validate = {}
  665         self.assertRaises(exception.SchemaValidationError,
  666                           self.update_domain_validator.validate,
  667                           request_to_validate)
  668 
  669     def test_validate_domain_update_request_with_name_too_long_fails(self):
  670         """Exception raised when updating a domain with `name` too long."""
  671         long_domain_name = 'a' * 65
  672         request_to_validate = {'name': long_domain_name}
  673         self.assertRaises(exception.SchemaValidationError,
  674                           self.update_domain_validator.validate,
  675                           request_to_validate)
  676 
  677     def test_validate_domain_update_fails_with_invalid_name(self):
  678         """Exception when validating an update request with invalid `name`."""
  679         for invalid_name in _INVALID_NAMES:
  680             request_to_validate = {'name': invalid_name}
  681             self.assertRaises(exception.SchemaValidationError,
  682                               self.update_domain_validator.validate,
  683                               request_to_validate)
  684 
  685     def test_validate_domain_update_with_tags(self):
  686         request_to_validate = {'name': uuid.uuid4().hex,
  687                                'tags': ['foo', 'bar']}
  688         self.update_domain_validator.validate(request_to_validate)
  689 
  690     def test_validate_domain_update_with_tags_invalid_char(self):
  691         invalid_chars = [',', '/']
  692         for char in invalid_chars:
  693             tag = uuid.uuid4().hex + char
  694             request_to_validate = {'name': uuid.uuid4().hex,
  695                                    'tags': ['foo', tag]}
  696             self.assertRaises(exception.SchemaValidationError,
  697                               self.update_domain_validator.validate,
  698                               request_to_validate)
  699 
  700     def test_validate_domain_update_with_tag_name_too_long(self):
  701         invalid_name = 'a' * 256
  702         request_to_validate = {'name': uuid.uuid4().hex,
  703                                'tags': ['foo', invalid_name]}
  704         self.assertRaises(exception.SchemaValidationError,
  705                           self.update_domain_validator.validate,
  706                           request_to_validate)
  707 
  708     def test_validate_domain_update_with_too_many_tags(self):
  709         tags = [uuid.uuid4().hex for _ in range(81)]
  710         request_to_validate = {'name': uuid.uuid4().hex,
  711                                'tags': tags}
  712         self.assertRaises(exception.SchemaValidationError,
  713                           self.update_domain_validator.validate,
  714                           request_to_validate)
  715 
  716 
  717 class RoleValidationTestCase(unit.BaseTestCase):
  718     """Test for V3 Role API validation."""
  719 
  720     def setUp(self):
  721         super(RoleValidationTestCase, self).setUp()
  722 
  723         self.role_name = 'My Role'
  724 
  725         create = assignment_schema.role_create
  726         update = assignment_schema.role_update
  727         self.create_role_validator = validators.SchemaValidator(create)
  728         self.update_role_validator = validators.SchemaValidator(update)
  729 
  730     def test_validate_role_request(self):
  731         """Test we can successfully validate a create role request."""
  732         request_to_validate = {'name': self.role_name}
  733         self.create_role_validator.validate(request_to_validate)
  734 
  735     def test_validate_role_create_without_name_raises_exception(self):
  736         """Test that we raise an exception when `name` isn't included."""
  737         request_to_validate = {'enabled': True}
  738         self.assertRaises(exception.SchemaValidationError,
  739                           self.create_role_validator.validate,
  740                           request_to_validate)
  741 
  742     def test_validate_role_create_fails_with_invalid_name(self):
  743         """Exception when validating a create request with invalid `name`."""
  744         for invalid_name in _INVALID_NAMES:
  745             request_to_validate = {'name': invalid_name}
  746             self.assertRaises(exception.SchemaValidationError,
  747                               self.create_role_validator.validate,
  748                               request_to_validate)
  749 
  750     def test_validate_role_create_request_with_name_too_long_fails(self):
  751         """Exception raised when creating a role with `name` too long."""
  752         long_role_name = 'a' * 256
  753         request_to_validate = {'name': long_role_name}
  754         self.assertRaises(exception.SchemaValidationError,
  755                           self.create_role_validator.validate,
  756                           request_to_validate)
  757 
  758     def test_validate_role_request_with_valid_description(self):
  759         """Test we can validate`description` in create role request."""
  760         request_to_validate = {'name': self.role_name,
  761                                'description': 'My Role'}
  762         self.create_role_validator.validate(request_to_validate)
  763 
  764     def test_validate_role_request_fails_with_invalid_description(self):
  765         """Exception is raised when `description` as a non-string value."""
  766         request_to_validate = {'name': self.role_name,
  767                                'description': False}
  768         self.assertRaises(exception.SchemaValidationError,
  769                           self.create_role_validator.validate,
  770                           request_to_validate)
  771 
  772     def test_validate_role_update_request(self):
  773         """Test that we validate a role update request."""
  774         request_to_validate = {'name': 'My New Role'}
  775         self.update_role_validator.validate(request_to_validate)
  776 
  777     def test_validate_role_update_fails_with_invalid_name(self):
  778         """Exception when validating an update request with invalid `name`."""
  779         for invalid_name in _INVALID_NAMES:
  780             request_to_validate = {'name': invalid_name}
  781             self.assertRaises(exception.SchemaValidationError,
  782                               self.update_role_validator.validate,
  783                               request_to_validate)
  784 
  785     def test_validate_role_update_request_with_name_too_long_fails(self):
  786         """Exception raised when updating a role with `name` too long."""
  787         long_role_name = 'a' * 256
  788         request_to_validate = {'name': long_role_name}
  789         self.assertRaises(exception.SchemaValidationError,
  790                           self.update_role_validator.validate,
  791                           request_to_validate)
  792 
  793 
  794 class PolicyValidationTestCase(unit.BaseTestCase):
  795     """Test for V3 Policy API validation."""
  796 
  797     def setUp(self):
  798         super(PolicyValidationTestCase, self).setUp()
  799 
  800         create = policy_schema.policy_create
  801         update = policy_schema.policy_update
  802         self.create_policy_validator = validators.SchemaValidator(create)
  803         self.update_policy_validator = validators.SchemaValidator(update)
  804 
  805     def test_validate_policy_succeeds(self):
  806         """Test that we validate a create policy request."""
  807         request_to_validate = {'blob': 'some blob information',
  808                                'type': 'application/json'}
  809         self.create_policy_validator.validate(request_to_validate)
  810 
  811     def test_validate_policy_without_blob_fails(self):
  812         """Exception raised without `blob` in request."""
  813         request_to_validate = {'type': 'application/json'}
  814         self.assertRaises(exception.SchemaValidationError,
  815                           self.create_policy_validator.validate,
  816                           request_to_validate)
  817 
  818     def test_validate_policy_without_type_fails(self):
  819         """Exception raised without `type` in request."""
  820         request_to_validate = {'blob': 'some blob information'}
  821         self.assertRaises(exception.SchemaValidationError,
  822                           self.create_policy_validator.validate,
  823                           request_to_validate)
  824 
  825     def test_validate_policy_create_with_extra_parameters_succeeds(self):
  826         """Validate policy create with extra parameters."""
  827         request_to_validate = {'blob': 'some blob information',
  828                                'type': 'application/json',
  829                                'extra': 'some extra stuff'}
  830         self.create_policy_validator.validate(request_to_validate)
  831 
  832     def test_validate_policy_create_with_invalid_type_fails(self):
  833         """Exception raised when `blob` and `type` are boolean."""
  834         for prop in ['blob', 'type']:
  835             request_to_validate = {prop: False}
  836             self.assertRaises(exception.SchemaValidationError,
  837                               self.create_policy_validator.validate,
  838                               request_to_validate)
  839 
  840     def test_validate_policy_update_without_parameters_fails(self):
  841         """Exception raised when updating policy without parameters."""
  842         request_to_validate = {}
  843         self.assertRaises(exception.SchemaValidationError,
  844                           self.update_policy_validator.validate,
  845                           request_to_validate)
  846 
  847     def test_validate_policy_update_with_extra_parameters_succeeds(self):
  848         """Validate policy update request with extra parameters."""
  849         request_to_validate = {'blob': 'some blob information',
  850                                'type': 'application/json',
  851                                'extra': 'some extra stuff'}
  852         self.update_policy_validator.validate(request_to_validate)
  853 
  854     def test_validate_policy_update_succeeds(self):
  855         """Test that we validate a policy update request."""
  856         request_to_validate = {'blob': 'some blob information',
  857                                'type': 'application/json'}
  858         self.update_policy_validator.validate(request_to_validate)
  859 
  860     def test_validate_policy_update_with_invalid_type_fails(self):
  861         """Exception raised when invalid `type` on policy update."""
  862         for prop in ['blob', 'type']:
  863             request_to_validate = {prop: False}
  864             self.assertRaises(exception.SchemaValidationError,
  865                               self.update_policy_validator.validate,
  866                               request_to_validate)
  867 
  868 
  869 class CredentialValidationTestCase(unit.BaseTestCase):
  870     """Test for V3 Credential API validation."""
  871 
  872     def setUp(self):
  873         super(CredentialValidationTestCase, self).setUp()
  874 
  875         create = credential_schema.credential_create
  876         update = credential_schema.credential_update
  877         self.create_credential_validator = validators.SchemaValidator(create)
  878         self.update_credential_validator = validators.SchemaValidator(update)
  879 
  880     def test_validate_credential_succeeds(self):
  881         """Test that we validate a credential request."""
  882         request_to_validate = {'blob': 'some string',
  883                                'project_id': uuid.uuid4().hex,
  884                                'type': 'ec2',
  885                                'user_id': uuid.uuid4().hex}
  886         self.create_credential_validator.validate(request_to_validate)
  887 
  888     def test_validate_credential_without_blob_fails(self):
  889         """Exception raised without `blob` in create request."""
  890         request_to_validate = {'type': 'ec2',
  891                                'user_id': uuid.uuid4().hex}
  892         self.assertRaises(exception.SchemaValidationError,
  893                           self.create_credential_validator.validate,
  894                           request_to_validate)
  895 
  896     def test_validate_credential_without_user_id_fails(self):
  897         """Exception raised without `user_id` in create request."""
  898         request_to_validate = {'blob': 'some credential blob',
  899                                'type': 'ec2'}
  900         self.assertRaises(exception.SchemaValidationError,
  901                           self.create_credential_validator.validate,
  902                           request_to_validate)
  903 
  904     def test_validate_credential_without_type_fails(self):
  905         """Exception raised without `type` in create request."""
  906         request_to_validate = {'blob': 'some credential blob',
  907                                'user_id': uuid.uuid4().hex}
  908         self.assertRaises(exception.SchemaValidationError,
  909                           self.create_credential_validator.validate,
  910                           request_to_validate)
  911 
  912     def test_validate_credential_ec2_without_project_id_fails(self):
  913         """Validate `project_id` is required for ec2.
  914 
  915         Test that a SchemaValidationError is raised when type is ec2
  916         and no `project_id` is provided in create request.
  917         """
  918         request_to_validate = {'blob': 'some credential blob',
  919                                'type': 'ec2',
  920                                'user_id': uuid.uuid4().hex}
  921         self.assertRaises(exception.SchemaValidationError,
  922                           self.create_credential_validator.validate,
  923                           request_to_validate)
  924 
  925     def test_validate_credential_with_project_id_succeeds(self):
  926         """Test that credential request works for all types."""
  927         cred_types = ['ec2', 'cert', uuid.uuid4().hex]
  928 
  929         for c_type in cred_types:
  930             request_to_validate = {'blob': 'some blob',
  931                                    'project_id': uuid.uuid4().hex,
  932                                    'type': c_type,
  933                                    'user_id': uuid.uuid4().hex}
  934             # Make sure an exception isn't raised
  935             self.create_credential_validator.validate(request_to_validate)
  936 
  937     def test_validate_credential_non_ec2_without_project_id_succeeds(self):
  938         """Validate `project_id` is not required for non-ec2.
  939 
  940         Test that create request without `project_id` succeeds for any
  941         non-ec2 credential.
  942         """
  943         cred_types = ['cert', uuid.uuid4().hex]
  944 
  945         for c_type in cred_types:
  946             request_to_validate = {'blob': 'some blob',
  947                                    'type': c_type,
  948                                    'user_id': uuid.uuid4().hex}
  949             # Make sure an exception isn't raised
  950             self.create_credential_validator.validate(request_to_validate)
  951 
  952     def test_validate_credential_with_extra_parameters_succeeds(self):
  953         """Validate create request with extra parameters."""
  954         request_to_validate = {'blob': 'some string',
  955                                'extra': False,
  956                                'project_id': uuid.uuid4().hex,
  957                                'type': 'ec2',
  958                                'user_id': uuid.uuid4().hex}
  959         self.create_credential_validator.validate(request_to_validate)
  960 
  961     def test_validate_credential_update_succeeds(self):
  962         """Test that a credential request is properly validated."""
  963         request_to_validate = {'blob': 'some string',
  964                                'project_id': uuid.uuid4().hex,
  965                                'type': 'ec2',
  966                                'user_id': uuid.uuid4().hex}
  967         self.update_credential_validator.validate(request_to_validate)
  968 
  969     def test_validate_credential_update_without_parameters_fails(self):
  970         """Exception is raised on update without parameters."""
  971         request_to_validate = {}
  972         self.assertRaises(exception.SchemaValidationError,
  973                           self.update_credential_validator.validate,
  974                           request_to_validate)
  975 
  976     def test_validate_credential_update_with_extra_parameters_succeeds(self):
  977         """Validate credential update with extra parameters."""
  978         request_to_validate = {'blob': 'some string',
  979                                'extra': False,
  980                                'project_id': uuid.uuid4().hex,
  981                                'type': 'ec2',
  982                                'user_id': uuid.uuid4().hex}
  983         self.update_credential_validator.validate(request_to_validate)
  984 
  985 
  986 class RegionValidationTestCase(unit.BaseTestCase):
  987     """Test for V3 Region API validation."""
  988 
  989     def setUp(self):
  990         super(RegionValidationTestCase, self).setUp()
  991 
  992         self.region_name = 'My Region'
  993 
  994         create = catalog_schema.region_create
  995         update = catalog_schema.region_update
  996         self.create_region_validator = validators.SchemaValidator(create)
  997         self.update_region_validator = validators.SchemaValidator(update)
  998 
  999     def test_validate_region_request(self):
 1000         """Test that we validate a basic region request."""
 1001         # Create_region doesn't take any parameters in the request so let's
 1002         # make sure we cover that case.
 1003         request_to_validate = {}
 1004         self.create_region_validator.validate(request_to_validate)
 1005 
 1006     def test_validate_region_create_request_with_parameters(self):
 1007         """Test that we validate a region request with parameters."""
 1008         request_to_validate = {'id': 'us-east',
 1009                                'description': 'US East Region',
 1010                                'parent_region_id': 'US Region'}
 1011         self.create_region_validator.validate(request_to_validate)
 1012 
 1013     def test_validate_region_create_with_uuid(self):
 1014         """Test that we validate a region request with a UUID as the id."""
 1015         request_to_validate = {'id': uuid.uuid4().hex,
 1016                                'description': 'US East Region',
 1017                                'parent_region_id': uuid.uuid4().hex}
 1018         self.create_region_validator.validate(request_to_validate)
 1019 
 1020     def test_validate_region_create_fails_with_invalid_region_id(self):
 1021         """Exception raised when passing invalid `id` in request."""
 1022         request_to_validate = {'id': 1234,
 1023                                'description': 'US East Region'}
 1024         self.assertRaises(exception.SchemaValidationError,
 1025                           self.create_region_validator.validate,
 1026                           request_to_validate)
 1027 
 1028     def test_validate_region_create_succeeds_with_extra_parameters(self):
 1029         """Validate create region request with extra values."""
 1030         request_to_validate = {'other_attr': uuid.uuid4().hex}
 1031         self.create_region_validator.validate(request_to_validate)
 1032 
 1033     def test_validate_region_create_succeeds_with_no_parameters(self):
 1034         """Validate create region request with no parameters."""
 1035         request_to_validate = {}
 1036         self.create_region_validator.validate(request_to_validate)
 1037 
 1038     def test_validate_region_update_succeeds(self):
 1039         """Test that we validate a region update request."""
 1040         request_to_validate = {'id': 'us-west',
 1041                                'description': 'US West Region',
 1042                                'parent_region_id': 'us-region'}
 1043         self.update_region_validator.validate(request_to_validate)
 1044 
 1045     def test_validate_region_update_succeeds_with_extra_parameters(self):
 1046         """Validate extra attributes in the region update request."""
 1047         request_to_validate = {'other_attr': uuid.uuid4().hex}
 1048         self.update_region_validator.validate(request_to_validate)
 1049 
 1050     def test_validate_region_update_fails_with_no_parameters(self):
 1051         """Exception raised when passing no parameters in a region update."""
 1052         # An update request should consist of at least one value to update
 1053         request_to_validate = {}
 1054         self.assertRaises(exception.SchemaValidationError,
 1055                           self.update_region_validator.validate,
 1056                           request_to_validate)
 1057 
 1058 
 1059 class ServiceValidationTestCase(unit.BaseTestCase):
 1060     """Test for V3 Service API validation."""
 1061 
 1062     def setUp(self):
 1063         super(ServiceValidationTestCase, self).setUp()
 1064 
 1065         create = catalog_schema.service_create
 1066         update = catalog_schema.service_update
 1067         self.create_service_validator = validators.SchemaValidator(create)
 1068         self.update_service_validator = validators.SchemaValidator(update)
 1069 
 1070     def test_validate_service_create_succeeds(self):
 1071         """Test that we validate a service create request."""
 1072         request_to_validate = {'name': 'Nova',
 1073                                'description': 'OpenStack Compute Service',
 1074                                'enabled': True,
 1075                                'type': 'compute'}
 1076         self.create_service_validator.validate(request_to_validate)
 1077 
 1078     def test_validate_service_create_succeeds_with_required_parameters(self):
 1079         """Validate a service create request with the required parameters."""
 1080         # The only parameter type required for service creation is 'type'
 1081         request_to_validate = {'type': 'compute'}
 1082         self.create_service_validator.validate(request_to_validate)
 1083 
 1084     def test_validate_service_create_fails_without_type(self):
 1085         """Exception raised when trying to create a service without `type`."""
 1086         request_to_validate = {'name': 'Nova'}
 1087         self.assertRaises(exception.SchemaValidationError,
 1088                           self.create_service_validator.validate,
 1089                           request_to_validate)
 1090 
 1091     def test_validate_service_create_succeeds_with_extra_parameters(self):
 1092         """Test that extra parameters pass validation on create service."""
 1093         request_to_validate = {'other_attr': uuid.uuid4().hex,
 1094                                'type': uuid.uuid4().hex}
 1095         self.create_service_validator.validate(request_to_validate)
 1096 
 1097     def test_validate_service_create_succeeds_with_valid_enabled(self):
 1098         """Validate boolean values as enabled values on service create."""
 1099         for valid_enabled in _VALID_ENABLED_FORMATS:
 1100             request_to_validate = {'enabled': valid_enabled,
 1101                                    'type': uuid.uuid4().hex}
 1102             self.create_service_validator.validate(request_to_validate)
 1103 
 1104     def test_validate_service_create_fails_with_invalid_enabled(self):
 1105         """Exception raised when boolean-like parameters as `enabled`.
 1106 
 1107         On service create, make sure an exception is raised if `enabled` is
 1108         not a boolean value.
 1109         """
 1110         for invalid_enabled in _INVALID_ENABLED_FORMATS:
 1111             request_to_validate = {'enabled': invalid_enabled,
 1112                                    'type': uuid.uuid4().hex}
 1113             self.assertRaises(exception.SchemaValidationError,
 1114                               self.create_service_validator.validate,
 1115                               request_to_validate)
 1116 
 1117     def test_validate_service_create_fails_when_name_too_long(self):
 1118         """Exception raised when `name` is greater than 255 characters."""
 1119         long_name = 'a' * 256
 1120         request_to_validate = {'type': 'compute',
 1121                                'name': long_name}
 1122         self.assertRaises(exception.SchemaValidationError,
 1123                           self.create_service_validator.validate,
 1124                           request_to_validate)
 1125 
 1126     def test_validate_service_create_fails_when_name_too_short(self):
 1127         """Exception is raised when `name` is too short."""
 1128         request_to_validate = {'type': 'compute',
 1129                                'name': ''}
 1130         self.assertRaises(exception.SchemaValidationError,
 1131                           self.create_service_validator.validate,
 1132                           request_to_validate)
 1133 
 1134     def test_validate_service_create_fails_when_type_too_long(self):
 1135         """Exception is raised when `type` is too long."""
 1136         long_type_name = 'a' * 256
 1137         request_to_validate = {'type': long_type_name}
 1138         self.assertRaises(exception.SchemaValidationError,
 1139                           self.create_service_validator.validate,
 1140                           request_to_validate)
 1141 
 1142     def test_validate_service_create_fails_when_type_too_short(self):
 1143         """Exception is raised when `type` is too short."""
 1144         request_to_validate = {'type': ''}
 1145         self.assertRaises(exception.SchemaValidationError,
 1146                           self.create_service_validator.validate,
 1147                           request_to_validate)
 1148 
 1149     def test_validate_service_update_request_succeeds(self):
 1150         """Test that we validate a service update request."""
 1151         request_to_validate = {'name': 'Cinder',
 1152                                'type': 'volume',
 1153                                'description': 'OpenStack Block Storage',
 1154                                'enabled': False}
 1155         self.update_service_validator.validate(request_to_validate)
 1156 
 1157     def test_validate_service_update_fails_with_no_parameters(self):
 1158         """Exception raised when updating a service without values."""
 1159         request_to_validate = {}
 1160         self.assertRaises(exception.SchemaValidationError,
 1161                           self.update_service_validator.validate,
 1162                           request_to_validate)
 1163 
 1164     def test_validate_service_update_succeeds_with_extra_parameters(self):
 1165         """Validate updating a service with extra parameters."""
 1166         request_to_validate = {'other_attr': uuid.uuid4().hex}
 1167         self.update_service_validator.validate(request_to_validate)
 1168 
 1169     def test_validate_service_update_succeeds_with_valid_enabled(self):
 1170         """Validate boolean formats as `enabled` on service update."""
 1171         for valid_enabled in _VALID_ENABLED_FORMATS:
 1172             request_to_validate = {'enabled': valid_enabled}
 1173             self.update_service_validator.validate(request_to_validate)
 1174 
 1175     def test_validate_service_update_fails_with_invalid_enabled(self):
 1176         """Exception raised when boolean-like values as `enabled`."""
 1177         for invalid_enabled in _INVALID_ENABLED_FORMATS:
 1178             request_to_validate = {'enabled': invalid_enabled}
 1179             self.assertRaises(exception.SchemaValidationError,
 1180                               self.update_service_validator.validate,
 1181                               request_to_validate)
 1182 
 1183     def test_validate_service_update_fails_with_name_too_long(self):
 1184         """Exception is raised when `name` is too long on update."""
 1185         long_name = 'a' * 256
 1186         request_to_validate = {'name': long_name}
 1187         self.assertRaises(exception.SchemaValidationError,
 1188                           self.update_service_validator.validate,
 1189                           request_to_validate)
 1190 
 1191     def test_validate_service_update_fails_with_name_too_short(self):
 1192         """Exception is raised when `name` is too short on update."""
 1193         request_to_validate = {'name': ''}
 1194         self.assertRaises(exception.SchemaValidationError,
 1195                           self.update_service_validator.validate,
 1196                           request_to_validate)
 1197 
 1198     def test_validate_service_update_fails_with_type_too_long(self):
 1199         """Exception is raised when `type` is too long on update."""
 1200         long_type_name = 'a' * 256
 1201         request_to_validate = {'type': long_type_name}
 1202         self.assertRaises(exception.SchemaValidationError,
 1203                           self.update_service_validator.validate,
 1204                           request_to_validate)
 1205 
 1206     def test_validate_service_update_fails_with_type_too_short(self):
 1207         """Exception is raised when `type` is too short on update."""
 1208         request_to_validate = {'type': ''}
 1209         self.assertRaises(exception.SchemaValidationError,
 1210                           self.update_service_validator.validate,
 1211                           request_to_validate)
 1212 
 1213 
 1214 class EndpointValidationTestCase(unit.BaseTestCase):
 1215     """Test for V3 Endpoint API validation."""
 1216 
 1217     def setUp(self):
 1218         super(EndpointValidationTestCase, self).setUp()
 1219 
 1220         create = catalog_schema.endpoint_create
 1221         update = catalog_schema.endpoint_update
 1222         self.create_endpoint_validator = validators.SchemaValidator(create)
 1223         self.update_endpoint_validator = validators.SchemaValidator(update)
 1224 
 1225     def test_validate_endpoint_request_succeeds(self):
 1226         """Test that we validate an endpoint request."""
 1227         request_to_validate = {'enabled': True,
 1228                                'interface': 'admin',
 1229                                'region_id': uuid.uuid4().hex,
 1230                                'service_id': uuid.uuid4().hex,
 1231                                'url': 'https://service.example.com:5000/'}
 1232         self.create_endpoint_validator.validate(request_to_validate)
 1233 
 1234     def test_validate_endpoint_create_succeeds_with_required_parameters(self):
 1235         """Validate an endpoint request with only the required parameters."""
 1236         # According to the Identity V3 API endpoint creation requires
 1237         # 'service_id', 'interface', and 'url'
 1238         request_to_validate = {'service_id': uuid.uuid4().hex,
 1239                                'interface': 'public',
 1240                                'url': 'https://service.example.com:5000/'}
 1241         self.create_endpoint_validator.validate(request_to_validate)
 1242 
 1243     def test_validate_endpoint_create_succeeds_with_valid_enabled(self):
 1244         """Validate an endpoint with boolean values.
 1245 
 1246         Validate boolean values as `enabled` in endpoint create requests.
 1247         """
 1248         for valid_enabled in _VALID_ENABLED_FORMATS:
 1249             request_to_validate = {'enabled': valid_enabled,
 1250                                    'service_id': uuid.uuid4().hex,
 1251                                    'interface': 'public',
 1252                                    'url': 'https://service.example.com:5000/'}
 1253             self.create_endpoint_validator.validate(request_to_validate)
 1254 
 1255     def test_validate_create_endpoint_fails_with_invalid_enabled(self):
 1256         """Exception raised when boolean-like values as `enabled`."""
 1257         for invalid_enabled in _INVALID_ENABLED_FORMATS:
 1258             request_to_validate = {'enabled': invalid_enabled,
 1259                                    'service_id': uuid.uuid4().hex,
 1260                                    'interface': 'public',
 1261                                    'url': 'https://service.example.com:5000/'}
 1262             self.assertRaises(exception.SchemaValidationError,
 1263                               self.create_endpoint_validator.validate,
 1264                               request_to_validate)
 1265 
 1266     def test_validate_endpoint_create_succeeds_with_extra_parameters(self):
 1267         """Test that extra parameters pass validation on create endpoint."""
 1268         request_to_validate = {'other_attr': uuid.uuid4().hex,
 1269                                'service_id': uuid.uuid4().hex,
 1270                                'interface': 'public',
 1271                                'url': 'https://service.example.com:5000/'}
 1272         self.create_endpoint_validator.validate(request_to_validate)
 1273 
 1274     def test_validate_endpoint_create_fails_without_service_id(self):
 1275         """Exception raised when `service_id` isn't in endpoint request."""
 1276         request_to_validate = {'interface': 'public',
 1277                                'url': 'https://service.example.com:5000/'}
 1278         self.assertRaises(exception.SchemaValidationError,
 1279                           self.create_endpoint_validator.validate,
 1280                           request_to_validate)
 1281 
 1282     def test_validate_endpoint_create_fails_without_interface(self):
 1283         """Exception raised when `interface` isn't in endpoint request."""
 1284         request_to_validate = {'service_id': uuid.uuid4().hex,
 1285                                'url': 'https://service.example.com:5000/'}
 1286         self.assertRaises(exception.SchemaValidationError,
 1287                           self.create_endpoint_validator.validate,
 1288                           request_to_validate)
 1289 
 1290     def test_validate_endpoint_create_fails_without_url(self):
 1291         """Exception raised when `url` isn't in endpoint request."""
 1292         request_to_validate = {'service_id': uuid.uuid4().hex,
 1293                                'interface': 'public'}
 1294         self.assertRaises(exception.SchemaValidationError,
 1295                           self.create_endpoint_validator.validate,
 1296                           request_to_validate)
 1297 
 1298     def test_validate_endpoint_create_succeeds_with_url(self):
 1299         """Validate `url` attribute in endpoint create request."""
 1300         request_to_validate = {'service_id': uuid.uuid4().hex,
 1301                                'interface': 'public'}
 1302         for url in _VALID_URLS:
 1303             request_to_validate['url'] = url
 1304             self.create_endpoint_validator.validate(request_to_validate)
 1305 
 1306     def test_validate_endpoint_create_fails_with_invalid_url(self):
 1307         """Exception raised when passing invalid `url` in request."""
 1308         request_to_validate = {'service_id': uuid.uuid4().hex,
 1309                                'interface': 'public'}
 1310         for url in _INVALID_URLS:
 1311             request_to_validate['url'] = url
 1312             self.assertRaises(exception.SchemaValidationError,
 1313                               self.create_endpoint_validator.validate,
 1314                               request_to_validate)
 1315 
 1316     def test_validate_endpoint_create_fails_with_invalid_interface(self):
 1317         """Exception raised with invalid `interface`."""
 1318         request_to_validate = {'interface': uuid.uuid4().hex,
 1319                                'service_id': uuid.uuid4().hex,
 1320                                'url': 'https://service.example.com:5000/'}
 1321         self.assertRaises(exception.SchemaValidationError,
 1322                           self.create_endpoint_validator.validate,
 1323                           request_to_validate)
 1324 
 1325     def test_validate_endpoint_create_fails_with_invalid_region_id(self):
 1326         """Exception raised when passing invalid `region(_id)` in request."""
 1327         request_to_validate = {'interface': 'admin',
 1328                                'region_id': 1234,
 1329                                'service_id': uuid.uuid4().hex,
 1330                                'url': 'https://service.example.com:5000/'}
 1331 
 1332         self.assertRaises(exception.SchemaValidationError,
 1333                           self.create_endpoint_validator.validate,
 1334                           request_to_validate)
 1335 
 1336         request_to_validate = {'interface': 'admin',
 1337                                'region': 1234,
 1338                                'service_id': uuid.uuid4().hex,
 1339                                'url': 'https://service.example.com:5000/'}
 1340 
 1341         self.assertRaises(exception.SchemaValidationError,
 1342                           self.create_endpoint_validator.validate,
 1343                           request_to_validate)
 1344 
 1345     def test_validate_endpoint_update_fails_with_invalid_enabled(self):
 1346         """Exception raised when `enabled` is boolean-like value."""
 1347         for invalid_enabled in _INVALID_ENABLED_FORMATS:
 1348             request_to_validate = {'enabled': invalid_enabled}
 1349             self.assertRaises(exception.SchemaValidationError,
 1350                               self.update_endpoint_validator.validate,
 1351                               request_to_validate)
 1352 
 1353     def test_validate_endpoint_update_succeeds_with_valid_enabled(self):
 1354         """Validate `enabled` as boolean values."""
 1355         for valid_enabled in _VALID_ENABLED_FORMATS:
 1356             request_to_validate = {'enabled': valid_enabled}
 1357             self.update_endpoint_validator.validate(request_to_validate)
 1358 
 1359     def test_validate_endpoint_update_fails_with_invalid_interface(self):
 1360         """Exception raised when invalid `interface` on endpoint update."""
 1361         request_to_validate = {'interface': uuid.uuid4().hex,
 1362                                'service_id': uuid.uuid4().hex,
 1363                                'url': 'https://service.example.com:5000/'}
 1364         self.assertRaises(exception.SchemaValidationError,
 1365                           self.update_endpoint_validator.validate,
 1366                           request_to_validate)
 1367 
 1368     def test_validate_endpoint_update_request_succeeds(self):
 1369         """Test that we validate an endpoint update request."""
 1370         request_to_validate = {'enabled': True,
 1371                                'interface': 'admin',
 1372                                'region_id': uuid.uuid4().hex,
 1373                                'service_id': uuid.uuid4().hex,
 1374                                'url': 'https://service.example.com:5000/'}
 1375         self.update_endpoint_validator.validate(request_to_validate)
 1376 
 1377     def test_validate_endpoint_update_fails_with_no_parameters(self):
 1378         """Exception raised when no parameters on endpoint update."""
 1379         request_to_validate = {}
 1380         self.assertRaises(exception.SchemaValidationError,
 1381                           self.update_endpoint_validator.validate,
 1382                           request_to_validate)
 1383 
 1384     def test_validate_endpoint_update_succeeds_with_extra_parameters(self):
 1385         """Test that extra parameters pass validation on update endpoint."""
 1386         request_to_validate = {'enabled': True,
 1387                                'interface': 'admin',
 1388                                'region_id': uuid.uuid4().hex,
 1389                                'service_id': uuid.uuid4().hex,
 1390                                'url': 'https://service.example.com:5000/',
 1391                                'other_attr': uuid.uuid4().hex}
 1392         self.update_endpoint_validator.validate(request_to_validate)
 1393 
 1394     def test_validate_endpoint_update_succeeds_with_url(self):
 1395         """Validate `url` attribute in endpoint update request."""
 1396         request_to_validate = {'service_id': uuid.uuid4().hex,
 1397                                'interface': 'public'}
 1398         for url in _VALID_URLS:
 1399             request_to_validate['url'] = url
 1400             self.update_endpoint_validator.validate(request_to_validate)
 1401 
 1402     def test_validate_endpoint_update_fails_with_invalid_url(self):
 1403         """Exception raised when passing invalid `url` in request."""
 1404         request_to_validate = {'service_id': uuid.uuid4().hex,
 1405                                'interface': 'public'}
 1406         for url in _INVALID_URLS:
 1407             request_to_validate['url'] = url
 1408             self.assertRaises(exception.SchemaValidationError,
 1409                               self.update_endpoint_validator.validate,
 1410                               request_to_validate)
 1411 
 1412     def test_validate_endpoint_update_fails_with_invalid_region_id(self):
 1413         """Exception raised when passing invalid `region(_id)` in request."""
 1414         request_to_validate = {'interface': 'admin',
 1415                                'region_id': 1234,
 1416                                'service_id': uuid.uuid4().hex,
 1417                                'url': 'https://service.example.com:5000/'}
 1418 
 1419         self.assertRaises(exception.SchemaValidationError,
 1420                           self.update_endpoint_validator.validate,
 1421                           request_to_validate)
 1422 
 1423         request_to_validate = {'interface': 'admin',
 1424                                'region': 1234,
 1425                                'service_id': uuid.uuid4().hex,
 1426                                'url': 'https://service.example.com:5000/'}
 1427 
 1428         self.assertRaises(exception.SchemaValidationError,
 1429                           self.update_endpoint_validator.validate,
 1430                           request_to_validate)
 1431 
 1432 
 1433 class EndpointGroupValidationTestCase(unit.BaseTestCase):
 1434     """Test for V3 Endpoint Group API validation."""
 1435 
 1436     def setUp(self):
 1437         super(EndpointGroupValidationTestCase, self).setUp()
 1438 
 1439         create = catalog_schema.endpoint_group_create
 1440         update = catalog_schema.endpoint_group_update
 1441         self.create_endpoint_grp_validator = validators.SchemaValidator(create)
 1442         self.update_endpoint_grp_validator = validators.SchemaValidator(update)
 1443 
 1444     def test_validate_endpoint_group_request_succeeds(self):
 1445         """Test that we validate an endpoint group request."""
 1446         request_to_validate = {'description': 'endpoint group description',
 1447                                'filters': {'interface': 'admin'},
 1448                                'name': 'endpoint_group_name'}
 1449         self.create_endpoint_grp_validator.validate(request_to_validate)
 1450 
 1451     def test_validate_endpoint_group_create_succeeds_with_req_parameters(self):
 1452         """Validate required endpoint group parameters.
 1453 
 1454         This test ensure that validation succeeds with only the required
 1455         parameters passed for creating an endpoint group.
 1456         """
 1457         request_to_validate = {'filters': {'interface': 'admin'},
 1458                                'name': 'endpoint_group_name'}
 1459         self.create_endpoint_grp_validator.validate(request_to_validate)
 1460 
 1461     def test_validate_endpoint_group_create_succeeds_with_valid_filters(self):
 1462         """Validate `filters` in endpoint group create requests."""
 1463         request_to_validate = {'description': 'endpoint group description',
 1464                                'name': 'endpoint_group_name'}
 1465         for valid_filters in _VALID_FILTERS:
 1466             request_to_validate['filters'] = valid_filters
 1467             self.create_endpoint_grp_validator.validate(request_to_validate)
 1468 
 1469     def test_validate_create_endpoint_group_fails_with_invalid_filters(self):
 1470         """Validate invalid `filters` value in endpoint group parameters.
 1471 
 1472         This test ensures that exception is raised when non-dict values is
 1473         used as `filters` in endpoint group create request.
 1474         """
 1475         request_to_validate = {'description': 'endpoint group description',
 1476                                'name': 'endpoint_group_name'}
 1477         for invalid_filters in _INVALID_FILTERS:
 1478             request_to_validate['filters'] = invalid_filters
 1479             self.assertRaises(exception.SchemaValidationError,
 1480                               self.create_endpoint_grp_validator.validate,
 1481                               request_to_validate)
 1482 
 1483     def test_validate_endpoint_group_create_fails_without_name(self):
 1484         """Exception raised when `name` isn't in endpoint group request."""
 1485         request_to_validate = {'description': 'endpoint group description',
 1486                                'filters': {'interface': 'admin'}}
 1487         self.assertRaises(exception.SchemaValidationError,
 1488                           self.create_endpoint_grp_validator.validate,
 1489                           request_to_validate)
 1490 
 1491     def test_validate_endpoint_group_create_fails_without_filters(self):
 1492         """Exception raised when `filters` isn't in endpoint group request."""
 1493         request_to_validate = {'description': 'endpoint group description',
 1494                                'name': 'endpoint_group_name'}
 1495         self.assertRaises(exception.SchemaValidationError,
 1496                           self.create_endpoint_grp_validator.validate,
 1497                           request_to_validate)
 1498 
 1499     def test_validate_endpoint_group_update_request_succeeds(self):
 1500         """Test that we validate an endpoint group update request."""
 1501         request_to_validate = {'description': 'endpoint group description',
 1502                                'filters': {'interface': 'admin'},
 1503                                'name': 'endpoint_group_name'}
 1504         self.update_endpoint_grp_validator.validate(request_to_validate)
 1505 
 1506     def test_validate_endpoint_group_update_fails_with_no_parameters(self):
 1507         """Exception raised when no parameters on endpoint group update."""
 1508         request_to_validate = {}
 1509         self.assertRaises(exception.SchemaValidationError,
 1510                           self.update_endpoint_grp_validator.validate,
 1511                           request_to_validate)
 1512 
 1513     def test_validate_endpoint_group_update_succeeds_with_name(self):
 1514         """Validate request with  only `name` in endpoint group update.
 1515 
 1516         This test ensures that passing only a `name` passes validation
 1517         on update endpoint group request.
 1518         """
 1519         request_to_validate = {'name': 'endpoint_group_name'}
 1520         self.update_endpoint_grp_validator.validate(request_to_validate)
 1521 
 1522     def test_validate_endpoint_group_update_succeeds_with_valid_filters(self):
 1523         """Validate `filters` as dict values."""
 1524         for valid_filters in _VALID_FILTERS:
 1525             request_to_validate = {'filters': valid_filters}
 1526             self.update_endpoint_grp_validator.validate(request_to_validate)
 1527 
 1528     def test_validate_endpoint_group_update_fails_with_invalid_filters(self):
 1529         """Exception raised when passing invalid `filters` in request."""
 1530         for invalid_filters in _INVALID_FILTERS:
 1531             request_to_validate = {'filters': invalid_filters}
 1532             self.assertRaises(exception.SchemaValidationError,
 1533                               self.update_endpoint_grp_validator.validate,
 1534                               request_to_validate)
 1535 
 1536 
 1537 class TrustValidationTestCase(unit.BaseTestCase):
 1538     """Test for V3 Trust API validation."""
 1539 
 1540     _valid_roles = [{'name': 'member'},
 1541                     {'id': uuid.uuid4().hex},
 1542                     {'id': str(uuid.uuid4())},
 1543                     {'name': '_member_'}]
 1544     _invalid_roles = [False, True, 123, None]
 1545 
 1546     def setUp(self):
 1547         super(TrustValidationTestCase, self).setUp()
 1548 
 1549         create = trust_schema.trust_create
 1550         self.create_trust_validator = validators.SchemaValidator(create)
 1551 
 1552     def test_validate_trust_succeeds(self):
 1553         """Test that we can validate a trust request."""
 1554         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1555                                'trustee_user_id': uuid.uuid4().hex,
 1556                                'impersonation': False}
 1557         self.create_trust_validator.validate(request_to_validate)
 1558 
 1559     def test_validate_trust_with_all_parameters_succeeds(self):
 1560         """Test that we can validate a trust request with all parameters."""
 1561         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1562                                'trustee_user_id': uuid.uuid4().hex,
 1563                                'impersonation': False,
 1564                                'project_id': uuid.uuid4().hex,
 1565                                'roles': [{'id': uuid.uuid4().hex},
 1566                                          {'id': uuid.uuid4().hex}],
 1567                                'expires_at': 'some timestamp',
 1568                                'remaining_uses': 2}
 1569         self.create_trust_validator.validate(request_to_validate)
 1570 
 1571     def test_validate_trust_without_trustor_id_fails(self):
 1572         """Validate trust request fails without `trustor_id`."""
 1573         request_to_validate = {'trustee_user_id': uuid.uuid4().hex,
 1574                                'impersonation': False}
 1575         self.assertRaises(exception.SchemaValidationError,
 1576                           self.create_trust_validator.validate,
 1577                           request_to_validate)
 1578 
 1579     def test_validate_trust_without_trustee_id_fails(self):
 1580         """Validate trust request fails without `trustee_id`."""
 1581         request_to_validate = {'trusor_user_id': uuid.uuid4().hex,
 1582                                'impersonation': False}
 1583         self.assertRaises(exception.SchemaValidationError,
 1584                           self.create_trust_validator.validate,
 1585                           request_to_validate)
 1586 
 1587     def test_validate_trust_without_impersonation_fails(self):
 1588         """Validate trust request fails without `impersonation`."""
 1589         request_to_validate = {'trustee_user_id': uuid.uuid4().hex,
 1590                                'trustor_user_id': uuid.uuid4().hex}
 1591         self.assertRaises(exception.SchemaValidationError,
 1592                           self.create_trust_validator.validate,
 1593                           request_to_validate)
 1594 
 1595     def test_validate_trust_with_extra_parameters_succeeds(self):
 1596         """Test that we can validate a trust request with extra parameters."""
 1597         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1598                                'trustee_user_id': uuid.uuid4().hex,
 1599                                'impersonation': False,
 1600                                'project_id': uuid.uuid4().hex,
 1601                                'roles': [{'id': uuid.uuid4().hex},
 1602                                          {'id': uuid.uuid4().hex}],
 1603                                'expires_at': 'some timestamp',
 1604                                'remaining_uses': 2,
 1605                                'extra': 'something extra!'}
 1606         self.create_trust_validator.validate(request_to_validate)
 1607 
 1608     def test_validate_trust_with_invalid_impersonation_fails(self):
 1609         """Validate trust request with invalid `impersonation` fails."""
 1610         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1611                                'trustee_user_id': uuid.uuid4().hex,
 1612                                'impersonation': 2}
 1613         self.assertRaises(exception.SchemaValidationError,
 1614                           self.create_trust_validator.validate,
 1615                           request_to_validate)
 1616 
 1617     def test_validate_trust_with_null_remaining_uses_succeeds(self):
 1618         """Validate trust request with null `remaining_uses`."""
 1619         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1620                                'trustee_user_id': uuid.uuid4().hex,
 1621                                'impersonation': False,
 1622                                'remaining_uses': None}
 1623         self.create_trust_validator.validate(request_to_validate)
 1624 
 1625     def test_validate_trust_with_remaining_uses_succeeds(self):
 1626         """Validate trust request with `remaining_uses` succeeds."""
 1627         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1628                                'trustee_user_id': uuid.uuid4().hex,
 1629                                'impersonation': False,
 1630                                'remaining_uses': 2}
 1631         self.create_trust_validator.validate(request_to_validate)
 1632 
 1633     def test_validate_trust_with_period_in_user_id_string(self):
 1634         """Validate trust request with a period in the user id string."""
 1635         request_to_validate = {'trustor_user_id': 'john.smith',
 1636                                'trustee_user_id': 'joe.developer',
 1637                                'impersonation': False}
 1638         self.create_trust_validator.validate(request_to_validate)
 1639 
 1640     def test_validate_trust_with_invalid_expires_at_fails(self):
 1641         """Validate trust request with invalid `expires_at` fails."""
 1642         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1643                                'trustee_user_id': uuid.uuid4().hex,
 1644                                'impersonation': False,
 1645                                'expires_at': 3}
 1646         self.assertRaises(exception.SchemaValidationError,
 1647                           self.create_trust_validator.validate,
 1648                           request_to_validate)
 1649 
 1650     def test_validate_trust_with_role_types_succeeds(self):
 1651         """Validate trust request with `roles` succeeds."""
 1652         for role in self._valid_roles:
 1653             request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1654                                    'trustee_user_id': uuid.uuid4().hex,
 1655                                    'impersonation': False,
 1656                                    'roles': [role]}
 1657             self.create_trust_validator.validate(request_to_validate)
 1658 
 1659     def test_validate_trust_with_invalid_role_type_fails(self):
 1660         """Validate trust request with invalid `roles` fails."""
 1661         for role in self._invalid_roles:
 1662             request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1663                                    'trustee_user_id': uuid.uuid4().hex,
 1664                                    'impersonation': False,
 1665                                    'roles': role}
 1666             self.assertRaises(exception.SchemaValidationError,
 1667                               self.create_trust_validator.validate,
 1668                               request_to_validate)
 1669 
 1670     def test_validate_trust_with_list_of_valid_roles_succeeds(self):
 1671         """Validate trust request with a list of valid `roles`."""
 1672         request_to_validate = {'trustor_user_id': uuid.uuid4().hex,
 1673                                'trustee_user_id': uuid.uuid4().hex,
 1674                                'impersonation': False,
 1675                                'roles': self._valid_roles}
 1676         self.create_trust_validator.validate(request_to_validate)
 1677 
 1678 
 1679 class ServiceProviderValidationTestCase(unit.BaseTestCase):
 1680     """Test for V3 Service Provider API validation."""
 1681 
 1682     def setUp(self):
 1683         super(ServiceProviderValidationTestCase, self).setUp()
 1684 
 1685         self.valid_auth_url = 'https://' + uuid.uuid4().hex + '.com'
 1686         self.valid_sp_url = 'https://' + uuid.uuid4().hex + '.com'
 1687 
 1688         create = federation_schema.service_provider_create
 1689         update = federation_schema.service_provider_update
 1690         self.create_sp_validator = validators.SchemaValidator(create)
 1691         self.update_sp_validator = validators.SchemaValidator(update)
 1692 
 1693     def test_validate_sp_request(self):
 1694         """Test that we validate `auth_url` and `sp_url` in request."""
 1695         request_to_validate = {
 1696             'auth_url': self.valid_auth_url,
 1697             'sp_url': self.valid_sp_url
 1698         }
 1699         self.create_sp_validator.validate(request_to_validate)
 1700 
 1701     def test_validate_sp_request_with_invalid_auth_url_fails(self):
 1702         """Validate request fails with invalid `auth_url`."""
 1703         request_to_validate = {
 1704             'auth_url': uuid.uuid4().hex,
 1705             'sp_url': self.valid_sp_url
 1706         }
 1707         self.assertRaises(exception.SchemaValidationError,
 1708                           self.create_sp_validator.validate,
 1709                           request_to_validate)
 1710 
 1711     def test_validate_sp_request_with_invalid_sp_url_fails(self):
 1712         """Validate request fails with invalid `sp_url`."""
 1713         request_to_validate = {
 1714             'auth_url': self.valid_auth_url,
 1715             'sp_url': uuid.uuid4().hex,
 1716         }
 1717         self.assertRaises(exception.SchemaValidationError,
 1718                           self.create_sp_validator.validate,
 1719                           request_to_validate)
 1720 
 1721     def test_validate_sp_request_without_auth_url_fails(self):
 1722         """Validate request fails without `auth_url`."""
 1723         request_to_validate = {
 1724             'sp_url': self.valid_sp_url
 1725         }
 1726         self.assertRaises(exception.SchemaValidationError,
 1727                           self.create_sp_validator.validate,
 1728                           request_to_validate)
 1729         request_to_validate = {
 1730             'auth_url': None,
 1731             'sp_url': self.valid_sp_url
 1732         }
 1733         self.assertRaises(exception.SchemaValidationError,
 1734                           self.create_sp_validator.validate,
 1735                           request_to_validate)
 1736 
 1737     def test_validate_sp_request_without_sp_url_fails(self):
 1738         """Validate request fails without `sp_url`."""
 1739         request_to_validate = {
 1740             'auth_url': self.valid_auth_url,
 1741         }
 1742         self.assertRaises(exception.SchemaValidationError,
 1743                           self.create_sp_validator.validate,
 1744                           request_to_validate)
 1745         request_to_validate = {
 1746             'auth_url': self.valid_auth_url,
 1747             'sp_url': None,
 1748         }
 1749         self.assertRaises(exception.SchemaValidationError,
 1750                           self.create_sp_validator.validate,
 1751                           request_to_validate)
 1752 
 1753     def test_validate_sp_request_with_enabled(self):
 1754         """Validate `enabled` as boolean-like values."""
 1755         for valid_enabled in _VALID_ENABLED_FORMATS:
 1756             request_to_validate = {
 1757                 'auth_url': self.valid_auth_url,
 1758                 'sp_url': self.valid_sp_url,
 1759                 'enabled': valid_enabled
 1760             }
 1761             self.create_sp_validator.validate(request_to_validate)
 1762 
 1763     def test_validate_sp_request_with_invalid_enabled_fails(self):
 1764         """Exception is raised when `enabled` isn't a boolean-like value."""
 1765         for invalid_enabled in _INVALID_ENABLED_FORMATS:
 1766             request_to_validate = {
 1767                 'auth_url': self.valid_auth_url,
 1768                 'sp_url': self.valid_sp_url,
 1769                 'enabled': invalid_enabled
 1770             }
 1771             self.assertRaises(exception.SchemaValidationError,
 1772                               self.create_sp_validator.validate,
 1773                               request_to_validate)
 1774 
 1775     def test_validate_sp_request_with_valid_description(self):
 1776         """Test that we validate `description` in create requests."""
 1777         request_to_validate = {
 1778             'auth_url': self.valid_auth_url,
 1779             'sp_url': self.valid_sp_url,
 1780             'description': 'My Service Provider'
 1781         }
 1782         self.create_sp_validator.validate(request_to_validate)
 1783 
 1784     def test_validate_sp_request_with_invalid_description_fails(self):
 1785         """Exception is raised when `description` as a non-string value."""
 1786         request_to_validate = {
 1787             'auth_url': self.valid_auth_url,
 1788             'sp_url': self.valid_sp_url,
 1789             'description': False
 1790         }
 1791         self.assertRaises(exception.SchemaValidationError,
 1792                           self.create_sp_validator.validate,
 1793                           request_to_validate)
 1794 
 1795     def test_validate_sp_request_with_extra_field_fails(self):
 1796         """Exception raised when passing extra fields in the body."""
 1797         # 'id' can't be passed in the body since it is passed in the URL
 1798         request_to_validate = {
 1799             'id': 'ACME',
 1800             'auth_url': self.valid_auth_url,
 1801             'sp_url': self.valid_sp_url,
 1802             'description': 'My Service Provider'
 1803         }
 1804         self.assertRaises(exception.SchemaValidationError,
 1805                           self.create_sp_validator.validate,
 1806                           request_to_validate)
 1807 
 1808     def test_validate_sp_update_request(self):
 1809         """Test that we validate a update request."""
 1810         request_to_validate = {'description': uuid.uuid4().hex}
 1811         self.update_sp_validator.validate(request_to_validate)
 1812 
 1813     def test_validate_sp_update_request_with_no_parameters_fails(self):
 1814         """Exception is raised when updating without parameters."""
 1815         request_to_validate = {}
 1816         self.assertRaises(exception.SchemaValidationError,
 1817                           self.update_sp_validator.validate,
 1818                           request_to_validate)
 1819 
 1820     def test_validate_sp_update_request_with_invalid_auth_url_fails(self):
 1821         """Exception raised when updating with invalid `auth_url`."""
 1822         request_to_validate = {'auth_url': uuid.uuid4().hex}
 1823         self.assertRaises(exception.SchemaValidationError,
 1824                           self.update_sp_validator.validate,
 1825                           request_to_validate)
 1826         request_to_validate = {'auth_url': None}
 1827         self.assertRaises(exception.SchemaValidationError,
 1828                           self.update_sp_validator.validate,
 1829                           request_to_validate)
 1830 
 1831     def test_validate_sp_update_request_with_invalid_sp_url_fails(self):
 1832         """Exception raised when updating with invalid `sp_url`."""
 1833         request_to_validate = {'sp_url': uuid.uuid4().hex}
 1834         self.assertRaises(exception.SchemaValidationError,
 1835                           self.update_sp_validator.validate,
 1836                           request_to_validate)
 1837         request_to_validate = {'sp_url': None}
 1838         self.assertRaises(exception.SchemaValidationError,
 1839                           self.update_sp_validator.validate,
 1840                           request_to_validate)
 1841 
 1842 
 1843 class UserValidationTestCase(unit.BaseTestCase):
 1844     """Test for V3 User API validation."""
 1845 
 1846     def setUp(self):
 1847         super(UserValidationTestCase, self).setUp()
 1848 
 1849         self.user_name = uuid.uuid4().hex
 1850 
 1851         create = identity_schema.user_create
 1852         update = identity_schema.user_update
 1853         self.create_user_validator = validators.SchemaValidator(create)
 1854         self.update_user_validator = validators.SchemaValidator(update)
 1855 
 1856     def test_validate_user_create_request_succeeds(self):
 1857         """Test that validating a user create request succeeds."""
 1858         request_to_validate = {'name': self.user_name}
 1859         self.create_user_validator.validate(request_to_validate)
 1860 
 1861     def test_validate_user_create_with_all_valid_parameters_succeeds(self):
 1862         """Test that validating a user create request succeeds."""
 1863         request_to_validate = unit.new_user_ref(domain_id=uuid.uuid4().hex,
 1864                                                 name=self.user_name)
 1865         self.create_user_validator.validate(request_to_validate)
 1866 
 1867     def test_validate_user_create_fails_without_name(self):
 1868         """Exception raised when validating a user without name."""
 1869         request_to_validate = {'email': uuid.uuid4().hex}
 1870         self.assertRaises(exception.SchemaValidationError,
 1871                           self.create_user_validator.validate,
 1872                           request_to_validate)
 1873 
 1874     def test_validate_user_create_succeeds_with_valid_enabled_formats(self):
 1875         """Validate acceptable enabled formats in create user requests."""
 1876         for enabled in _VALID_ENABLED_FORMATS:
 1877             request_to_validate = {'name': self.user_name,
 1878                                    'enabled': enabled}
 1879             self.create_user_validator.validate(request_to_validate)
 1880 
 1881     def test_validate_user_create_fails_with_invalid_enabled_formats(self):
 1882         """Exception raised when enabled is not an acceptable format."""
 1883         for invalid_enabled in _INVALID_ENABLED_FORMATS:
 1884             request_to_validate = {'name': self.user_name,
 1885                                    'enabled': invalid_enabled}
 1886             self.assertRaises(exception.SchemaValidationError,
 1887                               self.create_user_validator.validate,
 1888                               request_to_validate)
 1889 
 1890     def test_validate_user_create_succeeds_with_extra_attributes(self):
 1891         """Validate extra parameters on user create requests."""
 1892         request_to_validate = {'name': self.user_name,
 1893                                'other_attr': uuid.uuid4().hex}
 1894         self.create_user_validator.validate(request_to_validate)
 1895 
 1896     def test_validate_user_create_succeeds_with_password_of_zero_length(self):
 1897         """Validate empty password on user create requests."""
 1898         request_to_validate = {'name': self.user_name,
 1899                                'password': ''}
 1900         self.create_user_validator.validate(request_to_validate)
 1901 
 1902     def test_validate_user_create_succeeds_with_null_password(self):
 1903         """Validate that password is nullable on create user."""
 1904         request_to_validate = {'name': self.user_name,
 1905                                'password': None}
 1906         self.create_user_validator.validate(request_to_validate)
 1907 
 1908     def test_validate_user_create_fails_with_invalid_password_type(self):
 1909         """Exception raised when user password is of the wrong type."""
 1910         request_to_validate = {'name': self.user_name,
 1911                                'password': True}
 1912         self.assertRaises(exception.SchemaValidationError,
 1913                           self.create_user_validator.validate,
 1914                           request_to_validate)
 1915 
 1916     def test_validate_user_create_succeeds_with_null_description(self):
 1917         """Validate that description can be nullable on create user."""
 1918         request_to_validate = {'name': self.user_name,
 1919                                'description': None}
 1920         self.create_user_validator.validate(request_to_validate)
 1921 
 1922     def test_validate_user_create_fails_with_invalid_name(self):
 1923         """Exception when validating a create request with invalid `name`."""
 1924         for invalid_name in _INVALID_NAMES:
 1925             request_to_validate = {'name': invalid_name}
 1926             self.assertRaises(exception.SchemaValidationError,
 1927                               self.create_user_validator.validate,
 1928                               request_to_validate)
 1929 
 1930     def test_validate_user_update_succeeds(self):
 1931         """Validate an update user request."""
 1932         request_to_validate = {'email': uuid.uuid4().hex}
 1933         self.update_user_validator.validate(request_to_validate)
 1934 
 1935     def test_validate_user_update_fails_with_no_parameters(self):
 1936         """Exception raised when updating nothing."""
 1937         request_to_validate = {}
 1938         self.assertRaises(exception.SchemaValidationError,
 1939                           self.update_user_validator.validate,
 1940                           request_to_validate)
 1941 
 1942     def test_validate_user_update_succeeds_with_extra_parameters(self):
 1943         """Validate user update requests with extra parameters."""
 1944         request_to_validate = {'other_attr': uuid.uuid4().hex}
 1945         self.update_user_validator.validate(request_to_validate)
 1946 
 1947     def test_validate_user_update_fails_with_invalid_name(self):
 1948         """Exception when validating an update request with invalid `name`."""
 1949         for invalid_name in _INVALID_NAMES:
 1950             request_to_validate = {'name': invalid_name}
 1951             self.assertRaises(exception.SchemaValidationError,
 1952                               self.update_user_validator.validate,
 1953                               request_to_validate)
 1954 
 1955     def test_user_create_succeeds_with_empty_options(self):
 1956         request_to_validate = {
 1957             'name': self.user_name,
 1958             'options': {}
 1959         }
 1960         self.create_user_validator.validate(request_to_validate)
 1961 
 1962     def test_user_create_options_fails_invalid_option(self):
 1963         request_to_validate = {
 1964             'name': self.user_name,
 1965             'options': {
 1966                 'whatever': True
 1967             }
 1968         }
 1969         self.assertRaises(exception.SchemaValidationError,
 1970                           self.create_user_validator.validate,
 1971                           request_to_validate)
 1972 
 1973     def test_user_create_with_options_change_password_required(self):
 1974         request_to_validate = {
 1975             'name': self.user_name,
 1976             'options': {
 1977                 ro.IGNORE_CHANGE_PASSWORD_OPT.option_name: True
 1978             }
 1979         }
 1980         self.create_user_validator.validate(request_to_validate)
 1981 
 1982     def test_user_create_options_change_password_required_wrong_type(self):
 1983         request_to_validate = {
 1984             'name': self.user_name,
 1985             'options': {
 1986                 ro.IGNORE_CHANGE_PASSWORD_OPT.option_name: 'whatever'
 1987             }
 1988         }
 1989         self.assertRaises(exception.SchemaValidationError,
 1990                           self.create_user_validator.validate,
 1991                           request_to_validate)
 1992 
 1993     def test_user_create_options_change_password_required_none(self):
 1994         request_to_validate = {
 1995             'name': self.user_name,
 1996             'options': {
 1997                 ro.IGNORE_CHANGE_PASSWORD_OPT.option_name: None
 1998             }
 1999         }
 2000         self.create_user_validator.validate(request_to_validate)
 2001 
 2002     def test_user_update_with_options_change_password_required(self):
 2003         request_to_validate = {
 2004             'options': {
 2005                 ro.IGNORE_CHANGE_PASSWORD_OPT.option_name: False
 2006             }
 2007         }
 2008         self.update_user_validator.validate(request_to_validate)
 2009 
 2010     def test_user_create_with_options_lockout_password(self):
 2011         request_to_validate = {
 2012             'name': self.user_name,
 2013             'options': {
 2014                 ro.IGNORE_LOCKOUT_ATTEMPT_OPT.option_name: True
 2015             }
 2016         }
 2017         self.create_user_validator.validate(request_to_validate)
 2018 
 2019     def test_user_update_with_options_lockout_password(self):
 2020         request_to_validate = {
 2021             'options': {
 2022                 ro.IGNORE_LOCKOUT_ATTEMPT_OPT.option_name: False
 2023             }
 2024         }
 2025         self.update_user_validator.validate(request_to_validate)
 2026 
 2027     def test_user_update_with_two_options(self):
 2028         request_to_validate = {
 2029             'options': {
 2030                 ro.IGNORE_CHANGE_PASSWORD_OPT.option_name: True,
 2031                 ro.IGNORE_LOCKOUT_ATTEMPT_OPT.option_name: True
 2032             }
 2033         }
 2034         self.update_user_validator.validate(request_to_validate)
 2035 
 2036     def test_user_create_with_two_options(self):
 2037         request_to_validate = {
 2038             'name': self.user_name,
 2039             'options': {
 2040                 ro.IGNORE_CHANGE_PASSWORD_OPT.option_name: False,
 2041                 ro.IGNORE_LOCKOUT_ATTEMPT_OPT.option_name: True
 2042             }
 2043         }
 2044         self.create_user_validator.validate(request_to_validate)
 2045 
 2046     def test_user_create_with_mfa_rules(self):
 2047         request_to_validate = {
 2048             'name': self.user_name,
 2049             'options': {
 2050                 ro.MFA_RULES_OPT.option_name: [
 2051                     [uuid.uuid4().hex, uuid.uuid4().hex],
 2052                     [uuid.uuid4().hex],
 2053                 ]
 2054             }
 2055         }
 2056         self.create_user_validator.validate(request_to_validate)
 2057 
 2058     def test_user_update_with_mfa_rules(self):
 2059         request_to_validate = {
 2060             'options': {
 2061                 ro.MFA_RULES_OPT.option_name: [
 2062                     [uuid.uuid4().hex, uuid.uuid4().hex],
 2063                     [uuid.uuid4().hex],
 2064                 ]
 2065             }
 2066         }
 2067         self.update_user_validator.validate(request_to_validate)
 2068 
 2069     def test_user_create_with_mfa_rules_enabled(self):
 2070         request_to_validate = {
 2071             'name': self.user_name,
 2072             'options': {ro.MFA_ENABLED_OPT.option_name: True}
 2073         }
 2074         self.create_user_validator.validate(request_to_validate)
 2075 
 2076     def test_user_update_mfa_rules_enabled(self):
 2077         request_to_validate = {
 2078             'options': {ro.MFA_ENABLED_OPT.option_name: False}
 2079         }
 2080         self.update_user_validator.validate(request_to_validate)
 2081 
 2082     def test_user_option_validation_with_invalid_mfa_rules_fails(self):
 2083         # Test both json schema validation and the validator method in
 2084         # keystone.identity.backends.resource_options
 2085         test_cases = [
 2086             # Main Element Not an Array
 2087             (True, TypeError),
 2088             # Sub-Element Not an Array
 2089             ([True, False], TypeError),
 2090             # Sub-element Element not string
 2091             ([[True], [True, False]], TypeError),
 2092             # Duplicate sub-array
 2093             ([['duplicate_array'] for x in range(0, 2)], ValueError),
 2094             # Empty Sub element
 2095             ([[uuid.uuid4().hex], []], ValueError),
 2096             # Duplicate strings in sub-element
 2097             ([['duplicate' for x in range(0, 2)]], ValueError),
 2098         ]
 2099         for ruleset, exception_class in test_cases:
 2100             request_to_validate = {
 2101                 'options': {
 2102                     ro.MFA_RULES_OPT.option_name: ruleset
 2103                 }
 2104             }
 2105             # JSON Schema Validation
 2106             self.assertRaises(exception.SchemaValidationError,
 2107                               self.update_user_validator.validate,
 2108                               request_to_validate)
 2109             # Data Store Validation
 2110             self.assertRaises(
 2111                 exception_class,
 2112                 ro._mfa_rules_validator_list_of_lists_of_strings_no_duplicates,
 2113                 ruleset)
 2114 
 2115 
 2116 class GroupValidationTestCase(unit.BaseTestCase):
 2117     """Test for V3 Group API validation."""
 2118 
 2119     def setUp(self):
 2120         super(GroupValidationTestCase, self).setUp()
 2121 
 2122         self.group_name = uuid.uuid4().hex
 2123 
 2124         create = identity_schema.group_create
 2125         update = identity_schema.group_update
 2126         self.create_group_validator = validators.SchemaValidator(create)
 2127         self.update_group_validator = validators.SchemaValidator(update)
 2128 
 2129     def test_validate_group_create_succeeds(self):
 2130         """Validate create group requests."""
 2131         request_to_validate = {'name': self.group_name}
 2132         self.create_group_validator.validate(request_to_validate)
 2133 
 2134     def test_validate_group_create_succeeds_with_all_parameters(self):
 2135         """Validate create group requests with all parameters."""
 2136         request_to_validate = {'name': self.group_name,
 2137                                'description': uuid.uuid4().hex,
 2138                                'domain_id': uuid.uuid4().hex}
 2139         self.create_group_validator.validate(request_to_validate)
 2140 
 2141     def test_validate_group_create_fails_without_group_name(self):
 2142         """Exception raised when group name is not provided in request."""
 2143         request_to_validate = {'description': uuid.uuid4().hex}
 2144         self.assertRaises(exception.SchemaValidationError,
 2145                           self.create_group_validator.validate,
 2146                           request_to_validate)
 2147 
 2148     def test_validate_group_create_succeeds_with_extra_parameters(self):
 2149         """Validate extra attributes on group create requests."""
 2150         request_to_validate = {'name': self.group_name,
 2151                                'other_attr': uuid.uuid4().hex}
 2152         self.create_group_validator.validate(request_to_validate)
 2153 
 2154     def test_validate_group_create_fails_with_invalid_name(self):
 2155         """Exception when validating a create request with invalid `name`."""
 2156         for invalid_name in _INVALID_NAMES:
 2157             request_to_validate = {'name': invalid_name}
 2158             self.assertRaises(exception.SchemaValidationError,
 2159                               self.create_group_validator.validate,
 2160                               request_to_validate)
 2161 
 2162     def test_validate_group_update_succeeds(self):
 2163         """Validate group update requests."""
 2164         request_to_validate = {'description': uuid.uuid4().hex}
 2165         self.update_group_validator.validate(request_to_validate)
 2166 
 2167     def test_validate_group_update_fails_with_no_parameters(self):
 2168         """Exception raised when no parameters passed in on update."""
 2169         request_to_validate = {}
 2170         self.assertRaises(exception.SchemaValidationError,
 2171                           self.update_group_validator.validate,
 2172                           request_to_validate)
 2173 
 2174     def test_validate_group_update_succeeds_with_extra_parameters(self):
 2175         """Validate group update requests with extra parameters."""
 2176         request_to_validate = {'other_attr': uuid.uuid4().hex}
 2177         self.update_group_validator.validate(request_to_validate)
 2178 
 2179     def test_validate_group_update_fails_with_invalid_name(self):
 2180         """Exception when validating an update request with invalid `name`."""
 2181         for invalid_name in _INVALID_NAMES:
 2182             request_to_validate = {'name': invalid_name}
 2183             self.assertRaises(exception.SchemaValidationError,
 2184                               self.update_group_validator.validate,
 2185                               request_to_validate)
 2186 
 2187 
 2188 class ChangePasswordValidationTestCase(unit.BaseTestCase):
 2189     """Test for Change Password API validation."""
 2190 
 2191     def setUp(self):
 2192         super(ChangePasswordValidationTestCase, self).setUp()
 2193 
 2194         self.original_password = uuid.uuid4().hex
 2195         self.password = uuid.uuid4().hex
 2196 
 2197         change = identity_schema.password_change
 2198         self.change_password_validator = validators.SchemaValidator(change)
 2199 
 2200     def test_validate_password_change_request_succeeds(self):
 2201         """Test that validating a password change request succeeds."""
 2202         request_to_validate = {'original_password': self.original_password,
 2203                                'password': self.password}
 2204         self.change_password_validator.validate(request_to_validate)
 2205 
 2206     def test_validate_password_change_fails_without_all_fields(self):
 2207         """Test that validating a password change fails without all values."""
 2208         request_to_validate = {'original_password': self.original_password}
 2209         self.assertRaises(exception.SchemaValidationError,
 2210                           self.change_password_validator.validate,
 2211                           request_to_validate)
 2212         request_to_validate = {'password': self.password}
 2213         self.assertRaises(exception.SchemaValidationError,
 2214                           self.change_password_validator.validate,
 2215                           request_to_validate)
 2216 
 2217     def test_validate_password_change_fails_with_invalid_values(self):
 2218         """Test that validating a password change fails with bad values."""
 2219         request_to_validate = {'original_password': None,
 2220                                'password': None}
 2221         self.assertRaises(exception.SchemaValidationError,
 2222                           self.change_password_validator.validate,
 2223                           request_to_validate)
 2224         request_to_validate = {'original_password': 42,
 2225                                'password': True}
 2226         self.assertRaises(exception.SchemaValidationError,
 2227                           self.change_password_validator.validate,
 2228                           request_to_validate)
 2229 
 2230 
 2231 class IdentityProviderValidationTestCase(unit.BaseTestCase):
 2232     """Test for V3 Identity Provider API validation."""
 2233 
 2234     def setUp(self):
 2235         super(IdentityProviderValidationTestCase, self).setUp()
 2236 
 2237         create = federation_schema.identity_provider_create
 2238         update = federation_schema.identity_provider_update
 2239         self.create_idp_validator = validators.SchemaValidator(create)
 2240         self.update_idp_validator = validators.SchemaValidator(update)
 2241 
 2242     def test_validate_idp_request_succeeds(self):
 2243         """Test that we validate an identity provider request."""
 2244         request_to_validate = {'description': 'identity provider description',
 2245                                'enabled': True,
 2246                                'remote_ids': [uuid.uuid4().hex,
 2247                                               uuid.uuid4().hex]}
 2248         self.create_idp_validator.validate(request_to_validate)
 2249         self.update_idp_validator.validate(request_to_validate)
 2250 
 2251     def test_validate_idp_request_fails_with_invalid_params(self):
 2252         """Exception raised when unknown parameter is found."""
 2253         request_to_validate = {'bogus': uuid.uuid4().hex}
 2254         self.assertRaises(exception.SchemaValidationError,
 2255                           self.create_idp_validator.validate,
 2256                           request_to_validate)
 2257 
 2258         self.assertRaises(exception.SchemaValidationError,
 2259                           self.update_idp_validator.validate,
 2260                           request_to_validate)
 2261 
 2262     def test_validate_idp_request_with_enabled(self):
 2263         """Validate `enabled` as boolean-like values."""
 2264         for valid_enabled in _VALID_ENABLED_FORMATS:
 2265             request_to_validate = {'enabled': valid_enabled}
 2266             self.create_idp_validator.validate(request_to_validate)
 2267             self.update_idp_validator.validate(request_to_validate)
 2268 
 2269     def test_validate_idp_request_with_invalid_enabled_fails(self):
 2270         """Exception is raised when `enabled` isn't a boolean-like value."""
 2271         for invalid_enabled in _INVALID_ENABLED_FORMATS:
 2272             request_to_validate = {'enabled': invalid_enabled}
 2273             self.assertRaises(exception.SchemaValidationError,
 2274                               self.create_idp_validator.validate,
 2275                               request_to_validate)
 2276 
 2277             self.assertRaises(exception.SchemaValidationError,
 2278                               self.update_idp_validator.validate,
 2279                               request_to_validate)
 2280 
 2281     def test_validate_idp_request_no_parameters(self):
 2282         """Test that schema validation with empty request body."""
 2283         request_to_validate = {}
 2284         self.create_idp_validator.validate(request_to_validate)
 2285 
 2286         # Exception raised when no property on IdP update.
 2287         self.assertRaises(exception.SchemaValidationError,
 2288                           self.update_idp_validator.validate,
 2289                           request_to_validate)
 2290 
 2291     def test_validate_idp_request_with_invalid_description_fails(self):
 2292         """Exception is raised when `description` as a non-string value."""
 2293         request_to_validate = {'description': False}
 2294         self.assertRaises(exception.SchemaValidationError,
 2295                           self.create_idp_validator.validate,
 2296                           request_to_validate)
 2297 
 2298         self.assertRaises(exception.SchemaValidationError,
 2299                           self.update_idp_validator.validate,
 2300                           request_to_validate)
 2301 
 2302     def test_validate_idp_request_with_invalid_remote_id_fails(self):
 2303         """Exception is raised when `remote_ids` is not a array."""
 2304         request_to_validate = {"remote_ids": uuid.uuid4().hex}
 2305         self.assertRaises(exception.SchemaValidationError,
 2306                           self.create_idp_validator.validate,
 2307                           request_to_validate)
 2308 
 2309         self.assertRaises(exception.SchemaValidationError,
 2310                           self.update_idp_validator.validate,
 2311                           request_to_validate)
 2312 
 2313     def test_validate_idp_request_with_duplicated_remote_id(self):
 2314         """Exception is raised when the duplicated `remote_ids` is found."""
 2315         idp_id = uuid.uuid4().hex
 2316         request_to_validate = {"remote_ids": [idp_id, idp_id]}
 2317         self.assertRaises(exception.SchemaValidationError,
 2318                           self.create_idp_validator.validate,
 2319                           request_to_validate)
 2320 
 2321         self.assertRaises(exception.SchemaValidationError,
 2322                           self.update_idp_validator.validate,
 2323                           request_to_validate)
 2324 
 2325     def test_validate_idp_request_remote_id_nullable(self):
 2326         """Test that `remote_ids` could be explicitly set to None."""
 2327         request_to_validate = {'remote_ids': None}
 2328         self.create_idp_validator.validate(request_to_validate)
 2329         self.update_idp_validator.validate(request_to_validate)
 2330 
 2331 
 2332 class FederationProtocolValidationTestCase(unit.BaseTestCase):
 2333     """Test for V3 Federation Protocol API validation."""
 2334 
 2335     def setUp(self):
 2336         super(FederationProtocolValidationTestCase, self).setUp()
 2337 
 2338         create = federation_schema.protocol_create
 2339         update = federation_schema.protocol_update
 2340         self.create_protocol_validator = validators.SchemaValidator(create)
 2341         self.update_protocol_validator = validators.SchemaValidator(update)
 2342 
 2343     def test_validate_protocol_request_succeeds(self):
 2344         """Test that we validate a protocol request successfully."""
 2345         request_to_validate = {'mapping_id': uuid.uuid4().hex}
 2346         self.create_protocol_validator.validate(request_to_validate)
 2347 
 2348     def test_validate_protocol_request_succeeds_with_nonuuid_mapping_id(self):
 2349         """Test that we allow underscore in mapping_id value."""
 2350         request_to_validate = {'mapping_id': 'my_mapping_id'}
 2351         self.create_protocol_validator.validate(request_to_validate)
 2352 
 2353     def test_validate_protocol_request_fails_with_invalid_params(self):
 2354         """Exception raised when unknown parameter is found."""
 2355         request_to_validate = {'bogus': uuid.uuid4().hex}
 2356         self.assertRaises(exception.SchemaValidationError,
 2357                           self.create_protocol_validator.validate,
 2358                           request_to_validate)
 2359 
 2360     def test_validate_protocol_request_no_parameters(self):
 2361         """Test that schema validation with empty request body."""
 2362         request_to_validate = {}
 2363         # 'mapping_id' is required.
 2364         self.assertRaises(exception.SchemaValidationError,
 2365                           self.create_protocol_validator.validate,
 2366                           request_to_validate)
 2367 
 2368     def test_validate_protocol_request_fails_with_invalid_mapping_id(self):
 2369         """Exception raised when mapping_id is not string."""
 2370         request_to_validate = {'mapping_id': 12334}
 2371         self.assertRaises(exception.SchemaValidationError,
 2372                           self.create_protocol_validator.validate,
 2373                           request_to_validate)
 2374 
 2375     def test_validate_protocol_request_succeeds_on_update(self):
 2376         """Test that we validate a protocol update request successfully."""
 2377         request_to_validate = {'mapping_id': uuid.uuid4().hex}
 2378         self.update_protocol_validator.validate(request_to_validate)
 2379 
 2380     def test_validate_update_protocol_request_succeeds_with_nonuuid_id(self):
 2381         """Test that we allow underscore in mapping_id value when updating."""
 2382         request_to_validate = {'mapping_id': 'my_mapping_id'}
 2383         self.update_protocol_validator.validate(request_to_validate)
 2384 
 2385     def test_validate_update_protocol_request_fails_with_invalid_params(self):
 2386         """Exception raised when unknown parameter in protocol update."""
 2387         request_to_validate = {'bogus': uuid.uuid4().hex}
 2388         self.assertRaises(exception.SchemaValidationError,
 2389                           self.update_protocol_validator.validate,
 2390                           request_to_validate)
 2391 
 2392     def test_validate_update_protocol_with_no_parameters_fails(self):
 2393         """Test that updating a protocol requires at least one attribute."""
 2394         request_to_validate = {}
 2395         # 'mapping_id' is required.
 2396         self.assertRaises(exception.SchemaValidationError,
 2397                           self.update_protocol_validator.validate,
 2398                           request_to_validate)
 2399 
 2400     def test_validate_update_protocol_request_fails_with_invalid_id(self):
 2401         """Test that updating a protocol with a non-string mapping_id fail."""
 2402         for bad_mapping_id in [12345, True]:
 2403             request_to_validate = {'mapping_id': bad_mapping_id}
 2404             self.assertRaises(exception.SchemaValidationError,
 2405                               self.update_protocol_validator.validate,
 2406                               request_to_validate)
 2407 
 2408 
 2409 class OAuth1ValidationTestCase(unit.BaseTestCase):
 2410     """Test for V3 Identity OAuth1 API validation."""
 2411 
 2412     def setUp(self):
 2413         super(OAuth1ValidationTestCase, self).setUp()
 2414 
 2415         create = oauth1_schema.consumer_create
 2416         update = oauth1_schema.consumer_update
 2417         authorize = oauth1_schema.request_token_authorize
 2418         self.create_consumer_validator = validators.SchemaValidator(create)
 2419         self.update_consumer_validator = validators.SchemaValidator(update)
 2420         self.authorize_request_token_validator = validators.SchemaValidator(
 2421             authorize)
 2422 
 2423     def test_validate_consumer_request_succeeds(self):
 2424         """Test that we validate a consumer request successfully."""
 2425         request_to_validate = {'description': uuid.uuid4().hex,
 2426                                'name': uuid.uuid4().hex}
 2427         self.create_consumer_validator.validate(request_to_validate)
 2428         self.update_consumer_validator.validate(request_to_validate)
 2429 
 2430     def test_validate_consumer_request_with_no_parameters(self):
 2431         """Test that schema validation with empty request body."""
 2432         request_to_validate = {}
 2433         self.create_consumer_validator.validate(request_to_validate)
 2434         # At least one property should be given.
 2435         self.assertRaises(exception.SchemaValidationError,
 2436                           self.update_consumer_validator.validate,
 2437                           request_to_validate)
 2438 
 2439     def test_validate_consumer_request_with_invalid_description_fails(self):
 2440         """Exception is raised when `description` as a non-string value."""
 2441         for invalid_desc in _INVALID_DESC_FORMATS:
 2442             request_to_validate = {'description': invalid_desc}
 2443             self.assertRaises(exception.SchemaValidationError,
 2444                               self.create_consumer_validator.validate,
 2445                               request_to_validate)
 2446 
 2447             self.assertRaises(exception.SchemaValidationError,
 2448                               self.update_consumer_validator.validate,
 2449                               request_to_validate)
 2450 
 2451     def test_validate_update_consumer_request_fails_with_secret(self):
 2452         """Exception raised when secret is given."""
 2453         request_to_validate = {'secret': uuid.uuid4().hex}
 2454         self.assertRaises(exception.SchemaValidationError,
 2455                           self.update_consumer_validator.validate,
 2456                           request_to_validate)
 2457 
 2458     def test_validate_consumer_request_with_none_desc(self):
 2459         """Test that schema validation with None desc."""
 2460         request_to_validate = {'description': None}
 2461         self.create_consumer_validator.validate(request_to_validate)
 2462         self.update_consumer_validator.validate(request_to_validate)
 2463 
 2464     def test_validate_authorize_request_token(self):
 2465         request_to_validate = [
 2466             {
 2467                 "id": "711aa6371a6343a9a43e8a310fbe4a6f"
 2468             },
 2469             {
 2470                 "name": "test_role"
 2471             }
 2472         ]
 2473 
 2474         self.authorize_request_token_validator.validate(request_to_validate)
 2475 
 2476     def test_validate_authorize_request_token_with_additional_properties(self):
 2477         request_to_validate = [
 2478             {
 2479                 "id": "711aa6371a6343a9a43e8a310fbe4a6f",
 2480                 "fake_key": "fake_value"
 2481             }
 2482         ]
 2483 
 2484         self.assertRaises(exception.SchemaValidationError,
 2485                           self.authorize_request_token_validator.validate,
 2486                           request_to_validate)
 2487 
 2488     def test_validate_authorize_request_token_with_id_and_name(self):
 2489         request_to_validate = [
 2490             {
 2491                 "id": "711aa6371a6343a9a43e8a310fbe4a6f",
 2492                 "name": "admin"
 2493             }
 2494         ]
 2495 
 2496         self.assertRaises(exception.SchemaValidationError,
 2497                           self.authorize_request_token_validator.validate,
 2498                           request_to_validate)
 2499 
 2500     def test_validate_authorize_request_token_with_non_id_or_name(self):
 2501         request_to_validate = [
 2502             {
 2503                 "fake_key": "fake_value"
 2504             }
 2505         ]
 2506 
 2507         self.assertRaises(exception.SchemaValidationError,
 2508                           self.authorize_request_token_validator.validate,
 2509                           request_to_validate)
 2510 
 2511 
 2512 class PasswordValidationTestCase(unit.TestCase):
 2513     def setUp(self):
 2514         super(PasswordValidationTestCase, self).setUp()
 2515         # passwords requires: 1 letter, 1 digit, 7 chars
 2516         self.config_fixture.config(group='security_compliance',
 2517                                    password_regex=(
 2518                                        r'^(?=.*\d)(?=.*[a-zA-Z]).{7,}$'))
 2519 
 2520     def test_password_validate_with_valid_strong_password(self):
 2521         password = 'mypassword2'
 2522         validators.validate_password(password)
 2523 
 2524     def test_password_validate_with_invalid_strong_password(self):
 2525         # negative test: None
 2526         password = None
 2527         self.assertRaises(exception.PasswordValidationError,
 2528                           validators.validate_password,
 2529                           password)
 2530         # negative test: numeric
 2531         password = 1234
 2532         self.assertRaises(exception.PasswordValidationError,
 2533                           validators.validate_password,
 2534                           password)
 2535         # negative test: boolean
 2536         password = True
 2537         self.assertRaises(exception.PasswordValidationError,
 2538                           validators.validate_password,
 2539                           password)
 2540 
 2541     def test_password_validate_with_invalid_password_regex(self):
 2542         # invalid regular expression, missing beginning '['
 2543         self.config_fixture.config(group='security_compliance',
 2544                                    password_regex=r'\S]+')
 2545         password = 'mypassword2'
 2546         self.assertRaises(exception.PasswordValidationError,
 2547                           validators.validate_password,
 2548                           password)
 2549         # fix regular expression and validate
 2550         self.config_fixture.config(group='security_compliance',
 2551                                    password_regex=r'[\S]+')
 2552         validators.validate_password(password)
 2553 
 2554 
 2555 class LimitValidationTestCase(unit.BaseTestCase):
 2556     """Test for V3 Limits API validation."""
 2557 
 2558     def setUp(self):
 2559         super(LimitValidationTestCase, self).setUp()
 2560 
 2561         create_registered_limits = limit_schema.registered_limit_create
 2562         update_registered_limits = limit_schema.registered_limit_update
 2563         create_limits = limit_schema.limit_create
 2564         update_limits = limit_schema.limit_update
 2565 
 2566         self.create_registered_limits_validator = validators.SchemaValidator(
 2567             create_registered_limits)
 2568         self.update_registered_limits_validator = validators.SchemaValidator(
 2569             update_registered_limits)
 2570         self.create_limits_validator = validators.SchemaValidator(
 2571             create_limits)
 2572         self.update_limits_validator = validators.SchemaValidator(
 2573             update_limits)
 2574 
 2575     def test_validate_registered_limit_create_request_succeeds(self):
 2576         request_to_validate = [{'service_id': uuid.uuid4().hex,
 2577                                 'region_id': 'RegionOne',
 2578                                 'resource_name': 'volume',
 2579                                 'default_limit': 10,
 2580                                 'description': 'test description'}]
 2581         self.create_registered_limits_validator.validate(request_to_validate)
 2582 
 2583     def test_validate_registered_limit_create_request_without_optional(self):
 2584         request_to_validate = [{'service_id': uuid.uuid4().hex,
 2585                                 'resource_name': 'volume',
 2586                                 'default_limit': 10}]
 2587         self.create_registered_limits_validator.validate(request_to_validate)
 2588 
 2589     def test_validate_registered_limit_update_request_without_region(self):
 2590         request_to_validate = {'service_id': uuid.uuid4().hex,
 2591                                'resource_name': 'volume',
 2592                                'default_limit': 10}
 2593         self.update_registered_limits_validator.validate(request_to_validate)
 2594 
 2595     def test_validate_registered_limit_request_with_no_parameters(self):
 2596         request_to_validate = []
 2597         # At least one property should be given.
 2598         self.assertRaises(exception.SchemaValidationError,
 2599                           self.create_registered_limits_validator.validate,
 2600                           request_to_validate)
 2601 
 2602     def test_validate_registered_limit_create_request_with_invalid_input(self):
 2603         _INVALID_FORMATS = [{'service_id': 'fake_id'},
 2604                             {'region_id': 123},
 2605                             {'resource_name': 123},
 2606                             {'resource_name': ''},
 2607                             {'resource_name': 'a' * 256},
 2608                             {'default_limit': 'not_int'},
 2609                             {'default_limit': -10},
 2610                             {'default_limit': 10000000000000000},
 2611                             {'description': 123},
 2612                             {'description': True}]
 2613         for invalid_desc in _INVALID_FORMATS:
 2614             request_to_validate = [{'service_id': uuid.uuid4().hex,
 2615                                     'region_id': 'RegionOne',
 2616                                     'resource_name': 'volume',
 2617                                     'default_limit': 10,
 2618                                     'description': 'test description'}]
 2619             request_to_validate[0].update(invalid_desc)
 2620 
 2621             self.assertRaises(exception.SchemaValidationError,
 2622                               self.create_registered_limits_validator.validate,
 2623                               request_to_validate)
 2624 
 2625     def test_validate_registered_limit_update_request_with_invalid_input(self):
 2626         _INVALID_FORMATS = [{'service_id': 'fake_id'},
 2627                             {'region_id': 123},
 2628                             {'resource_name': 123},
 2629                             {'resource_name': ''},
 2630                             {'resource_name': 'a' * 256},
 2631                             {'default_limit': 'not_int'},
 2632                             {'default_limit': -10},
 2633                             {'default_limit': 10000000000000000},
 2634                             {'description': 123}]
 2635         for invalid_desc in _INVALID_FORMATS:
 2636             request_to_validate = {'service_id': uuid.uuid4().hex,
 2637                                    'region_id': 'RegionOne',
 2638                                    'resource_name': 'volume',
 2639                                    'default_limit': 10,
 2640                                    'description': 'test description'}
 2641             request_to_validate.update(invalid_desc)
 2642 
 2643             self.assertRaises(exception.SchemaValidationError,
 2644                               self.update_registered_limits_validator.validate,
 2645                               request_to_validate)
 2646 
 2647     def test_validate_registered_limit_create_request_with_addition(self):
 2648         request_to_validate = [{'service_id': uuid.uuid4().hex,
 2649                                 'region_id': 'RegionOne',
 2650                                 'resource_name': 'volume',
 2651                                 'default_limit': 10,
 2652                                 'more_key': 'more_value'}]
 2653         self.assertRaises(exception.SchemaValidationError,
 2654                           self.create_registered_limits_validator.validate,
 2655                           request_to_validate)
 2656 
 2657     def test_validate_registered_limit_update_request_with_addition(self):
 2658         request_to_validate = {'service_id': uuid.uuid4().hex,
 2659                                'region_id': 'RegionOne',
 2660                                'resource_name': 'volume',
 2661                                'default_limit': 10,
 2662                                'more_key': 'more_value'}
 2663         self.assertRaises(exception.SchemaValidationError,
 2664                           self.update_registered_limits_validator.validate,
 2665                           request_to_validate)
 2666 
 2667     def test_validate_registered_limit_create_request_without_required(self):
 2668         for key in ['service_id', 'resource_name', 'default_limit']:
 2669             request_to_validate = [{'service_id': uuid.uuid4().hex,
 2670                                     'region_id': 'RegionOne',
 2671                                     'resource_name': 'volume',
 2672                                     'default_limit': 10}]
 2673             request_to_validate[0].pop(key)
 2674             self.assertRaises(exception.SchemaValidationError,
 2675                               self.create_registered_limits_validator.validate,
 2676                               request_to_validate)
 2677 
 2678     def test_validate_project_limit_create_request_succeeds(self):
 2679         request_to_validate = [{'project_id': uuid.uuid4().hex,
 2680                                 'service_id': uuid.uuid4().hex,
 2681                                 'region_id': 'RegionOne',
 2682                                 'resource_name': 'volume',
 2683                                 'resource_limit': 10,
 2684                                 'description': 'test description'}]
 2685         self.create_limits_validator.validate(request_to_validate)
 2686 
 2687     def test_validate_domain_limit_create_request_succeeds(self):
 2688         request_to_validate = [{'domain_id': uuid.uuid4().hex,
 2689                                 'service_id': uuid.uuid4().hex,
 2690                                 'region_id': 'RegionOne',
 2691                                 'resource_name': 'volume',
 2692                                 'resource_limit': 10,
 2693                                 'description': 'test description'}]
 2694         self.create_limits_validator.validate(request_to_validate)
 2695 
 2696     def test_validate_limit_create_request_without_optional(self):
 2697         request_to_validate = [{'project_id': uuid.uuid4().hex,
 2698                                 'service_id': uuid.uuid4().hex,
 2699                                 'resource_name': 'volume',
 2700                                 'resource_limit': 10}]
 2701         self.create_limits_validator.validate(request_to_validate)
 2702 
 2703     def test_validate_limit_update_request_succeeds(self):
 2704         request_to_validate = {'resource_limit': 10,
 2705                                'description': 'test description'}
 2706         self.update_limits_validator.validate(request_to_validate)
 2707 
 2708     def test_validate_limit_update_request_without_optional(self):
 2709         request_to_validate = {'resource_limit': 10}
 2710         self.update_limits_validator.validate(request_to_validate)
 2711 
 2712     def test_validate_limit_request_with_no_parameters(self):
 2713         request_to_validate = []
 2714         # At least one property should be given.
 2715         self.assertRaises(exception.SchemaValidationError,
 2716                           self.create_limits_validator.validate,
 2717                           request_to_validate)
 2718 
 2719     def test_validate_limit_create_request_with_invalid_input(self):
 2720         _INVALID_FORMATS = [{'project_id': 'fake_id'},
 2721                             {'service_id': 'fake_id'},
 2722                             {'region_id': 123},
 2723                             {'resource_name': 123},
 2724                             {'resource_name': ''},
 2725                             {'resource_name': 'a' * 256},
 2726                             {'resource_limit': -10},
 2727                             {'resource_limit': 10000000000000000},
 2728                             {'resource_limit': 'not_int'},
 2729                             {'description': 123}]
 2730         for invalid_attribute in _INVALID_FORMATS:
 2731             request_to_validate = [{'project_id': uuid.uuid4().hex,
 2732                                     'service_id': uuid.uuid4().hex,
 2733                                     'region_id': 'RegionOne',
 2734                                     'resource_name': 'volume',
 2735                                     'resource_limit': 10,
 2736                                     'description': 'test description'}]
 2737             request_to_validate[0].update(invalid_attribute)
 2738 
 2739             self.assertRaises(exception.SchemaValidationError,
 2740                               self.create_limits_validator.validate,
 2741                               request_to_validate)
 2742 
 2743     def test_validate_limit_create_request_with_invalid_domain(self):
 2744         request_to_validate = [{'domain_id': 'fake_id',
 2745                                 'service_id': uuid.uuid4().hex,
 2746                                 'region_id': 'RegionOne',
 2747                                 'resource_name': 'volume',
 2748                                 'resource_limit': 10,
 2749                                 'description': 'test description'}]
 2750         self.assertRaises(exception.SchemaValidationError,
 2751                           self.create_limits_validator.validate,
 2752                           request_to_validate)
 2753 
 2754     def test_validate_limit_update_request_with_invalid_input(self):
 2755         _INVALID_FORMATS = [{'resource_name': 123},
 2756                             {'resource_limit': 'not_int'},
 2757                             {'resource_name': ''},
 2758                             {'resource_name': 'a' * 256},
 2759                             {'resource_limit': -10},
 2760                             {'resource_limit': 10000000000000000},
 2761                             {'description': 123}]
 2762         for invalid_desc in _INVALID_FORMATS:
 2763             request_to_validate = [{'project_id': uuid.uuid4().hex,
 2764                                     'service_id': uuid.uuid4().hex,
 2765                                     'region_id': 'RegionOne',
 2766                                     'resource_name': 'volume',
 2767                                     'resource_limit': 10,
 2768                                     'description': 'test description'}]
 2769             request_to_validate[0].update(invalid_desc)
 2770 
 2771             self.assertRaises(exception.SchemaValidationError,
 2772                               self.update_limits_validator.validate,
 2773                               request_to_validate)
 2774 
 2775     def test_validate_limit_create_request_with_addition_input_fails(self):
 2776         request_to_validate = [{'service_id': uuid.uuid4().hex,
 2777                                 'region_id': 'RegionOne',
 2778                                 'resource_name': 'volume',
 2779                                 'resource_limit': 10,
 2780                                 'more_key': 'more_value'}]
 2781         self.assertRaises(exception.SchemaValidationError,
 2782                           self.create_limits_validator.validate,
 2783                           request_to_validate)
 2784 
 2785     def test_validate_limit_update_request_with_addition_input_fails(self):
 2786         request_to_validate = {'id': uuid.uuid4().hex,
 2787                                'resource_limit': 10,
 2788                                'more_key': 'more_value'}
 2789         self.assertRaises(exception.SchemaValidationError,
 2790                           self.update_limits_validator.validate,
 2791                           request_to_validate)
 2792 
 2793     def test_validate_project_limit_create_request_without_required_fails(
 2794             self):
 2795         for key in ['project_id', 'service_id', 'resource_name',
 2796                     'resource_limit']:
 2797             request_to_validate = [{'project_id': uuid.uuid4().hex,
 2798                                     'service_id': uuid.uuid4().hex,
 2799                                     'region_id': 'RegionOne',
 2800                                     'resource_name': 'volume',
 2801                                     'resource_limit': 10}]
 2802             request_to_validate[0].pop(key)
 2803             self.assertRaises(exception.SchemaValidationError,
 2804                               self.create_limits_validator.validate,
 2805                               request_to_validate)
 2806 
 2807     def test_validate_domain_limit_create_request_without_required_fails(self):
 2808         for key in ['domain_id', 'service_id', 'resource_name',
 2809                     'resource_limit']:
 2810             request_to_validate = [{'domain_id': uuid.uuid4().hex,
 2811                                     'service_id': uuid.uuid4().hex,
 2812                                     'region_id': 'RegionOne',
 2813                                     'resource_name': 'volume',
 2814                                     'resource_limit': 10}]
 2815             request_to_validate[0].pop(key)
 2816             self.assertRaises(exception.SchemaValidationError,
 2817                               self.create_limits_validator.validate,
 2818                               request_to_validate)
 2819 
 2820     def test_validate_limit_create_request_with_both_project_and_domain(self):
 2821         request_to_validate = [{'project_id': uuid.uuid4().hex,
 2822                                 'domain_id': uuid.uuid4().hex,
 2823                                 'service_id': uuid.uuid4().hex,
 2824                                 'region_id': 'RegionOne',
 2825                                 'resource_name': 'volume',
 2826                                 'resource_limit': 10,
 2827                                 'description': 'test description'}]
 2828         self.assertRaises(exception.SchemaValidationError,
 2829                           self.create_limits_validator.validate,
 2830                           request_to_validate)
 2831 
 2832 
 2833 class ApplicationCredentialValidatorTestCase(unit.TestCase):
 2834     _valid_roles = [{'name': 'member'},
 2835                     {'id': uuid.uuid4().hex},
 2836                     {'id': str(uuid.uuid4())},
 2837                     {'name': '_member_'}]
 2838     _invalid_roles = [True, 123, None, {'badkey': 'badval'}]
 2839 
 2840     def setUp(self):
 2841         super(ApplicationCredentialValidatorTestCase, self).setUp()
 2842 
 2843         create = app_cred_schema.application_credential_create
 2844         self.create_app_cred_validator = validators.SchemaValidator(create)
 2845 
 2846     def test_validate_app_cred_request(self):
 2847         request_to_validate = {
 2848             'name': 'myappcred',
 2849             'description': 'My App Cred',
 2850             'roles': [{'name': 'member'}],
 2851             'expires_at': 'tomorrow'
 2852         }
 2853         self.create_app_cred_validator.validate(request_to_validate)
 2854 
 2855     def test_validate_app_cred_request_without_name_fails(self):
 2856         request_to_validate = {
 2857             'description': 'My App Cred',
 2858             'roles': [{'name': 'member'}],
 2859             'expires_at': 'tomorrow'
 2860         }
 2861         self.assertRaises(exception.SchemaValidationError,
 2862                           self.create_app_cred_validator.validate,
 2863                           request_to_validate)
 2864 
 2865     def test_validate_app_cred_with_invalid_expires_at_fails(self):
 2866         request_to_validate = {
 2867             'name': 'myappcred',
 2868             'description': 'My App Cred',
 2869             'roles': [{'name': 'member'}],
 2870             'expires_at': 3
 2871         }
 2872         self.assertRaises(exception.SchemaValidationError,
 2873                           self.create_app_cred_validator.validate,
 2874                           request_to_validate)
 2875 
 2876     def test_validate_app_cred_with_null_expires_at_succeeds(self):
 2877         request_to_validate = {
 2878             'name': 'myappcred',
 2879             'description': 'My App Cred',
 2880             'roles': [{'name': 'member'}],
 2881         }
 2882         self.create_app_cred_validator.validate(request_to_validate)
 2883 
 2884     def test_validate_app_cred_with_unrestricted_flag_succeeds(self):
 2885         request_to_validate = {
 2886             'name': 'myappcred',
 2887             'description': 'My App Cred',
 2888             'roles': [{'name': 'member'}],
 2889             'unrestricted': True
 2890         }
 2891         self.create_app_cred_validator.validate(request_to_validate)
 2892 
 2893     def test_validate_app_cred_with_secret_succeeds(self):
 2894         request_to_validate = {
 2895             'name': 'myappcred',
 2896             'description': 'My App Cred',
 2897             'roles': [{'name': 'member'}],
 2898             'secret': 'secretsecretsecretsecret'
 2899         }
 2900         self.create_app_cred_validator.validate(request_to_validate)
 2901 
 2902     def test_validate_app_cred_invalid_roles_fails(self):
 2903         for role in self._invalid_roles:
 2904             request_to_validate = {
 2905                 'name': 'myappcred',
 2906                 'description': 'My App Cred',
 2907                 'roles': [role]
 2908             }
 2909             self.assertRaises(exception.SchemaValidationError,
 2910                               self.create_app_cred_validator.validate,
 2911                               request_to_validate)