Merge "Add test namespace object functions in images"

This commit is contained in:
Jenkins 2017-01-05 23:16:56 +00:00 committed by Gerrit Code Review
commit 051ebd06b0
7 changed files with 391 additions and 2 deletions

@ -0,0 +1,9 @@
---
features:
- |
As in the [doc]:
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html,
there are some apis are not included, add them.
* namespace_objects_client(v2)

@ -142,6 +142,7 @@ class BaseV2ImageTest(BaseImageTest):
cls.namespaces_client = cls.os.namespaces_client
cls.resource_types_client = cls.os.resource_types_client
cls.namespace_properties_client = cls.os.namespace_properties_client
cls.namespace_objects_client = cls.os.namespace_objects_client
cls.schemas_client = cls.os.schemas_client
def create_namespace(cls, namespace_name=None, visibility='public',

@ -0,0 +1,73 @@
# 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.api.image import base
from tempest.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest import test
class MetadataNamespaceObjectsTest(base.BaseV2ImageTest):
"""Test the Metadata definition namespace objects basic functionality"""
def _create_namespace_object(self, namespace):
object_name = data_utils.rand_name(self.__class__.__name__ + '-object')
namespace_object = self.namespace_objects_client.\
create_namespace_object(namespace['namespace'], name=object_name)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.namespace_objects_client.delete_namespace_object,
namespace['namespace'], object_name)
return namespace_object
@test.idempotent_id('b1a3775e-3b5c-4f6a-a3b4-1ba3574ae718')
def test_create_update_delete_meta_namespace_objects(self):
# Create a namespace
namespace = self.create_namespace()
# Create a namespace object
body = self._create_namespace_object(namespace)
# Update a namespace object
up_object_name = data_utils.rand_name('update-object')
body = self.namespace_objects_client.update_namespace_object(
namespace['namespace'], body['name'],
name=up_object_name)
self.assertEqual(up_object_name, body['name'])
# Delete a namespace object
self.namespace_objects_client.delete_namespace_object(
namespace['namespace'], up_object_name)
# List namespace objects and validate deletion
namespace_objects = [
namespace_object['name'] for namespace_object in
self.namespace_objects_client.list_namespace_objects(
namespace['namespace'])['objects']]
self.assertNotIn(up_object_name, namespace_objects)
@test.idempotent_id('a2a3615e-3b5c-3f6a-a2b1-1ba3574ae738')
def test_list_meta_namespace_objects(self):
# Create a namespace object
namespace = self.create_namespace()
meta_namespace_object = self._create_namespace_object(namespace)
# List namespace objects
namespace_objects = [
namespace_object['name'] for namespace_object in
self.namespace_objects_client.list_namespace_objects(
namespace['namespace'])['objects']]
self.assertIn(meta_namespace_object['name'], namespace_objects)
@test.idempotent_id('b1a3674e-3b4c-3f6a-a3b4-1ba3573ca768')
def test_show_meta_namespace_objects(self):
# Create a namespace object
namespace = self.create_namespace()
namespace_object = self._create_namespace_object(namespace)
# Show a namespace object
body = self.namespace_objects_client.show_namespace_object(
namespace['namespace'], namespace_object['name'])
self.assertEqual(namespace_object['name'], body['name'])

@ -127,6 +127,8 @@ class Manager(clients.ServiceClients):
self.image_member_client_v2 = self.image_v2.ImageMembersClient()
self.namespaces_client = self.image_v2.NamespacesClient()
self.resource_types_client = self.image_v2.ResourceTypesClient()
self.namespace_objects_client = \
self.image_v2.NamespaceObjectsClient()
self.schemas_client = self.image_v2.SchemasClient()
self.namespace_properties_client = \
self.image_v2.NamespacePropertiesClient()

@ -15,6 +15,8 @@
from tempest.lib.services.image.v2.image_members_client import \
ImageMembersClient
from tempest.lib.services.image.v2.images_client import ImagesClient
from tempest.lib.services.image.v2.namespace_objects_client import \
NamespaceObjectsClient
from tempest.lib.services.image.v2.namespace_properties_client import \
NamespacePropertiesClient
from tempest.lib.services.image.v2.namespaces_client import NamespacesClient
@ -22,5 +24,6 @@ from tempest.lib.services.image.v2.resource_types_client import \
ResourceTypesClient
from tempest.lib.services.image.v2.schemas_client import SchemasClient
__all__ = ['ImageMembersClient', 'ImagesClient', 'NamespacePropertiesClient',
'NamespacesClient', 'ResourceTypesClient', 'SchemasClient']
__all__ = ['ImageMembersClient', 'ImagesClient', 'NamespaceObjectsClient',
'NamespacePropertiesClient', 'NamespacesClient',
'ResourceTypesClient', 'SchemasClient']

@ -0,0 +1,91 @@
# Copyright 2016 EasyStack.
# 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 oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.lib.common import rest_client
class NamespaceObjectsClient(rest_client.RestClient):
api_version = "v2"
def list_namespace_objects(self, namespace, **kwargs):
"""Lists all namespace objects.
For a full list of available parameters, please refer to the official
API reference:
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-objects
"""
url = 'metadefs/namespaces/%s/objects' % namespace
if kwargs:
url += '?%s' % urllib.urlencode(kwargs)
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def create_namespace_object(self, namespace, **kwargs):
"""Create a namespace object
For a full list of available parameters, please refer to the official
API reference:
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-object
"""
url = 'metadefs/namespaces/%s/objects' % namespace
data = json.dumps(kwargs)
resp, body = self.post(url, data)
self.expected_success(201, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def update_namespace_object(self, namespace, object_name, **kwargs):
"""Update a namespace object
For a full list of available parameters, please refer to the official
API reference:
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-object
"""
url = 'metadefs/namespaces/%s/objects/%s' % (namespace, object_name)
data = json.dumps(kwargs)
resp, body = self.put(url, data)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def show_namespace_object(self, namespace, object_name):
"""Show a namespace object
For a full list of available parameters, please refer to the official
API reference:
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#show-object
"""
url = 'metadefs/namespaces/%s/objects/%s' % (namespace, object_name)
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def delete_namespace_object(self, namespace, object_name):
"""Delete a namespace object
For a full list of available parameters, please refer to the official
API reference:
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-object
"""
url = 'metadefs/namespaces/%s/objects/%s' % (namespace, object_name)
resp, _ = self.delete(url)
self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp)

@ -0,0 +1,210 @@
# Copyright 2016 EasyStack. 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.image.v2 import namespace_objects_client
from tempest.tests.lib import fake_auth_provider
from tempest.tests.lib.services import base
class TestNamespaceObjectClient(base.BaseServiceTest):
FAKE_CREATE_SHOW_OBJECTS = {
"created_at": "2016-09-19T18:20:56Z",
"description": "You can configure the CPU limits.",
"name": "CPU Limits",
"properties": {
"quota:cpu_period": {
"description": "Specifies the enforcement interval",
"maximum": 1000000,
"minimum": 1000,
"title": "Quota: CPU Period",
"type": "integer"
},
"quota:cpu_quota": {
"description": "Specifies the maximum allowed bandwidth ",
"title": "Quota: CPU Quota",
"type": "integer"
},
"quota:cpu_shares": {
"description": "Specifies the proportional weighted share.",
"title": "Quota: CPU Shares",
"type": "integer"
}
},
"required": [],
"schema": "/v2/schemas/metadefs/object",
"self": "/v2/metadefs/namespaces/OS::Compute::Quota/objects/CPU",
"updated_at": "2016-09-19T18:20:56Z"
}
FAKE_LIST_OBJECTS = {
"objects": [
{
"created_at": "2016-09-18T18:16:35Z",
"description": "You can configure the CPU limits.",
"name": "CPU Limits",
"properties": {
"quota:cpu_period": {
"description": "Specifies the enforcement interval ",
"maximum": 1000000,
"minimum": 1000,
"title": "Quota: CPU Period",
"type": "integer"
},
"quota:cpu_quota": {
"description": "Specifies the maximum.",
"title": "Quota: CPU Quota",
"type": "integer"
},
"quota:cpu_shares": {
"description": " Desc.",
"title": "Quota: CPU Shares",
"type": "integer"
}
},
"required": [],
"schema": "/v2/schemas/metadefs/object",
"self":
"/v2/metadefs/namespaces/OS::Compute::Quota/objects/CPU"
},
{
"created_at": "2016-09-18T18:16:35Z",
"description": "Using disk I/O quotas.",
"name": "Disk QoS",
"properties": {
"quota:disk_read_bytes_sec": {
"description": "Sets disk I/O quota.",
"title": "Quota: Disk read bytes / sec",
"type": "integer"
},
"quota:disk_read_iops_sec": {
"description": "Sets disk I/O quota",
"title": "Quota: Disk read IOPS / sec",
"type": "integer"
},
"quota:disk_total_bytes_sec": {
"description": "Sets disk I/O quota.",
"title": "Quota: Disk Total Bytes / sec",
"type": "integer"
},
"quota:disk_total_iops_sec": {
"description": "Sets disk I/O quota.",
"title": "Quota: Disk Total IOPS / sec",
"type": "integer"
},
"quota:disk_write_bytes_sec": {
"description": "Sets disk I/O quota.",
"title": "Quota: Disk Write Bytes / sec",
"type": "integer"
},
"quota:disk_write_iops_sec": {
"description": "Sets disk I/O quota.",
"title": "Quota: Disk Write IOPS / sec",
"type": "integer"
}
},
"required": [],
"schema": "/v2/schemas/metadefs/object",
"self":
"/v2/metadefs/namespaces/OS::Compute::Quota/objects/Disk QoS"
},
],
"schema": "v2/schemas/metadefs/objects"
}
FAKE_UPDATE_OBJECTS = {
"description": "You can configure the CPU limits.",
"name": "CPU",
"properties": {
"quota:cpu_shares": {
"description": "Specify.",
"title": "Quota: CPU Shares",
"type": "integer"
}
},
"required": []
}
def setUp(self):
super(TestNamespaceObjectClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
self.client = namespace_objects_client.NamespaceObjectsClient(
fake_auth, 'image', 'regionOne')
def _test_create_namespace_objects(self, bytes_body=False):
self.check_service_client_function(
self.client.create_namespace_object,
'tempest.lib.common.rest_client.RestClient.post',
self.FAKE_CREATE_SHOW_OBJECTS,
bytes_body, status=201,
namespace="OS::Compute::Hypervisor",
object_name="OS::Glance::Image")
def _test_list_namespace_objects(self, bytes_body=False):
self.check_service_client_function(
self.client.list_namespace_objects,
'tempest.lib.common.rest_client.RestClient.get',
self.FAKE_LIST_OBJECTS,
bytes_body,
namespace="OS::Compute::Hypervisor")
def _test_show_namespace_objects(self, bytes_body=False):
self.check_service_client_function(
self.client.show_namespace_object,
'tempest.lib.common.rest_client.RestClient.get',
self.FAKE_CREATE_SHOW_OBJECTS,
bytes_body,
namespace="OS::Compute::Hypervisor",
object_name="OS::Glance::Image")
def _test_update_namespace_objects(self, bytes_body=False):
self.check_service_client_function(
self.client.update_namespace_object,
'tempest.lib.common.rest_client.RestClient.put',
self.FAKE_UPDATE_OBJECTS,
bytes_body,
namespace="OS::Compute::Hypervisor",
object_name="OS::Glance::Image",
name="CPU")
def test_create_namespace_object_with_str_body(self):
self._test_create_namespace_objects()
def test_create_namespace_object_with_bytes_body(self):
self._test_create_namespace_objects(bytes_body=True)
def test_list_namespace_object_with_str_body(self):
self._test_list_namespace_objects()
def test_list_namespace_object_with_bytes_body(self):
self._test_list_namespace_objects(bytes_body=True)
def test_show_namespace_object_with_str_body(self):
self._test_show_namespace_objects()
def test_show_namespace_object_with_bytes_body(self):
self._test_show_namespace_objects(bytes_body=True)
def test_update_namespace_object_with_str_body(self):
self._test_update_namespace_objects()
def test_update_namespace_object_with_bytes_body(self):
self._test_update_namespace_objects(bytes_body=True)
def test_delete_namespace_objects(self):
self.check_service_client_function(
self.client.delete_namespace_object,
'tempest.lib.common.rest_client.RestClient.delete',
{}, namespace="OS::Compute::Hypervisor",
object_name="OS::Glance::Image",
status=204)