Merge "port some flavor tests into nova v3 part2"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index e0a5376..73d274c 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -260,6 +260,7 @@
cls.servers_client = cls.os.servers_v3_client
cls.images_client = cls.os.image_client
+ cls.flavors_client = cls.os.flavors_v3_client
cls.services_client = cls.os.services_v3_client
cls.extensions_client = cls.os.extensions_v3_client
cls.availability_zone_client = cls.os.availability_zone_v3_client
@@ -333,3 +334,4 @@
cls.os_adm.availability_zone_v3_client
cls.hypervisor_admin_client = cls.os_adm.hypervisor_v3_client
cls.tenant_usages_admin_client = cls.os_adm.tenant_usages_v3_client
+ cls.flavors_admin_client = cls.os_adm.flavors_v3_client
diff --git a/tempest/api/compute/v3/admin/test_flavors_access.py b/tempest/api/compute/v3/admin/test_flavors_access.py
index 048312b..86194af 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access.py
@@ -20,7 +20,7 @@
from tempest import test
-class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
+class FlavorsAccessV3TestJSON(base.BaseV3ComputeAdminTest):
"""
Tests Flavor Access API extension.
@@ -31,19 +31,15 @@
@classmethod
def setUpClass(cls):
- super(FlavorsAccessTestJSON, cls).setUpClass()
- if not test.is_extension_enabled('FlavorExtraData', 'compute'):
- msg = "FlavorExtraData extension not enabled."
- raise cls.skipException(msg)
+ super(FlavorsAccessV3TestJSON, cls).setUpClass()
- cls.client = cls.os_adm.flavors_client
+ cls.client = cls.flavors_admin_client
admin_client = cls._get_identity_admin_client()
cls.tenant = admin_client.get_tenant_by_name(cls.flavors_client.
tenant_name)
cls.tenant_id = cls.tenant['id']
- cls.adm_tenant = admin_client.get_tenant_by_name(cls.os_adm.
- flavors_client.
- tenant_name)
+ cls.adm_tenant = admin_client.get_tenant_by_name(
+ cls.flavors_admin_client.tenant_name)
cls.adm_tenant_id = cls.adm_tenant['id']
cls.flavor_name_prefix = 'test_flavor_access_'
cls.ram = 512
@@ -61,7 +57,7 @@
new_flavor_id,
is_public='False')
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- self.assertEqual(resp.status, 200)
+ self.assertEqual(resp.status, 201)
resp, flavor_access = self.client.list_flavor_access(new_flavor_id)
self.assertEqual(resp.status, 200)
self.assertEqual(len(flavor_access), 1, str(flavor_access))
@@ -107,5 +103,5 @@
self.assertNotIn(new_flavor['id'], map(lambda x: x['id'], flavors))
-class FlavorsAdminTestXML(FlavorsAccessTestJSON):
+class FlavorsAdminV3TestXML(FlavorsAccessV3TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_flavors_access_negative.py b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
index 976124e..df6557e 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
@@ -23,7 +23,7 @@
from tempest import test
-class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
+class FlavorsAccessNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
"""
Tests Flavor Access API extension.
@@ -34,19 +34,15 @@
@classmethod
def setUpClass(cls):
- super(FlavorsAccessNegativeTestJSON, cls).setUpClass()
- if not test.is_extension_enabled('FlavorExtraData', 'compute'):
- msg = "FlavorExtraData extension not enabled."
- raise cls.skipException(msg)
+ super(FlavorsAccessNegativeV3TestJSON, cls).setUpClass()
- cls.client = cls.os_adm.flavors_client
+ cls.client = cls.flavors_admin_client
admin_client = cls._get_identity_admin_client()
cls.tenant = admin_client.get_tenant_by_name(cls.flavors_client.
tenant_name)
cls.tenant_id = cls.tenant['id']
- cls.adm_tenant = admin_client.get_tenant_by_name(cls.os_adm.
- flavors_client.
- tenant_name)
+ cls.adm_tenant = admin_client.get_tenant_by_name(
+ cls.flavors_admin_client.tenant_name)
cls.adm_tenant_id = cls.adm_tenant['id']
cls.flavor_name_prefix = 'test_flavor_access_'
cls.ram = 512
@@ -64,7 +60,7 @@
new_flavor_id,
is_public='True')
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- self.assertEqual(resp.status, 200)
+ self.assertEqual(resp.status, 201)
self.assertRaises(exceptions.NotFound,
self.client.list_flavor_access,
new_flavor_id)
@@ -148,5 +144,5 @@
str(uuid.uuid4()))
-class FlavorsAdminNegativeTestXML(FlavorsAccessNegativeTestJSON):
+class FlavorsAdminNegativeV3TestXML(FlavorsAccessNegativeV3TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
index 875f742..d745829 100644
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
@@ -20,7 +20,7 @@
from tempest import test
-class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
+class FlavorsExtraSpecsV3TestJSON(base.BaseV3ComputeAdminTest):
"""
Tests Flavor Extra Spec API extension.
@@ -32,12 +32,9 @@
@classmethod
def setUpClass(cls):
- super(FlavorsExtraSpecsTestJSON, cls).setUpClass()
- if not test.is_extension_enabled('FlavorExtraData', 'compute'):
- msg = "FlavorExtraData extension not enabled."
- raise cls.skipException(msg)
+ super(FlavorsExtraSpecsV3TestJSON, cls).setUpClass()
- cls.client = cls.os_adm.flavors_client
+ cls.client = cls.flavors_admin_client
flavor_name = data_utils.rand_name('test_flavor')
ram = 512
vcpus = 1
@@ -58,7 +55,7 @@
def tearDownClass(cls):
resp, body = cls.client.delete_flavor(cls.flavor['id'])
cls.client.wait_for_resource_deletion(cls.flavor['id'])
- super(FlavorsExtraSpecsTestJSON, cls).tearDownClass()
+ super(FlavorsExtraSpecsV3TestJSON, cls).tearDownClass()
@test.attr(type='gate')
def test_flavor_set_get_update_show_unset_keys(self):
@@ -69,7 +66,7 @@
# SET extra specs to the flavor created in setUp
set_resp, set_body = \
self.client.set_flavor_extra_spec(self.flavor['id'], specs)
- self.assertEqual(set_resp.status, 200)
+ self.assertEqual(set_resp.status, 201)
self.assertEqual(set_body, specs)
# GET extra specs and verify
get_resp, get_body = \
@@ -95,10 +92,10 @@
# UNSET extra specs that were set in this test
unset_resp, _ = \
self.client.unset_flavor_extra_spec(self.flavor['id'], "key1")
- self.assertEqual(unset_resp.status, 200)
+ self.assertEqual(unset_resp.status, 204)
unset_resp, _ = \
self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
- self.assertEqual(unset_resp.status, 200)
+ self.assertEqual(unset_resp.status, 204)
@test.attr(type='gate')
def test_flavor_non_admin_get_all_keys(self):
@@ -117,7 +114,7 @@
specs = {"key1": "value1", "key2": "value2"}
resp, body = self.client.set_flavor_extra_spec(
self.flavor['id'], specs)
- self.assertEqual(resp.status, 200)
+ self.assertEqual(resp.status, 201)
self.assertEqual(body['key1'], 'value1')
self.assertIn('key2', body)
resp, body = self.flavors_client.get_flavor_extra_spec_with_key(
@@ -127,5 +124,5 @@
self.assertNotIn('key2', body)
-class FlavorsExtraSpecsTestXML(FlavorsExtraSpecsTestJSON):
+class FlavorsExtraSpecsV3TestXML(FlavorsExtraSpecsV3TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
index fb09a63..1d5e447 100644
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
@@ -22,7 +22,7 @@
from tempest import test
-class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
+class FlavorsExtraSpecsNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
"""
Negative Tests Flavor Extra Spec API extension.
@@ -33,12 +33,9 @@
@classmethod
def setUpClass(cls):
- super(FlavorsExtraSpecsNegativeTestJSON, cls).setUpClass()
- if not test.is_extension_enabled('FlavorExtraData', 'compute'):
- msg = "FlavorExtraData extension not enabled."
- raise cls.skipException(msg)
+ super(FlavorsExtraSpecsNegativeV3TestJSON, cls).setUpClass()
- cls.client = cls.os_adm.flavors_client
+ cls.client = cls.flavors_admin_client
flavor_name = data_utils.rand_name('test_flavor')
ram = 512
vcpus = 1
@@ -59,7 +56,7 @@
def tearDownClass(cls):
resp, body = cls.client.delete_flavor(cls.flavor['id'])
cls.client.wait_for_resource_deletion(cls.flavor['id'])
- super(FlavorsExtraSpecsNegativeTestJSON, cls).tearDownClass()
+ super(FlavorsExtraSpecsNegativeV3TestJSON, cls).tearDownClass()
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_set_keys(self):
@@ -76,7 +73,7 @@
specs = {"key1": "value1", "key2": "value2"}
resp, body = self.client.set_flavor_extra_spec(
self.flavor['id'], specs)
- self.assertEqual(resp.status, 200)
+ self.assertEqual(resp.status, 201)
self.assertEqual(body['key1'], 'value1')
self.assertRaises(exceptions.Unauthorized,
self.flavors_client.
@@ -131,5 +128,5 @@
key2="value")
-class FlavorsExtraSpecsNegativeTestXML(FlavorsExtraSpecsNegativeTestJSON):
+class FlavorsExtraSpecsNegativeV3TestXML(FlavorsExtraSpecsNegativeV3TestJSON):
_interface = 'xml'
diff --git a/tempest/clients.py b/tempest/clients.py
index a38f915..1f2e1de 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -56,6 +56,7 @@
CertificatesV3ClientJSON
from tempest.services.compute.v3.json.extensions_client import \
ExtensionsV3ClientJSON
+from tempest.services.compute.v3.json.flavors_client import FlavorsV3ClientJSON
from tempest.services.compute.v3.json.hypervisor_client import \
HypervisorV3ClientJSON
from tempest.services.compute.v3.json.interfaces_client import \
@@ -74,6 +75,7 @@
CertificatesV3ClientXML
from tempest.services.compute.v3.xml.extensions_client import \
ExtensionsV3ClientXML
+from tempest.services.compute.v3.xml.flavors_client import FlavorsV3ClientXML
from tempest.services.compute.v3.xml.hypervisor_client import \
HypervisorV3ClientXML
from tempest.services.compute.v3.xml.interfaces_client import \
@@ -228,6 +230,7 @@
self.keypairs_client = KeyPairsClientXML(*client_args)
self.quotas_client = QuotasClientXML(*client_args)
self.flavors_client = FlavorsClientXML(*client_args)
+ self.flavors_v3_client = FlavorsV3ClientXML(*client_args)
self.extensions_v3_client = ExtensionsV3ClientXML(*client_args)
self.extensions_client = ExtensionsClientXML(*client_args)
self.volumes_extensions_client = VolumesExtensionsClientXML(
@@ -285,6 +288,7 @@
self.keypairs_client = KeyPairsClientJSON(*client_args)
self.quotas_client = QuotasClientJSON(*client_args)
self.flavors_client = FlavorsClientJSON(*client_args)
+ self.flavors_v3_client = FlavorsV3ClientJSON(*client_args)
self.extensions_v3_client = ExtensionsV3ClientJSON(*client_args)
self.extensions_client = ExtensionsClientJSON(*client_args)
self.volumes_extensions_client = VolumesExtensionsClientJSON(
diff --git a/tempest/services/compute/v3/json/flavors_client.py b/tempest/services/compute/v3/json/flavors_client.py
index 00d6f8a..e99ac91 100644
--- a/tempest/services/compute/v3/json/flavors_client.py
+++ b/tempest/services/compute/v3/json/flavors_client.py
@@ -21,12 +21,12 @@
from tempest.common.rest_client import RestClient
-class FlavorsClientJSON(RestClient):
+class FlavorsV3ClientJSON(RestClient):
def __init__(self, config, username, password, auth_url, tenant_name=None):
- super(FlavorsClientJSON, self).__init__(config, username, password,
- auth_url, tenant_name)
- self.service = self.config.compute.catalog_type
+ super(FlavorsV3ClientJSON, self).__init__(config, username, password,
+ auth_url, tenant_name)
+ self.service = self.config.compute.catalog_v3_type
def list_flavors(self, params=None):
url = 'flavors'
@@ -67,7 +67,7 @@
if kwargs.get('rxtx'):
post_body['rxtx_factor'] = kwargs.get('rxtx')
if kwargs.get('is_public'):
- post_body['os-flavor-access:is_public'] = kwargs.get('is_public')
+ post_body['flavor-access:is_public'] = kwargs.get('is_public')
post_body = json.dumps({'flavor': post_body})
resp, body = self.post('flavors', post_body, self.headers)
@@ -91,27 +91,27 @@
def set_flavor_extra_spec(self, flavor_id, specs):
"""Sets extra Specs to the mentioned flavor."""
post_body = json.dumps({'extra_specs': specs})
- resp, body = self.post('flavors/%s/os-extra_specs' % flavor_id,
+ resp, body = self.post('flavors/%s/flavor-extra-specs' % flavor_id,
post_body, self.headers)
body = json.loads(body)
return resp, body['extra_specs']
def get_flavor_extra_spec(self, flavor_id):
"""Gets extra Specs details of the mentioned flavor."""
- resp, body = self.get('flavors/%s/os-extra_specs' % flavor_id)
+ resp, body = self.get('flavors/%s/flavor-extra-specs' % flavor_id)
body = json.loads(body)
return resp, body['extra_specs']
def get_flavor_extra_spec_with_key(self, flavor_id, key):
"""Gets extra Specs key-value of the mentioned flavor and key."""
- resp, body = self.get('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
- key))
+ resp, body = self.get('flavors/%s/flavor-extra-specs/%s' %
+ (str(flavor_id), key))
body = json.loads(body)
return resp, body
def update_flavor_extra_spec(self, flavor_id, key, **kwargs):
"""Update specified extra Specs of the mentioned flavor and key."""
- resp, body = self.put('flavors/%s/os-extra_specs/%s' %
+ resp, body = self.put('flavors/%s/flavor-extra-specs/%s' %
(flavor_id, key),
json.dumps(kwargs), self.headers)
body = json.loads(body)
@@ -119,12 +119,12 @@
def unset_flavor_extra_spec(self, flavor_id, key):
"""Unsets extra Specs from the mentioned flavor."""
- return self.delete('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
- key))
+ return self.delete('flavors/%s/flavor-extra-specs/%s' %
+ (str(flavor_id), key))
def list_flavor_access(self, flavor_id):
"""Gets flavor access information given the flavor id."""
- resp, body = self.get('flavors/%s/os-flavor-access' % flavor_id,
+ resp, body = self.get('flavors/%s/flavor-access' % flavor_id,
self.headers)
body = json.loads(body)
return resp, body['flavor_access']
@@ -132,8 +132,8 @@
def add_flavor_access(self, flavor_id, tenant_id):
"""Add flavor access for the specified tenant."""
post_body = {
- 'addTenantAccess': {
- 'tenant': tenant_id
+ 'add_tenant_access': {
+ 'tenant_id': tenant_id
}
}
post_body = json.dumps(post_body)
@@ -145,8 +145,8 @@
def remove_flavor_access(self, flavor_id, tenant_id):
"""Remove flavor access from the specified tenant."""
post_body = {
- 'removeTenantAccess': {
- 'tenant': tenant_id
+ 'remove_tenant_access': {
+ 'tenant_id': tenant_id
}
}
post_body = json.dumps(post_body)
diff --git a/tempest/services/compute/v3/xml/flavors_client.py b/tempest/services/compute/v3/xml/flavors_client.py
index a1c74d9..04c21b4 100644
--- a/tempest/services/compute/v3/xml/flavors_client.py
+++ b/tempest/services/compute/v3/xml/flavors_client.py
@@ -24,21 +24,18 @@
from tempest.services.compute.xml.common import Element
from tempest.services.compute.xml.common import Text
from tempest.services.compute.xml.common import xml_to_json
-from tempest.services.compute.xml.common import XMLNS_11
+from tempest.services.compute.xml.common import XMLNS_V3
-
-XMLNS_OS_FLV_EXT_DATA = \
- "http://docs.openstack.org/compute/ext/flavor_extra_data/api/v1.1"
XMLNS_OS_FLV_ACCESS = \
- "http://docs.openstack.org/compute/ext/flavor_access/api/v2"
+ "http://docs.openstack.org/compute/core/flavor-access/api/v3"
-class FlavorsClientXML(RestClientXML):
+class FlavorsV3ClientXML(RestClientXML):
def __init__(self, config, username, password, auth_url, tenant_name=None):
- super(FlavorsClientXML, self).__init__(config, username, password,
- auth_url, tenant_name)
- self.service = self.config.compute.catalog_type
+ super(FlavorsV3ClientXML, self).__init__(config, username, password,
+ auth_url, tenant_name)
+ self.service = self.config.compute.catalog_v3_type
def _format_flavor(self, f):
flavor = {'links': []}
@@ -51,15 +48,12 @@
flavor['links'].append(v)
continue
- if k == '{%s}ephemeral' % XMLNS_OS_FLV_EXT_DATA:
- k = 'OS-FLV-EXT-DATA:ephemeral'
-
if k == '{%s}is_public' % XMLNS_OS_FLV_ACCESS:
- k = 'os-flavor-access:is_public'
+ k = 'flavor-access:is_public'
v = True if v == 'True' else False
if k == 'extra_specs':
- k = 'OS-FLV-WITH-EXT-SPECS:extra_specs'
+ k = 'flavor-extra-specs:extra_specs'
flavor[k] = dict(v)
continue
@@ -103,7 +97,7 @@
def create_flavor(self, name, ram, vcpus, disk, flavor_id, **kwargs):
"""Creates a new flavor or instance type."""
flavor = Element("flavor",
- xmlns=XMLNS_11,
+ xmlns=XMLNS_V3,
ram=ram,
vcpus=vcpus,
disk=disk,
@@ -114,13 +108,11 @@
if kwargs.get('swap'):
flavor.add_attr('swap', kwargs.get('swap'))
if kwargs.get('ephemeral'):
- flavor.add_attr('OS-FLV-EXT-DATA:ephemeral',
- kwargs.get('ephemeral'))
+ flavor.add_attr('ephemeral', kwargs.get('ephemeral'))
if kwargs.get('is_public'):
- flavor.add_attr('os-flavor-access:is_public',
+ flavor.add_attr('flavor-access:is_public',
kwargs.get('is_public'))
- flavor.add_attr('xmlns:OS-FLV-EXT-DATA', XMLNS_OS_FLV_EXT_DATA)
- flavor.add_attr('xmlns:os-flavor-access', XMLNS_OS_FLV_ACCESS)
+ flavor.add_attr('xmlns:flavor-access', XMLNS_OS_FLV_ACCESS)
resp, body = self.post('flavors', str(Document(flavor)), self.headers)
body = xml_to_json(etree.fromstring(body))
flavor = self._format_flavor(body)
@@ -145,21 +137,21 @@
extra_specs = Element("extra_specs")
for key in specs.keys():
extra_specs.add_attr(key, specs[key])
- resp, body = self.post('flavors/%s/os-extra_specs' % flavor_id,
+ resp, body = self.post('flavors/%s/flavor-extra-specs' % flavor_id,
str(Document(extra_specs)), self.headers)
body = xml_to_json(etree.fromstring(body))
return resp, body
def get_flavor_extra_spec(self, flavor_id):
"""Gets extra Specs of the mentioned flavor."""
- resp, body = self.get('flavors/%s/os-extra_specs' % flavor_id,
+ resp, body = self.get('flavors/%s/flavor-extra-specs' % flavor_id,
self.headers)
body = xml_to_json(etree.fromstring(body))
return resp, body
def get_flavor_extra_spec_with_key(self, flavor_id, key):
"""Gets extra Specs key-value of the mentioned flavor and key."""
- resp, xml_body = self.get('flavors/%s/os-extra_specs/%s' %
+ resp, xml_body = self.get('flavors/%s/flavor-extra-specs/%s' %
(str(flavor_id), key), self.headers)
body = {}
element = etree.fromstring(xml_body)
@@ -176,7 +168,7 @@
value = Text(v)
element.append(value)
- resp, body = self.put('flavors/%s/os-extra_specs/%s' %
+ resp, body = self.put('flavors/%s/flavor-extra-specs/%s' %
(flavor_id, key),
str(doc), self.headers)
body = xml_to_json(etree.fromstring(body))
@@ -184,15 +176,15 @@
def unset_flavor_extra_spec(self, flavor_id, key):
"""Unsets an extra spec based on the mentioned flavor and key."""
- return self.delete('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
- key))
+ return self.delete('flavors/%s/flavor-extra-specs/%s' %
+ (str(flavor_id), key))
def _parse_array_access(self, node):
return [xml_to_json(x) for x in node]
def list_flavor_access(self, flavor_id):
"""Gets flavor access information given the flavor id."""
- resp, body = self.get('flavors/%s/os-flavor-access' % str(flavor_id),
+ resp, body = self.get('flavors/%s/flavor-access' % str(flavor_id),
self.headers)
body = self._parse_array(etree.fromstring(body))
return resp, body
@@ -200,9 +192,9 @@
def add_flavor_access(self, flavor_id, tenant_id):
"""Add flavor access for the specified tenant."""
doc = Document()
- server = Element("addTenantAccess")
+ server = Element("add_tenant_access")
doc.append(server)
- server.add_attr("tenant", tenant_id)
+ server.add_attr("tenant_id", tenant_id)
resp, body = self.post('flavors/%s/action' % str(flavor_id),
str(doc), self.headers)
body = self._parse_array_access(etree.fromstring(body))
@@ -211,9 +203,9 @@
def remove_flavor_access(self, flavor_id, tenant_id):
"""Remove flavor access from the specified tenant."""
doc = Document()
- server = Element("removeTenantAccess")
+ server = Element("remove_tenant_access")
doc.append(server)
- server.add_attr("tenant", tenant_id)
+ server.add_attr("tenant_id", tenant_id)
resp, body = self.post('flavors/%s/action' % str(flavor_id),
str(doc), self.headers)
body = self._parse_array_access(etree.fromstring(body))