Merge "Add test namespace object functions in images"
This commit is contained in:
commit
051ebd06b0
@ -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']
|
||||
|
91
tempest/lib/services/image/v2/namespace_objects_client.py
Normal file
91
tempest/lib/services/image/v2/namespace_objects_client.py
Normal file
@ -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)
|
Loading…
x
Reference in New Issue
Block a user