Merge "Add "list versions" test for Keystone"
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add versions_client module for identity service.
|
||||||
|
This new module provides list_versions() method which shows API versions
|
||||||
|
from Identity service.
|
@@ -178,6 +178,7 @@ class BaseIdentityV3Test(BaseIdentityTest):
|
|||||||
cls.non_admin_users_client = cls.os.users_v3_client
|
cls.non_admin_users_client = cls.os.users_v3_client
|
||||||
cls.non_admin_token = cls.os.token_v3_client
|
cls.non_admin_token = cls.os.token_v3_client
|
||||||
cls.non_admin_projects_client = cls.os.projects_client
|
cls.non_admin_projects_client = cls.os.projects_client
|
||||||
|
cls.non_admin_versions_client = cls.os.identity_versions_v3_client
|
||||||
|
|
||||||
|
|
||||||
class BaseIdentityV3AdminTest(BaseIdentityV3Test):
|
class BaseIdentityV3AdminTest(BaseIdentityV3Test):
|
||||||
|
@@ -21,6 +21,20 @@ from tempest import test
|
|||||||
class TestApiDiscovery(base.BaseIdentityV3Test):
|
class TestApiDiscovery(base.BaseIdentityV3Test):
|
||||||
"""Tests for API discovery features."""
|
"""Tests for API discovery features."""
|
||||||
|
|
||||||
|
@decorators.idempotent_id('721f480f-35b6-46c7-846e-047e6acea0dc')
|
||||||
|
@test.attr(type='smoke')
|
||||||
|
def test_list_api_versions(self):
|
||||||
|
# NOTE: Actually this API doesn't depend on v3 API at all, because
|
||||||
|
# the API operation is "GET /" without v3's endpoint. The reason of
|
||||||
|
# this test path is just v3 API is CURRENT on Keystone side.
|
||||||
|
versions = self.non_admin_versions_client.list_versions()
|
||||||
|
expected_resources = ('id', 'links', 'media-types', 'status',
|
||||||
|
'updated')
|
||||||
|
|
||||||
|
for version in versions['versions']["values"]:
|
||||||
|
for res in expected_resources:
|
||||||
|
self.assertIn(res, version)
|
||||||
|
|
||||||
@test.attr(type='smoke')
|
@test.attr(type='smoke')
|
||||||
@decorators.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
|
@decorators.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
|
||||||
def test_api_version_resources(self):
|
def test_api_version_resources(self):
|
||||||
|
@@ -225,6 +225,8 @@ class Manager(clients.ServiceClients):
|
|||||||
self.credentials_client = self.identity_v3.CredentialsClient(
|
self.credentials_client = self.identity_v3.CredentialsClient(
|
||||||
**params_v3)
|
**params_v3)
|
||||||
self.groups_client = self.identity_v3.GroupsClient(**params_v3)
|
self.groups_client = self.identity_v3.GroupsClient(**params_v3)
|
||||||
|
self.identity_versions_v3_client = self.identity_v3.VersionsClient(
|
||||||
|
**params_v3)
|
||||||
|
|
||||||
# Token clients do not use the catalog. They only need default_params.
|
# Token clients do not use the catalog. They only need default_params.
|
||||||
# They read auth_url, so they should only be set if the corresponding
|
# They read auth_url, so they should only be set if the corresponding
|
||||||
|
@@ -23,6 +23,7 @@ import jsonschema
|
|||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_serialization import jsonutils as json
|
from oslo_serialization import jsonutils as json
|
||||||
import six
|
import six
|
||||||
|
from six.moves import urllib
|
||||||
|
|
||||||
from tempest.lib.common import http
|
from tempest.lib.common import http
|
||||||
from tempest.lib.common import jsonschema_validator
|
from tempest.lib.common import jsonschema_validator
|
||||||
@@ -915,6 +916,16 @@ class RestClient(object):
|
|||||||
msg = ("HTTP response header is invalid (%s)" % ex)
|
msg = ("HTTP response header is invalid (%s)" % ex)
|
||||||
raise exceptions.InvalidHTTPResponseHeader(msg)
|
raise exceptions.InvalidHTTPResponseHeader(msg)
|
||||||
|
|
||||||
|
def _get_base_version_url(self):
|
||||||
|
# TODO(oomichi): This method can be used for auth's replace_version().
|
||||||
|
# So it is nice to have common logic for the maintenance.
|
||||||
|
endpoint = self.base_url
|
||||||
|
url = urllib.parse.urlsplit(endpoint)
|
||||||
|
new_path = re.split(r'(^|/)+v\d+(\.\d+)?', url.path)[0]
|
||||||
|
url = list(url)
|
||||||
|
url[2] = new_path + '/'
|
||||||
|
return urllib.parse.urlunsplit(url)
|
||||||
|
|
||||||
|
|
||||||
class ResponseBody(dict):
|
class ResponseBody(dict):
|
||||||
"""Class that wraps an http response and dict body into a single value.
|
"""Class that wraps an http response and dict body into a single value.
|
||||||
|
@@ -12,10 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from oslo_serialization import jsonutils as json
|
from oslo_serialization import jsonutils as json
|
||||||
from six.moves import urllib
|
|
||||||
|
|
||||||
from tempest.lib.api_schema.response.compute.v2_1 import versions as schema
|
from tempest.lib.api_schema.response.compute.v2_1 import versions as schema
|
||||||
from tempest.lib.common import rest_client
|
from tempest.lib.common import rest_client
|
||||||
@@ -24,19 +21,6 @@ from tempest.lib.services.compute import base_compute_client
|
|||||||
|
|
||||||
class VersionsClient(base_compute_client.BaseComputeClient):
|
class VersionsClient(base_compute_client.BaseComputeClient):
|
||||||
|
|
||||||
def _get_base_version_url(self):
|
|
||||||
# NOTE: The URL which is got from keystone's catalog contains
|
|
||||||
# API version and project-id like "/app-name/v2/{project-id}" or
|
|
||||||
# "/v2/{project-id}", but we need to access the URL which doesn't
|
|
||||||
# contain API version for getting API versions. For that, here
|
|
||||||
# should use raw_request() instead of get().
|
|
||||||
endpoint = self.base_url
|
|
||||||
url = urllib.parse.urlsplit(endpoint)
|
|
||||||
new_path = re.split(r'(^|/)+v\d+(\.\d+)?', url.path)[0]
|
|
||||||
url = list(url)
|
|
||||||
url[2] = new_path + '/'
|
|
||||||
return urllib.parse.urlunsplit(url)
|
|
||||||
|
|
||||||
def list_versions(self):
|
def list_versions(self):
|
||||||
version_url = self._get_base_version_url()
|
version_url = self._get_base_version_url()
|
||||||
resp, body = self.raw_request(version_url, 'GET')
|
resp, body = self.raw_request(version_url, 'GET')
|
||||||
|
@@ -30,9 +30,10 @@ from tempest.lib.services.identity.v3.services_client import ServicesClient
|
|||||||
from tempest.lib.services.identity.v3.token_client import V3TokenClient
|
from tempest.lib.services.identity.v3.token_client import V3TokenClient
|
||||||
from tempest.lib.services.identity.v3.trusts_client import TrustsClient
|
from tempest.lib.services.identity.v3.trusts_client import TrustsClient
|
||||||
from tempest.lib.services.identity.v3.users_client import UsersClient
|
from tempest.lib.services.identity.v3.users_client import UsersClient
|
||||||
|
from tempest.lib.services.identity.v3.versions_client import VersionsClient
|
||||||
|
|
||||||
__all__ = ['CredentialsClient', 'DomainsClient', 'EndPointsClient',
|
__all__ = ['CredentialsClient', 'DomainsClient', 'EndPointsClient',
|
||||||
'GroupsClient', 'IdentityClient', 'InheritedRolesClient',
|
'GroupsClient', 'IdentityClient', 'InheritedRolesClient',
|
||||||
'PoliciesClient', 'ProjectsClient', 'RegionsClient',
|
'PoliciesClient', 'ProjectsClient', 'RegionsClient',
|
||||||
'RoleAssignmentsClient', 'RolesClient', 'ServicesClient',
|
'RoleAssignmentsClient', 'RolesClient', 'ServicesClient',
|
||||||
'V3TokenClient', 'TrustsClient', 'UsersClient', ]
|
'V3TokenClient', 'TrustsClient', 'UsersClient', 'VersionsClient']
|
||||||
|
38
tempest/lib/services/identity/v3/versions_client.py
Normal file
38
tempest/lib/services/identity/v3/versions_client.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Copyright 2017 NEC Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
from oslo_serialization import jsonutils as json
|
||||||
|
|
||||||
|
from tempest.lib.common import rest_client
|
||||||
|
|
||||||
|
|
||||||
|
class VersionsClient(rest_client.RestClient):
|
||||||
|
api_version = "v3"
|
||||||
|
|
||||||
|
def list_versions(self):
|
||||||
|
"""List API versions"""
|
||||||
|
version_url = self._get_base_version_url()
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
|
resp, body = self.raw_request(version_url, 'GET')
|
||||||
|
end = time.time()
|
||||||
|
self._log_request('GET', version_url, resp, secs=(end - start),
|
||||||
|
resp_body=body)
|
||||||
|
self._error_checker(resp, body)
|
||||||
|
|
||||||
|
self.expected_success(300, resp.status)
|
||||||
|
body = json.loads(body)
|
||||||
|
return rest_client.ResponseBody(resp, body)
|
@@ -0,0 +1,70 @@
|
|||||||
|
# Copyright 2017 NEC Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from tempest.lib.services.identity.v3 import versions_client
|
||||||
|
from tempest.tests.lib import fake_auth_provider
|
||||||
|
from tempest.tests.lib.services import base
|
||||||
|
|
||||||
|
|
||||||
|
class TestIdentityClient(base.BaseServiceTest):
|
||||||
|
|
||||||
|
FAKE_VERSIONS_INFO = {
|
||||||
|
"versions": {
|
||||||
|
"values": [
|
||||||
|
{"status": "stable", "updated": "2017-02-22T00:00:00Z",
|
||||||
|
"media-types": [
|
||||||
|
{"base": "application/json", "type":
|
||||||
|
"application/vnd.openstack.identity-v3+json"}
|
||||||
|
],
|
||||||
|
"id": "v3.8",
|
||||||
|
"links": [
|
||||||
|
{"href": "https://15.184.67.226/identity_admin/v3/",
|
||||||
|
"rel": "self"}
|
||||||
|
]},
|
||||||
|
{"status": "deprecated", "updated": "2016-08-04T00:00:00Z",
|
||||||
|
"media-types": [
|
||||||
|
{"base": "application/json",
|
||||||
|
"type": "application/vnd.openstack.identity-v2.0+json"}
|
||||||
|
],
|
||||||
|
"id": "v2.0",
|
||||||
|
"links": [
|
||||||
|
{"href": "https://15.184.67.226/identity_admin/v2.0/",
|
||||||
|
"rel": "self"},
|
||||||
|
{"href": "https://docs.openstack.org/",
|
||||||
|
"type": "text/html", "rel": "describedby"}
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestIdentityClient, self).setUp()
|
||||||
|
fake_auth = fake_auth_provider.FakeAuthProvider()
|
||||||
|
self.client = versions_client.VersionsClient(fake_auth,
|
||||||
|
'identity',
|
||||||
|
'regionOne')
|
||||||
|
|
||||||
|
def _test_list_versions(self, bytes_body=False):
|
||||||
|
self.check_service_client_function(
|
||||||
|
self.client.list_versions,
|
||||||
|
'tempest.lib.common.rest_client.RestClient.raw_request',
|
||||||
|
self.FAKE_VERSIONS_INFO,
|
||||||
|
bytes_body,
|
||||||
|
300)
|
||||||
|
|
||||||
|
def test_list_versions_with_str_body(self):
|
||||||
|
self._test_list_versions()
|
||||||
|
|
||||||
|
def test_list_versions_with_bytes_body(self):
|
||||||
|
self._test_list_versions(bytes_body=True)
|
Reference in New Issue
Block a user