Addition of XML support to test_quotas.py

Added logic to test_quotas.py file so as to support XML calls.
Hence added exclusive client files for XML. Also modified JSON client
file, manager.py and clients.py according to new addition of
XML support.

Change-Id: Ibbdd87c2d1bb4e26ff0f77441dc91d71abc00d7f
Implements: blueprint add-xml-support
This commit is contained in:
rajalakshmi-ganesan 2013-01-10 14:56:45 +05:30
parent be4150871d
commit 1982c3cac9
9 changed files with 230 additions and 26 deletions

View File

@ -32,7 +32,7 @@ from tempest.services.compute.json.servers_client import ServersClientJSON
from tempest.services.compute.json.security_groups_client import \
SecurityGroupsClientJSON
from tempest.services.compute.json.keypairs_client import KeyPairsClientJSON
from tempest.services.compute.json.quotas_client import QuotasClient
from tempest.services.compute.json.quotas_client import QuotasClientJSON
from tempest.services.compute.json.volumes_extensions_client import \
VolumesExtensionsClientJSON
from tempest.services.compute.json.console_output_client import \
@ -44,6 +44,7 @@ from tempest.services.compute.xml.floating_ips_client import \
from tempest.services.compute.xml.images_client import ImagesClientXML
from tempest.services.compute.xml.keypairs_client import KeyPairsClientXML
from tempest.services.compute.xml.limits_client import LimitsClientXML
from tempest.services.compute.xml.quotas_client import QuotasClientXML
from tempest.services.compute.xml.security_groups_client \
import SecurityGroupsClientXML
from tempest.services.compute.xml.servers_client import ServersClientXML
@ -79,6 +80,11 @@ KEYPAIRS_CLIENTS = {
"xml": KeyPairsClientXML,
}
QUOTAS_CLIENTS = {
"json": QuotasClientJSON,
"xml": QuotasClientXML,
}
SERVERS_CLIENTS = {
"json": ServersClientJSON,
"xml": ServersClientXML,
@ -180,6 +186,7 @@ class Manager(object):
self.limits_client = LIMITS_CLIENTS[interface](*client_args)
self.images_client = IMAGES_CLIENTS[interface](*client_args)
self.keypairs_client = KEYPAIRS_CLIENTS[interface](*client_args)
self.quotas_client = QUOTAS_CLIENTS[interface](*client_args)
self.flavors_client = FLAVORS_CLIENTS[interface](*client_args)
ext_cli = EXTENSIONS_CLIENTS[interface](*client_args)
self.extensions_client = ext_cli
@ -196,7 +203,6 @@ class Manager(object):
except KeyError:
msg = "Unsupported interface type `%s'" % interface
raise exceptions.InvalidConfiguration(msg)
self.quotas_client = QuotasClient(*client_args)
self.network_client = NetworkClient(*client_args)
self.account_client = AccountClient(*client_args)
self.container_client = ContainerClient(*client_args)

View File

@ -55,7 +55,7 @@ KeyPairsClient = keypairs_client.KeyPairsClientJSON
VolumesExtensionsClient = volumes_extensions_client.VolumesExtensionsClientJSON
VolumesClient = volumes_client.VolumesClientJSON
ConsoleOutputsClient = console_output_client.ConsoleOutputsClientJSON
QuotasClient = quotas_client.QuotasClient
QuotasClient = quotas_client.QuotasClientJSON
LOG = logging.getLogger(__name__)

View File

@ -17,14 +17,14 @@
import json
from tempest.services.compute.json.quotas_client import QuotasClient
from tempest.services.compute.json.quotas_client import QuotasClientJSON
class AdminQuotasClient(QuotasClient):
class AdminQuotasClientJSON(QuotasClientJSON):
def __init__(self, config, username, password, auth_url, tenant_name=None):
super(AdminQuotasClient, self).__init__(config, username, password,
auth_url, tenant_name)
super(AdminQuotasClientJSON, self).__init__(config, username, password,
auth_url, tenant_name)
def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
metadata_items=None, ram=None, floating_ips=None,

View File

@ -0,0 +1,88 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 NTT Data
# 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 urllib
from lxml import etree
from tempest.common.rest_client import RestClientXML
from tempest.services.compute.xml.common import Document
from tempest.services.compute.xml.common import Element
from tempest.services.compute.xml.common import xml_to_json
from tempest.services.compute.xml.common import XMLNS_11
from tempest.services.compute.xml.quotas_client import QuotasClientXML
class AdminQuotasClientXML(QuotasClientXML):
def __init__(self, config, username, password, auth_url, tenant_name=None):
super(AdminQuotasClientXML, self).__init__(config, username, password,
auth_url, tenant_name)
def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
metadata_items=None, ram=None, floating_ips=None,
key_pairs=None, instances=None,
security_group_rules=None, injected_files=None,
cores=None, injected_file_path_bytes=None,
security_groups=None):
"""
Updates the tenant's quota limits for one or more resources
"""
post_body = Element("quota_set",
xmlns=XMLNS_11)
if injected_file_content_bytes is not None:
post_body.add_attr('injected_file_content_bytes',
injected_file_content_bytes)
if metadata_items is not None:
post_body.add_attr('metadata_items', metadata_items)
if ram is not None:
post_body.add_attr('ram', ram)
if floating_ips is not None:
post_body.add_attr('floating_ips', floating_ips)
if key_pairs is not None:
post_body.add_attr('key_pairs', key_pairs)
if instances is not None:
post_body.add_attr('instances', instances)
if security_group_rules is not None:
post_body.add_attr('security_group_rules', security_group_rules)
if injected_files is not None:
post_body.add_attr('injected_files', injected_files)
if cores is not None:
post_body.add_attr('cores', cores)
if injected_file_path_bytes is not None:
post_body.add_attr('injected_file_path_bytes',
injected_file_path_bytes)
if security_groups is not None:
post_body.add_attr('security_groups', security_groups)
resp, body = self.put('os-quota-sets/%s' % str(tenant_id),
str(Document(post_body)),
self.headers)
body = xml_to_json(etree.fromstring(body))
body = self._format_quota(body)
return resp, body

View File

@ -20,11 +20,11 @@ import json
from tempest.common.rest_client import RestClient
class QuotasClient(RestClient):
class QuotasClientJSON(RestClient):
def __init__(self, config, username, password, auth_url, tenant_name=None):
super(QuotasClient, self).__init__(config, username, password,
auth_url, tenant_name)
super(QuotasClientJSON, self).__init__(config, username, password,
auth_url, tenant_name)
self.service = self.config.compute.catalog_type
def get_quota_set(self, tenant_id):

View File

@ -0,0 +1,58 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 NTT Data
# 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 urllib
from lxml import etree
from tempest.common.rest_client import RestClientXML
from tempest.services.compute.xml.common import Document
from tempest.services.compute.xml.common import Element
from tempest.services.compute.xml.common import xml_to_json
from tempest.services.compute.xml.common import XMLNS_11
class QuotasClientXML(RestClientXML):
def __init__(self, config, username, password, auth_url, tenant_name=None):
super(QuotasClientXML, self).__init__(config, username, password,
auth_url, tenant_name)
self.service = self.config.compute.catalog_type
def _format_quota(self, q):
quota = {}
for k, v in q.items():
try:
v = int(v)
except ValueError:
pass
quota[k] = v
return quota
def _parse_array(self, node):
return [self._format_quota(xml_to_json(x)) for x in node]
def get_quota_set(self, tenant_id):
"""List the quota set for a tenant."""
url = 'os-quota-sets/%s' % str(tenant_id)
resp, body = self.get(url, self.headers)
body = xml_to_json(etree.fromstring(body))
body = self._format_quota(body)
return resp, body

View File

@ -18,23 +18,21 @@
from nose.plugins.attrib import attr
from tempest import exceptions
from tempest.services.compute.admin.json import quotas_client as adm_quotas
from tempest.tests.compute.base import BaseComputeTest
from tempest.services.compute.admin.json \
import quotas_client as adm_quotas_json
from tempest.services.compute.admin.xml import quotas_client as adm_quotas_xml
from tempest.tests import compute
from tempest.tests.compute import base
class QuotasTest(BaseComputeTest):
class QuotasAdminTestBase(object):
@classmethod
def setUpClass(cls):
super(QuotasTest, cls).setUpClass()
c_adm_user = cls.config.compute_admin.username
c_adm_pass = cls.config.compute_admin.password
c_adm_tenant = cls.config.compute_admin.tenant_name
auth_url = cls.config.identity.uri
cls.adm_client = adm_quotas.AdminQuotasClient(cls.config, c_adm_user,
c_adm_pass, auth_url,
c_adm_tenant)
cls.c_adm_user = cls.config.compute_admin.username
cls.c_adm_pass = cls.config.compute_admin.password
cls.c_adm_tenant = cls.config.compute_admin.tenant_name
cls.auth_url = cls.config.identity.uri
cls.client = cls.os.quotas_client
cls.identity_admin_client = cls._get_identity_admin_client()
resp, tenants = cls.identity_admin_client.list_tenants()
@ -63,7 +61,6 @@ class QuotasTest(BaseComputeTest):
cls.servers_client.delete_server(server['id'])
except exceptions.NotFound:
continue
super(QuotasTest, cls).tearDownClass()
@attr(type='smoke')
def test_get_default_quotas(self):
@ -155,3 +152,43 @@ class QuotasTest(BaseComputeTest):
finally:
self.adm_client.update_quota_set(self.demo_tenant_id,
ram=default_mem_quota)
class QuotasAdminTestJSON(QuotasAdminTestBase, base.BaseComputeAdminTestJSON,
base.BaseComputeTest):
@classmethod
def setUpClass(cls):
base.BaseComputeAdminTestJSON.setUpClass()
base.BaseComputeTest.setUpClass()
super(QuotasAdminTestJSON, cls).setUpClass()
cls.adm_client = adm_quotas_json.AdminQuotasClientJSON(
cls.config, cls.c_adm_user, cls.c_adm_pass,
cls.auth_url, cls.c_adm_tenant)
@classmethod
def tearDownClass(cls):
super(QuotasAdminTestJSON, cls).tearDownClass()
base.BaseComputeTest.tearDownClass()
class QuotasAdminTestXML(QuotasAdminTestBase, base.BaseComputeAdminTestXML,
base.BaseComputeTest):
@classmethod
def setUpClass(cls):
base.BaseComputeAdminTestXML.setUpClass()
base.BaseComputeTest.setUpClass()
super(QuotasAdminTestXML, cls).setUpClass()
cls.adm_client = adm_quotas_xml.AdminQuotasClientXML(cls.config,
cls.c_adm_user,
cls.c_adm_pass,
cls.auth_url,
cls.c_adm_tenant)
@classmethod
def tearDownClass(cls):
super(QuotasAdminTestXML, cls).tearDownClass()
base.BaseComputeTest.tearDownClass()

View File

@ -17,14 +17,13 @@
from nose.plugins.attrib import attr
from tempest.tests.compute.base import BaseComputeTest
from tempest.tests.compute import base
class QuotasTest(BaseComputeTest):
class QuotasTestBase(object):
@classmethod
def setUpClass(cls):
super(QuotasTest, cls).setUpClass()
cls.client = cls.quotas_client
cls.admin_client = cls._get_identity_admin_client()
resp, tenants = cls.admin_client.list_tenants()
@ -47,3 +46,19 @@ class QuotasTest(BaseComputeTest):
self.assertSequenceEqual(expected_quota_set, quota_set)
except Exception:
self.fail("Quota set for tenant did not have default limits")
class QuotasTestJSON(QuotasTestBase, base.BaseComputeTestJSON):
@classmethod
def setUpClass(cls):
base.BaseComputeTestJSON.setUpClass()
super(QuotasTestJSON, cls).setUpClass()
class QuotasTestXML(QuotasTestBase, base.BaseComputeTestXML):
@classmethod
def setUpClass(cls):
base.BaseComputeTestXML.setUpClass()
super(QuotasTestXML, cls).setUpClass()