class TestIdentityMimicOSKSCatalogAdminListExternalServices( SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/services``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/services" self.eeapi_name = u"externalServiceName" self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"GET" @ddt.data(0, 1, 10) def test_listing(self, api_entry_count): """ GET will list the registered services. """ # create the desired number of services per test parameter api_list = [ ExternalApiStore( text_type(uuid.uuid4()), self.eeapi_name + text_type(uuid.uuid4()), 'service-' + text_type(uuid.uuid4()), ) for ignored in range(api_entry_count) ] # add the services for api in api_list: self.core.add_api(api) # retrieve the listing using the REST interface (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) def validate_api(api_id, api_type, api_name): """ Lookup the API in the test's set of APIs and match the values """ matching_apis = [api for api in api_list if api.uuid_key == api_id] self.assertEqual(len(matching_apis), 1) [matching_api] = matching_apis self.assertEqual(api_id, matching_api.uuid_key) self.assertEqual(api_type, matching_api.type_key) self.assertEqual(api_name, matching_api.name_key) self.assertEqual(response.code, 200) self.assertEqual(len(json_body["OS-KSADM:services"]), len(api_list)) # ensure all services in the response match one in the generated # initially generated set for entry in json_body["OS-KSADM:services"]: validate_api(entry['id'], entry['type'], entry['name'])
def test_get_external_apis(self): """ Validate retrieving the list of external APIs """ eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) core = MimicCore(Clock(), []) self.assertEqual(len(core.get_external_apis()), 0) core.add_api(eeapi) api_list = core.get_external_apis() self.assertEqual(len(api_list), 1) self.assertEqual(list(api_list), [eeapi.uuid_key])
def test_get_external_apis(self): """ Validate retrieving the list of external APIs """ eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) core = MimicCore(Clock(), []) self.assertEqual(len(core.get_external_apis()), 0) core.add_api(eeapi) api_list = core.get_external_apis() self.assertEqual(len(api_list), 1) self.assertEqual(list(api_list), [eeapi.uuid_key])
class TestIdentityOSKSCatalogTenantAdminEndpointTemplatesList( SynchronousTestCase, IdentityAuthMixin, ServiceIdHeaderMixin): """ Tests for ``/identity/v2.0/<tenant-id>/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.tenant_id = 'some_tenant' self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = ( "/identity/v2.0/tenants/" + self.tenant_id + "/OS-KSCATALOG/endpoints" ) self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"GET" def test_list_only_internal_apis_available(self): """ GET will not list Internal APIs. """ self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 0) self.assertEqual(len(json_body['endpoints_links']), 0) def test_list_single_template(self): """ GET will list an external API if it has a endpoint template. """ self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 1) self.assertEqual(len(json_body['endpoints_links']), 0) def test_list_template_all_disabled(self): """ GET will not list endpoint templates that are disabled. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) self.eeapi.endpoint_templates[id_key].enabled_key = False (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 0) self.assertEqual(len(json_body['endpoints_links']), 0) def test_list_single_template_external_and_internal_apis(self): """ GET will only list external API endpoint templates. """ self.core.add_api(self.eeapi) self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 1) self.assertEqual(len(json_body['endpoints_links']), 0) def test_multiple_external_apis(self): """ GET will list multiple external APIs. """ api_list = [ make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4()), set_enabled=True ) for ignored in range(10) ] # eeapi should be the first entry in the list api_list.insert(0, self.eeapi) for api in api_list: self.core.add_api(api) self.assertEqual(len(self.core._uuid_to_api_external), len(api_list)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) def get_header(header_name): return response.headers.getRawHeaders(header_name)[0].decode("utf-8") self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), len(api_list)) self.assertEqual(len(json_body['endpoints_links']), 0)
class TestIdentityOSKSCatalogTenantAdminEndpointTemplatesCreate( SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/<tenant-id>/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.tenant_id = 'some_tenant' self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = ( "/identity/v2.0/tenants/" + self.tenant_id + "/OS-KSCATALOG/endpoints" ) self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=False ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"POST" def test_json_body_missing_required_field_oskscatalog(self): """ POST with the OS-KSCATALOG:endointTemplate body entirely missing results in 400. """ data = { 'id': text_type(uuid.uuid4()), } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue( json_body['badRequest']['message'].startswith( "Invalid Content. OS-KSCATALOG:endpointTemplate:id is " "required." ) ) def test_json_body_missing_required_field_template_id(self): """ POST with the OS-KSCATALOG:endointTemplate body missing it's content results in 400. """ data = { "OS-KSCATALOG:endpointTemplate": { } } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue( json_body['badRequest']['message'].startswith( "Invalid Content. OS-KSCATALOG:endpointTemplate:id is " "required." ) ) def test_invalid_template_id(self): """ POST with invalid endpointTemplate ID results in 404. """ self.core.add_api(self.eeapi) data = { "OS-KSCATALOG:endpointTemplate": { "id": "some-id" } } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertTrue( json_body['itemNotFound']['message'].startswith( "Unable to locate an External API with the given Template ID." ) ) def test_enable_template(self): """ POST can update an existing endpoint template resulting in a 201. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) data = { "OS-KSCATALOG:endpointTemplate": { "id": id_key } } req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityOSKSCatalogAdminEndpointTemplatesDelete(SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"DELETE" self.ept_template_id = get_template_id(self, self.eeapi) self.uri = ( "/identity/v2.0/OS-KSCATALOG/endpointTemplates/" + self.ept_template_id ) def test_invalid_template_id(self): """ DELTE requires a valid endpoint template id, otherwise results in 404. """ self.eeapi.remove_template(self.ept_template_id) self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Unable to locate an External API with the given Template ID." ) def test_invalid_template_id_with_service_header(self): """ DELETE requires the endpoint template to exist, otherwise results in 404. """ self.eeapi.remove_template(self.ept_template_id) self.core.add_api(self.eeapi) self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Unable to locate an External API with the given Template ID." ) @ddt.data( True, False ) def test_remove_template_id(self, has_service_header): """ DELETE removes an existing endpoint template, service id header is optional. """ self.core.add_api(self.eeapi) if has_service_header: self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] req = request(self, self.root, self.verb, self.uri, headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 204)
class TestIdentityOSKSCatalogAdminEndpointTemplatesDelete( SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"DELETE" self.ept_template_id = get_template_id(self, self.eeapi) self.uri = ("/identity/v2.0/OS-KSCATALOG/endpointTemplates/" + self.ept_template_id) def test_invalid_template_id(self): """ DELTE requires a valid endpoint template id, otherwise results in 404. """ self.eeapi.remove_template(self.ept_template_id) self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Unable to locate an External API with the given Template ID.") def test_invalid_template_id_with_service_header(self): """ DELETE requires the endpoint template to exist, otherwise results in 404. """ self.eeapi.remove_template(self.ept_template_id) self.core.add_api(self.eeapi) self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Unable to locate an External API with the given Template ID.") @ddt.data(True, False) def test_remove_template_id(self, has_service_header): """ DELETE removes an existing endpoint template, service id header is optional. """ self.core.add_api(self.eeapi) if has_service_header: self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] req = request(self, self.root, self.verb, self.uri, headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 204)
class TestIdentityOSKSCatalogAdminEndpointTemplatesList( SynchronousTestCase, IdentityAuthMixin, ServiceIdHeaderMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/OS-KSCATALOG/endpointTemplates" self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"GET" def test_list_only_internal_apis_available(self): """ GET will return an empty listing when there are no External API endpoint templates. """ self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), 0) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0) def test_list_single_template(self): """ GET will return a endpoint template when there are External API endpoint templates. """ self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), 1) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0) def test_list_single_template_external_and_internal_apis(self): """ GET will only return the External API endpoint templates when they are available, even if there are also Internal APIs. """ self.core.add_api(self.eeapi) self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), 1) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0) def test_multiple_external_apis(self): """ GET can retrieve numerous External APIs that have External API Templates. """ api_list = [ make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4())) for ignored in range(10) ] # eeapi needs to be the first in the list api_list.insert(0, self.eeapi) for api in api_list: self.core.add_api(api) self.assertEqual(len(self.core._uuid_to_api_external), len(api_list)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), len(api_list)) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0)
class TestIdentityMimicOSKSCatalogAdminCreateExternalService( SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/services``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/services" self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"POST" @ddt.data( 'type', 'name' ) def test_json_body_missing_required_field(self, remove_field): """ POST requires 'name' field otherwise 400 is generated. """ # normal JSON body data = { 'type': 'some-type', 'name': 'some-name' } # remove a portion of the body per the DDT data del data[remove_field] # POST the resulting JSON to the REST API (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) # API should return 400 since a required field is missing self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertEqual(json_body['badRequest']['message'], "Invalid Content. 'name' and 'type' fields are " "required.") @ddt.data( (True, False, "Conflict: Service with the same name already exists."), (False, True, "Conflict: Service with the same uuid already exists."), ) @ddt.unpack def test_service_name_or_id_already_exists(self, name_exists, id_exists, msg): """ POST requires a unique UUID for the Service ID. """ self.core.add_api(self.eeapi) data = { 'id': self.eeapi.uuid_key if id_exists else text_type(uuid.uuid4()), 'name': self.eeapi.name_key if name_exists else "some-other-name", 'type': self.eeapi.type_key } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual(json_body['conflict']['message'], msg) @ddt.data( (True, True), (True, False), (False, True), (False, False) ) @ddt.unpack def test_successfully_add_service(self, has_id_field, has_description): """ POST accepts the service type and name regardless of whether an ID field is provided. """ data = { 'name': self.eeapi.name_key, 'type': self.eeapi.type_key, 'id': text_type(uuid.uuid4()), 'description': 'testing external API' } if not has_id_field: del data['id'] if not has_description: del data['description'] req = request(self, self.root, self.verb, "/identity/v2.0/services", body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityMimicOSKSCatalogAdminListExternalServices(SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/services``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/services" self.eeapi_name = u"externalServiceName" self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"GET" @ddt.data( 0, 1, 10 ) def test_listing(self, api_entry_count): """ GET will list the registered services. """ # create the desired number of services per test parameter api_list = [ ExternalApiStore( text_type(uuid.uuid4()), self.eeapi_name + text_type(uuid.uuid4()), 'service-' + text_type(uuid.uuid4()), ) for ignored in range(api_entry_count) ] # add the services for api in api_list: self.core.add_api(api) # retrieve the listing using the REST interface (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) def validate_api(api_id, api_type, api_name): """ Lookup the API in the test's set of APIs and match the values """ matching_apis = [ api for api in api_list if api.uuid_key == api_id ] self.assertEqual(len(matching_apis), 1) [matching_api] = matching_apis self.assertEqual(api_id, matching_api.uuid_key) self.assertEqual(api_type, matching_api.type_key) self.assertEqual(api_name, matching_api.name_key) self.assertEqual(response.code, 200) self.assertEqual(len(json_body["OS-KSADM:services"]), len(api_list)) # ensure all services in the response match one in the generated # initially generated set for entry in json_body["OS-KSADM:services"]: validate_api(entry['id'], entry['type'], entry['name'])
class TestIdentityMimicOSKSCatalogAdminDeleteExternalService(SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/services/<service-id>``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_id = u"some-id" self.uri = "/identity/v2.0/services/" + self.eeapi_id self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) self.eeapi2 = make_example_external_api( self, name=self.eeapi_name + " alternate" ) self.eeapi.uuid_key = self.eeapi_id self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"DELETE" def test_invalid_service(self): """ DELETE an unknown service will generate a 404. """ data = { 'name': 'some-name', 'type': 'some-type', 'id': 'some-id' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual(json_body['itemNotFound']['message'], "Service not found. Unable to remove.") def test_service_has_template(self): """ DELETE a service that still has a template results in 409. """ self.core.add_api(self.eeapi) data = { 'name': self.eeapi.name_key, 'type': self.eeapi.type_key, 'id': self.eeapi.uuid_key } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual(json_body['conflict']['message'], "Service still has endpoint templates.") def test_remove_service(self): """ DELETE a service. """ templates_to_remove = list(self.eeapi.endpoint_templates.keys()) for template_id in templates_to_remove: self.eeapi.remove_template(template_id) self.core.add_api(self.eeapi) self.core.add_api(self.eeapi2) data = { 'name': self.eeapi.name_key, 'type': self.eeapi.type_key, 'id': self.eeapi.uuid_key } req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 204)
class TestIdentityOSKSCatalogTenantAdminEndpointTemplatesDelete( SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/<tenant-id>/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.tenant_id = 'some_tenant' self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name) self.template_id = get_template_id(self, self.eeapi) self.assertIsNotNone(self.template_id) self.uri = ("/identity/v2.0/tenants/" + self.tenant_id + "/OS-KSCATALOG/endpoints/" + self.template_id) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"DELETE" def test_invalid_template_id(self): """ DELETE with an invalid endpoint template id results in 404. """ self.eeapi.remove_template(self.template_id) self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertTrue(json_body['itemNotFound']['message'].startswith( "Unable to locate an External API with the given Template ID.")) def test_template_id_not_enabled_for_tenant(self): """ DELETE for endpoint template not enabled for a tenant or globally results in 404. """ self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual(json_body['itemNotFound']['message'], "Template not enabled for tenant") def test_disable_template(self): """ DELETE for endpoint template enabled for tenant results in 204. """ self.core.add_api(self.eeapi) self.eeapi.enable_endpoint_for_tenant(self.tenant_id, self.template_id) eeapi2 = make_example_external_api(self, name="alternate " + self.eeapi_name) ept_id2 = get_template_id(self, eeapi2) eeapi2.remove_template(ept_id2) self.core.add_api(eeapi2) req = request(self, self.root, self.verb, self.uri, headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 204)
class TestIdentityOSKSCatalogTenantAdminEndpointTemplatesList( SynchronousTestCase, IdentityAuthMixin, ServiceIdHeaderMixin): """ Tests for ``/identity/v2.0/<tenant-id>/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.tenant_id = 'some_tenant' self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = ("/identity/v2.0/tenants/" + self.tenant_id + "/OS-KSCATALOG/endpoints") self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"GET" def test_list_only_internal_apis_available(self): """ GET will not list Internal APIs. """ self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 0) self.assertEqual(len(json_body['endpoints_links']), 0) def test_list_single_template(self): """ GET will list an external API if it has a endpoint template. """ self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 1) self.assertEqual(len(json_body['endpoints_links']), 0) def test_list_template_all_disabled(self): """ GET will not list endpoint templates that are disabled. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) self.eeapi.endpoint_templates[id_key].enabled_key = False (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 0) self.assertEqual(len(json_body['endpoints_links']), 0) def test_list_single_template_external_and_internal_apis(self): """ GET will only list external API endpoint templates. """ self.core.add_api(self.eeapi) self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), 1) self.assertEqual(len(json_body['endpoints_links']), 0) def test_multiple_external_apis(self): """ GET will list multiple external APIs. """ api_list = [ make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4()), set_enabled=True) for ignored in range(10) ] # eeapi should be the first entry in the list api_list.insert(0, self.eeapi) for api in api_list: self.core.add_api(api) self.assertEqual(len(self.core._uuid_to_api_external), len(api_list)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) def get_header(header_name): return response.headers.getRawHeaders(header_name)[0].decode( "utf-8") self.assertEqual(response.code, 200) self.assertEqual(len(json_body['endpoints']), len(api_list)) self.assertEqual(len(json_body['endpoints_links']), 0)
class TestIdentityOSKSCatalogTenantAdminEndpointTemplatesCreate( SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/<tenant-id>/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.tenant_id = 'some_tenant' self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = ("/identity/v2.0/tenants/" + self.tenant_id + "/OS-KSCATALOG/endpoints") self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=False) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"POST" def test_json_body_missing_required_field_oskscatalog(self): """ POST with the OS-KSCATALOG:endointTemplate body entirely missing results in 400. """ data = { 'id': text_type(uuid.uuid4()), } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue(json_body['badRequest']['message'].startswith( "Invalid Content. OS-KSCATALOG:endpointTemplate:id is " "required.")) def test_json_body_missing_required_field_template_id(self): """ POST with the OS-KSCATALOG:endointTemplate body missing it's content results in 400. """ data = {"OS-KSCATALOG:endpointTemplate": {}} (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue(json_body['badRequest']['message'].startswith( "Invalid Content. OS-KSCATALOG:endpointTemplate:id is " "required.")) def test_invalid_template_id(self): """ POST with invalid endpointTemplate ID results in 404. """ self.core.add_api(self.eeapi) data = {"OS-KSCATALOG:endpointTemplate": {"id": "some-id"}} (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertTrue(json_body['itemNotFound']['message'].startswith( "Unable to locate an External API with the given Template ID.")) def test_enable_template(self): """ POST can update an existing endpoint template resulting in a 201. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) data = {"OS-KSCATALOG:endpointTemplate": {"id": id_key}} req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityMimicOSKSCatalogAdminCreateExternalService( SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/services``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/services" self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"POST" @ddt.data('type', 'name') def test_json_body_missing_required_field(self, remove_field): """ POST requires 'name' field otherwise 400 is generated. """ # normal JSON body data = {'type': 'some-type', 'name': 'some-name'} # remove a portion of the body per the DDT data del data[remove_field] # POST the resulting JSON to the REST API (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) # API should return 400 since a required field is missing self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertEqual( json_body['badRequest']['message'], "Invalid Content. 'name' and 'type' fields are " "required.") @ddt.data( (True, False, "Conflict: Service with the same name already exists."), (False, True, "Conflict: Service with the same uuid already exists."), ) @ddt.unpack def test_service_name_or_id_already_exists(self, name_exists, id_exists, msg): """ POST requires a unique UUID for the Service ID. """ self.core.add_api(self.eeapi) data = { 'id': self.eeapi.uuid_key if id_exists else text_type(uuid.uuid4()), 'name': self.eeapi.name_key if name_exists else "some-other-name", 'type': self.eeapi.type_key } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual(json_body['conflict']['message'], msg) @ddt.data((True, True), (True, False), (False, True), (False, False)) @ddt.unpack def test_successfully_add_service(self, has_id_field, has_description): """ POST accepts the service type and name regardless of whether an ID field is provided. """ data = { 'name': self.eeapi.name_key, 'type': self.eeapi.type_key, 'id': text_type(uuid.uuid4()), 'description': 'testing external API' } if not has_id_field: del data['id'] if not has_description: del data['description'] req = request(self, self.root, self.verb, "/identity/v2.0/services", body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityOSKSCatalogTenantAdminEndpointTemplatesDelete(SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/<tenant-id>/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.tenant_id = 'some_tenant' self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name ) self.template_id = get_template_id(self, self.eeapi) self.assertIsNotNone(self.template_id) self.uri = ( "/identity/v2.0/tenants/" + self.tenant_id + "/OS-KSCATALOG/endpoints/" + self.template_id ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"DELETE" def test_invalid_template_id(self): """ DELETE with an invalid endpoint template id results in 404. """ self.eeapi.remove_template(self.template_id) self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertTrue( json_body['itemNotFound']['message'].startswith( "Unable to locate an External API with the given Template ID." ) ) def test_template_id_not_enabled_for_tenant(self): """ DELETE for endpoint template not enabled for a tenant or globally results in 404. """ self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Template not enabled for tenant" ) def test_disable_template(self): """ DELETE for endpoint template enabled for tenant results in 204. """ self.core.add_api(self.eeapi) self.eeapi.enable_endpoint_for_tenant( self.tenant_id, self.template_id ) eeapi2 = make_example_external_api( self, name="alternate " + self.eeapi_name ) ept_id2 = get_template_id(self, eeapi2) eeapi2.remove_template(ept_id2) self.core.add_api(eeapi2) req = request(self, self.root, self.verb, self.uri, headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 204)
class TestIdentityOSKSCatalogAdminEndpointTemplatesAdd(SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/OS-KSCATALOG/endpointTemplates" self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"POST" @ddt.data('name', 'id', 'type', 'region') def test_json_body_missing_required_field(self, remove_field): """ POST - required fields must be present otherwise 400 is generated. """ data = { 'id': text_type(uuid.uuid4()), 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } del data[remove_field] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue(json_body['badRequest']['message'].startswith( "JSON body does not contain the required parameters:")) def test_invalid_service_id_in_json_body(self): """ POST - Service ID must be valid, otherwise results in 404. """ # Add a second API eeapi2 = make_example_external_api( self, name='d' + self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4())) eeapi2.id_key = '0' # ensure only one instance of the API has the endpoint template eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) self.core.add_api(self.eeapi) data = { 'id': text_type(uuid.uuid4()), 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual(json_body['itemNotFound']['message'], "Service API for endoint template not found") def test_existing_endpoint_template(self): """ POST does not overwrite an existing endpoint template, 409 is generated instead. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) data = { 'id': id_key, 'name': self.eeapi_name, 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "ID value is already assigned to an existing template") def test_new_endpoint_template_wrong_service_type(self): """ POST requires that the endpoint template and service have the same service types. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) data = { 'id': text_type(uuid.uuid4()), 'name': self.eeapi_name, 'type': 'some-type', 'region': 'some-region' } self.assertNotEqual(id_key, data['id']) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "Endpoint already exists or service type does not match.") @ddt.data(True, False) def test_new_endpoint_template(self, has_service_header): """ POST to add a endpoint template results in 201, service-id header is optional. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) eeapi2 = make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4())) eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) data = { 'id': text_type(uuid.uuid4()), 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } self.assertNotEqual(id_key, data['id']) if has_service_header: self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityOSKSCatalogAdminEndpointTemplatesAdd( SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/OS-KSCATALOG/endpointTemplates" self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"POST" @ddt.data( 'name', 'id', 'type', 'region' ) def test_json_body_missing_required_field(self, remove_field): """ POST - required fields must be present otherwise 400 is generated. """ data = { 'id': text_type(uuid.uuid4()), 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } del data[remove_field] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue( json_body['badRequest']['message'].startswith( "JSON body does not contain the required parameters:" ) ) def test_invalid_service_id_in_json_body(self): """ POST - Service ID must be valid, otherwise results in 404. """ # Add a second API eeapi2 = make_example_external_api( self, name='d' + self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4()) ) eeapi2.id_key = '0' # ensure only one instance of the API has the endpoint template eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) self.core.add_api(self.eeapi) data = { 'id': text_type(uuid.uuid4()), 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Service API for endoint template not found" ) def test_existing_endpoint_template(self): """ POST does not overwrite an existing endpoint template, 409 is generated instead. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) data = { 'id': id_key, 'name': self.eeapi_name, 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "ID value is already assigned to an existing template" ) def test_new_endpoint_template_wrong_service_type(self): """ POST requires that the endpoint template and service have the same service types. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) data = { 'id': text_type(uuid.uuid4()), 'name': self.eeapi_name, 'type': 'some-type', 'region': 'some-region' } self.assertNotEqual(id_key, data['id']) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "Endpoint already exists or service type does not match." ) @ddt.data( True, False ) def test_new_endpoint_template(self, has_service_header): """ POST to add a endpoint template results in 201, service-id header is optional. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) eeapi2 = make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4()) ) eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) data = { 'id': text_type(uuid.uuid4()), 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } self.assertNotEqual(id_key, data['id']) if has_service_header: self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityOSKSCatalogAdminEndpointTemplatesUpdate( SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"PUT" self.ept_template_id = get_template_id(self, self.eeapi) self.uri = ("/identity/v2.0/OS-KSCATALOG/endpointTemplates/" + self.ept_template_id) @ddt.data('id', 'name', 'type', 'region') def test_json_body_missing_required_field_name(self, remove_field): """ PUT - required fields must be present otherwise 400 is generated. """ data = { 'id': self.ept_template_id, 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } del data[remove_field] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue(json_body['badRequest']['message'].startswith( "JSON body does not contain the required parameters:")) def test_invalid_service_id_in_json_body(self): """ PUT requires that the service id map to an existing service, otherwise results in a 404. """ data = { 'id': self.ept_template_id, 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual(json_body['itemNotFound']['message'], "Service API for endoint template not found") def test_new_endpoint_template_wrong_service_type(self): """ PUT requires that the service matches, otherwise results in 409. """ self.core.add_api(self.eeapi) data = { 'id': self.ept_template_id, 'name': self.eeapi_name, 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "Endpoint already exists and service id or service type does not " "match.") def test_json_body_id_value_not_matching_url(self): """ PUT requires that the endpoint template id in the URL and JSON data match, otherwise results in 409. """ self.core.add_api(self.eeapi) eeapi2 = make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4())) eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) data = { 'id': 'some-random-key', 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "Template ID in URL does not match that of the JSON body") def test_invalid_template_id(self): """ PUT requires the endpoint template id to match an existing endpoint template, otherwise results in 404. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) self.eeapi.remove_template(id_key) data = { 'id': id_key, 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Unable to update non-existent template. Template must " "first be added before it can be updated.", ) @ddt.data(True, False) def test_update_endpoint_template(self, has_service_header): """ PUT to update an endpoint template results in 201, service-id header is optional. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) eeapi2 = make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4())) eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) data = { 'id': id_key, 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } if has_service_header: self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityOSKSCatalogAdminEndpointTemplatesList( SynchronousTestCase, IdentityAuthMixin, ServiceIdHeaderMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.uri = "/identity/v2.0/OS-KSCATALOG/endpointTemplates" self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"GET" def test_list_only_internal_apis_available(self): """ GET will return an empty listing when there are no External API endpoint templates. """ self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), 0) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0) def test_list_single_template(self): """ GET will return a endpoint template when there are External API endpoint templates. """ self.core.add_api(self.eeapi) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), 1) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0) def test_list_single_template_external_and_internal_apis(self): """ GET will only return the External API endpoint templates when they are available, even if there are also Internal APIs. """ self.core.add_api(self.eeapi) self.core.add_api(make_example_internal_api(self)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), 1) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0) def test_multiple_external_apis(self): """ GET can retrieve numerous External APIs that have External API Templates. """ api_list = [ make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4()) ) for ignored in range(10) ] # eeapi needs to be the first in the list api_list.insert(0, self.eeapi) for api in api_list: self.core.add_api(api) self.assertEqual(len(self.core._uuid_to_api_external), len(api_list)) (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, headers=self.headers)) self.assertEqual(response.code, 200) self.assertEqual(len(json_body['OS-KSCATALOG']), len(api_list)) self.assertEqual( len(json_body['OS-KSCATALOG:endpointsTemplates_links']), 0)
class TestIdentityOSKSCatalogAdminEndpointTemplatesUpdate( SynchronousTestCase, IdentityAuthMixin, InvalidJsonMixin): """ Tests for ``/identity/v2.0/OS-KSCATALOG/endpointTemplates``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api( self, name=self.eeapi_name, set_enabled=True ) self.headers = { b'X-Auth-Token': [b'ABCDEF987654321'] } self.verb = b"PUT" self.ept_template_id = get_template_id(self, self.eeapi) self.uri = ( "/identity/v2.0/OS-KSCATALOG/endpointTemplates/" + self.ept_template_id ) @ddt.data( 'id', 'name', 'type', 'region' ) def test_json_body_missing_required_field_name(self, remove_field): """ PUT - required fields must be present otherwise 400 is generated. """ data = { 'id': self.ept_template_id, 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } del data[remove_field] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 400) self.assertEqual(json_body['badRequest']['code'], 400) self.assertTrue( json_body['badRequest']['message'].startswith( "JSON body does not contain the required parameters:" ) ) def test_invalid_service_id_in_json_body(self): """ PUT requires that the service id map to an existing service, otherwise results in a 404. """ data = { 'id': self.ept_template_id, 'name': 'some-name', 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Service API for endoint template not found" ) def test_new_endpoint_template_wrong_service_type(self): """ PUT requires that the service matches, otherwise results in 409. """ self.core.add_api(self.eeapi) data = { 'id': self.ept_template_id, 'name': self.eeapi_name, 'type': 'some-type', 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "Endpoint already exists and service id or service type does not " "match." ) def test_json_body_id_value_not_matching_url(self): """ PUT requires that the endpoint template id in the URL and JSON data match, otherwise results in 409. """ self.core.add_api(self.eeapi) eeapi2 = make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4()) ) eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) data = { 'id': 'some-random-key', 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual( json_body['conflict']['message'], "Template ID in URL does not match that of the JSON body" ) def test_invalid_template_id(self): """ PUT requires the endpoint template id to match an existing endpoint template, otherwise results in 404. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) self.eeapi.remove_template(id_key) data = { 'id': id_key, 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual( json_body['itemNotFound']['message'], "Unable to update non-existent template. Template must " "first be added before it can be updated.", ) @ddt.data( True, False ) def test_update_endpoint_template(self, has_service_header): """ PUT to update an endpoint template results in 201, service-id header is optional. """ self.core.add_api(self.eeapi) id_key = get_template_id(self, self.eeapi) eeapi2 = make_example_external_api( self, name=self.eeapi_name + text_type(uuid.uuid4()), service_type='service-' + text_type(uuid.uuid4()) ) eeapi2.remove_template(get_template_id(self, eeapi2)) self.core.add_api(eeapi2) data = { 'id': id_key, 'name': self.eeapi_name, 'type': self.eeapi.type_key, 'region': 'some-region' } if has_service_header: self.headers[b'serviceid'] = [self.eeapi.uuid_key.encode('utf8')] req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 201)
class TestIdentityMimicOSKSCatalogAdminDeleteExternalService( SynchronousTestCase, IdentityAuthMixin): """ Tests for ``/identity/v2.0/services/<service-id>``, provided by :obj:`mimic.rest.idenity_api.IdentityApi` """ def setUp(self): self.core = MimicCore(Clock(), []) self.root = MimicRoot(self.core).app.resource() self.eeapi_id = u"some-id" self.uri = "/identity/v2.0/services/" + self.eeapi_id self.eeapi_name = u"externalServiceName" self.eeapi = make_example_external_api(self, name=self.eeapi_name, set_enabled=True) self.eeapi2 = make_example_external_api(self, name=self.eeapi_name + " alternate") self.eeapi.uuid_key = self.eeapi_id self.headers = {b'X-Auth-Token': [b'ABCDEF987654321']} self.verb = b"DELETE" def test_invalid_service(self): """ DELETE an unknown service will generate a 404. """ data = {'name': 'some-name', 'type': 'some-type', 'id': 'some-id'} (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 404) self.assertEqual(json_body['itemNotFound']['code'], 404) self.assertEqual(json_body['itemNotFound']['message'], "Service not found. Unable to remove.") def test_service_has_template(self): """ DELETE a service that still has a template results in 409. """ self.core.add_api(self.eeapi) data = { 'name': self.eeapi.name_key, 'type': self.eeapi.type_key, 'id': self.eeapi.uuid_key } (response, json_body) = self.successResultOf( json_request(self, self.root, self.verb, self.uri, body=data, headers=self.headers)) self.assertEqual(response.code, 409) self.assertEqual(json_body['conflict']['code'], 409) self.assertEqual(json_body['conflict']['message'], "Service still has endpoint templates.") def test_remove_service(self): """ DELETE a service. """ templates_to_remove = list(self.eeapi.endpoint_templates.keys()) for template_id in templates_to_remove: self.eeapi.remove_template(template_id) self.core.add_api(self.eeapi) self.core.add_api(self.eeapi2) data = { 'name': self.eeapi.name_key, 'type': self.eeapi.type_key, 'id': self.eeapi.uuid_key } req = request(self, self.root, self.verb, self.uri, body=json.dumps(data).encode("utf-8"), headers=self.headers) response = self.successResultOf(req) self.assertEqual(response.code, 204)