From 1c5f3e256fc730675966d597213bed488cb77598 Mon Sep 17 00:00:00 2001 From: Dolph Mathews Date: Tue, 28 Feb 2012 17:00:26 -0600 Subject: GET /v2.0 (bug 930321) Change-Id: Ide2a6073a0a54e017d1fcb8d9065ec6f348e07cd --- keystone/service.py | 90 ++++++++++++++++++++++++++++----------------- tests/test_content_types.py | 84 ++++++++++++++++++++++++------------------ 2 files changed, 106 insertions(+), 68 deletions(-) diff --git a/keystone/service.py b/keystone/service.py index 4f934ec21..d0d447057 100644 --- a/keystone/service.py +++ b/keystone/service.py @@ -34,6 +34,11 @@ class AdminRouter(wsgi.ComposingRouter): def __init__(self): mapper = routes.Mapper() + version_controller = VersionController('admin') + mapper.connect('/', + controller=version_controller, + action='get_version') + # Token Operations auth_controller = TokenController() mapper.connect('/tokens', @@ -76,10 +81,10 @@ class PublicRouter(wsgi.ComposingRouter): def __init__(self): mapper = routes.Mapper() - noop_controller = NoopController() + version_controller = VersionController('public') mapper.connect('/', - controller=noop_controller, - action='noop') + controller=version_controller, + action='get_version') # Token Operations auth_controller = TokenController() @@ -131,6 +136,7 @@ class VersionController(wsgi.Application): def __init__(self, version_type): self.catalog_api = catalog.Manager() self.url_key = "%sURL" % version_type + super(VersionController, self).__init__() def _get_identity_url(self, context): @@ -145,45 +151,63 @@ class VersionController(wsgi.Application): raise NotImplementedError() - def get_versions(self, context): + def _get_versions_list(self, context): + """The list of versions is dependent on the context.""" identity_url = self._get_identity_url(context) if not identity_url.endswith('/'): identity_url = identity_url + '/' + versions = {} + versions['v2.0'] = { + "id": "v2.0", + "status": "beta", + "updated": "2011-11-19T00:00:00Z", + "links": [ + { + "rel": "self", + "href": identity_url, + }, { + "rel": "describedby", + "type": "text/html", + "href": "http://docs.openstack.org/api/openstack-" + "identity-service/2.0/content/" + }, { + "rel": "describedby", + "type": "application/pdf", + "href": "http://docs.openstack.org/api/openstack-" + "identity-service/2.0/identity-dev-guide-" + "2.0.pdf" + } + ], + "media-types": [ + { + "base": "application/json", + "type": "application/vnd.openstack.identity-v2.0" + "+json" + }, { + "base": "application/xml", + "type": "application/vnd.openstack.identity-v2.0" + "+xml" + } + ] + } + + return versions + + def get_versions(self, context): + versions = self._get_versions_list(context) return wsgi.render_response(status=(300, 'Multiple Choices'), body={ "versions": { - "values": [{ - "id": "v2.0", - "status": "beta", - "updated": "2011-11-19T00:00:00Z", - "links": [{ - "rel": "self", - "href": identity_url, - }, { - "rel": "describedby", - "type": "text/html", - "href": "http://docs.openstack.org/api/openstack-" - "identity-service/2.0/content/" - }, { - "rel": "describedby", - "type": "application/pdf", - "href": "http://docs.openstack.org/api/openstack-" - "identity-service/2.0/identity-dev-guide-" - "2.0.pdf" - }], - "media-types": [{ - "base": "application/json", - "type": "application/vnd.openstack.identity-v2.0" - "+json" - }, { - "base": "application/xml", - "type": "application/vnd.openstack.identity-v2.0" - "+xml" - }] - }] + "values": versions.values() } }) + def get_version(self, context): + versions = self._get_versions_list(context) + return wsgi.render_response(body={ + "version": versions['v2.0'] + }) + class NoopController(wsgi.Application): def __init__(self): diff --git a/tests/test_content_types.py b/tests/test_content_types.py index 6dd8a4d3c..b98ae7733 100644 --- a/tests/test_content_types.py +++ b/tests/test_content_types.py @@ -241,6 +241,18 @@ class CoreApiTests(object): self.assertIsNotNone(error.get('title')) self.assertIsNotNone(error.get('message')) + def assertValidVersion(self, version): + """Applicable to XML and JSON. + + However, navigating links and media-types differs between content + types so they need to be validated seperately. + + """ + self.assertIsNotNone(version) + self.assertIsNotNone(version.get('id')) + self.assertIsNotNone(version.get('status')) + self.assertIsNotNone(version.get('updated')) + def assertValidExtension(self, extension): """Applicable to XML and JSON. @@ -284,14 +296,10 @@ class CoreApiTests(object): self.assertValidMultipleChoiceResponse(r) def test_public_version(self): - raise nose.exc.SkipTest('Blocked by bug 925548') - r = self.public_request(path='/v2.0/') self.assertValidVersionResponse(r) def test_admin_version(self): - raise nose.exc.SkipTest('Blocked by bug 925548') - r = self.admin_request(path='/v2.0/') self.assertValidVersionResponse(r) @@ -495,27 +503,30 @@ class JsonTestCase(RestfulTestCase, CoreApiTests): for role in r.body['roles']: self.assertValidRole(role) + def assertValidVersion(self, version): + super(JsonTestCase, self).assertValidVersion(version) + + self.assertIsNotNone(version.get('links')) + self.assertTrue(len(version.get('links'))) + for link in version.get('links'): + self.assertIsNotNone(link.get('rel')) + self.assertIsNotNone(link.get('href')) + + self.assertIsNotNone(version.get('media-types')) + self.assertTrue(len(version.get('media-types'))) + for media in version.get('media-types'): + self.assertIsNotNone(media.get('base')) + self.assertIsNotNone(media.get('type')) + def assertValidMultipleChoiceResponse(self, r): self.assertIsNotNone(r.body.get('versions')) self.assertIsNotNone(r.body['versions'].get('values')) self.assertTrue(len(r.body['versions']['values'])) for version in r.body['versions']['values']: - self.assertIsNotNone(version.get('id')) - self.assertIsNotNone(version.get('status')) - self.assertIsNotNone(version.get('updated')) - self.assertIsNotNone(version.get('links')) - self.assertTrue(len(version.get('links'))) - for link in version.get('links'): - self.assertIsNotNone(link.get('rel')) - self.assertIsNotNone(link.get('href')) - self.assertIsNotNone(version.get('media-types')) - self.assertTrue(len(version.get('media-types'))) - for media in version.get('media-types'): - self.assertIsNotNone(media.get('base')) - self.assertIsNotNone(media.get('type')) + self.assertValidVersion(version) def assertValidVersionResponse(self, r): - raise NotImplementedError() + self.assertValidVersion(r.body.get('version')) class XmlTestCase(RestfulTestCase, CoreApiTests): @@ -559,31 +570,34 @@ class XmlTestCase(RestfulTestCase, CoreApiTests): self.assertValidExtension(xml) + def assertValidVersion(self, version): + super(XmlTestCase, self).assertValidVersion(version) + + self.assertTrue(len(version.findall(self._tag('link')))) + for link in version.findall(self._tag('link')): + self.assertIsNotNone(link.get('rel')) + self.assertIsNotNone(link.get('href')) + + media_types = version.find(self._tag('media-types')) + self.assertIsNotNone(media_types) + self.assertTrue(len(media_types.findall(self._tag('media-type')))) + for media in media_types.findall(self._tag('media-type')): + self.assertIsNotNone(media.get('base')) + self.assertIsNotNone(media.get('type')) + def assertValidMultipleChoiceResponse(self, r): xml = r.body self.assertEqual(xml.tag, self._tag('versions')) self.assertTrue(len(xml.findall(self._tag('version')))) for version in xml.findall(self._tag('version')): - # validate service endpoint - self.assertIsNotNone(version.get('id')) - self.assertIsNotNone(version.get('status')) - self.assertIsNotNone(version.get('updated')) - - self.assertTrue(len(version.findall(self._tag('link')))) - for link in version.findall(self._tag('link')): - self.assertIsNotNone(link.get('rel')) - self.assertIsNotNone(link.get('href')) - - media_types = version.find(self._tag('media-types')) - self.assertIsNotNone(media_types) - self.assertTrue(len(media_types.findall(self._tag('media-type')))) - for media in media_types.findall(self._tag('media-type')): - self.assertIsNotNone(media.get('base')) - self.assertIsNotNone(media.get('type')) + self.assertValidVersion(version) def assertValidVersionResponse(self, r): - raise NotImplementedError() + xml = r.body + self.assertEqual(xml.tag, self._tag('version')) + + self.assertValidVersion(xml) def assertValidTokenCatalogResponse(self, r): xml = r.body -- cgit v1.2.1