Add config options for enabled extensions

This commit adds a new set of config options to the feature_enabled
groups for a list of enabled extensions. These options are used to
specify whether all extensions are enabled or which subset is expected
to be enabled. This just sets up the initial framework for doing
this and converts the FlavorExtraSpecs tests to use it.

paritally implements bp config-cleanup

Change-Id: I6a5a9b16e62eb8a216334a0662c99f0dd0d16873
This commit is contained in:
Matthew Treinish 2013-11-26 19:14:58 +00:00
parent 1461c786f1
commit e3d26143ab
13 changed files with 156 additions and 89 deletions

View File

@ -524,6 +524,16 @@
#disk_format=raw
[debug]
#
# Options defined in tempest.config
#
# Enable diagnostic commands (boolean value)
#enable=true
[dashboard]
#
@ -610,14 +620,15 @@
#operator_role=Member
[debug]
[network-feature-enabled]
#
# Options defined in tempest.config
#
# Enable diagnostic commands (boolean value)
#enable=true
# A list of enabled extensions with a special entry all which
# indicates every extension is enabled (list value)
#api_extensions=all
[service_available]
@ -671,8 +682,13 @@
# If false, skip disk config tests (boolean value)
#disk_config=true
# If false, skip flavor extra data test (boolean value)
#flavor_extra=true
# A list of enabled extensions with a special entry all which
# indicates every extension is enabled (list value)
#api_extensions=all
# A list of enabled v3 extensions with a special entry all
# which indicates every extension is enabled (list value)
#api_v3_extensions=all
# Does the test environment support changing the admin
# password? (boolean value)
@ -730,4 +746,8 @@
# (boolean value)
#multi_backend=false
# A list of enabled extensions with a special entry all which
# indicates every extension is enabled (list value)
#api_extensions=all

View File

@ -26,7 +26,6 @@ CREATE_IMAGE_ENABLED = CONFIG.compute_feature_enabled.create_image
RESIZE_AVAILABLE = CONFIG.compute_feature_enabled.resize
CHANGE_PASSWORD_AVAILABLE = CONFIG.compute_feature_enabled.change_password
DISK_CONFIG_ENABLED = CONFIG.compute_feature_enabled.disk_config
FLAVOR_EXTRA_DATA_ENABLED = CONFIG.compute_feature_enabled.flavor_extra
MULTI_USER = True

View File

@ -17,12 +17,10 @@
import uuid
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
from tempest.test import skip_because
from tempest import test
class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
@ -36,7 +34,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsAdminTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -87,19 +85,19 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
return flavor['id']
@attr(type='gate')
@test.attr(type='gate')
def test_create_flavor_with_int_id(self):
flavor_id = data_utils.rand_int_id(start=1000)
new_flavor_id = self._create_flavor(flavor_id)
self.assertEqual(new_flavor_id, str(flavor_id))
@attr(type='gate')
@test.attr(type='gate')
def test_create_flavor_with_uuid_id(self):
flavor_id = str(uuid.uuid4())
new_flavor_id = self._create_flavor(flavor_id)
self.assertEqual(new_flavor_id, flavor_id)
@attr(type='gate')
@test.attr(type='gate')
def test_create_flavor_with_none_id(self):
# If nova receives a request with None as flavor_id,
# nova generates flavor_id of uuid.
@ -107,7 +105,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
new_flavor_id = self._create_flavor(flavor_id)
self.assertEqual(new_flavor_id, str(uuid.UUID(new_flavor_id)))
@attr(type='gate')
@test.attr(type='gate')
def test_create_flavor_verify_entry_in_list_details(self):
# Create a flavor and ensure it's details are listed
# This operation requires the user to have 'admin' role
@ -132,7 +130,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
flag = True
self.assertTrue(flag)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_get_flavor_details_for_deleted_flavor(self):
# Delete a flavor and ensure it is not listed
# Create a test flavor
@ -166,7 +164,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
flag = False
self.assertTrue(flag)
@attr(type='gate')
@test.attr(type='gate')
def test_create_list_flavor_without_extra_data(self):
# Create a flavor and ensure it is listed
# This operation requires the user to have 'admin' role
@ -210,8 +208,8 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
flag = True
self.assertTrue(flag)
@skip_because(bug="1209101")
@attr(type='gate')
@test.skip_because(bug="1209101")
@test.attr(type='gate')
def test_list_non_public_flavor(self):
# Create a flavor with os-flavor-access:is_public false should
# be present in list_details.
@ -244,7 +242,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
flag = True
self.assertFalse(flag)
@attr(type='gate')
@test.attr(type='gate')
def test_create_server_with_non_public_flavor(self):
# Create a flavor with os-flavor-access:is_public false
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -264,7 +262,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
self.os.servers_client.create_server,
'test', self.image_ref, flavor['id'])
@attr(type='gate')
@test.attr(type='gate')
def test_list_public_flavor_with_other_user(self):
# Create a Flavor with public access.
# Try to List/Get flavor with another user
@ -288,7 +286,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
flag = True
self.assertTrue(flag)
@attr(type='gate')
@test.attr(type='gate')
def test_is_public_string_variations(self):
flavor_id_not_public = data_utils.rand_int_id(start=1000)
flavor_name_not_public = data_utils.rand_name(self.flavor_name_prefix)
@ -331,7 +329,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
_test_string_variations(['t', 'true', 'yes', '1'],
flavor_name_public)
@attr(type='gate')
@test.attr(type='gate')
def test_create_flavor_using_string_ram(self):
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
@ -349,13 +347,13 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
self.assertEqual(flavor['ram'], int(ram))
self.assertEqual(int(flavor['id']), new_flavor_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_invalid_is_public_string(self):
self.assertRaises(exceptions.BadRequest,
self.client.list_flavors_with_detail,
{'is_public': 'invalid'})
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_create_flavor_as_user(self):
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
@ -366,13 +364,13 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
new_flavor_id, ephemeral=self.ephemeral,
swap=self.swap, rxtx=self.rxtx)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_delete_flavor_as_user(self):
self.assertRaises(exceptions.Unauthorized,
self.user_client.delete_flavor,
self.flavor_ref_alt)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_create_flavor_using_invalid_ram(self):
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
@ -382,7 +380,7 @@ class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
flavor_name, -1, self.vcpus,
self.disk, new_flavor_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_create_flavor_using_invalid_vcpus(self):
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)

View File

@ -15,10 +15,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest import test
class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
@ -33,7 +32,7 @@ class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsAccessTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -51,7 +50,7 @@ class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
cls.vcpus = 1
cls.disk = 10
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_access_list_with_private_flavor(self):
# Test to list flavor access successfully by querying private flavor
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -70,7 +69,7 @@ class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
self.assertEqual(str(new_flavor_id), str(first_flavor['flavor_id']))
self.assertEqual(self.adm_tenant_id, first_flavor['tenant_id'])
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_access_add_remove(self):
# Test to add and remove flavor access to a given tenant.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)

View File

@ -17,11 +17,10 @@
import uuid
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
from tempest import test
class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
@ -36,7 +35,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsAccessNegativeTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -54,7 +53,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
cls.vcpus = 1
cls.disk = 10
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_access_list_with_public_flavor(self):
# Test to list flavor access with exceptions by querying public flavor
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -70,7 +69,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.client.list_flavor_access,
new_flavor_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_add(self):
# Test to add flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -86,7 +85,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
new_flavor['id'],
self.tenant_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_remove(self):
# Test to remove flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -106,7 +105,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
new_flavor['id'],
self.tenant_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_add_flavor_access_duplicate(self):
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -130,7 +129,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
new_flavor['id'],
self.tenant_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_remove_flavor_access_not_found(self):
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)

View File

@ -15,10 +15,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest import test
class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
@ -34,7 +33,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsExtraSpecsTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -61,7 +60,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
cls.client.wait_for_resource_deletion(cls.flavor['id'])
super(FlavorsExtraSpecsTestJSON, cls).tearDownClass()
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_set_get_update_show_unset_keys(self):
# Test to SET, GET, UPDATE, SHOW, UNSET flavor extra
# spec as a user with admin privileges.
@ -101,7 +100,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
self.assertEqual(unset_resp.status, 200)
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_non_admin_get_all_keys(self):
specs = {"key1": "value1", "key2": "value2"}
set_resp, set_body = self.client.set_flavor_extra_spec(
@ -113,7 +112,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
for key in specs:
self.assertEqual(body[key], specs[key])
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_non_admin_get_specific_key(self):
specs = {"key1": "value1", "key2": "value2"}
resp, body = self.client.set_flavor_extra_spec(

View File

@ -16,11 +16,10 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
from tempest import test
class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
@ -35,7 +34,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsExtraSpecsNegativeTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -62,7 +61,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
cls.client.wait_for_resource_deletion(cls.flavor['id'])
super(FlavorsExtraSpecsNegativeTestJSON, cls).tearDownClass()
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_set_keys(self):
# Test to SET flavor extra spec as a user without admin privileges.
specs = {"key1": "value1", "key2": "value2"}
@ -71,7 +70,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.flavor['id'],
specs)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_update_specific_key(self):
# non admin user is not allowed to update flavor extra spec
specs = {"key1": "value1", "key2": "value2"}
@ -86,7 +85,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
'key1',
key1='value1_new')
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_unset_keys(self):
specs = {"key1": "value1", "key2": "value2"}
set_resp, set_body = self.client.set_flavor_extra_spec(
@ -97,7 +96,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.flavor['id'],
'key1')
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_unset_nonexistent_key(self):
nonexistent_key = data_utils.rand_name('flavor_key')
self.assertRaises(exceptions.NotFound,
@ -105,14 +104,14 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.flavor['id'],
nonexistent_key)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_get_nonexistent_key(self):
self.assertRaises(exceptions.NotFound,
self.flavors_client.get_flavor_extra_spec_with_key,
self.flavor['id'],
"nonexistent_key")
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_update_mismatch_key(self):
# the key will be updated should be match the key in the body
self.assertRaises(exceptions.BadRequest,
@ -121,7 +120,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
"key2",
key1="value")
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_update_more_key(self):
# there should be just one item in the request body
self.assertRaises(exceptions.BadRequest,

View File

@ -15,10 +15,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest import test
class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
@ -33,7 +32,7 @@ class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsAccessTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -51,7 +50,7 @@ class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
cls.vcpus = 1
cls.disk = 10
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_access_list_with_private_flavor(self):
# Test to list flavor access successfully by querying private flavor
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -70,7 +69,7 @@ class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
self.assertEqual(str(new_flavor_id), str(first_flavor['flavor_id']))
self.assertEqual(self.adm_tenant_id, first_flavor['tenant_id'])
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_access_add_remove(self):
# Test to add and remove flavor access to a given tenant.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)

View File

@ -17,11 +17,10 @@
import uuid
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
from tempest import test
class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
@ -36,7 +35,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsAccessNegativeTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -54,7 +53,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
cls.vcpus = 1
cls.disk = 10
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_access_list_with_public_flavor(self):
# Test to list flavor access with exceptions by querying public flavor
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -70,7 +69,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.client.list_flavor_access,
new_flavor_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_add(self):
# Test to add flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -86,7 +85,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
new_flavor['id'],
self.tenant_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_remove(self):
# Test to remove flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -106,7 +105,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
new_flavor['id'],
self.tenant_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_add_flavor_access_duplicate(self):
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@ -130,7 +129,7 @@ class FlavorsAccessNegativeTestJSON(base.BaseV2ComputeAdminTest):
new_flavor['id'],
self.tenant_id)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_remove_flavor_access_not_found(self):
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)

View File

@ -15,10 +15,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest import test
class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
@ -34,7 +33,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsExtraSpecsTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -61,7 +60,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
cls.client.wait_for_resource_deletion(cls.flavor['id'])
super(FlavorsExtraSpecsTestJSON, cls).tearDownClass()
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_set_get_update_show_unset_keys(self):
# Test to SET, GET, UPDATE, SHOW, UNSET flavor extra
# spec as a user with admin privileges.
@ -101,7 +100,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
self.assertEqual(unset_resp.status, 200)
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_non_admin_get_all_keys(self):
specs = {"key1": "value1", "key2": "value2"}
set_resp, set_body = self.client.set_flavor_extra_spec(
@ -113,7 +112,7 @@ class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
for key in specs:
self.assertEqual(body[key], specs[key])
@attr(type='gate')
@test.attr(type='gate')
def test_flavor_non_admin_get_specific_key(self):
specs = {"key1": "value1", "key2": "value2"}
resp, body = self.client.set_flavor_extra_spec(

View File

@ -16,11 +16,10 @@
# License for the specific language governing permissions and limitations
# under the License.
from tempest.api import compute
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
from tempest import test
class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
@ -35,7 +34,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
@classmethod
def setUpClass(cls):
super(FlavorsExtraSpecsNegativeTestJSON, cls).setUpClass()
if not compute.FLAVOR_EXTRA_DATA_ENABLED:
if not test.is_extension_enabled('FlavorExtraData', 'compute'):
msg = "FlavorExtraData extension not enabled."
raise cls.skipException(msg)
@ -62,7 +61,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
cls.client.wait_for_resource_deletion(cls.flavor['id'])
super(FlavorsExtraSpecsNegativeTestJSON, cls).tearDownClass()
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_set_keys(self):
# Test to SET flavor extra spec as a user without admin privileges.
specs = {"key1": "value1", "key2": "value2"}
@ -71,7 +70,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.flavor['id'],
specs)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_update_specific_key(self):
# non admin user is not allowed to update flavor extra spec
specs = {"key1": "value1", "key2": "value2"}
@ -86,7 +85,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
'key1',
key1='value1_new')
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_unset_keys(self):
specs = {"key1": "value1", "key2": "value2"}
set_resp, set_body = self.client.set_flavor_extra_spec(
@ -97,7 +96,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.flavor['id'],
'key1')
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_unset_nonexistent_key(self):
nonexistent_key = data_utils.rand_name('flavor_key')
self.assertRaises(exceptions.NotFound,
@ -105,14 +104,14 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
self.flavor['id'],
nonexistent_key)
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_get_nonexistent_key(self):
self.assertRaises(exceptions.NotFound,
self.flavors_client.get_flavor_extra_spec_with_key,
self.flavor['id'],
"nonexistent_key")
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_update_mismatch_key(self):
# the key will be updated should be match the key in the body
self.assertRaises(exceptions.BadRequest,
@ -121,7 +120,7 @@ class FlavorsExtraSpecsNegativeTestJSON(base.BaseV2ComputeAdminTest):
"key2",
key1="value")
@attr(type=['negative', 'gate'])
@test.attr(type=['negative', 'gate'])
def test_flavor_update_more_key(self):
# there should be just one item in the request body
self.assertRaises(exceptions.BadRequest,

View File

@ -208,9 +208,14 @@ ComputeFeaturesGroup = [
cfg.BoolOpt('disk_config',
default=True,
help="If false, skip disk config tests"),
cfg.BoolOpt('flavor_extra',
default=True,
help="If false, skip flavor extra data test"),
cfg.ListOpt('api_extensions',
default=['all'],
help='A list of enabled extensions with a special entry all '
'which indicates every extension is enabled'),
cfg.ListOpt('api_v3_extensions',
default=['all'],
help='A list of enabled v3 extensions with a special entry all'
' which indicates every extension is enabled'),
cfg.BoolOpt('change_password',
default=False,
help="Does the test environment support changing the admin "
@ -317,6 +322,16 @@ NetworkGroup = [
"connectivity"),
]
network_feature_group = cfg.OptGroup(name='network-feature-enabled',
title='Enabled network service features')
NetworkFeaturesGroup = [
cfg.ListOpt('api_extensions',
default=['all'],
help='A list of enabled extensions with a special entry all '
'which indicates every extension is enabled'),
]
volume_group = cfg.OptGroup(name='volume',
title='Block Storage Options')
@ -360,7 +375,11 @@ volume_feature_group = cfg.OptGroup(name='volume-feature-enabled',
VolumeFeaturesGroup = [
cfg.BoolOpt('multi_backend',
default=False,
help="Runs Cinder multi-backend test (requires 2 backends)")
help="Runs Cinder multi-backend test (requires 2 backends)"),
cfg.ListOpt('api_extensions',
default=['all'],
help='A list of enabled extensions with a special entry all '
'which indicates every extension is enabled'),
]
@ -659,6 +678,8 @@ class TempestConfig:
register_opt_group(cfg.CONF, image_group, ImageGroup)
register_opt_group(cfg.CONF, image_feature_group, ImageFeaturesGroup)
register_opt_group(cfg.CONF, network_group, NetworkGroup)
register_opt_group(cfg.CONF, network_feature_group,
NetworkFeaturesGroup)
register_opt_group(cfg.CONF, volume_group, VolumeGroup)
register_opt_group(cfg.CONF, volume_feature_group,
VolumeFeaturesGroup)
@ -680,6 +701,7 @@ class TempestConfig:
self.images = cfg.CONF.image
self.image_feature_enabled = cfg.CONF['image-feature-enabled']
self.network = cfg.CONF.network
self.network_feature_enabled = cfg.CONF['network-feature-enabled']
self.volume = cfg.CONF.volume
self.volume_feature_enabled = cfg.CONF['volume-feature-enabled']
self.object_storage = cfg.CONF['object-storage']

View File

@ -123,6 +123,42 @@ def skip_because(*args, **kwargs):
return decorator
def requires_ext(*args, **kwargs):
"""A decorator to skip tests if an extension is not enabled
@param extension
@param service
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*func_args, **func_kwargs):
if not is_extension_enabled(kwargs['extension'],
kwargs['service']):
msg = "Skipped because %s extension: %s is not enabled" % (
kwargs['service'], kwargs['extension'])
raise testtools.TestCase.skipException(msg)
return func(*func_args, **func_kwargs)
return wrapper
return decorator
def is_extension_enabled(extension_name, service):
"""A function that will check the list of enabled extensions from config
"""
configs = config.TempestConfig()
config_dict = {
'compute': configs.compute_feature_enabled.api_extensions,
'compute_v3': configs.compute_feature_enabled.api_v3_extensions,
'volume': configs.volume_feature_enabled.api_extensions,
'network': configs.network_feature_enabled.api_extensions,
}
if config_dict[service][0] == 'all':
return True
if extension_name in config_dict[service]:
return True
return False
# there is a mis-match between nose and testtools for older pythons.
# testtools will set skipException to be either
# unittest.case.SkipTest, unittest2.case.SkipTest or an internal skip