Merge "Fixed up an error message"
diff --git a/etc/whitelist.yaml b/etc/whitelist.yaml
index 1c12b6c..2d8b741 100644
--- a/etc/whitelist.yaml
+++ b/etc/whitelist.yaml
@@ -78,6 +78,8 @@
ceilometer-acentral:
- module: "ceilometer.central.manager"
message: "403 Forbidden"
+ - module: "ceilometer.central.manager"
+ message: "get_samples\\(\\) got an unexpected keyword argument 'resources'"
ceilometer-alarm-evaluator:
- module: "ceilometer.alarm.service"
@@ -133,6 +135,8 @@
message: "but the actual state is deleting to caller"
- module: "nova.openstack.common.rpc.common"
message: "Traceback \\(most recent call last"
+ - module: "nova.openstack.common.threadgroup"
+ message: "Service with host .* topic conductor exists."
n-sch:
- module: "nova.scheduler.filter_scheduler"
diff --git a/run_tempest.sh b/run_tempest.sh
index be9b38a..f6c330d 100755
--- a/run_tempest.sh
+++ b/run_tempest.sh
@@ -13,7 +13,7 @@
echo " -t, --serial Run testr serially"
echo " -C, --config Config file location"
echo " -h, --help Print this usage message"
- echo " -d, --debug Debug this script -- set -o xtrace"
+ echo " -d, --debug Run tests with testtools instead of testr. This allows you to use PDB"
echo " -l, --logging Enable logging"
echo " -L, --logging-config Logging config file location. Default is etc/logging.conf"
echo " -- [TESTROPTIONS] After the first '--' you can pass arbitrary arguments to testr "
@@ -26,6 +26,7 @@
always_venv=0
never_venv=0
no_site_packages=0
+debug=0
force=0
wrapper=""
config_file=""
@@ -50,7 +51,7 @@
-n|--no-site-packages) no_site_packages=1;;
-f|--force) force=1;;
-u|--update) update=1;;
- -d|--debug) set -o xtrace;;
+ -d|--debug) debug=1;;
-C|--config) config_file=$2; shift;;
-s|--smoke) testrargs+="smoke"; noseargs+="--attr=type=smoke";;
-t|--serial) serial=1;;
@@ -94,6 +95,14 @@
testr_init
${wrapper} find . -type f -name "*.pyc" -delete
export OS_TEST_PATH=./tempest/test_discover
+ if [ $debug -eq 1 ]; then
+ if [ "$testrargs" = "" ]; then
+ testrargs="discover ./tempest/test_discover"
+ fi
+ ${wrapper} python -m testtools.run $testrargs
+ return $?
+ fi
+
if [ $serial -eq 1 ]; then
${wrapper} testr run --subunit $testrargs | ${wrapper} subunit-2to1 | ${wrapper} tools/colorizer.py
else
diff --git a/run_tests.sh b/run_tests.sh
index 3f00453..eaa7fd7 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -13,7 +13,7 @@
echo " -p, --pep8 Just run pep8"
echo " -c, --coverage Generate coverage report"
echo " -h, --help Print this usage message"
- echo " -d, --debug Debug this script -- set -o xtrace"
+ echo " -d, --debug Run tests with testtools instead of testr. This allows you to use PDB"
echo " -- [TESTROPTIONS] After the first '--' you can pass arbitrary arguments to testr "
}
@@ -25,6 +25,7 @@
always_venv=0
never_venv=0
no_site_packages=0
+debug=0
force=0
coverage=0
wrapper=""
@@ -48,7 +49,7 @@
-n|--no-site-packages) no_site_packages=1;;
-f|--force) force=1;;
-u|--update) update=1;;
- -d|--debug) set -o xtrace;;
+ -d|--debug) debug=1;;
-p|--pep8) let just_pep8=1;;
-c|--coverage) coverage=1;;
-t|--serial) serial=1;;
@@ -75,6 +76,14 @@
testr_init
${wrapper} find . -type f -name "*.pyc" -delete
export OS_TEST_PATH=./tempest/tests
+ if [ $debug -eq 1 ]; then
+ if [ "$testrargs" = "" ]; then
+ testrargs="discover ./tempest/tests"
+ fi
+ ${wrapper} python -m testtools.run $testrargs
+ return $?
+ fi
+
if [ $serial -eq 1 ]; then
${wrapper} testr run --subunit $testrargs | ${wrapper} subunit-2to1 | ${wrapper} tools/colorizer.py
else
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 362cf2d..98d2550 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -108,7 +108,6 @@
@attr(type='gate')
def test_aggregate_create_update_with_az(self):
# Update an aggregate and ensure properties are updated correctly
- self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
az_name = data_utils.rand_name(self.az_name_prefix)
resp, aggregate = self.client.create_aggregate(aggregate_name, az_name)
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index 0c36837..cfb2f0e 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -14,8 +14,11 @@
# under the License.
from tempest.api.compute import base
+from tempest import config
from tempest.test import attr
+CONF = config.CONF
+
class FixedIPsTestJson(base.BaseV2ComputeAdminTest):
_interface = 'json'
@@ -23,7 +26,7 @@
@classmethod
def setUpClass(cls):
super(FixedIPsTestJson, cls).setUpClass()
- if cls.config.service_available.neutron:
+ if CONF.service_available.neutron:
msg = ("%s skipped as neutron is available" % cls.__name__)
raise cls.skipException(msg)
cls.client = cls.os_adm.fixed_ips_client
diff --git a/tempest/api/compute/admin/test_fixed_ips_negative.py b/tempest/api/compute/admin/test_fixed_ips_negative.py
index bf7fd51..def9810 100644
--- a/tempest/api/compute/admin/test_fixed_ips_negative.py
+++ b/tempest/api/compute/admin/test_fixed_ips_negative.py
@@ -13,9 +13,12 @@
# under the License.
from tempest.api.compute import base
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class FixedIPsNegativeTestJson(base.BaseV2ComputeAdminTest):
_interface = 'json'
@@ -23,7 +26,7 @@
@classmethod
def setUpClass(cls):
super(FixedIPsNegativeTestJson, cls).setUpClass()
- if cls.config.service_available.neutron:
+ if CONF.service_available.neutron:
msg = ("%s skipped as neutron is available" % cls.__name__)
raise cls.skipException(msg)
cls.client = cls.os_adm.fixed_ips_client
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 5539894..441c87d 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -17,10 +17,12 @@
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
import tempest.test
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -37,15 +39,15 @@
os = cls.get_client_manager()
cls.os = os
- cls.build_interval = cls.config.compute.build_interval
- cls.build_timeout = cls.config.compute.build_timeout
- cls.ssh_user = cls.config.compute.ssh_user
- cls.image_ref = cls.config.compute.image_ref
- cls.image_ref_alt = cls.config.compute.image_ref_alt
- cls.flavor_ref = cls.config.compute.flavor_ref
- cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt
- cls.image_ssh_user = cls.config.compute.image_ssh_user
- cls.image_ssh_password = cls.config.compute.image_ssh_password
+ cls.build_interval = CONF.compute.build_interval
+ cls.build_timeout = CONF.compute.build_timeout
+ cls.ssh_user = CONF.compute.ssh_user
+ cls.image_ref = CONF.compute.image_ref
+ cls.image_ref_alt = CONF.compute.image_ref_alt
+ cls.flavor_ref = CONF.compute.flavor_ref
+ cls.flavor_ref_alt = CONF.compute.flavor_ref_alt
+ cls.image_ssh_user = CONF.compute.image_ssh_user
+ cls.image_ssh_password = CONF.compute.image_ssh_password
cls.servers = []
cls.images = []
cls.multi_user = cls.get_multi_user()
@@ -57,14 +59,14 @@
# used in testing. If the test cases are allowed to create
# users (config.compute.allow_tenant_isolation is true,
# then we allow multi-user.
- if not cls.config.compute.allow_tenant_isolation:
- user1 = cls.config.identity.username
- user2 = cls.config.identity.alt_username
+ if not CONF.compute.allow_tenant_isolation:
+ user1 = CONF.identity.username
+ user2 = CONF.identity.alt_username
if not user2 or user1 == user2:
multi_user = False
else:
- user2_password = cls.config.identity.alt_password
- user2_tenant_name = cls.config.identity.alt_tenant_name
+ user2_password = CONF.identity.alt_password
+ user2_tenant_name = CONF.identity.alt_tenant_name
if not user2_password or not user2_tenant_name:
msg = ("Alternate user specified but not alternate "
"tenant or password: alt_tenant_name=%s "
@@ -234,14 +236,14 @@
@classmethod
def setUpClass(cls):
super(BaseV2ComputeAdminTest, cls).setUpClass()
- admin_username = cls.config.compute_admin.username
- admin_password = cls.config.compute_admin.password
- admin_tenant = cls.config.compute_admin.tenant_name
+ admin_username = CONF.compute_admin.username
+ admin_password = CONF.compute_admin.password
+ admin_tenant = CONF.compute_admin.tenant_name
if not (admin_username and admin_password and admin_tenant):
msg = ("Missing Compute Admin API credentials "
"in configuration.")
raise cls.skipException(msg)
- if (cls.config.compute.allow_tenant_isolation or
+ if (CONF.compute.allow_tenant_isolation or
cls.force_tenant_isolation is True):
creds = cls.isolated_creds.get_admin_creds()
admin_username, admin_tenant_name, admin_password = creds
@@ -265,7 +267,7 @@
cls.set_network_resources()
super(BaseV3ComputeTest, cls).setUpClass()
- if not cls.config.compute_feature_enabled.api_v3:
+ if not CONF.compute_feature_enabled.api_v3:
cls.tearDownClass()
skip_msg = ("%s skipped as nova v3 api is not available" %
cls.__name__)
@@ -330,14 +332,14 @@
@classmethod
def setUpClass(cls):
super(BaseV3ComputeAdminTest, cls).setUpClass()
- admin_username = cls.config.compute_admin.username
- admin_password = cls.config.compute_admin.password
- admin_tenant = cls.config.compute_admin.tenant_name
+ admin_username = CONF.compute_admin.username
+ admin_password = CONF.compute_admin.password
+ admin_tenant = CONF.compute_admin.tenant_name
if not (admin_username and admin_password and admin_tenant):
msg = ("Missing Compute Admin API credentials "
"in configuration.")
raise cls.skipException(msg)
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_admin_creds()
admin_username, admin_tenant_name, admin_password = creds
os_adm = clients.Manager(username=admin_username,
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 2c89391..56bd291 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -96,9 +96,7 @@
# to specific server should change the association of the Floating IP
# Create server so as to use for Multiple association
new_name = rand_name('floating_server')
- resp, body = self.servers_client.create_server(new_name,
- self.image_ref,
- self.flavor_ref)
+ resp, body = self.create_test_server(name=new_name)
self.servers_client.wait_for_server_status(body['id'], 'ACTIVE')
self.new_server_id = body['id']
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index e4d83c5..f24343b 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -17,9 +17,12 @@
from tempest.api.compute.floating_ips import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class FloatingIPsNegativeTestJSON(base.BaseFloatingIPsTest):
_interface = 'json'
@@ -40,7 +43,7 @@
cls.floating_ip_ids.append(body[i]['id'])
while True:
cls.non_exist_id = data_utils.rand_int_id(start=999)
- if cls.config.service_available.neutron:
+ if CONF.service_available.neutron:
cls.non_exist_id = str(uuid.uuid4())
if cls.non_exist_id not in cls.floating_ip_ids:
break
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index bb1c828..8d60e7d 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -17,9 +17,12 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class FloatingIPDetailsNegativeTestJSON(base.BaseV2ComputeTest):
_interface = 'json'
@@ -34,7 +37,7 @@
# Negative test:Should not be able to GET the details
# of non-existent floating IP
# Creating a non-existent floatingIP id
- if self.config.service_available.neutron:
+ if CONF.service_available.neutron:
non_exist_id = str(uuid.uuid4())
else:
non_exist_id = data_utils.rand_int_id(start=999)
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index fc09741..4cc36c9 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -15,9 +15,12 @@
from tempest.api.compute import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class ImagesTestJSON(base.BaseV2ComputeTest):
_interface = 'json'
@@ -25,7 +28,7 @@
@classmethod
def setUpClass(cls):
super(ImagesTestJSON, cls).setUpClass()
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
cls.client = cls.images_client
@@ -34,7 +37,7 @@
cls.image_ids = []
if cls.multi_user:
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.alt_manager = clients.Manager(username=username,
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 0cb748b..8d60623 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -55,7 +55,7 @@
def setUpClass(cls):
super(ImagesOneServerTestJSON, cls).setUpClass()
cls.client = cls.images_client
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
@@ -69,7 +69,7 @@
cls.image_ids = []
if cls.multi_user:
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.alt_manager = clients.Manager(username=username,
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 3f93fbe..c96c4a4 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -17,11 +17,14 @@
from tempest.api.compute import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
from tempest.test import attr
from tempest.test import skip_because
+CONF = config.CONF
+
LOG = logging.getLogger(__name__)
@@ -57,7 +60,7 @@
def setUpClass(cls):
super(ImagesOneServerNegativeTestJSON, cls).setUpClass()
cls.client = cls.images_client
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
@@ -71,7 +74,7 @@
cls.image_ids = []
if cls.multi_user:
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.alt_manager = clients.Manager(username=username,
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index c04729c..f82143e 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -14,10 +14,12 @@
# under the License.
from tempest.api.compute import base
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
from tempest.test import attr
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -28,7 +30,7 @@
@classmethod
def setUpClass(cls):
super(ListImageFiltersTestJSON, cls).setUpClass()
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
cls.client = cls.images_client
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index ae1e8d0..ed38442 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -14,8 +14,11 @@
# under the License.
from tempest.api.compute import base
+from tempest import config
from tempest.test import attr
+CONF = config.CONF
+
class ListImagesTestJSON(base.BaseV2ComputeTest):
_interface = 'json'
@@ -23,7 +26,7 @@
@classmethod
def setUpClass(cls):
super(ListImagesTestJSON, cls).setUpClass()
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
cls.client = cls.images_client
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 6aa5cb5..375105e 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -15,8 +15,11 @@
from tempest.api.compute.security_groups import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest.test import attr
+CONF = config.CONF
+
class SecurityGroupRulesTestJSON(base.BaseSecurityGroupsTest):
_interface = 'json'
@@ -25,7 +28,7 @@
def setUpClass(cls):
super(SecurityGroupRulesTestJSON, cls).setUpClass()
cls.client = cls.security_groups_client
- cls.neutron_available = cls.config.service_available.neutron
+ cls.neutron_available = CONF.service_available.neutron
@attr(type='smoke')
def test_security_group_rules_create(self):
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index bff6e14..2c67581 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -121,9 +121,7 @@
# Create server and add the security group created
# above to the server we just created
server_name = data_utils.rand_name('server')
- resp, server = self.servers_client.create_server(server_name,
- self.image_ref,
- self.flavor_ref)
+ resp, server = self.create_test_server(name=server_name)
server_id = server['id']
self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
resp, body = self.servers_client.add_security_group(server_id,
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index 98ed8e8..ce1eada 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -31,7 +31,7 @@
def setUpClass(cls):
super(SecurityGroupsNegativeTestJSON, cls).setUpClass()
cls.client = cls.security_groups_client
- cls.neutron_available = cls.config.service_available.neutron
+ cls.neutron_available = CONF.service_available.neutron
def _delete_security_group(self, securitygroup_id):
resp, _ = self.client.delete_security_group(securitygroup_id)
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 4dacb48..9cdac55 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -14,18 +14,21 @@
# under the License.
from tempest.api.compute import base
+from tempest import config
from tempest import exceptions
from tempest.test import attr
import time
+CONF = config.CONF
+
class AttachInterfacesTestJSON(base.BaseV2ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- if not cls.config.service_available.neutron:
+ if not CONF.service_available.neutron:
raise cls.skipException("Neutron is required")
# This test class requires network and subnet
cls.set_network_resources(network=True, subnet=True)
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 1dc0a39..15b3faa 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -71,7 +71,7 @@
flavor=cls.flavor_ref_alt,
wait_until='ACTIVE')
- cls.fixed_network_name = cls.config.compute.fixed_network_name
+ cls.fixed_network_name = CONF.compute.fixed_network_name
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@attr(type='gate')
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index fea8dd5..f113047 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -369,7 +369,7 @@
resp, server = self.client.shelve_server(self.server_id)
self.assertEqual(202, resp.status)
- offload_time = self.config.compute.shelved_offload_time
+ offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
self.client.wait_for_server_status(self.server_id,
'SHELVED_OFFLOADED',
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 80ac4da..ad4931c 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -14,8 +14,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
class ServerMetadataTestJSON(base.BaseV2ComputeTest):
@@ -28,8 +27,6 @@
cls.quotas = cls.quotas_client
cls.admin_client = cls._get_identity_admin_client()
resp, tenants = cls.admin_client.list_tenants()
- cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
- cls.client.tenant_name][0]
resp, server = cls.create_test_server(meta={}, wait_until='ACTIVE')
cls.server_id = server['id']
@@ -40,7 +37,7 @@
resp, _ = self.client.set_server_metadata(self.server_id, meta)
self.assertEqual(resp.status, 200)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_list_server_metadata(self):
# All metadata key/value pairs for a server should be returned
resp, resp_metadata = self.client.list_server_metadata(self.server_id)
@@ -50,7 +47,7 @@
expected = {'key1': 'value1', 'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_set_server_metadata(self):
# The server's metadata should be replaced with the provided values
# Create a new set of metadata for the server
@@ -64,22 +61,7 @@
resp, resp_metadata = self.client.list_server_metadata(self.server_id)
self.assertEqual(resp_metadata, req_metadata)
- @attr(type='gate')
- def test_server_create_metadata_key_too_long(self):
- # Attempt to start a server with a meta-data key that is > 255
- # characters
-
- # Try a few values
- for sz in [256, 257, 511, 1023]:
- key = "k" * sz
- meta = {key: 'data1'}
- self.assertRaises(exceptions.OverLimit,
- self.create_test_server,
- meta=meta)
-
- # no teardown - all creates should fail
-
- @attr(type='gate')
+ @test.attr(type='gate')
def test_update_server_metadata(self):
# The server's metadata values should be updated to the
# provided values
@@ -93,7 +75,7 @@
expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_update_metadata_empty_body(self):
# The original metadata should not be lost if empty metadata body is
# passed
@@ -103,14 +85,14 @@
expected = {'key1': 'value1', 'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_get_server_metadata_item(self):
# The value for a specific metadata key should be returned
resp, meta = self.client.get_server_metadata_item(self.server_id,
'key2')
self.assertEqual('value2', meta['key2'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_set_server_metadata_item(self):
# The item's value should be updated to the provided value
# Update the metadata value
@@ -124,7 +106,7 @@
expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_delete_server_metadata_item(self):
# The metadata value/key pair should be deleted from the server
resp, meta = self.client.delete_server_metadata_item(self.server_id,
@@ -136,80 +118,6 @@
expected = {'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
- @attr(type=['negative', 'gate'])
- def test_server_metadata_negative(self):
- # Blank key should trigger an error.
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- meta=meta)
-
- # GET on a non-existent server should not succeed
- self.assertRaises(exceptions.NotFound,
- self.client.get_server_metadata_item, 999, 'test2')
-
- # List metadata on a non-existent server should not succeed
- self.assertRaises(exceptions.NotFound,
- self.client.list_server_metadata, 999)
-
- # Raise BadRequest if key in uri does not match
- # the key passed in body.
- meta = {'testkey': 'testvalue'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata_item,
- self.server_id, 'key', meta)
-
- # Set metadata on a non-existent server should not succeed
- meta = {'meta1': 'data1'}
- self.assertRaises(exceptions.NotFound,
- self.client.set_server_metadata, 999, meta)
-
- # An update should not happen for a non-existent image
- meta = {'key1': 'value1', 'key2': 'value2'}
- self.assertRaises(exceptions.NotFound,
- self.client.update_server_metadata, 999, meta)
-
- # Blank key should trigger an error
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.update_server_metadata,
- self.server_id, meta=meta)
-
- # Should not be able to delete metadata item from a non-existent server
- self.assertRaises(exceptions.NotFound,
- self.client.delete_server_metadata_item, 999, 'd')
-
- # Raise a 413 OverLimit exception while exceeding metadata items limit
- # for tenant.
- _, quota_set = self.quotas.get_quota_set(self.tenant_id)
- quota_metadata = quota_set['metadata_items']
- req_metadata = {}
- for num in range(1, quota_metadata + 2):
- req_metadata['key' + str(num)] = 'val' + str(num)
- self.assertRaises(exceptions.OverLimit,
- self.client.set_server_metadata,
- self.server_id, req_metadata)
-
- # Raise a 413 OverLimit exception while exceeding metadata items limit
- # for tenant (update).
- self.assertRaises(exceptions.OverLimit,
- self.client.update_server_metadata,
- self.server_id, req_metadata)
-
- # Raise a bad request error for blank key.
- # set_server_metadata will replace all metadata with new value
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata,
- self.server_id, meta=meta)
-
- # Raise a bad request error for a missing metadata field
- # set_server_metadata will replace all metadata with new value
- meta = {'meta1': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata,
- self.server_id, meta=meta, no_metadata_field=True)
-
class ServerMetadataTestXML(ServerMetadataTestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
new file mode 100644
index 0000000..d12f91c
--- /dev/null
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -0,0 +1,165 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# 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.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class ServerMetadataNegativeTestJSON(base.BaseV2ComputeTest):
+ _interface = 'json'
+
+ @classmethod
+ def setUpClass(cls):
+ super(ServerMetadataNegativeTestJSON, cls).setUpClass()
+ cls.client = cls.servers_client
+ cls.quotas = cls.quotas_client
+ cls.admin_client = cls._get_identity_admin_client()
+ resp, tenants = cls.admin_client.list_tenants()
+ cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+ cls.client.tenant_name][0]
+ resp, server = cls.create_test_server(meta={}, wait_until='ACTIVE')
+
+ cls.server_id = server['id']
+
+ @test.attr(type=['gate', 'negative'])
+ def test_server_create_metadata_key_too_long(self):
+ # Attempt to start a server with a meta-data key that is > 255
+ # characters
+
+ # Tryset_server_metadata_item a few values
+ for sz in [256, 257, 511, 1023]:
+ key = "k" * sz
+ meta = {key: 'data1'}
+ self.assertRaises(exceptions.OverLimit,
+ self.create_test_server,
+ meta=meta)
+
+ # no teardown - all creates should fail
+
+ @test.attr(type=['negative', 'gate'])
+ def test_create_server_metadata_blank_key(self):
+ # Blank key should trigger an error.
+ meta = {'': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.create_test_server,
+ meta=meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_server_metadata_non_existent_server(self):
+ # GET on a non-existent server should not succeed
+ non_existent_server_id = data_utils.rand_uuid()
+ self.assertRaises(exceptions.NotFound,
+ self.client.get_server_metadata_item,
+ non_existent_server_id,
+ 'test2')
+
+ @test.attr(type=['negative', 'gate'])
+ def test_list_server_metadata_non_existent_server(self):
+ # List metadata on a non-existent server should not succeed
+ non_existent_server_id = data_utils.rand_uuid()
+ self.assertRaises(exceptions.NotFound,
+ self.client.list_server_metadata,
+ non_existent_server_id)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_wrong_key_passed_in_body(self):
+ # Raise BadRequest if key in uri does not match
+ # the key passed in body.
+ meta = {'testkey': 'testvalue'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.set_server_metadata_item,
+ self.server_id, 'key', meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_set_metadata_non_existent_server(self):
+ # Set metadata on a non-existent server should not succeed
+ non_existent_server_id = data_utils.rand_uuid()
+ meta = {'meta1': 'data1'}
+ self.assertRaises(exceptions.NotFound,
+ self.client.set_server_metadata,
+ non_existent_server_id,
+ meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_update_metadata_non_existent_server(self):
+ # An update should not happen for a non-existent server
+ non_existent_server_id = data_utils.rand_uuid()
+ meta = {'key1': 'value1', 'key2': 'value2'}
+ self.assertRaises(exceptions.NotFound,
+ self.client.update_server_metadata,
+ non_existent_server_id,
+ meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_update_metadata_with_blank_key(self):
+ # Blank key should trigger an error
+ meta = {'': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.update_server_metadata,
+ self.server_id, meta=meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_delete_metadata_non_existent_server(self):
+ # Should not be able to delete metadata item from a non-existent server
+ non_existent_server_id = data_utils.rand_uuid()
+ self.assertRaises(exceptions.NotFound,
+ self.client.delete_server_metadata_item,
+ non_existent_server_id,
+ 'd')
+
+ @test.attr(type=['negative', 'gate'])
+ def test_metadata_items_limit(self):
+ # Raise a 413 OverLimit exception while exceeding metadata items limit
+ # for tenant.
+ _, quota_set = self.quotas.get_quota_set(self.tenant_id)
+ quota_metadata = quota_set['metadata_items']
+ req_metadata = {}
+ for num in range(1, quota_metadata + 2):
+ req_metadata['key' + str(num)] = 'val' + str(num)
+ self.assertRaises(exceptions.OverLimit,
+ self.client.set_server_metadata,
+ self.server_id, req_metadata)
+
+ # Raise a 413 OverLimit exception while exceeding metadata items limit
+ # for tenant (update).
+ self.assertRaises(exceptions.OverLimit,
+ self.client.update_server_metadata,
+ self.server_id, req_metadata)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_set_server_metadata_blank_key(self):
+ # Raise a bad request error for blank key.
+ # set_server_metadata will replace all metadata with new value
+ meta = {'': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.set_server_metadata,
+ self.server_id, meta=meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_set_server_metadata_missing_metadata(self):
+ # Raise a bad request error for a missing metadata field
+ # set_server_metadata will replace all metadata with new value
+ meta = {'meta1': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.set_server_metadata,
+ self.server_id, meta=meta, no_metadata_field=True)
+
+
+class ServerMetadataNegativeTestXML(ServerMetadataNegativeTestJSON):
+ _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 8f49aec..e0181b9 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -19,9 +19,12 @@
from tempest.api.compute import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest import test
+CONF = config.CONF
+
class ServersNegativeTestJSON(base.BaseV2ComputeTest):
_interface = 'json'
@@ -408,7 +411,7 @@
self.assertEqual(202, resp.status)
self.addCleanup(self.client.unshelve_server, self.server_id)
- offload_time = self.config.compute.shelved_offload_time
+ offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
self.client.wait_for_server_status(self.server_id,
'SHELVED_OFFLOADED',
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 32376eb..95703d4 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -19,12 +19,12 @@
from tempest import config
from tempest import test
+CONF = config.CONF
+
class VirtualInterfacesTestJSON(base.BaseV2ComputeTest):
_interface = 'json'
- CONF = config.CONF
-
@classmethod
def setUpClass(cls):
# This test needs a network and a subnet
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 13b75cf..4774fec 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -16,10 +16,13 @@
from tempest.api.compute import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
from tempest.test import attr
+CONF = config.CONF
+
LOG = logging.getLogger(__name__)
@@ -39,7 +42,7 @@
cls.keypairs_client = cls.os.keypairs_client
cls.security_client = cls.os.security_groups_client
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.alt_manager = clients.Manager(username=username,
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index aac635c..55146e5 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -15,9 +15,12 @@
from tempest.api.compute import base
+from tempest import config
from tempest.openstack.common import log as logging
from tempest import test
+CONF = config.CONF
+
LOG = logging.getLogger(__name__)
@@ -28,11 +31,11 @@
@test.attr(type='gate')
def test_list_extensions(self):
# List of all extensions
- if len(self.config.compute_feature_enabled.api_extensions) == 0:
+ if len(CONF.compute_feature_enabled.api_extensions) == 0:
raise self.skipException('There are not any extensions configured')
resp, extensions = self.extensions_client.list_extensions()
self.assertEqual(200, resp.status)
- ext = self.config.compute_feature_enabled.api_extensions[0]
+ ext = CONF.compute_feature_enabled.api_extensions[0]
if ext == 'all':
self.assertIn('Hosts', map(lambda x: x['name'], extensions))
elif ext:
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index 85d314b..fcd055b 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -23,13 +23,13 @@
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
_host_key = 'OS-EXT-SRV-ATTR:host'
_interface = 'json'
- CONF = config.CONF
-
@classmethod
def setUpClass(cls):
super(LiveBlockMigrationTestJSON, cls).setUpClass()
@@ -57,8 +57,7 @@
def _migrate_server_to(self, server_id, dest_host):
_resp, body = self.admin_servers_client.live_migrate_server(
server_id, dest_host,
- self.config.compute_feature_enabled.
- block_migration_for_live_migration)
+ CONF.compute_feature_enabled.block_migration_for_live_migration)
return body
def _get_host_other_than(self, host):
diff --git a/tempest/api/compute/v3/admin/test_quotas.py b/tempest/api/compute/v3/admin/test_quotas.py
index e116734..ad3519d 100644
--- a/tempest/api/compute/v3/admin/test_quotas.py
+++ b/tempest/api/compute/v3/admin/test_quotas.py
@@ -15,9 +15,12 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest import test
+CONF = config.CONF
+
class QuotasAdminV3TestJSON(base.BaseV3ComputeAdminTest):
_interface = 'json'
@@ -26,7 +29,7 @@
@classmethod
def setUpClass(cls):
super(QuotasAdminV3TestJSON, cls).setUpClass()
- cls.auth_url = cls.config.identity.uri
+ cls.auth_url = CONF.identity.uri
cls.client = cls.quotas_client
cls.adm_client = cls.quotas_admin_client
cls.identity_admin_client = cls._get_identity_admin_client()
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
index f6f5673..a8e1a0a 100644
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ b/tempest/api/compute/v3/admin/test_servers.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import exceptions
+from tempest import test
from tempest.test import attr
from tempest.test import skip_because
@@ -62,6 +63,7 @@
self.assertEqual('200', resp['status'])
self.assertEqual([], servers)
+ @test.skip_because(bug='1265416')
@attr(type='gate')
def test_list_servers_by_admin_with_all_tenants(self):
# Listing servers by admin user with all tenants parameter
diff --git a/tempest/api/compute/v3/images/test_image_metadata.py b/tempest/api/compute/v3/images/test_image_metadata.py
index d0d2daf..e9ca04a 100644
--- a/tempest/api/compute/v3/images/test_image_metadata.py
+++ b/tempest/api/compute/v3/images/test_image_metadata.py
@@ -15,8 +15,11 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest.test import attr
+CONF = config.CONF
+
class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
_interface = 'json'
@@ -24,7 +27,7 @@
@classmethod
def setUpClass(cls):
super(ImagesMetadataTestJSON, cls).setUpClass()
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
diff --git a/tempest/api/compute/v3/images/test_images.py b/tempest/api/compute/v3/images/test_images.py
index 52772e0..4ef6f25 100644
--- a/tempest/api/compute/v3/images/test_images.py
+++ b/tempest/api/compute/v3/images/test_images.py
@@ -15,9 +15,12 @@
from tempest.api.compute import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class ImagesV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
@@ -25,14 +28,14 @@
@classmethod
def setUpClass(cls):
super(ImagesV3TestJSON, cls).setUpClass()
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
cls.client = cls.images_client
cls.servers_client = cls.servers_client
if cls.multi_user:
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.alt_manager = clients.Manager(username=username,
diff --git a/tempest/api/compute/v3/images/test_images_oneserver.py b/tempest/api/compute/v3/images/test_images_oneserver.py
index babf452..992d158 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver.py
@@ -55,7 +55,7 @@
def setUpClass(cls):
super(ImagesOneServerTestJSON, cls).setUpClass()
cls.client = cls.images_client
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
@@ -69,7 +69,7 @@
cls.image_ids = []
if cls.multi_user:
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.alt_manager = clients.Manager(username=username,
@@ -119,10 +119,6 @@
@attr(type=['gate'])
def test_create_image_specify_multibyte_character_image_name(self):
- if self.__class__._interface == "xml":
- # NOTE(sdague): not entirely accurage, but we'd need a ton of work
- # in our XML client to make this good
- raise self.skipException("Not testable in XML")
# prefix character is:
# http://www.fileformat.info/info/unicode/char/1F4A9/index.htm
utf8_name = data_utils.rand_name(u'\xF0\x9F\x92\xA9')
diff --git a/tempest/api/compute/v3/images/test_images_oneserver_negative.py b/tempest/api/compute/v3/images/test_images_oneserver_negative.py
index dc628dc..3404823 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver_negative.py
@@ -17,11 +17,14 @@
from tempest.api.compute import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
from tempest.test import attr
from tempest.test import skip_because
+CONF = config.CONF
+
LOG = logging.getLogger(__name__)
@@ -57,7 +60,7 @@
def setUpClass(cls):
super(ImagesOneServerNegativeTestJSON, cls).setUpClass()
cls.client = cls.images_client
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
@@ -71,7 +74,7 @@
cls.image_ids = []
if cls.multi_user:
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.alt_manager = clients.Manager(username=username,
@@ -85,8 +88,6 @@
@skip_because(bug="1006725")
@attr(type=['negative', 'gate'])
def test_create_image_specify_multibyte_character_image_name(self):
- if self.__class__._interface == "xml":
- raise self.skipException("Not testable in XML")
# invalid multibyte sequence from:
# http://stackoverflow.com/questions/1301402/
# example-invalid-utf8-string
diff --git a/tempest/api/compute/v3/images/test_list_image_filters.py b/tempest/api/compute/v3/images/test_list_image_filters.py
index ad93b3d..82b9625 100644
--- a/tempest/api/compute/v3/images/test_list_image_filters.py
+++ b/tempest/api/compute/v3/images/test_list_image_filters.py
@@ -14,10 +14,12 @@
# under the License.
from tempest.api.compute import base
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
from tempest.test import attr
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -28,7 +30,7 @@
@classmethod
def setUpClass(cls):
super(ListImageFiltersTestJSON, cls).setUpClass()
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
cls.client = cls.images_client
@@ -135,8 +137,6 @@
# Verify only the expected number of results are returned
params = {'limit': '1'}
resp, images = self.client.list_images(params)
- # when _interface='xml', one element for images_links in images
- # ref: Question #224349
self.assertEqual(1, len([x for x in images if 'id' in x]))
@attr(type='gate')
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index aa85424..634d06f 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -14,18 +14,21 @@
# under the License.
from tempest.api.compute import base
+from tempest import config
from tempest import exceptions
from tempest.test import attr
import time
+CONF = config.CONF
+
class AttachInterfacesV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- if not cls.config.service_available.neutron:
+ if not CONF.service_available.neutron:
raise cls.skipException("Neutron is required")
# This test class requires network and subnet
cls.set_network_resources(network=True, subnet=True)
diff --git a/tempest/api/compute/v3/servers/test_attach_volume.py b/tempest/api/compute/v3/servers/test_attach_volume.py
index 2529af9..6ae74ff 100644
--- a/tempest/api/compute/v3/servers/test_attach_volume.py
+++ b/tempest/api/compute/v3/servers/test_attach_volume.py
@@ -36,8 +36,8 @@
@classmethod
def setUpClass(cls):
super(AttachVolumeV3TestJSON, cls).setUpClass()
- cls.device = cls.config.compute.volume_device_name
- if not cls.config.service_available.cinder:
+ cls.device = CONF.compute.volume_device_name
+ if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index 15d6fa2..533a2c2 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -71,7 +71,7 @@
flavor=cls.flavor_ref_alt,
wait_until='ACTIVE')
- cls.fixed_network_name = cls.config.compute.fixed_network_name
+ cls.fixed_network_name = CONF.compute.fixed_network_name
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@attr(type='gate')
@@ -123,7 +123,6 @@
# Verify only the expected number of servers are returned
params = {'limit': 1}
resp, servers = self.client.list_servers(params)
- # when _interface='xml', one element for servers_links in servers
self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
@utils.skip_unless_attr('multiple_images', 'Only one image found')
diff --git a/tempest/api/compute/v3/servers/test_list_servers_negative.py b/tempest/api/compute/v3/servers/test_list_servers_negative.py
index 10d36bf..23f2bda 100644
--- a/tempest/api/compute/v3/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_list_servers_negative.py
@@ -103,7 +103,6 @@
# List servers by specifying limits
resp, body = self.client.list_servers({'limit': 1})
self.assertEqual('200', resp['status'])
- # when _interface='xml', one element for servers_links in servers
self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
@attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index fdf23f8..b8dc85b 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -359,7 +359,7 @@
resp, server = self.client.shelve_server(self.server_id)
self.assertEqual(202, resp.status)
- offload_time = self.config.compute.shelved_offload_time
+ offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
self.client.wait_for_server_status(self.server_id,
'SHELVED_OFFLOADED',
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index e58d33d..191701e 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -19,9 +19,12 @@
from tempest.api.compute import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest import test
+CONF = config.CONF
+
class ServersNegativeV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
@@ -155,9 +158,6 @@
@test.attr(type=['negative', 'gate'])
def test_create_numeric_server_name(self):
# Create a server with a numeric name
- if self.__class__._interface == "xml":
- raise self.skipException("Not testable in XML")
-
server_name = 12345
self.assertRaises(exceptions.BadRequest,
self.create_test_server,
@@ -396,7 +396,7 @@
self.assertEqual(202, resp.status)
self.addCleanup(self.client.unshelve_server, self.server_id)
- offload_time = self.config.compute.shelved_offload_time
+ offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
self.client.wait_for_server_status(self.server_id,
'SHELVED_OFFLOADED',
diff --git a/tempest/api/compute/v3/test_extensions.py b/tempest/api/compute/v3/test_extensions.py
index 32f62d5..775d70a 100644
--- a/tempest/api/compute/v3/test_extensions.py
+++ b/tempest/api/compute/v3/test_extensions.py
@@ -15,9 +15,11 @@
from tempest.api.compute import base
+from tempest import config
from tempest.openstack.common import log as logging
from tempest import test
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -28,11 +30,11 @@
@test.attr(type='gate')
def test_list_extensions(self):
# List of all extensions
- if len(self.config.compute_feature_enabled.api_v3_extensions) == 0:
+ if len(CONF.compute_feature_enabled.api_v3_extensions) == 0:
raise self.skipException('There are not any extensions configured')
resp, extensions = self.extensions_client.list_extensions()
self.assertEqual(200, resp.status)
- ext = self.config.compute_feature_enabled.api_v3_extensions[0]
+ ext = CONF.compute_feature_enabled.api_v3_extensions[0]
if ext == 'all':
self.assertIn('Hosts', map(lambda x: x['name'], extensions))
elif ext:
diff --git a/tempest/api/compute/v3/test_live_block_migration.py b/tempest/api/compute/v3/test_live_block_migration.py
index 087bffb..c881206 100644
--- a/tempest/api/compute/v3/test_live_block_migration.py
+++ b/tempest/api/compute/v3/test_live_block_migration.py
@@ -23,13 +23,13 @@
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class LiveBlockMigrationV3TestJSON(base.BaseV3ComputeAdminTest):
_host_key = 'os-extended-server-attributes:host'
_interface = 'json'
- CONF = config.CONF
-
@classmethod
def setUpClass(cls):
super(LiveBlockMigrationV3TestJSON, cls).setUpClass()
@@ -57,7 +57,7 @@
def _migrate_server_to(self, server_id, dest_host):
_resp, body = self.admin_servers_client.live_migrate_server(
server_id, dest_host,
- self.config.compute_feature_enabled.
+ CONF.compute_feature_enabled.
block_migration_for_live_migration)
return body
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index d51bf13..8d8e3ec 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -36,8 +36,8 @@
@classmethod
def setUpClass(cls):
super(AttachVolumeTestJSON, cls).setUpClass()
- cls.device = cls.config.compute.volume_device_name
- if not cls.config.service_available.cinder:
+ cls.device = CONF.compute.volume_device_name
+ if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index d8cc190..b5a4802 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -55,7 +55,7 @@
# GET Volume
resp, fetched_volume = self.client.get_volume(volume['id'])
self.assertEqual(200, resp.status)
- # Verfication of details of fetched Volume
+ # Verification of details of fetched Volume
self.assertEqual(v_name,
fetched_volume['displayName'],
'The fetched Volume is different '
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index ac89f99..bec2ef4 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -15,8 +15,11 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest.test import attr
+CONF = config.CONF
+
class VolumesTestJSON(base.BaseV2ComputeTest):
@@ -34,7 +37,7 @@
def setUpClass(cls):
super(VolumesTestJSON, cls).setUpClass()
cls.client = cls.volumes_extensions_client
- if not cls.config.service_available.cinder:
+ if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
# Create 3 Volumes
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index e01e349..85b30e2 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -17,9 +17,12 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class VolumesNegativeTest(base.BaseV2ComputeTest):
_interface = 'json'
@@ -28,7 +31,7 @@
def setUpClass(cls):
super(VolumesNegativeTest, cls).setUpClass()
cls.client = cls.volumes_extensions_client
- if not cls.config.service_available.cinder:
+ if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
diff --git a/tempest/api/data_processing/__init__.py b/tempest/api/data_processing/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/data_processing/__init__.py
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
new file mode 100644
index 0000000..ab882cd
--- /dev/null
+++ b/tempest/api/data_processing/base.py
@@ -0,0 +1,91 @@
+# Copyright (c) 2013 Mirantis Inc.
+#
+# 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 import config
+import tempest.test
+
+
+CONF = config.CONF
+
+
+class BaseDataProcessingTest(tempest.test.BaseTestCase):
+ _interface = 'json'
+
+ @classmethod
+ def setUpClass(cls):
+ super(BaseDataProcessingTest, cls).setUpClass()
+ os = cls.get_client_manager()
+ if not CONF.service_available.savanna:
+ raise cls.skipException("Savanna support is required")
+ cls.client = os.data_processing_client
+
+ # set some constants
+ cls.flavor_ref = CONF.compute.flavor_ref
+ cls.simple_node_group_template = {
+ 'plugin_name': 'vanilla',
+ 'hadoop_version': '1.2.1',
+ 'node_processes': [
+ "datanode",
+ "tasktracker"
+ ],
+ 'flavor_id': cls.flavor_ref,
+ 'node_configs': {
+ 'HDFS': {
+ 'Data Node Heap Size': 1024
+ },
+ 'MapReduce': {
+ 'Task Tracker Heap Size': 1024
+ }
+ }
+ }
+
+ # add lists for watched resources
+ cls._node_group_templates = []
+
+ @classmethod
+ def tearDownClass(cls):
+ # cleanup node group templates
+ for ngt_id in cls._node_group_templates:
+ try:
+ cls.client.delete_node_group_template(ngt_id)
+ except Exception:
+ # ignore errors while auto removing created resource
+ pass
+
+ super(BaseDataProcessingTest, cls).tearDownClass()
+
+ @classmethod
+ def create_node_group_template(cls, name, plugin_name, hadoop_version,
+ node_processes, flavor_id,
+ node_configs=None, **kwargs):
+ """Creates watched node group template with specified params.
+
+ It supports passing additional params using kwargs and returns created
+ object. All resources created in this method will be automatically
+ removed in tearDownClass method.
+ """
+
+ resp, body = cls.client.create_node_group_template(name, plugin_name,
+ hadoop_version,
+ node_processes,
+ flavor_id,
+ node_configs,
+ **kwargs)
+
+ # store id of created node group template
+ template_id = body['id']
+ cls._node_group_templates.append(template_id)
+
+ return resp, body, template_id
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
new file mode 100644
index 0000000..ff4fa6a
--- /dev/null
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -0,0 +1,83 @@
+# Copyright (c) 2013 Mirantis Inc.
+#
+# 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.data_processing import base as dp_base
+from tempest.common.utils import data_utils
+from tempest.test import attr
+
+
+class NodeGroupTemplateTest(dp_base.BaseDataProcessingTest):
+ def _create_simple_node_group_template(self, template_name=None):
+ """Creates simple Node Group Template with optional name specified.
+
+ It creates template and ensures response status and template name.
+ Returns id and name of created template.
+ """
+
+ if template_name is None:
+ # generate random name if it's not specified
+ template_name = data_utils.rand_name('savanna')
+
+ # create simple node group template
+ resp, body, template_id = self.create_node_group_template(
+ template_name, **self.simple_node_group_template)
+
+ # ensure that template created successfully
+ self.assertEqual(202, resp.status)
+ self.assertEqual(template_name, body['name'])
+
+ return template_id, template_name
+
+ @attr(type='smoke')
+ def test_node_group_template_create(self):
+ # just create and ensure template
+ self._create_simple_node_group_template()
+
+ @attr(type='smoke')
+ def test_node_group_template_list(self):
+ template_info = self._create_simple_node_group_template()
+
+ # check for node group template in list
+ resp, templates = self.client.list_node_group_templates()
+
+ self.assertEqual(200, resp.status)
+ templates_info = list([(template['id'], template['name'])
+ for template in templates])
+ self.assertIn(template_info, templates_info)
+
+ @attr(type='smoke')
+ def test_node_group_template_get(self):
+ template_id, template_name = self._create_simple_node_group_template()
+
+ # check node group template fetch by id
+ resp, template = self.client.get_node_group_template(template_id)
+
+ self.assertEqual(200, resp.status)
+ self.assertEqual(template_name, template['name'])
+ self.assertEqual(self.simple_node_group_template['plugin_name'],
+ template['plugin_name'])
+ self.assertEqual(self.simple_node_group_template['node_processes'],
+ template['node_processes'])
+ self.assertEqual(self.simple_node_group_template['flavor_id'],
+ template['flavor_id'])
+
+ @attr(type='smoke')
+ def test_node_group_template_delete(self):
+ template_id, template_name = self._create_simple_node_group_template()
+
+ # delete the node group template by id
+ resp = self.client.delete_node_group_template(template_id)
+
+ self.assertEqual('204', resp[0]['status'])
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 0bded78..1bebad4 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -31,7 +31,7 @@
if not CONF.identity_feature_enabled.trust:
raise self.skipException("Trusts aren't enabled")
- self.trustee_username = self.config.identity.alt_username
+ self.trustee_username = CONF.identity.alt_username
self.trust_id = None
def tearDown(self):
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 2e69579..37b848c 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -17,10 +17,13 @@
from tempest import clients
from tempest.common import isolated_creds
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
import tempest.test
+CONF = config.CONF
+
LOG = logging.getLogger(__name__)
@@ -35,10 +38,10 @@
cls._interface = 'json'
cls.isolated_creds = isolated_creds.IsolatedCreds(
cls.__name__, network_resources=cls.network_resources)
- if not cls.config.service_available.glance:
+ if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_primary_creds()
username, tenant_name, password = creds
cls.os = clients.Manager(username=username,
@@ -83,7 +86,7 @@
def setUpClass(cls):
super(BaseV1ImageTest, cls).setUpClass()
cls.client = cls.os.image_client
- if not cls.config.image_feature_enabled.api_v1:
+ if not CONF.image_feature_enabled.api_v1:
msg = "Glance API v1 not supported"
raise cls.skipException(msg)
@@ -92,7 +95,7 @@
@classmethod
def setUpClass(cls):
super(BaseV1ImageMembersTest, cls).setUpClass()
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.os_alt = clients.Manager(username=username,
@@ -124,7 +127,7 @@
def setUpClass(cls):
super(BaseV2ImageTest, cls).setUpClass()
cls.client = cls.os.image_client_v2
- if not cls.config.image_feature_enabled.api_v2:
+ if not CONF.image_feature_enabled.api_v2:
msg = "Glance API v2 not supported"
raise cls.skipException(msg)
@@ -134,7 +137,7 @@
@classmethod
def setUpClass(cls):
super(BaseV2MemberImageTest, cls).setUpClass()
- if cls.config.compute.allow_tenant_isolation:
+ if CONF.compute.allow_tenant_isolation:
creds = cls.isolated_creds.get_alt_creds()
username, tenant_name, password = creds
cls.os_alt = clients.Manager(username=username,
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 0085cd6..1c2c4b0 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -17,10 +17,13 @@
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.openstack.common import log as logging
import tempest.test
+CONF = config.CONF
+
LOG = logging.getLogger(__name__)
@@ -52,8 +55,7 @@
cls.set_network_resources()
super(BaseNetworkTest, cls).setUpClass()
os = clients.Manager(interface=cls._interface)
- cls.network_cfg = os.config.network
- if not cls.config.service_available.neutron:
+ if not CONF.service_available.neutron:
raise cls.skipException("Neutron support is required")
cls.client = os.network_client
cls.networks = []
@@ -123,8 +125,8 @@
@classmethod
def create_subnet(cls, network, ip_version=4):
"""Wrapper utility that returns a test subnet."""
- cidr = netaddr.IPNetwork(cls.network_cfg.tenant_network_cidr)
- mask_bits = cls.network_cfg.tenant_network_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+ mask_bits = CONF.network.tenant_network_mask_bits
# Find a cidr that is not in use yet and create a subnet with it
body = None
failure = None
@@ -260,9 +262,9 @@
@classmethod
def setUpClass(cls):
super(BaseAdminNetworkTest, cls).setUpClass()
- admin_username = cls.config.compute_admin.username
- admin_password = cls.config.compute_admin.password
- admin_tenant = cls.config.compute_admin.tenant_name
+ admin_username = CONF.compute_admin.username
+ admin_password = CONF.compute_admin.password
+ admin_tenant = CONF.compute_admin.tenant_name
if not (admin_username and admin_password and admin_tenant):
msg = ("Missing Administrative Network API credentials "
"in configuration.")
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index a7c1bd2..69367ab 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -15,8 +15,11 @@
from tempest.api.network import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest.test import attr
+CONF = config.CONF
+
class FloatingIPTestJSON(base.BaseNetworkTest):
_interface = 'json'
@@ -43,7 +46,7 @@
@classmethod
def setUpClass(cls):
super(FloatingIPTestJSON, cls).setUpClass()
- cls.ext_net_id = cls.config.network.public_network_id
+ cls.ext_net_id = CONF.network.public_network_id
# Create network, subnet, router and add interface
cls.network = cls.create_network()
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index b1f4608..3aa765c 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -17,9 +17,12 @@
from tempest.api.network import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+CONF = config.CONF
+
class NetworksTestJSON(base.BaseNetworkTest):
_interface = 'json'
@@ -76,8 +79,8 @@
updated_net = body['network']
self.assertEqual(updated_net['name'], new_name)
# Find a cidr that is not in use yet and create a subnet with it
- cidr = netaddr.IPNetwork(self.network_cfg.tenant_network_cidr)
- mask_bits = self.network_cfg.tenant_network_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+ mask_bits = CONF.network.tenant_network_mask_bits
for subnet_cidr in cidr.subnet(mask_bits):
try:
resp, body = self.client.create_subnet(
@@ -321,8 +324,8 @@
@attr(type='smoke')
def test_bulk_create_delete_subnet(self):
# Creates 2 subnets in one request
- cidr = netaddr.IPNetwork(self.network_cfg.tenant_network_cidr)
- mask_bits = self.network_cfg.tenant_network_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+ mask_bits = CONF.network.tenant_network_mask_bits
cidrs = []
for subnet_cidr in cidr.subnet(mask_bits):
cidrs.append(subnet_cidr)
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 426273c..f3fac93 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -17,8 +17,11 @@
from tempest.api.network import base_routers as base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import test
+CONF = config.CONF
+
class RoutersTest(base.BaseRouterTest):
_interface = 'json'
@@ -35,14 +38,14 @@
name = data_utils.rand_name('router-')
resp, create_body = self.client.create_router(
name, external_gateway_info={
- "network_id": self.network_cfg.public_network_id},
+ "network_id": CONF.network.public_network_id},
admin_state_up=False)
self.assertEqual('201', resp['status'])
self.addCleanup(self._delete_router, create_body['router']['id'])
self.assertEqual(create_body['router']['name'], name)
self.assertEqual(
create_body['router']['external_gateway_info']['network_id'],
- self.network_cfg.public_network_id)
+ CONF.network.public_network_id)
self.assertEqual(create_body['router']['admin_state_up'], False)
# Show details of the created router
resp, show_body = self.client.show_router(
@@ -51,7 +54,7 @@
self.assertEqual(show_body['router']['name'], name)
self.assertEqual(
show_body['router']['external_gateway_info']['network_id'],
- self.network_cfg.public_network_id)
+ CONF.network.public_network_id)
self.assertEqual(show_body['router']['admin_state_up'], False)
# List routers and verify if created router is there in response
resp, list_body = self.client.list_routers()
@@ -123,14 +126,14 @@
def _verify_gateway_port(self, router_id):
resp, list_body = self.admin_client.list_ports(
- network_id=self.network_cfg.public_network_id,
+ network_id=CONF.network.public_network_id,
device_id=router_id)
self.assertEqual(len(list_body['ports']), 1)
gw_port = list_body['ports'][0]
fixed_ips = gw_port['fixed_ips']
self.assertEqual(len(fixed_ips), 1)
resp, public_net_body = self.admin_client.show_network(
- self.network_cfg.public_network_id)
+ CONF.network.public_network_id)
public_subnet_id = public_net_body['network']['subnets'][0]
self.assertEqual(fixed_ips[0]['subnet_id'], public_subnet_id)
@@ -140,40 +143,42 @@
self.client.update_router(
router['id'],
external_gateway_info={
- 'network_id': self.network_cfg.public_network_id})
+ 'network_id': CONF.network.public_network_id})
# Verify operation - router
resp, show_body = self.client.show_router(router['id'])
self.assertEqual('200', resp['status'])
self._verify_router_gateway(
router['id'],
- {'network_id': self.network_cfg.public_network_id})
+ {'network_id': CONF.network.public_network_id})
self._verify_gateway_port(router['id'])
+ @test.requires_ext(extension='ext-gw-mode', service='network')
@test.attr(type='smoke')
def test_update_router_set_gateway_with_snat_explicit(self):
router = self.create_router(data_utils.rand_name('router-'))
self.admin_client.update_router_with_snat_gw_info(
router['id'],
external_gateway_info={
- 'network_id': self.network_cfg.public_network_id,
+ 'network_id': CONF.network.public_network_id,
'enable_snat': True})
self._verify_router_gateway(
router['id'],
- {'network_id': self.network_cfg.public_network_id,
+ {'network_id': CONF.network.public_network_id,
'enable_snat': True})
self._verify_gateway_port(router['id'])
+ @test.requires_ext(extension='ext-gw-mode', service='network')
@test.attr(type='smoke')
def test_update_router_set_gateway_without_snat(self):
router = self.create_router(data_utils.rand_name('router-'))
self.admin_client.update_router_with_snat_gw_info(
router['id'],
external_gateway_info={
- 'network_id': self.network_cfg.public_network_id,
+ 'network_id': CONF.network.public_network_id,
'enable_snat': False})
self._verify_router_gateway(
router['id'],
- {'network_id': self.network_cfg.public_network_id,
+ {'network_id': CONF.network.public_network_id,
'enable_snat': False})
self._verify_gateway_port(router['id'])
@@ -181,28 +186,29 @@
def test_update_router_unset_gateway(self):
router = self.create_router(
data_utils.rand_name('router-'),
- external_network_id=self.network_cfg.public_network_id)
+ external_network_id=CONF.network.public_network_id)
self.client.update_router(router['id'], external_gateway_info={})
self._verify_router_gateway(router['id'])
# No gateway port expected
resp, list_body = self.admin_client.list_ports(
- network_id=self.network_cfg.public_network_id,
+ network_id=CONF.network.public_network_id,
device_id=router['id'])
self.assertFalse(list_body['ports'])
+ @test.requires_ext(extension='ext-gw-mode', service='network')
@test.attr(type='smoke')
def test_update_router_reset_gateway_without_snat(self):
router = self.create_router(
data_utils.rand_name('router-'),
- external_network_id=self.network_cfg.public_network_id)
+ external_network_id=CONF.network.public_network_id)
self.admin_client.update_router_with_snat_gw_info(
router['id'],
external_gateway_info={
- 'network_id': self.network_cfg.public_network_id,
+ 'network_id': CONF.network.public_network_id,
'enable_snat': False})
self._verify_router_gateway(
router['id'],
- {'network_id': self.network_cfg.public_network_id,
+ {'network_id': CONF.network.public_network_id,
'enable_snat': False})
self._verify_gateway_port(router['id'])
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
index 089f9ef..64b8a41 100644
--- a/tempest/api/network/test_vpnaas_extensions.py
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -15,8 +15,11 @@
from tempest.api.network import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import test
+CONF = config.CONF
+
class VPNaaSJSON(base.BaseNetworkTest):
_interface = 'json'
@@ -43,7 +46,7 @@
cls.subnet = cls.create_subnet(cls.network)
cls.router = cls.create_router(
data_utils.rand_name("router-"),
- external_network_id=cls.network_cfg.public_network_id)
+ external_network_id=CONF.network.public_network_id)
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
cls.vpnservice = cls.create_vpnservice(cls.subnet['id'],
cls.router['id'])
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index 3b07e17..c8f8096 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
#
# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index e75f21d..f8f29de 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
#
# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index 0d477d9..18199ef 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -43,6 +43,7 @@
# create a container
container_name = data_utils.rand_name(name='TestContainer')
resp, _ = self.container_client.create_container(container_name)
+ self.assertHeaders(resp, 'Container', 'PUT')
self.containers.append(container_name)
# delete container
resp, _ = self.container_client.delete_container(container_name)
@@ -58,12 +59,14 @@
# create a container
container_name = data_utils.rand_name(name='TestContainer')
resp, _ = self.container_client.create_container(container_name)
+ self.assertHeaders(resp, 'Container', 'PUT')
self.containers.append(container_name)
# create object
object_name = data_utils.rand_name(name='TestObject')
data = data_utils.arbitrary_string()
resp, _ = self.object_client.create_object(container_name,
object_name, data)
+ self.assertHeaders(resp, 'Object', 'PUT')
# set object metadata
meta_key = data_utils.rand_name(name='Meta-Test-')
meta_value = data_utils.rand_name(name='MetaValue-')
@@ -71,6 +74,7 @@
resp, _ = self.object_client.update_object_metadata(container_name,
object_name,
orig_metadata)
+ self.assertHeaders(resp, 'Object', 'POST')
# get container contents list
params = {'format': 'json'}
resp, object_list = \
@@ -91,6 +95,7 @@
# create a container
container_name = data_utils.rand_name(name='TestContainer')
resp, _ = self.container_client.create_container(container_name)
+ self.assertHeaders(resp, 'Container', 'PUT')
self.containers.append(container_name)
# update container metadata
metadata = {'name': 'Pictures',
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index 7ca0e51..3aae0a1 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -28,30 +28,34 @@
cls.container_name = data_utils.rand_name(name='TestContainer')
cls.container_client.create_container(cls.container_name)
+ def setUp(self):
+ super(ObjectExpiryTest, self).setUp()
+ # create object
+ self.object_name = data_utils.rand_name(name='TestObject')
+ resp, _ = self.object_client.create_object(self.container_name,
+ self.object_name, '')
+
@classmethod
def tearDownClass(cls):
cls.delete_containers([cls.container_name])
super(ObjectExpiryTest, cls).tearDownClass()
def _test_object_expiry(self, metadata):
- # create object
- object_name = data_utils.rand_name(name='TestObject')
- resp, _ = self.object_client.create_object(self.container_name,
- object_name, '')
# update object metadata
resp, _ = \
self.object_client.update_object_metadata(self.container_name,
- object_name, metadata,
+ self.object_name,
+ metadata,
metadata_prefix='')
# verify object metadata
resp, _ = \
self.object_client.list_object_metadata(self.container_name,
- object_name)
+ self.object_name)
self.assertEqual(resp['status'], '200')
self.assertHeaders(resp, 'Object', 'HEAD')
self.assertIn('x-delete-at', resp)
resp, body = self.object_client.get_object(self.container_name,
- object_name)
+ self.object_name)
self.assertEqual(resp['status'], '200')
self.assertHeaders(resp, 'Object', 'GET')
self.assertIn('x-delete-at', resp)
@@ -61,7 +65,7 @@
# object should not be there anymore
self.assertRaises(exceptions.NotFound, self.object_client.get_object,
- self.container_name, object_name)
+ self.container_name, self.object_name)
@attr(type='gate')
def test_get_object_after_expiry_time(self):
diff --git a/tempest/api/object_storage/test_object_formpost_negative.py b/tempest/api/object_storage/test_object_formpost_negative.py
index a07e277..e02a058 100644
--- a/tempest/api/object_storage/test_object_formpost_negative.py
+++ b/tempest/api/object_storage/test_object_formpost_negative.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
#
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 13f197b..bca9b93 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -14,7 +14,6 @@
# under the License.
import hashlib
-import re
from tempest.api.object_storage import base
from tempest.common import custom_matchers
@@ -264,23 +263,15 @@
resp, _ = self.object_client.list_object_metadata(
self.container_name, object_name)
- # Check only the existence of common headers with custom matcher
- self.assertThat(resp, custom_matchers.ExistsAllResponseHeaders(
- 'Object', 'HEAD'))
- self.assertIn('x-object-manifest', resp)
-
# Etag value of a large object is enclosed in double-quotations.
- # This is a special case, therefore the formats of response headers
- # are checked without a custom matcher.
+ # After etag quotes are checked they are removed and the response is
+ # checked if all common headers are present and well formatted
self.assertTrue(resp['etag'].startswith('\"'))
self.assertTrue(resp['etag'].endswith('\"'))
- self.assertTrue(resp['etag'].strip('\"').isalnum())
- self.assertTrue(re.match("^\d+\.?\d*\Z", resp['x-timestamp']))
- self.assertNotEqual(len(resp['content-type']), 0)
- self.assertTrue(re.match("^tx[0-9a-f]*-[0-9a-f]*$",
- resp['x-trans-id']))
- self.assertNotEqual(len(resp['date']), 0)
- self.assertEqual(resp['accept-ranges'], 'bytes')
+ resp['etag'] = resp['etag'].strip('"')
+ self.assertHeaders(resp, 'Object', 'HEAD')
+
+ self.assertIn('x-object-manifest', resp)
self.assertEqual(resp['x-object-manifest'],
'%s/%s/' % (self.container_name, object_name))
diff --git a/tempest/api/object_storage/test_object_slo.py b/tempest/api/object_storage/test_object_slo.py
index ee7f6a4..0443a80 100644
--- a/tempest/api/object_storage/test_object_slo.py
+++ b/tempest/api/object_storage/test_object_slo.py
@@ -14,7 +14,6 @@
import hashlib
import json
-import re
from tempest.api.object_storage import base
from tempest.common import custom_matchers
@@ -95,29 +94,19 @@
return object_name
def _assertHeadersSLO(self, resp, method):
- # Check the existence of common headers with custom matcher
- self.assertThat(resp, custom_matchers.ExistsAllResponseHeaders(
- 'Object', method))
# When sending GET or HEAD requests to SLO the response contains
# 'X-Static-Large-Object' header
if method in ('GET', 'HEAD'):
self.assertIn('x-static-large-object', resp)
+ self.assertEqual(resp['x-static-large-object'], 'True')
- # Check common headers for all HTTP methods
- self.assertTrue(re.match("^tx[0-9a-f]*-[0-9a-f]*$",
- resp['x-trans-id']))
- self.assertTrue(resp['content-length'].isdigit())
- self.assertNotEqual(len(resp['date']), 0)
# Etag value of a large object is enclosed in double-quotations.
+ # After etag quotes are checked they are removed and the response is
+ # checked if all common headers are present and well formatted
self.assertTrue(resp['etag'].startswith('\"'))
self.assertTrue(resp['etag'].endswith('\"'))
- self.assertTrue(resp['etag'].strip('\"').isalnum())
- # Check header formats for a specific method
- if method in ('GET', 'HEAD'):
- self.assertTrue(re.match("^\d+\.?\d*\Z", resp['x-timestamp']))
- self.assertNotEqual(len(resp['content-type']), 0)
- self.assertEqual(resp['accept-ranges'], 'bytes')
- self.assertEqual(resp['x-static-large-object'], 'True')
+ resp['etag'] = resp['etag'].strip('"')
+ self.assertHeaders(resp, 'Object', method)
@test.attr(type='gate')
def test_upload_manifest(self):
diff --git a/tempest/api/object_storage/test_object_temp_url_negative.py b/tempest/api/object_storage/test_object_temp_url_negative.py
index cc507c5..cf24f66 100644
--- a/tempest/api/object_storage/test_object_temp_url_negative.py
+++ b/tempest/api/object_storage/test_object_temp_url_negative.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
#
# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
diff --git a/tempest/api/orchestration/stacks/test_templates.py b/tempest/api/orchestration/stacks/test_templates.py
index 6cbc872..2da819d 100644
--- a/tempest/api/orchestration/stacks/test_templates.py
+++ b/tempest/api/orchestration/stacks/test_templates.py
@@ -10,17 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-import logging
-
from tempest.api.orchestration import base
from tempest.common.utils import data_utils
-from tempest import exceptions
from tempest.test import attr
-LOG = logging.getLogger(__name__)
-
-
class TemplateYAMLTestJSON(base.BaseOrchestrationTest):
_interface = 'json'
@@ -59,14 +53,6 @@
self.parameters)
self.assertEqual('200', resp['status'])
- @attr(type=['gate', 'negative'])
- def test_validate_template_url(self):
- """Validating template passing url to it."""
- self.assertRaises(exceptions.BadRequest,
- self.client.validate_template_url,
- template_url=self.invalid_template_url,
- parameters=self.parameters)
-
class TemplateAWSTestJSON(TemplateYAMLTestJSON):
template = """
diff --git a/tempest/api/orchestration/stacks/test_templates_negative.py b/tempest/api/orchestration/stacks/test_templates_negative.py
new file mode 100644
index 0000000..c55f6ee
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_templates_negative.py
@@ -0,0 +1,62 @@
+# Copyright 2014 NEC Corporation. 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.api.orchestration import base
+from tempest import exceptions
+from tempest import test
+
+
+class TemplateYAMLNegativeTestJSON(base.BaseOrchestrationTest):
+ _interface = 'json'
+
+ template = """
+HeatTemplateFormatVersion: '2012-12-12'
+Description: |
+ Template which creates only a new user
+Resources:
+ CfnUser:
+ Type: AWS::IAM::User
+"""
+
+ invalid_template_url = 'http://www.example.com/template.yaml'
+
+ @classmethod
+ def setUpClass(cls):
+ super(TemplateYAMLNegativeTestJSON, cls).setUpClass()
+ cls.client = cls.orchestration_client
+ cls.parameters = {}
+
+ @test.attr(type=['gate', 'negative'])
+ def test_validate_template_url(self):
+ """Validating template passing url to it."""
+ self.assertRaises(exceptions.BadRequest,
+ self.client.validate_template_url,
+ template_url=self.invalid_template_url,
+ parameters=self.parameters)
+
+
+class TemplateAWSNegativeTestJSON(TemplateYAMLNegativeTestJSON):
+ template = """
+{
+ "AWSTemplateFormatVersion" : "2010-09-09",
+ "Description" : "Template which creates only a new user",
+ "Resources" : {
+ "CfnUser" : {
+ "Type" : "AWS::IAM::User"
+ }
+ }
+}
+"""
+
+ invalid_template_url = 'http://www.example.com/template.template'
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 0ea999a..4add2c1 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -15,27 +15,12 @@
from tempest.api.volume import base
from tempest.common.utils import data_utils
-from tempest.services.volume.json.admin import volume_types_client
from tempest.test import attr
-class VolumeTypesTest(base.BaseVolumeV1Test):
+class VolumeTypesTest(base.BaseVolumeV1AdminTest):
_interface = "json"
- @classmethod
- def setUpClass(cls):
- super(VolumeTypesTest, cls).setUpClass()
- adm_user = cls.config.identity.admin_username
- adm_pass = cls.config.identity.admin_password
- adm_tenant = cls.config.identity.admin_tenant_name
- auth_url = cls.config.identity.uri
-
- cls.client = volume_types_client.VolumeTypesClientJSON(cls.config,
- adm_user,
- adm_pass,
- auth_url,
- adm_tenant)
-
def _delete_volume(self, volume_id):
resp, _ = self.volumes_client.delete_volume(volume_id)
self.assertEqual(202, resp.status)
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 6d23c0a..ec732d1 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from testtools.matchers import ContainsAll
+
from tempest.api.volume import base
from tempest import test
@@ -49,7 +51,7 @@
# Get the metadata of the volume
resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
self.assertEqual(200, resp.status)
- self.assertEqual(metadata, body)
+ self.assertThat(body.items(), ContainsAll(metadata.items()))
# Delete one item metadata of the volume
rsp, body = self.volumes_client.delete_volume_metadata_item(
self.volume_id,
@@ -76,7 +78,7 @@
# Get the metadata of the volume
resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
self.assertEqual(200, resp.status)
- self.assertEqual(metadata, body)
+ self.assertThat(body.items(), ContainsAll(metadata.items()))
# Update metadata
resp, body = self.volumes_client.update_volume_metadata(
self.volume_id,
@@ -85,7 +87,7 @@
# Get the metadata of the volume
resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
self.assertEqual(200, resp.status)
- self.assertEqual(update, body)
+ self.assertThat(body.items(), ContainsAll(update.items()))
@test.attr(type='gate')
def test_update_volume_metadata_item(self):
@@ -93,9 +95,6 @@
metadata = {"key1": "value1",
"key2": "value2",
"key3": "value3"}
- create_expect = {"key1": "value1",
- "key2": "value2",
- "key3": "value3"}
update_item = {"key3": "value3_update"}
expect = {"key1": "value1",
"key2": "value2",
@@ -105,7 +104,7 @@
self.volume_id,
metadata)
self.assertEqual(200, resp.status)
- self.assertEqual(create_expect, body)
+ self.assertThat(body.items(), ContainsAll(metadata.items()))
# Update metadata item
resp, body = self.volumes_client.update_volume_metadata_item(
self.volume_id,
@@ -115,7 +114,7 @@
# Get the metadata of the volume
resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
self.assertEqual(200, resp.status)
- self.assertEqual(expect, body)
+ self.assertThat(body.items(), ContainsAll(expect.items()))
class VolumeMetadataTestXML(VolumeMetadataTest):
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 79a4365..eb4f3e9 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from testtools.matchers import ContainsAll
+
from tempest.api.volume import base
from tempest.common.utils import data_utils
from tempest.test import attr
@@ -66,16 +68,16 @@
self.assertEqual(200, resp.status)
self.assertEqual(v_name,
fetched_volume['display_name'],
- 'The fetched Volume is different '
+ 'The fetched Volume name is different '
'from the created Volume')
self.assertEqual(volume['id'],
fetched_volume['id'],
- 'The fetched Volume is different '
+ 'The fetched Volume id is different '
'from the created Volume')
- self.assertEqual(metadata,
- fetched_volume['metadata'],
- 'The fetched Volume is different '
- 'from the created Volume')
+ self.assertThat(fetched_volume['metadata'].items(),
+ ContainsAll(metadata.items()),
+ 'The fetched Volume metadata misses data '
+ 'from the created Volume')
# NOTE(jdg): Revert back to strict true/false checking
# after fix for bug #1227837 merges
@@ -102,7 +104,10 @@
self.assertEqual(volume['id'], updated_volume['id'])
self.assertEqual(new_v_name, updated_volume['display_name'])
self.assertEqual(new_desc, updated_volume['display_description'])
- self.assertEqual(metadata, updated_volume['metadata'])
+ self.assertThat(updated_volume['metadata'].items(),
+ ContainsAll(metadata.items()),
+ 'The fetched Volume metadata misses data '
+ 'from the created Volume')
# NOTE(jdg): Revert back to strict true/false checking
# after fix for bug #1227837 merges
@@ -112,18 +117,6 @@
if 'imageRef' not in kwargs:
self.assertEqual(boot_flag, False)
- @attr(type='gate')
- def test_volume_get_metadata_none(self):
- # Create a volume without passing metadata, get details, and delete
-
- # Create a volume without metadata
- volume = self.create_volume(metadata={})
-
- # GET Volume
- resp, fetched_volume = self.client.get_volume(volume['id'])
- self.assertEqual(200, resp.status)
- self.assertEqual(fetched_volume['metadata'], {})
-
@attr(type='smoke')
def test_volume_create_get_update_delete(self):
self._volume_create_get_update_delete()
diff --git a/tempest/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index f71a2de..5dcb708 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -18,7 +18,10 @@
import subprocess
import tempest.cli
+from tempest import config
+
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -30,6 +33,13 @@
their own. They only verify the structure of output if present.
"""
+ @classmethod
+ def setUpClass(cls):
+ if not CONF.service_available.cinder:
+ msg = ("%s skipped as Cinder is not available" % cls.__name__)
+ raise cls.skipException(msg)
+ super(SimpleReadOnlyCinderClientTest, cls).setUpClass()
+
def test_cinder_fake_action(self):
self.assertRaises(subprocess.CalledProcessError,
self.cinder,
@@ -47,6 +57,12 @@
def test_cinder_volumes_list(self):
self.cinder('list')
+ self.cinder('list', params='--all-tenants 1')
+ self.cinder('list', params='--all-tenants 0')
+ self.assertRaises(subprocess.CalledProcessError,
+ self.cinder,
+ 'list',
+ params='--all-tenants bad')
def test_cinder_quota_class_show(self):
"""This CLI can accept and string as param."""
diff --git a/tempest/cli/simple_read_only/test_glance.py b/tempest/cli/simple_read_only/test_glance.py
index 0e0f995..b558190 100644
--- a/tempest/cli/simple_read_only/test_glance.py
+++ b/tempest/cli/simple_read_only/test_glance.py
@@ -35,6 +35,13 @@
their own. They only verify the structure of output if present.
"""
+ @classmethod
+ def setUpClass(cls):
+ if not CONF.service_available.glance:
+ msg = ("%s skipped as Glance is not available" % cls.__name__)
+ raise cls.skipException(msg)
+ super(SimpleReadOnlyGlanceClientTest, cls).setUpClass()
+
def test_glance_fake_action(self):
self.assertRaises(subprocess.CalledProcessError,
self.glance,
diff --git a/tempest/cli/simple_read_only/test_nova.py b/tempest/cli/simple_read_only/test_nova.py
index 822e531..f8ba971 100644
--- a/tempest/cli/simple_read_only/test_nova.py
+++ b/tempest/cli/simple_read_only/test_nova.py
@@ -42,6 +42,13 @@
"""
+ @classmethod
+ def setUpClass(cls):
+ if not CONF.service_available.nova:
+ msg = ("%s skipped as Nova is not available" % cls.__name__)
+ raise cls.skipException(msg)
+ super(SimpleReadOnlyNovaClientTest, cls).setUpClass()
+
def test_admin_fake_action(self):
self.assertRaises(subprocess.CalledProcessError,
self.nova,
diff --git a/tempest/cli/simple_read_only/test_nova_manage.py b/tempest/cli/simple_read_only/test_nova_manage.py
index a92e8da..13a1589 100644
--- a/tempest/cli/simple_read_only/test_nova_manage.py
+++ b/tempest/cli/simple_read_only/test_nova_manage.py
@@ -16,9 +16,11 @@
import subprocess
import tempest.cli
+from tempest import config
from tempest.openstack.common import log as logging
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -34,6 +36,13 @@
"""
+ @classmethod
+ def setUpClass(cls):
+ if not CONF.service_available.nova:
+ msg = ("%s skipped as Nova is not available" % cls.__name__)
+ raise cls.skipException(msg)
+ super(SimpleReadOnlyNovaManageTest, cls).setUpClass()
+
def test_admin_fake_action(self):
self.assertRaises(subprocess.CalledProcessError,
self.nova_manage,
diff --git a/tempest/clients.py b/tempest/clients.py
index 4c40ce0..d0a1491 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -17,7 +17,6 @@
from tempest import exceptions
from tempest.openstack.common import log as logging
from tempest.services.baremetal.v1.client_json import BaremetalClientJSON
-from tempest.services.baremetal.v1.client_xml import BaremetalClientXML
from tempest.services import botoclients
from tempest.services.compute.json.aggregates_client import \
AggregatesClientJSON
@@ -217,7 +216,6 @@
if interface == 'xml':
self.certificates_client = CertificatesClientXML(*client_args)
- self.baremetal_client = BaremetalClientXML(*client_args)
self.servers_client = ServersClientXML(*client_args)
self.limits_client = LimitsClientXML(*client_args)
self.images_client = ImagesClientXML(*client_args)
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 2ce05ee..d8afab3 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -354,7 +354,7 @@
# file. Closing socket too soon will cause response
# reads to fail with socket IO error 'Bad file descriptor'.
self.sock = None
- super(VerifiedHTTPSConnection, self).close()
+ httplib.HTTPSConnection.close(self)
class ResponseBodyIterator(object):
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index ea614c3..146fac9 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -146,18 +146,28 @@
else:
self.identity_admin_client.tenants.delete(tenant)
- def _create_creds(self, suffix=None, admin=False):
- data_utils.rand_name_root = data_utils.rand_name(self.name)
- if suffix:
- data_utils.rand_name_root += suffix
- tenant_name = data_utils.rand_name_root + "-tenant"
+ def _create_creds(self, suffix="", admin=False):
+ """Create random credentials under the following schema.
+
+ If the name contains a '.' is the full class path of something, and
+ we don't really care. If it isn't, it's probably a meaningful name,
+ so use it.
+
+ For logging purposes, -user and -tenant are long and redundant,
+ don't use them. The user# will be sufficient to figure it out.
+ """
+ if '.' in self.name:
+ root = ""
+ else:
+ root = self.name
+
+ tenant_name = data_utils.rand_name(root) + suffix
tenant_desc = tenant_name + "-desc"
tenant = self._create_tenant(name=tenant_name,
description=tenant_desc)
- if suffix:
- data_utils.rand_name_root += suffix
- username = data_utils.rand_name_root + "-user"
- email = data_utils.rand_name_root + "@example.com"
+
+ username = data_utils.rand_name(root) + suffix
+ email = data_utils.rand_name(root) + suffix + "@example.com"
user = self._create_user(username, self.password,
tenant, email)
if admin:
@@ -462,7 +472,11 @@
net_client = self.network_admin_client
for cred in self.isolated_net_resources:
network, subnet, router = self.isolated_net_resources.get(cred)
- if self.network_resources.get('router'):
+ LOG.debug("Clearing network: %(network)s, "
+ "subnet: %(subnet)s, router: %(router)s",
+ {'network': network, 'subnet': subnet, 'router': router})
+ if (not self.network_resources or
+ self.network_resources.get('router')):
try:
if self.tempest_client:
net_client.remove_router_interface_with_subnet_id(
@@ -475,13 +489,16 @@
router['name'])
pass
self._clear_isolated_router(router['id'], router['name'])
- if self.network_resources.get('network'):
+ if (not self.network_resources or
+ self.network_resources.get('network')):
# TODO(mlavalle) This method call will be removed once patch
# https://review.openstack.org/#/c/46563/ merges in Neutron
self._cleanup_ports(network['id'])
- if self.network_resources.get('subnet'):
+ if (not self.network_resources or
+ self.network_resources.get('subnet')):
self._clear_isolated_subnet(subnet['id'], subnet['name'])
- if self.network_resources.get('network'):
+ if (not self.network_resources or
+ self.network_resources.get('network')):
self._clear_isolated_network(network['id'], network['name'])
def clear_isolated_creds(self):
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index a90c924..b1fef99 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -126,21 +126,6 @@
return self.token
- def basic_auth(self, user, password, auth_url):
- """
- Provides authentication for the target API.
- """
-
- params = {}
- params['headers'] = {'User-Agent': 'Test-Client', 'X-Auth-User': user,
- 'X-Auth-Key': password}
-
- resp, body = self.http_obj.request(auth_url, 'GET', **params)
- try:
- return resp['x-auth-token'], resp['x-server-management-url']
- except Exception:
- raise
-
def keystone_auth(self, user, password, auth_url, service, tenant_name):
"""
Provides authentication via Keystone using v2 identity API.
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index 2b2963c..cd32720 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -30,8 +30,12 @@
return uuid.uuid4().hex
-def rand_name(name='test'):
- return name + "-tempest-" + str(random.randint(1, 0x7fffffff))
+def rand_name(name=''):
+ randbits = str(random.randint(1, 0x7fffffff))
+ if name:
+ return name + '-' + randbits
+ else:
+ return randbits
def rand_int_id(start=0, end=0x7fffffff):
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 5276d49..bb2fcfb 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -14,7 +14,6 @@
import time
from tempest.common.ssh import Client
-from tempest.common import utils
from tempest import config
from tempest.exceptions import ServerUnreachable
@@ -76,11 +75,10 @@
return output
def get_boot_time(self):
- cmd = 'date -d "`cut -f1 -d. /proc/uptime` seconds ago" \
- "+%Y-%m-%d %H:%M:%S"'
- boot_time_string = self.ssh_client.exec_command(cmd)
- boot_time_string = boot_time_string.replace('\n', '')
- return time.strptime(boot_time_string, utils.LAST_REBOOT_TIME_FORMAT)
+ cmd = 'cut -f1 -d. /proc/uptime'
+ boot_secs = self.ssh_client.exec_command(cmd)
+ boot_time = time.time() - int(boot_secs)
+ return time.localtime(boot_time)
def write_to_console(self, message):
message = re.sub("([$\\`])", "\\\\\\\\\\1", message)
diff --git a/tempest/openstack/common/fixture/mockpatch.py b/tempest/openstack/common/fixture/mockpatch.py
index 858e77c..d7dcc11 100644
--- a/tempest/openstack/common/fixture/mockpatch.py
+++ b/tempest/openstack/common/fixture/mockpatch.py
@@ -22,14 +22,15 @@
class PatchObject(fixtures.Fixture):
"""Deal with code around mock."""
- def __init__(self, obj, attr, **kwargs):
+ def __init__(self, obj, attr, new=mock.DEFAULT, **kwargs):
self.obj = obj
self.attr = attr
self.kwargs = kwargs
+ self.new = new
def setUp(self):
super(PatchObject, self).setUp()
- _p = mock.patch.object(self.obj, self.attr, **self.kwargs)
+ _p = mock.patch.object(self.obj, self.attr, self.new, **self.kwargs)
self.mock = _p.start()
self.addCleanup(_p.stop)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 04882f3..32b9d7e 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -128,15 +128,16 @@
def _get_object_storage_client(self, username, password, tenant_name):
auth_url = self.config.identity.uri
- # add current tenant to Member group.
+ # add current tenant to swift operator role group.
keystone_admin = self._get_identity_client(
self.config.identity.admin_username,
self.config.identity.admin_password,
self.config.identity.admin_tenant_name)
- # enable test user to operate swift by adding Member role to him.
+ # enable test user to operate swift by adding operator role to him.
roles = keystone_admin.roles.list()
- member_role = [role for role in roles if role.name == 'Member'][0]
+ operator_role = self.config.object_storage.operator_role
+ member_role = [role for role in roles if role.name == operator_role][0]
# NOTE(maurosr): This is surrounded in the try-except block cause
# neutron tests doesn't have tenant isolation.
try:
@@ -233,7 +234,7 @@
def setUpClass(cls):
super(OfficialClientTest, cls).setUpClass()
cls.isolated_creds = isolated_creds.IsolatedCreds(
- __name__, tempest_client=False,
+ cls.__name__, tempest_client=False,
network_resources=cls.network_resources)
username, password, tenant_name = cls.credentials()
diff --git a/tempest/services/baremetal/v1/client_xml.py b/tempest/services/baremetal/v1/client_xml.py
deleted file mode 100644
index 4c214fe..0000000
--- a/tempest/services/baremetal/v1/client_xml.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# 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.common import rest_client
-from tempest.services.baremetal.v1 import base_v1 as base
-from tempest.services.compute.xml import common as xml
-
-
-class BaremetalClientXML(rest_client.RestClientXML, base.BaremetalClientV1):
- """Tempest REST client for Ironic XML API v1."""
-
- def __init__(self, config, username, password, auth_url, tenant_name=None):
- super(BaremetalClientXML, self).__init__(config, username, password,
- auth_url, tenant_name)
-
- self.serialize = self.json_to_xml
- self.deserialize = xml.xml_to_json
-
- def json_to_xml(self, object_type, object_dict):
- """
- Brainlessly converts a specification of an object to XML string.
-
- :param object_type: Kind of the object.
- :param object_dict: Specification of the object attributes as a dict.
- :return: An XML string that corresponds to the specification.
-
- """
- root = xml.Element(object_type)
-
- for attr_name, value in object_dict:
- # Handle nested dictionaries
- if isinstance(value, dict):
- value = self.json_to_xml(attr_name, value)
-
- root.append(xml.Element(attr_name, value))
-
- return str(xml.Document(root))
-
- def _patch_request(self, resource_name, uuid, patch_object):
- """Changes Content-Type header to application/json for jsonpatch."""
-
- self.headers['Content-Type'] = 'application/json'
- try:
- super(self)._patch_request(self, resource_name, uuid, patch_object)
- finally:
- self.headers['Content-Type'] = 'application/xml'
diff --git a/tempest/services/compute/v3/json/flavors_client.py b/tempest/services/compute/v3/json/flavors_client.py
index f8c762c..739c870 100644
--- a/tempest/services/compute/v3/json/flavors_client.py
+++ b/tempest/services/compute/v3/json/flavors_client.py
@@ -63,7 +63,7 @@
if kwargs.get('swap'):
post_body['swap'] = kwargs.get('swap')
if kwargs.get('rxtx'):
- post_body['rxtx_factor'] = kwargs.get('rxtx')
+ post_body['os-flavor-rxtx:rxtx_factor'] = kwargs.get('rxtx')
if kwargs.get('is_public'):
post_body['flavor-access:is_public'] = kwargs.get('is_public')
post_body = json.dumps({'flavor': post_body})
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 8d46bf3..d8662e9 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
diff --git a/tempest/services/telemetry/telemetry_client_base.py b/tempest/services/telemetry/telemetry_client_base.py
index 59127b9..883bf33 100644
--- a/tempest/services/telemetry/telemetry_client_base.py
+++ b/tempest/services/telemetry/telemetry_client_base.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
diff --git a/tempest/services/telemetry/xml/telemetry_client.py b/tempest/services/telemetry/xml/telemetry_client.py
index 245ccb5..ac5fa32 100644
--- a/tempest/services/telemetry/xml/telemetry_client.py
+++ b/tempest/services/telemetry/xml/telemetry_client.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
diff --git a/tempest/tests/test_ssh.py b/tempest/tests/test_ssh.py
index 09bb588..429ed56 100644
--- a/tempest/tests/test_ssh.py
+++ b/tempest/tests/test_ssh.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright 2014 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may