Add "list versions" test for Keystone
"list versions" is an inportant API to know which versions are supported on clouds. This patch adds the corresponding test for Keystone API. Change-Id: Ic4aaa16ac1c15d2b82e3dc90402a5b30d19bcd4e
This commit is contained in:

committed by
Ken'ichi Ohmichi

parent
5e1543f753
commit
da26b16874
@@ -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.
|
@@ -171,6 +171,7 @@ class BaseIdentityV3Test(BaseIdentityTest):
|
||||
cls.non_admin_users_client = cls.os.users_v3_client
|
||||
cls.non_admin_token = cls.os.token_v3_client
|
||||
cls.non_admin_projects_client = cls.os.projects_client
|
||||
cls.non_admin_versions_client = cls.os.identity_versions_v3_client
|
||||
|
||||
|
||||
class BaseIdentityV3AdminTest(BaseIdentityV3Test):
|
||||
|
@@ -21,6 +21,20 @@ from tempest import test
|
||||
class TestApiDiscovery(base.BaseIdentityV3Test):
|
||||
"""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')
|
||||
@decorators.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
|
||||
def test_api_version_resources(self):
|
||||
|
@@ -225,6 +225,8 @@ class Manager(clients.ServiceClients):
|
||||
self.credentials_client = self.identity_v3.CredentialsClient(
|
||||
**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.
|
||||
# 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_serialization import jsonutils as json
|
||||
import six
|
||||
from six.moves import urllib
|
||||
|
||||
from tempest.lib.common import http
|
||||
from tempest.lib.common import jsonschema_validator
|
||||
@@ -915,6 +916,16 @@ class RestClient(object):
|
||||
msg = ("HTTP response header is invalid (%s)" % ex)
|
||||
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 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
|
||||
# under the License.
|
||||
|
||||
import re
|
||||
|
||||
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.common import rest_client
|
||||
@@ -24,19 +21,6 @@ from tempest.lib.services.compute import base_compute_client
|
||||
|
||||
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):
|
||||
version_url = self._get_base_version_url()
|
||||
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.trusts_client import TrustsClient
|
||||
from tempest.lib.services.identity.v3.users_client import UsersClient
|
||||
from tempest.lib.services.identity.v3.versions_client import VersionsClient
|
||||
|
||||
__all__ = ['CredentialsClient', 'DomainsClient', 'EndPointsClient',
|
||||
'GroupsClient', 'IdentityClient', 'InheritedRolesClient',
|
||||
'PoliciesClient', 'ProjectsClient', 'RegionsClient',
|
||||
'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