Merge "Don't run extensions list if service isn't available"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index f7f74b8..48ca905 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -494,7 +494,7 @@
# Matching flavors become parameters for scenario tests
# (string value)
-#flavor_regex=^m1.(micro|nano|tiny)$
+#flavor_regex=^m1.nano$
# SSH verification in tests is skippedfor matching images
# (string value)
diff --git a/requirements.txt b/requirements.txt
index 3b3e1fa..8c0f872 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,22 +1,22 @@
pbr>=0.5.21,<1.0
anyjson>=0.3.3
nose
-httplib2
-jsonschema>=1.3.0,!=1.4.0
-testtools>=0.9.32
+httplib2>=0.7.5
+jsonschema>=2.0.0,<3.0.0
+testtools>=0.9.34
lxml>=2.3
boto>=2.12.0,!=2.13.0
-paramiko>=1.8.0
+paramiko>=1.9.0
netaddr>=0.7.6
python-glanceclient>=0.9.0
-python-keystoneclient>=0.4.1
+python-keystoneclient>=0.4.2
python-novaclient>=2.15.0
-python-neutronclient>=2.3.0,<3
+python-neutronclient>=2.3.3,<3
python-cinderclient>=1.0.6
python-heatclient>=0.2.3
python-swiftclient>=1.5
testresources>=0.2.4
-keyring>=1.6.1,<2.0
+keyring>=1.6.1,<2.0,>=2.1
testrepository>=0.0.17
oslo.config>=1.2.0
six>=1.4.1
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 441c87d..f8b0051 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -229,6 +229,18 @@
cls.password = server['adminPass']
return server['id']
+ @classmethod
+ def delete_volume(cls, volume_id):
+ """Deletes the given volume and waits for it to be gone."""
+ try:
+ resp, _ = cls.volumes_extensions_client.delete_volume(volume_id)
+ # TODO(mriedem): We should move the wait_for_resource_deletion
+ # into the delete_volume method as a convenience to the caller.
+ cls.volumes_extensions_client.wait_for_resource_deletion(volume_id)
+ except exceptions.NotFound:
+ LOG.warn("Unable to delete volume '%s' since it was not found. "
+ "Maybe it was already deleted?" % volume_id)
+
class BaseV2ComputeAdminTest(BaseV2ComputeTest):
"""Base test case class for Compute Admin V2 API tests."""
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 15b3faa..15b7b9e 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -143,6 +143,22 @@
# when _interface='xml', one element for servers_links in servers
self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
+ @attr(type='gate')
+ def test_list_servers_filter_by_zero_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 0}
+ resp, servers = self.client.list_servers(params)
+ self.assertEqual(0, len(servers['servers']))
+
+ @attr(type='gate')
+ def test_list_servers_filter_by_exceed_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 100000}
+ resp, servers = self.client.list_servers(params)
+ resp, all_servers = self.client.list_servers()
+ self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
+ len([x for x in servers['servers'] if 'id' in x]))
+
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@attr(type='gate')
def test_list_servers_detailed_filter_by_image(self):
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index d12f91c..e52ea4a 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
diff --git a/tempest/api/compute/v3/admin/test_aggregates.py b/tempest/api/compute/v3/admin/test_aggregates.py
index 956eddd..205b7a4 100644
--- a/tempest/api/compute/v3/admin/test_aggregates.py
+++ b/tempest/api/compute/v3/admin/test_aggregates.py
@@ -19,7 +19,7 @@
from tempest import test
-class AggregatesAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class AggregatesAdminV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Aggregates API that require admin privileges
@@ -30,7 +30,7 @@
@classmethod
def setUpClass(cls):
- super(AggregatesAdminV3TestJSON, cls).setUpClass()
+ super(AggregatesAdminV3Test, cls).setUpClass()
cls.client = cls.aggregates_admin_client
cls.user_client = cls.aggregates_client
cls.aggregate_name_prefix = 'test_aggregate_'
diff --git a/tempest/api/compute/v3/admin/test_aggregates_negative.py b/tempest/api/compute/v3/admin/test_aggregates_negative.py
index da3568a..078056a 100644
--- a/tempest/api/compute/v3/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/v3/admin/test_aggregates_negative.py
@@ -20,7 +20,7 @@
from tempest import test
-class AggregatesAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class AggregatesAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Aggregates API that require admin privileges
@@ -30,7 +30,7 @@
@classmethod
def setUpClass(cls):
- super(AggregatesAdminNegativeV3TestJSON, cls).setUpClass()
+ super(AggregatesAdminNegativeV3Test, cls).setUpClass()
cls.client = cls.aggregates_admin_client
cls.user_client = cls.aggregates_client
cls.aggregate_name_prefix = 'test_aggregate_'
diff --git a/tempest/api/compute/v3/admin/test_availability_zone.py b/tempest/api/compute/v3/admin/test_availability_zone.py
index 5ced2b1..57ac869 100644
--- a/tempest/api/compute/v3/admin/test_availability_zone.py
+++ b/tempest/api/compute/v3/admin/test_availability_zone.py
@@ -17,7 +17,7 @@
from tempest.test import attr
-class AZAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class AZAdminV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Availability Zone API List
@@ -27,7 +27,7 @@
@classmethod
def setUpClass(cls):
- super(AZAdminV3TestJSON, cls).setUpClass()
+ super(AZAdminV3Test, cls).setUpClass()
cls.client = cls.availability_zone_admin_client
cls.non_adm_client = cls.availability_zone_client
diff --git a/tempest/api/compute/v3/admin/test_availability_zone_negative.py b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
index 60cd1d6..180f298 100644
--- a/tempest/api/compute/v3/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
@@ -18,7 +18,7 @@
from tempest.test import attr
-class AZAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class AZAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Availability Zone API List
@@ -28,7 +28,7 @@
@classmethod
def setUpClass(cls):
- super(AZAdminNegativeV3TestJSON, cls).setUpClass()
+ super(AZAdminNegativeV3Test, cls).setUpClass()
cls.client = cls.availability_zone_admin_client
cls.non_adm_client = cls.availability_zone_client
diff --git a/tempest/api/compute/v3/admin/test_flavors_access.py b/tempest/api/compute/v3/admin/test_flavors_access.py
index d668640..43dc726 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access.py
@@ -18,7 +18,7 @@
from tempest import test
-class FlavorsAccessV3TestJSON(base.BaseV3ComputeAdminTest):
+class FlavorsAccessV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Flavor Access API extension.
@@ -29,7 +29,7 @@
@classmethod
def setUpClass(cls):
- super(FlavorsAccessV3TestJSON, cls).setUpClass()
+ super(FlavorsAccessV3Test, cls).setUpClass()
cls.client = cls.flavors_admin_client
admin_client = cls._get_identity_admin_client()
@@ -44,6 +44,7 @@
cls.vcpus = 1
cls.disk = 10
+ @test.skip_because(bug='1265416')
@test.attr(type='gate')
def test_flavor_access_list_with_private_flavor(self):
# Test to list flavor access successfully by querying private flavor
@@ -63,6 +64,7 @@
self.assertEqual(str(new_flavor_id), str(first_flavor['flavor_id']))
self.assertEqual(self.adm_tenant_id, first_flavor['tenant_id'])
+ @test.skip_because(bug='1265416')
@test.attr(type='gate')
def test_flavor_access_add_remove(self):
# Test to add and remove flavor access to a given tenant.
diff --git a/tempest/api/compute/v3/admin/test_flavors_access_negative.py b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
index 8595b2c..6a2e826 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
@@ -21,7 +21,7 @@
from tempest import test
-class FlavorsAccessNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class FlavorsAccessNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Flavor Access API extension.
@@ -32,7 +32,7 @@
@classmethod
def setUpClass(cls):
- super(FlavorsAccessNegativeV3TestJSON, cls).setUpClass()
+ super(FlavorsAccessNegativeV3Test, cls).setUpClass()
cls.client = cls.flavors_admin_client
admin_client = cls._get_identity_admin_client()
@@ -63,6 +63,7 @@
self.client.list_flavor_access,
new_flavor_id)
+ @test.skip_because(bug='1265416')
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_add(self):
# Test to add flavor access as a user without admin privileges.
@@ -79,6 +80,7 @@
new_flavor['id'],
self.tenant_id)
+ @test.skip_because(bug='1265416')
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_remove(self):
# Test to remove flavor access as a user without admin privileges.
@@ -99,6 +101,7 @@
new_flavor['id'],
self.tenant_id)
+ @test.skip_because(bug='1265416')
@test.attr(type=['negative', 'gate'])
def test_add_flavor_access_duplicate(self):
# Create a new flavor.
@@ -123,6 +126,7 @@
new_flavor['id'],
self.tenant_id)
+ @test.skip_because(bug='1265416')
@test.attr(type=['negative', 'gate'])
def test_remove_flavor_access_not_found(self):
# Create a new flavor.
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
index 0363fcb..4d22027 100644
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
@@ -18,7 +18,7 @@
from tempest import test
-class FlavorsExtraSpecsV3TestJSON(base.BaseV3ComputeAdminTest):
+class FlavorsExtraSpecsV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Flavor Extra Spec API extension.
@@ -30,7 +30,7 @@
@classmethod
def setUpClass(cls):
- super(FlavorsExtraSpecsV3TestJSON, cls).setUpClass()
+ super(FlavorsExtraSpecsV3Test, cls).setUpClass()
cls.client = cls.flavors_admin_client
flavor_name = data_utils.rand_name('test_flavor')
@@ -53,7 +53,7 @@
def tearDownClass(cls):
resp, body = cls.client.delete_flavor(cls.flavor['id'])
cls.client.wait_for_resource_deletion(cls.flavor['id'])
- super(FlavorsExtraSpecsV3TestJSON, cls).tearDownClass()
+ super(FlavorsExtraSpecsV3Test, cls).tearDownClass()
@test.attr(type='gate')
def test_flavor_set_get_update_show_unset_keys(self):
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
index 0f300a1..98e6e3d 100644
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
@@ -20,7 +20,7 @@
from tempest import test
-class FlavorsExtraSpecsNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class FlavorsExtraSpecsNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Negative Tests Flavor Extra Spec API extension.
@@ -31,7 +31,7 @@
@classmethod
def setUpClass(cls):
- super(FlavorsExtraSpecsNegativeV3TestJSON, cls).setUpClass()
+ super(FlavorsExtraSpecsNegativeV3Test, cls).setUpClass()
cls.client = cls.flavors_admin_client
flavor_name = data_utils.rand_name('test_flavor')
@@ -54,7 +54,7 @@
def tearDownClass(cls):
resp, body = cls.client.delete_flavor(cls.flavor['id'])
cls.client.wait_for_resource_deletion(cls.flavor['id'])
- super(FlavorsExtraSpecsNegativeV3TestJSON, cls).tearDownClass()
+ super(FlavorsExtraSpecsNegativeV3Test, cls).tearDownClass()
@test.attr(type=['negative', 'gate'])
def test_flavor_non_admin_set_keys(self):
diff --git a/tempest/api/compute/v3/admin/test_hosts.py b/tempest/api/compute/v3/admin/test_hosts.py
index 8199ee8..2c9369f 100644
--- a/tempest/api/compute/v3/admin/test_hosts.py
+++ b/tempest/api/compute/v3/admin/test_hosts.py
@@ -17,7 +17,7 @@
from tempest import test
-class HostsAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class HostsAdminV3Test(base.BaseV3ComputeAdminTest):
"""
Tests hosts API using admin privileges.
@@ -27,7 +27,7 @@
@classmethod
def setUpClass(cls):
- super(HostsAdminV3TestJSON, cls).setUpClass()
+ super(HostsAdminV3Test, cls).setUpClass()
cls.client = cls.hosts_admin_client
@test.attr(type='gate')
diff --git a/tempest/api/compute/v3/admin/test_hosts_negative.py b/tempest/api/compute/v3/admin/test_hosts_negative.py
index aa50618..ac5d7de 100644
--- a/tempest/api/compute/v3/admin/test_hosts_negative.py
+++ b/tempest/api/compute/v3/admin/test_hosts_negative.py
@@ -18,7 +18,7 @@
from tempest import test
-class HostsAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class HostsAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Tests hosts API using admin privileges.
@@ -28,7 +28,7 @@
@classmethod
def setUpClass(cls):
- super(HostsAdminNegativeV3TestJSON, cls).setUpClass()
+ super(HostsAdminNegativeV3Test, cls).setUpClass()
cls.client = cls.hosts_admin_client
cls.non_admin_client = cls.hosts_client
diff --git a/tempest/api/compute/v3/admin/test_hypervisor.py b/tempest/api/compute/v3/admin/test_hypervisor.py
index 8bd4abb..0f96bba 100644
--- a/tempest/api/compute/v3/admin/test_hypervisor.py
+++ b/tempest/api/compute/v3/admin/test_hypervisor.py
@@ -17,7 +17,7 @@
from tempest.test import attr
-class HypervisorAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class HypervisorAdminV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Hypervisors API that require admin privileges
@@ -27,7 +27,7 @@
@classmethod
def setUpClass(cls):
- super(HypervisorAdminV3TestJSON, cls).setUpClass()
+ super(HypervisorAdminV3Test, cls).setUpClass()
cls.client = cls.hypervisor_admin_client
def _list_hypervisors(self):
diff --git a/tempest/api/compute/v3/admin/test_hypervisor_negative.py b/tempest/api/compute/v3/admin/test_hypervisor_negative.py
index 63e8cae..aee354a 100644
--- a/tempest/api/compute/v3/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/v3/admin/test_hypervisor_negative.py
@@ -21,7 +21,7 @@
from tempest.test import attr
-class HypervisorAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class HypervisorAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Hypervisors API that require admin privileges
@@ -31,7 +31,7 @@
@classmethod
def setUpClass(cls):
- super(HypervisorAdminNegativeV3TestJSON, cls).setUpClass()
+ super(HypervisorAdminNegativeV3Test, cls).setUpClass()
cls.client = cls.hypervisor_admin_client
cls.non_adm_client = cls.hypervisor_client
diff --git a/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py b/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py
index 9651338..a86b7f5 100644
--- a/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py
@@ -20,13 +20,13 @@
from tempest import test
-class InstanceUsageAuditLogV3TestJSON(base.BaseV3ComputeAdminTest):
+class InstanceUsageAuditLogV3Test(base.BaseV3ComputeAdminTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(InstanceUsageAuditLogV3TestJSON, cls).setUpClass()
+ super(InstanceUsageAuditLogV3Test, cls).setUpClass()
cls.adm_client = cls.instance_usages_audit_log_admin_client
@test.attr(type='gate')
diff --git a/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py b/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py
index 8ed1a98..0438825 100644
--- a/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py
+++ b/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py
@@ -18,13 +18,13 @@
from tempest import test
-class InstanceUsageLogNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class InstanceUsageLogNegativeV3Test(base.BaseV3ComputeAdminTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(InstanceUsageLogNegativeV3TestJSON, cls).setUpClass()
+ super(InstanceUsageLogNegativeV3Test, cls).setUpClass()
cls.adm_client = cls.instance_usages_audit_log_admin_client
@test.attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/v3/admin/test_quotas.py b/tempest/api/compute/v3/admin/test_quotas.py
index ad3519d..ccb9d8e 100644
--- a/tempest/api/compute/v3/admin/test_quotas.py
+++ b/tempest/api/compute/v3/admin/test_quotas.py
@@ -22,13 +22,13 @@
CONF = config.CONF
-class QuotasAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class QuotasAdminV3Test(base.BaseV3ComputeAdminTest):
_interface = 'json'
force_tenant_isolation = True
@classmethod
def setUpClass(cls):
- super(QuotasAdminV3TestJSON, cls).setUpClass()
+ super(QuotasAdminV3Test, cls).setUpClass()
cls.auth_url = CONF.identity.uri
cls.client = cls.quotas_client
cls.adm_client = cls.quotas_admin_client
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
index a8e1a0a..ef9eedc 100644
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ b/tempest/api/compute/v3/admin/test_servers.py
@@ -20,7 +20,7 @@
from tempest.test import skip_because
-class ServersAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class ServersAdminV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Servers API using admin privileges
@@ -30,7 +30,7 @@
@classmethod
def setUpClass(cls):
- super(ServersAdminV3TestJSON, cls).setUpClass()
+ super(ServersAdminV3Test, cls).setUpClass()
cls.client = cls.servers_admin_client
cls.non_admin_client = cls.servers_client
cls.flavors_client = cls.flavors_admin_client
diff --git a/tempest/api/compute/v3/admin/test_servers_negative.py b/tempest/api/compute/v3/admin/test_servers_negative.py
index a86bdfc..a6a5736 100644
--- a/tempest/api/compute/v3/admin/test_servers_negative.py
+++ b/tempest/api/compute/v3/admin/test_servers_negative.py
@@ -20,7 +20,7 @@
from tempest.test import attr
-class ServersAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class ServersAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Servers API using admin privileges
@@ -30,7 +30,7 @@
@classmethod
def setUpClass(cls):
- super(ServersAdminNegativeV3TestJSON, cls).setUpClass()
+ super(ServersAdminNegativeV3Test, cls).setUpClass()
cls.client = cls.servers_admin_client
cls.non_adm_client = cls.servers_client
cls.flavors_client = cls.flavors_admin_client
diff --git a/tempest/api/compute/v3/admin/test_services.py b/tempest/api/compute/v3/admin/test_services.py
index 9e55e78..8d6e549 100644
--- a/tempest/api/compute/v3/admin/test_services.py
+++ b/tempest/api/compute/v3/admin/test_services.py
@@ -18,7 +18,7 @@
from tempest.test import attr
-class ServicesAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class ServicesAdminV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Services API. List and Enable/Disable require admin privileges.
@@ -28,7 +28,7 @@
@classmethod
def setUpClass(cls):
- super(ServicesAdminV3TestJSON, cls).setUpClass()
+ super(ServicesAdminV3Test, cls).setUpClass()
cls.client = cls.services_admin_client
@attr(type='gate')
diff --git a/tempest/api/compute/v3/admin/test_services_negative.py b/tempest/api/compute/v3/admin/test_services_negative.py
index 1382347..c270842 100644
--- a/tempest/api/compute/v3/admin/test_services_negative.py
+++ b/tempest/api/compute/v3/admin/test_services_negative.py
@@ -19,7 +19,7 @@
from tempest.test import attr
-class ServicesAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class ServicesAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
"""
Tests Services API. List and Enable/Disable require admin privileges.
@@ -29,7 +29,7 @@
@classmethod
def setUpClass(cls):
- super(ServicesAdminNegativeV3TestJSON, cls).setUpClass()
+ super(ServicesAdminNegativeV3Test, cls).setUpClass()
cls.client = cls.services_admin_client
cls.non_admin_client = cls.services_client
diff --git a/tempest/api/compute/v3/admin/test_simple_tenant_usage.py b/tempest/api/compute/v3/admin/test_simple_tenant_usage.py
index 7ee835b..e16332f 100644
--- a/tempest/api/compute/v3/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/v3/admin/test_simple_tenant_usage.py
@@ -21,13 +21,13 @@
import time
-class TenantUsagesV3TestJSON(base.BaseV3ComputeAdminTest):
+class TenantUsagesV3Test(base.BaseV3ComputeAdminTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(TenantUsagesV3TestJSON, cls).setUpClass()
+ super(TenantUsagesV3Test, cls).setUpClass()
cls.adm_client = cls.tenant_usages_admin_client
cls.client = cls.tenant_usages_client
cls.identity_client = cls._get_identity_admin_client()
diff --git a/tempest/api/compute/v3/admin/test_simple_tenant_usage_negative.py b/tempest/api/compute/v3/admin/test_simple_tenant_usage_negative.py
index 00068dc..17849c5 100644
--- a/tempest/api/compute/v3/admin/test_simple_tenant_usage_negative.py
+++ b/tempest/api/compute/v3/admin/test_simple_tenant_usage_negative.py
@@ -21,13 +21,13 @@
from tempest.test import attr
-class TenantUsagesNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+class TenantUsagesNegativeV3Test(base.BaseV3ComputeAdminTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(TenantUsagesNegativeV3TestJSON, cls).setUpClass()
+ super(TenantUsagesNegativeV3Test, cls).setUpClass()
cls.adm_client = cls.os_adm.tenant_usages_client
cls.client = cls.os.tenant_usages_client
cls.identity_client = cls._get_identity_admin_client()
diff --git a/tempest/api/compute/v3/certificates/test_certificates.py b/tempest/api/compute/v3/certificates/test_certificates.py
index b24f4d8..5c980c0 100644
--- a/tempest/api/compute/v3/certificates/test_certificates.py
+++ b/tempest/api/compute/v3/certificates/test_certificates.py
@@ -17,7 +17,7 @@
from tempest.test import attr
-class CertificatesV3TestJSON(base.BaseV3ComputeTest):
+class CertificatesV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@attr(type='gate')
diff --git a/tempest/api/compute/v3/images/test_image_metadata.py b/tempest/api/compute/v3/images/test_image_metadata.py
index e9ca04a..cd4e5e7 100644
--- a/tempest/api/compute/v3/images/test_image_metadata.py
+++ b/tempest/api/compute/v3/images/test_image_metadata.py
@@ -21,12 +21,12 @@
CONF = config.CONF
-class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
+class ImagesMetadataTest(base.BaseV2ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ImagesMetadataTestJSON, cls).setUpClass()
+ super(ImagesMetadataTest, cls).setUpClass()
if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
@@ -47,10 +47,10 @@
@classmethod
def tearDownClass(cls):
cls.client.delete_image(cls.image_id)
- super(ImagesMetadataTestJSON, cls).tearDownClass()
+ super(ImagesMetadataTest, cls).tearDownClass()
def setUp(self):
- super(ImagesMetadataTestJSON, self).setUp()
+ super(ImagesMetadataTest, self).setUp()
meta = {'key1': 'value1', 'key2': 'value2'}
resp, _ = self.client.set_image_metadata(self.image_id, meta)
self.assertEqual(resp.status, 200)
diff --git a/tempest/api/compute/v3/images/test_image_metadata_negative.py b/tempest/api/compute/v3/images/test_image_metadata_negative.py
index 6e7cc8f..e76af2c 100644
--- a/tempest/api/compute/v3/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/v3/images/test_image_metadata_negative.py
@@ -19,12 +19,12 @@
from tempest.test import attr
-class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
+class ImagesMetadataTest(base.BaseV2ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ImagesMetadataTestJSON, cls).setUpClass()
+ super(ImagesMetadataTest, cls).setUpClass()
cls.client = cls.images_client
@attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/v3/images/test_images.py b/tempest/api/compute/v3/images/test_images.py
index 4ef6f25..bbb84fb 100644
--- a/tempest/api/compute/v3/images/test_images.py
+++ b/tempest/api/compute/v3/images/test_images.py
@@ -22,12 +22,12 @@
CONF = config.CONF
-class ImagesV3TestJSON(base.BaseV3ComputeTest):
+class ImagesV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ImagesV3TestJSON, cls).setUpClass()
+ super(ImagesV3Test, cls).setUpClass()
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_oneserver.py b/tempest/api/compute/v3/images/test_images_oneserver.py
index 992d158..18772df 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver.py
@@ -26,7 +26,7 @@
LOG = logging.getLogger(__name__)
-class ImagesOneServerTestJSON(base.BaseV2ComputeTest):
+class ImagesOneServerTest(base.BaseV2ComputeTest):
_interface = 'json'
def tearDown(self):
@@ -34,12 +34,12 @@
for image_id in self.image_ids:
self.client.delete_image(image_id)
self.image_ids.remove(image_id)
- super(ImagesOneServerTestJSON, self).tearDown()
+ super(ImagesOneServerTest, self).tearDown()
def setUp(self):
# NOTE(afazekas): Normally we use the same server with all test cases,
# but if it has an issue, we build a new one
- super(ImagesOneServerTestJSON, self).setUp()
+ super(ImagesOneServerTest, self).setUp()
# Check if the server is in a clean state after test
try:
self.servers_client.wait_for_server_status(self.server_id,
@@ -53,7 +53,7 @@
@classmethod
def setUpClass(cls):
- super(ImagesOneServerTestJSON, cls).setUpClass()
+ super(ImagesOneServerTest, cls).setUpClass()
cls.client = cls.images_client
if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
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 3404823..bc276d1 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver_negative.py
@@ -28,7 +28,7 @@
LOG = logging.getLogger(__name__)
-class ImagesOneServerNegativeTestJSON(base.BaseV2ComputeTest):
+class ImagesOneServerNegativeTest(base.BaseV2ComputeTest):
_interface = 'json'
def tearDown(self):
@@ -36,12 +36,12 @@
for image_id in self.image_ids:
self.client.delete_image(image_id)
self.image_ids.remove(image_id)
- super(ImagesOneServerNegativeTestJSON, self).tearDown()
+ super(ImagesOneServerNegativeTest, self).tearDown()
def setUp(self):
# NOTE(afazekas): Normally we use the same server with all test cases,
# but if it has an issue, we build a new one
- super(ImagesOneServerNegativeTestJSON, self).setUp()
+ super(ImagesOneServerNegativeTest, self).setUp()
# Check if the server is in a clean state after test
try:
self.servers_client.wait_for_server_status(self.server_id,
@@ -58,7 +58,7 @@
@classmethod
def setUpClass(cls):
- super(ImagesOneServerNegativeTestJSON, cls).setUpClass()
+ super(ImagesOneServerNegativeTest, cls).setUpClass()
cls.client = cls.images_client
if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
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 82b9625..457ca53 100644
--- a/tempest/api/compute/v3/images/test_list_image_filters.py
+++ b/tempest/api/compute/v3/images/test_list_image_filters.py
@@ -24,12 +24,12 @@
LOG = logging.getLogger(__name__)
-class ListImageFiltersTestJSON(base.BaseV2ComputeTest):
+class ListImageFiltersTest(base.BaseV2ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ListImageFiltersTestJSON, cls).setUpClass()
+ super(ListImageFiltersTest, cls).setUpClass()
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/keypairs/test_keypairs.py b/tempest/api/compute/v3/keypairs/test_keypairs.py
index 4aef8b1..8eef811 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs.py
@@ -18,12 +18,12 @@
from tempest import test
-class KeyPairsV3TestJSON(base.BaseV3ComputeTest):
+class KeyPairsV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(KeyPairsV3TestJSON, cls).setUpClass()
+ super(KeyPairsV3Test, cls).setUpClass()
cls.client = cls.keypairs_client
def _delete_keypair(self, keypair_name):
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
index 87f62b7..ae22ccc 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
@@ -20,12 +20,12 @@
from tempest import test
-class KeyPairsNegativeV3TestJSON(base.BaseV3ComputeTest):
+class KeyPairsNegativeV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(KeyPairsNegativeV3TestJSON, cls).setUpClass()
+ super(KeyPairsNegativeV3Test, cls).setUpClass()
cls.client = cls.keypairs_client
def _create_keypair(self, keypair_name, pub_key=None):
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index 634d06f..272cb53 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -23,7 +23,7 @@
CONF = config.CONF
-class AttachInterfacesV3TestJSON(base.BaseV3ComputeTest):
+class AttachInterfacesV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
@@ -32,7 +32,7 @@
raise cls.skipException("Neutron is required")
# This test class requires network and subnet
cls.set_network_resources(network=True, subnet=True)
- super(AttachInterfacesV3TestJSON, cls).setUpClass()
+ super(AttachInterfacesV3Test, cls).setUpClass()
cls.client = cls.interfaces_client
def _check_interface(self, iface, port_id=None, network_id=None,
diff --git a/tempest/api/compute/v3/servers/test_attach_volume.py b/tempest/api/compute/v3/servers/test_attach_volume.py
index 6ae74ff..d693be5 100644
--- a/tempest/api/compute/v3/servers/test_attach_volume.py
+++ b/tempest/api/compute/v3/servers/test_attach_volume.py
@@ -23,19 +23,19 @@
CONF = config.CONF
-class AttachVolumeV3TestJSON(base.BaseV3ComputeTest):
+class AttachVolumeV3Test(base.BaseV3ComputeTest):
_interface = 'json'
run_ssh = CONF.compute.run_ssh
def __init__(self, *args, **kwargs):
- super(AttachVolumeV3TestJSON, self).__init__(*args, **kwargs)
+ super(AttachVolumeV3Test, self).__init__(*args, **kwargs)
self.server = None
self.volume = None
self.attached = False
@classmethod
def setUpClass(cls):
- super(AttachVolumeV3TestJSON, cls).setUpClass()
+ super(AttachVolumeV3Test, cls).setUpClass()
cls.device = CONF.compute.volume_device_name
if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
index cb02894..7a4c877 100644
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ b/tempest/api/compute/v3/servers/test_create_server.py
@@ -27,14 +27,14 @@
CONF = config.CONF
-class ServersV3TestJSON(base.BaseV3ComputeTest):
+class ServersV3Test(base.BaseV3ComputeTest):
_interface = 'json'
run_ssh = CONF.compute.run_ssh
disk_config = 'AUTO'
@classmethod
def setUpClass(cls):
- super(ServersV3TestJSON, cls).setUpClass()
+ super(ServersV3Test, cls).setUpClass()
cls.meta = {'hello': 'world'}
cls.accessIPv4 = '1.1.1.1'
cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
@@ -115,14 +115,14 @@
self.assertTrue(linux_client.hostname_equals_servername(self.name))
-class ServersWithSpecificFlavorV3TestJSON(base.BaseV3ComputeAdminTest):
+class ServersWithSpecificFlavorV3Test(base.BaseV3ComputeAdminTest):
_interface = 'json'
run_ssh = CONF.compute.run_ssh
disk_config = 'AUTO'
@classmethod
def setUpClass(cls):
- super(ServersWithSpecificFlavorV3TestJSON, cls).setUpClass()
+ super(ServersWithSpecificFlavorV3Test, cls).setUpClass()
cls.meta = {'hello': 'world'}
cls.accessIPv4 = '1.1.1.1'
cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
@@ -213,7 +213,7 @@
self.assertEqual(partition_num + 1, linux_client.get_partitions())
-class ServersV3TestManualDisk(ServersV3TestJSON):
+class ServersV3TestManualDisk(ServersV3Test):
disk_config = 'MANUAL'
@classmethod
diff --git a/tempest/api/compute/v3/servers/test_instance_actions.py b/tempest/api/compute/v3/servers/test_instance_actions.py
index dd5dd30..d536871 100644
--- a/tempest/api/compute/v3/servers/test_instance_actions.py
+++ b/tempest/api/compute/v3/servers/test_instance_actions.py
@@ -18,12 +18,12 @@
from tempest.test import attr
-class InstanceActionsV3TestJSON(base.BaseV3ComputeTest):
+class InstanceActionsV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(InstanceActionsV3TestJSON, cls).setUpClass()
+ super(InstanceActionsV3Test, cls).setUpClass()
cls.client = cls.servers_client
resp, server = cls.create_test_server(wait_until='ACTIVE')
cls.request_id = resp['x-compute-request-id']
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 533a2c2..9082eda 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -24,12 +24,12 @@
CONF = config.CONF
-class ListServerFiltersV3TestJSON(base.BaseV3ComputeTest):
+class ListServerFiltersV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ListServerFiltersV3TestJSON, cls).setUpClass()
+ super(ListServerFiltersV3Test, cls).setUpClass()
cls.client = cls.servers_client
# Check to see if the alternate image ref actually exists...
@@ -125,6 +125,22 @@
resp, servers = self.client.list_servers(params)
self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
+ @attr(type='gate')
+ def test_list_servers_filter_by_zero_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 0}
+ resp, servers = self.client.list_servers(params)
+ self.assertEqual(0, len(servers['servers']))
+
+ @attr(type='gate')
+ def test_list_servers_filter_by_exceed_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 100000}
+ resp, servers = self.client.list_servers(params)
+ resp, all_servers = self.client.list_servers()
+ self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
+ len([x for x in servers['servers'] if 'id' in x]))
+
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@attr(type='gate')
def test_list_servers_detailed_filter_by_image(self):
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 23f2bda..09e1bb6 100644
--- a/tempest/api/compute/v3/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_list_servers_negative.py
@@ -20,13 +20,13 @@
from tempest.test import attr
-class ListServersNegativeV3TestJSON(base.BaseV3ComputeTest):
+class ListServersNegativeV3Test(base.BaseV3ComputeTest):
_interface = 'json'
force_tenant_isolation = True
@classmethod
def setUpClass(cls):
- super(ListServersNegativeV3TestJSON, cls).setUpClass()
+ super(ListServersNegativeV3Test, cls).setUpClass()
cls.client = cls.servers_client
# The following servers are created for use
diff --git a/tempest/api/compute/v3/servers/test_multiple_create.py b/tempest/api/compute/v3/servers/test_multiple_create.py
index 429a8ba..f1ae5f8 100644
--- a/tempest/api/compute/v3/servers/test_multiple_create.py
+++ b/tempest/api/compute/v3/servers/test_multiple_create.py
@@ -19,7 +19,7 @@
from tempest import test
-class MultipleCreateV3TestJSON(base.BaseV3ComputeTest):
+class MultipleCreateV3Test(base.BaseV3ComputeTest):
_interface = 'json'
_name = 'multiple-create-test'
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index b8dc85b..0dae796 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -28,7 +28,7 @@
CONF = config.CONF
-class ServerActionsV3TestJSON(base.BaseV3ComputeTest):
+class ServerActionsV3Test(base.BaseV3ComputeTest):
_interface = 'json'
resize_available = CONF.compute_feature_enabled.resize
run_ssh = CONF.compute.run_ssh
@@ -36,7 +36,7 @@
def setUp(self):
# NOTE(afazekas): Normally we use the same server with all test cases,
# but if it has an issue, we build a new one
- super(ServerActionsV3TestJSON, self).setUp()
+ super(ServerActionsV3Test, self).setUp()
# Check if the server is in a clean state after test
try:
self.client.wait_for_server_status(self.server_id, 'ACTIVE')
@@ -46,7 +46,7 @@
@classmethod
def setUpClass(cls):
- super(ServerActionsV3TestJSON, cls).setUpClass()
+ super(ServerActionsV3Test, cls).setUpClass()
cls.client = cls.servers_client
cls.server_id = cls.rebuild_server(None)
diff --git a/tempest/api/compute/v3/servers/test_server_metadata.py b/tempest/api/compute/v3/servers/test_server_metadata.py
index 1758b0b..13c82dd 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata.py
@@ -14,16 +14,15 @@
# under the License.
from tempest.api.compute import base
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
-class ServerMetadataV3TestJSON(base.BaseV3ComputeTest):
+class ServerMetadataV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ServerMetadataV3TestJSON, cls).setUpClass()
+ super(ServerMetadataV3Test, cls).setUpClass()
cls.client = cls.servers_client
cls.quotas = cls.quotas_client
cls.admin_client = cls._get_identity_admin_client()
@@ -35,12 +34,12 @@
cls.server_id = server['id']
def setUp(self):
- super(ServerMetadataV3TestJSON, self).setUp()
+ super(ServerMetadataV3Test, self).setUp()
meta = {'key1': 'value1', 'key2': 'value2'}
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 +49,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 +63,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 +77,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 +87,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 +108,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,
@@ -135,77 +119,3 @@
resp, resp_metadata = self.client.list_server_metadata(self.server_id)
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)
diff --git a/tempest/api/compute/v3/servers/test_server_metadata_negative.py b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
new file mode 100644
index 0000000..4062696
--- /dev/null
+++ b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
@@ -0,0 +1,158 @@
+# 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.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class ServerMetadataV3NegativeTestJSON(base.BaseV3ComputeTest):
+ _interface = 'json'
+
+ @classmethod
+ def setUpClass(cls):
+ super(ServerMetadataV3NegativeTestJSON, 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)
diff --git a/tempest/api/compute/v3/servers/test_server_rescue.py b/tempest/api/compute/v3/servers/test_server_rescue.py
index 99e8f68..f8be1c1 100644
--- a/tempest/api/compute/v3/servers/test_server_rescue.py
+++ b/tempest/api/compute/v3/servers/test_server_rescue.py
@@ -18,12 +18,12 @@
from tempest.test import attr
-class ServerRescueV3TestJSON(base.BaseV3ComputeTest):
+class ServerRescueV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ServerRescueV3TestJSON, cls).setUpClass()
+ super(ServerRescueV3Test, cls).setUpClass()
cls.device = 'vdf'
# Create a volume and wait for it to become ready for attach
@@ -58,17 +58,17 @@
cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
def setUp(self):
- super(ServerRescueV3TestJSON, self).setUp()
+ super(ServerRescueV3Test, self).setUp()
@classmethod
def tearDownClass(cls):
client = cls.volumes_client
client.delete_volume(str(cls.volume_to_attach['id']).strip())
client.delete_volume(str(cls.volume_to_detach['id']).strip())
- super(ServerRescueV3TestJSON, cls).tearDownClass()
+ super(ServerRescueV3Test, cls).tearDownClass()
def tearDown(self):
- super(ServerRescueV3TestJSON, self).tearDown()
+ super(ServerRescueV3Test, self).tearDown()
def _detach(self, server_id, volume_id):
self.servers_client.detach_volume(server_id, volume_id)
diff --git a/tempest/api/compute/v3/servers/test_servers.py b/tempest/api/compute/v3/servers/test_servers.py
index c476b78..dc64c40 100644
--- a/tempest/api/compute/v3/servers/test_servers.py
+++ b/tempest/api/compute/v3/servers/test_servers.py
@@ -18,17 +18,17 @@
from tempest import test
-class ServersV3TestJSON(base.BaseV3ComputeTest):
+class ServersV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ServersV3TestJSON, cls).setUpClass()
+ super(ServersV3Test, cls).setUpClass()
cls.client = cls.servers_client
def tearDown(self):
self.clear_servers()
- super(ServersV3TestJSON, self).tearDown()
+ super(ServersV3Test, self).tearDown()
@test.attr(type='gate')
def test_create_server_with_admin_password(self):
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index 191701e..c153699 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -26,11 +26,11 @@
CONF = config.CONF
-class ServersNegativeV3TestJSON(base.BaseV3ComputeTest):
+class ServersNegativeV3Test(base.BaseV3ComputeTest):
_interface = 'json'
def setUp(self):
- super(ServersNegativeV3TestJSON, self).setUp()
+ super(ServersNegativeV3Test, self).setUp()
try:
self.client.wait_for_server_status(self.server_id, 'ACTIVE')
except Exception:
@@ -38,7 +38,7 @@
@classmethod
def setUpClass(cls):
- super(ServersNegativeV3TestJSON, cls).setUpClass()
+ super(ServersNegativeV3Test, cls).setUpClass()
cls.client = cls.servers_client
cls.alt_os = clients.AltManager()
cls.alt_client = cls.alt_os.servers_v3_client
diff --git a/tempest/api/compute/v3/test_extensions.py b/tempest/api/compute/v3/test_extensions.py
index 775d70a..09f5ab4 100644
--- a/tempest/api/compute/v3/test_extensions.py
+++ b/tempest/api/compute/v3/test_extensions.py
@@ -24,7 +24,7 @@
LOG = logging.getLogger(__name__)
-class ExtensionsV3TestJSON(base.BaseV3ComputeTest):
+class ExtensionsV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@test.attr(type='gate')
diff --git a/tempest/api/compute/v3/test_live_block_migration.py b/tempest/api/compute/v3/test_live_block_migration.py
index c881206..144cadb 100644
--- a/tempest/api/compute/v3/test_live_block_migration.py
+++ b/tempest/api/compute/v3/test_live_block_migration.py
@@ -26,13 +26,13 @@
CONF = config.CONF
-class LiveBlockMigrationV3TestJSON(base.BaseV3ComputeAdminTest):
+class LiveBlockMigrationV3Test(base.BaseV3ComputeAdminTest):
_host_key = 'os-extended-server-attributes:host'
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(LiveBlockMigrationV3TestJSON, cls).setUpClass()
+ super(LiveBlockMigrationV3Test, cls).setUpClass()
cls.admin_hosts_client = cls.hosts_admin_client
cls.admin_servers_client = cls.servers_admin_client
@@ -161,4 +161,4 @@
for server_id in cls.created_server_ids:
cls.servers_client.delete_server(server_id)
- super(LiveBlockMigrationV3TestJSON, cls).tearDownClass()
+ super(LiveBlockMigrationV3Test, cls).tearDownClass()
diff --git a/tempest/api/compute/v3/test_quotas.py b/tempest/api/compute/v3/test_quotas.py
index 1cbfa2b..33b90ff 100644
--- a/tempest/api/compute/v3/test_quotas.py
+++ b/tempest/api/compute/v3/test_quotas.py
@@ -17,12 +17,12 @@
from tempest import test
-class QuotasV3TestJSON(base.BaseV3ComputeTest):
+class QuotasV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(QuotasV3TestJSON, cls).setUpClass()
+ super(QuotasV3Test, cls).setUpClass()
cls.client = cls.quotas_client
cls.admin_client = cls._get_identity_admin_client()
resp, tenants = cls.admin_client.list_tenants()
diff --git a/tempest/api/compute/v3/test_version.py b/tempest/api/compute/v3/test_version.py
index 6fbe794..9161d4d 100644
--- a/tempest/api/compute/v3/test_version.py
+++ b/tempest/api/compute/v3/test_version.py
@@ -18,7 +18,7 @@
from tempest import test
-class VersionV3TestJSON(base.BaseV3ComputeTest):
+class VersionV3Test(base.BaseV3ComputeTest):
_interface = 'json'
@test.attr(type='gate')
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 3fc7c55..bcab891 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -44,7 +44,7 @@
resp, volume = self.client.create_volume(size=1,
display_name=v_name,
metadata=metadata)
- self.addCleanup(self._delete_volume, volume)
+ self.addCleanup(self.delete_volume, volume['id'])
self.assertEqual(200, resp.status)
self.assertIn('id', volume)
self.assertIn('displayName', volume)
@@ -72,16 +72,6 @@
'The fetched Volume metadata misses data '
'from the created Volume')
- def _delete_volume(self, volume):
- # Delete the Volume created in this method
- try:
- resp, _ = self.client.delete_volume(volume['id'])
- self.assertEqual(202, resp.status)
- # Checking if the deleted Volume still exists
- self.client.wait_for_resource_deletion(volume['id'])
- except KeyError:
- return
-
class VolumesGetTestXML(VolumesGetTestJSON):
_interface = "xml"
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index bec2ef4..48b1b7e 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -62,7 +62,7 @@
# too small. So, here, we clean up whatever we did manage
# to create and raise a SkipTest
for volume in cls.volume_list:
- cls.client.delete_volume(volume)
+ cls.delete_volume(volume['id'])
msg = ("Failed to create ALL necessary volumes to run "
"test. This typically means that the backing file "
"size of the nova-volumes group is too small to "
@@ -74,8 +74,7 @@
def tearDownClass(cls):
# Delete the created Volumes
for volume in cls.volume_list:
- resp, _ = cls.client.delete_volume(volume['id'])
- cls.client.wait_for_resource_deletion(volume['id'])
+ cls.delete_volume(volume['id'])
super(VolumesTestJSON, cls).tearDownClass()
@attr(type='gate')
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 3211ef8..12fda92 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -64,6 +64,19 @@
status)
super(SnapshotsActionsTest, self).tearDown()
+ def _create_reset_and_force_delete_temp_snapshot(self, status=None):
+ # Create snapshot, reset snapshot status,
+ # and force delete temp snapshot
+ temp_snapshot = self.create_snapshot(self.volume['id'])
+ if status:
+ resp, body = self.admin_snapshots_client.\
+ reset_snapshot_status(temp_snapshot['id'], status)
+ self.assertEqual(202, resp.status)
+ resp_delete, volume_delete = self.admin_snapshots_client.\
+ force_delete_snapshot(temp_snapshot['id'])
+ self.assertEqual(202, resp_delete.status)
+ self.client.wait_for_resource_deletion(temp_snapshot['id'])
+
def _get_progress_alias(self):
return 'os-extended-snapshot-attributes:progress'
@@ -99,6 +112,26 @@
self.assertEqual(status, snapshot_get['status'])
self.assertEqual(progress, snapshot_get[progress_alias])
+ @attr(type='gate')
+ def test_snapshot_force_delete_when_snapshot_is_creating(self):
+ # test force delete when status of snapshot is creating
+ self._create_reset_and_force_delete_temp_snapshot('creating')
+
+ @attr(type='gate')
+ def test_snapshot_force_delete_when_snapshot_is_deleting(self):
+ # test force delete when status of snapshot is deleting
+ self._create_reset_and_force_delete_temp_snapshot('deleting')
+
+ @attr(type='gate')
+ def test_snapshot_force_delete_when_snapshot_is_error(self):
+ # test force delete when status of snapshot is error
+ self._create_reset_and_force_delete_temp_snapshot('error')
+
+ @attr(type='gate')
+ def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
+ # test force delete when status of snapshot is error_deleting
+ self._create_reset_and_force_delete_temp_snapshot('error_deleting')
+
class SnapshotsActionsTestXML(SnapshotsActionsTest):
_interface = "xml"
diff --git a/tempest/common/commands.py b/tempest/common/commands.py
index af7a692..6405eaa 100644
--- a/tempest/common/commands.py
+++ b/tempest/common/commands.py
@@ -29,7 +29,8 @@
subprocess_args = {'stdout': subprocess.PIPE,
'stderr': subprocess.STDOUT}
try:
- proc = subprocess.Popen(['/usr/bin/sudo'] + args, **subprocess_args)
+ proc = subprocess.Popen(['/usr/bin/sudo', '-n'] + args,
+ **subprocess_args)
return proc.communicate()[0]
if proc.returncode != 0:
LOG.error(cmd + "returned with: " +
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 636e2bf..8d07545 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -261,7 +261,8 @@
elif resp.status == 401:
raise exceptions.AuthenticationFailure(user=user,
- password=password)
+ password=password,
+ tenant=project_name)
else:
self.LOG.error("Failed to obtain token using V3 authentication"
" (auth URL is '%s'), the response status is %s" %
diff --git a/tempest/config.py b/tempest/config.py
index 704556f..ccb3125 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -667,7 +667,7 @@
default='^cirros-0.3.1-x86_64-uec$',
help="Matching images become parameters for scenario tests"),
cfg.StrOpt('flavor_regex',
- default='^m1.(micro|nano|tiny)$',
+ default='^m1.nano$',
help="Matching flavors become parameters for scenario tests"),
cfg.StrOpt('non_ssh_image_regex',
default='^.*[Ww]in.*$',
@@ -727,9 +727,7 @@
path = os.path.join(conf_dir, conf_file)
- if not (os.path.isfile(path) or
- 'TEMPEST_CONFIG_DIR' in os.environ or
- 'TEMPEST_CONFIG' in os.environ):
+ if not os.path.isfile(path):
path = failsafe_path
# only parse the config file if we expect one to exist. This is needed
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 809037d..3b3f3eb 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -123,8 +123,7 @@
class RateLimitExceeded(TempestException):
- message = ("Rate limit exceeded.\nMessage: %(message)s\n"
- "Details: %(details)s")
+ message = "Rate limit exceeded"
class OverLimit(TempestException):
@@ -162,10 +161,6 @@
message = "The server is not reachable via the configured network"
-class SQLException(TempestException):
- message = "SQL error: %(message)s"
-
-
class TearDownException(TempestException):
message = "%(num)d cleanUp operation failed"
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 12d81cc..59a3aeb 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -397,7 +397,8 @@
if new_status.lower() == error_status.lower():
message = ("%s failed to get to expected status. "
"In %s state.") % (thing, new_status)
- raise exceptions.BuildErrorException(message)
+ raise exceptions.BuildErrorException(message,
+ server_id=thing_id)
elif new_status == expected_status and expected_status is not None:
return True # All good.
LOG.debug("Waiting for %s to get to %s status. "
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index be0e045..020a256 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -196,7 +196,8 @@
floating_ip = self._create_floating_ip(server, public_network_id)
self.floating_ips[floating_ip] = server
- def _check_public_network_connectivity(self, should_connect=True):
+ def _check_public_network_connectivity(self, should_connect=True,
+ msg=None):
# The target login is assumed to have been configured for
# key-based authentication by cloud-init.
ssh_login = CONF.compute.image_ssh_user
@@ -212,7 +213,10 @@
private_key,
should_connect=should_connect)
except Exception:
- LOG.exception('Public network connectivity check failed')
+ ex_msg = 'Public network connectivity check failed'
+ if msg:
+ ex_msg += ": " + msg
+ LOG.exception(ex_msg)
self._log_console_output(servers=self.servers.keys())
debug.log_ip_ns()
raise
@@ -242,6 +246,10 @@
self._check_tenant_network_connectivity()
self._check_public_network_connectivity(should_connect=True)
self._disassociate_floating_ips()
- self._check_public_network_connectivity(should_connect=False)
+ self._check_public_network_connectivity(should_connect=False,
+ msg="after disassociate "
+ "floating ip")
self._reassociate_floating_ips()
- self._check_public_network_connectivity(should_connect=True)
+ self._check_public_network_connectivity(should_connect=True,
+ msg="after re-associate "
+ "floating ip")
diff --git a/tempest/scenario/test_swift_basic_ops.py b/tempest/scenario/test_swift_basic_ops.py
index b367f7f..60df606 100644
--- a/tempest/scenario/test_swift_basic_ops.py
+++ b/tempest/scenario/test_swift_basic_ops.py
@@ -93,7 +93,7 @@
for obj in not_present_obj:
self.assertNotIn(obj, object_list)
- @services('object')
+ @services('object_storage')
def test_swift_basic_ops(self):
self._get_swift_stat()
container_name = self._create_container()
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 21d3a5a..c0a2db2 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -39,11 +39,12 @@
fixed_ip=None):
post_body = dict(interfaceAttachment=dict())
if port_id:
- post_body['port_id'] = port_id
+ post_body['interfaceAttachment']['port_id'] = port_id
if network_id:
- post_body['net_id'] = network_id
+ post_body['interfaceAttachment']['net_id'] = network_id
if fixed_ip:
- post_body['fixed_ips'] = [dict(ip_address=fixed_ip)]
+ fip = dict(ip_address=fixed_ip)
+ post_body['interfaceAttachment']['fixed_ips'] = [fip]
post_body = json.dumps(post_body)
resp, body = self.post('servers/%s/os-interface' % server,
headers=self.headers,
diff --git a/tempest/services/compute/xml/common.py b/tempest/services/compute/xml/common.py
index 9c562b7..4def19f 100644
--- a/tempest/services/compute/xml/common.py
+++ b/tempest/services/compute/xml/common.py
@@ -112,11 +112,27 @@
others, it requires a little hand-editing of the result.
"""
json = {}
+ bool_flag = False
+ int_flag = False
+ long_flag = False
for attr in node.keys():
if not attr.startswith("xmlns"):
json[attr] = node.get(attr)
+ if json[attr] == 'bool':
+ bool_flag = True
+ elif json[attr] == 'int':
+ int_flag = True
+ elif json[attr] == 'long':
+ long_flag = True
if not node.getchildren():
- return node.text or json
+ if bool_flag:
+ return node.text == 'True'
+ elif int_flag:
+ return int(node.text)
+ elif long_flag:
+ return long(node.text)
+ else:
+ return node.text or json
for child in node.getchildren():
tag = child.tag
if tag.startswith("{"):
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index 68268a1..c16d4a3 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -381,7 +381,7 @@
server_status = body['status']
if server_status == 'ERROR' and not ignore_error:
- raise exceptions.BuildErrorException
+ raise exceptions.BuildErrorException(server_id=server_id)
if int(time.time()) - start_time >= self.build_timeout:
raise exceptions.TimeoutException
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index a36083b..e8926bd 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -187,3 +187,10 @@
url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
resp, body = self.delete(url, self.headers)
return resp, body
+
+ def force_delete_snapshot(self, snapshot_id):
+ """Force Delete Snapshot."""
+ post_body = json.dumps({'os-force_delete': {}})
+ resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body,
+ self.headers)
+ return resp, body
diff --git a/tempest/services/volume/xml/snapshots_client.py b/tempest/services/volume/xml/snapshots_client.py
index 3e85041..5e62b6d 100644
--- a/tempest/services/volume/xml/snapshots_client.py
+++ b/tempest/services/volume/xml/snapshots_client.py
@@ -226,3 +226,12 @@
"""Delete metadata item for the snapshot."""
url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
return self.delete(url)
+
+ def force_delete_snapshot(self, snapshot_id):
+ """Force Delete Snapshot."""
+ post_body = Element("os-force_delete")
+ url = 'snapshots/%s/action' % str(snapshot_id)
+ resp, body = self.post(url, str(Document(post_body)), self.headers)
+ if body:
+ body = xml_to_json(etree.fromstring(body))
+ return resp, body
diff --git a/tempest/stress/README.rst b/tempest/stress/README.rst
index 20e58d4..b56f96b 100644
--- a/tempest/stress/README.rst
+++ b/tempest/stress/README.rst
@@ -1,7 +1,7 @@
Tempest Field Guide to Stress Tests
===================================
-Nova is a distributed, asynchronous system that is prone to race condition
+OpenStack is a distributed, asynchronous system that is prone to race condition
bugs. These bugs will not be easily found during
functional testing but will be encountered by users in large deployments in a
way that is hard to debug. The stress test tries to cause these bugs to happen
diff --git a/tempest/test.py b/tempest/test.py
index 5898358..1a3ca0d 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -67,7 +67,7 @@
exercised by a test case.
"""
valid_service_list = ['compute', 'image', 'volume', 'orchestration',
- 'network', 'identity', 'object', 'dashboard']
+ 'network', 'identity', 'object_storage', 'dashboard']
def decorator(f):
for service in args:
@@ -270,7 +270,7 @@
level=None))
@classmethod
- def get_client_manager(cls):
+ def get_client_manager(cls, interface=None):
"""
Returns an Openstack client manager
"""
@@ -282,12 +282,27 @@
force_tenant_isolation):
creds = cls.isolated_creds.get_primary_creds()
username, tenant_name, password = creds
- os = clients.Manager(username=username,
- password=password,
- tenant_name=tenant_name,
- interface=cls._interface)
+ if getattr(cls, '_interface', None):
+ os = clients.Manager(username=username,
+ password=password,
+ tenant_name=tenant_name,
+ interface=cls._interface)
+ elif interface:
+ os = clients.Manager(username=username,
+ password=password,
+ tenant_name=tenant_name,
+ interface=interface)
+ else:
+ os = clients.Manager(username=username,
+ password=password,
+ tenant_name=tenant_name)
else:
- os = clients.Manager(interface=cls._interface)
+ if getattr(cls, '_interface', None):
+ os = clients.Manager(interface=cls._interface)
+ elif interface:
+ os = clients.Manager(interface=interface)
+ else:
+ os = clients.Manager()
return os
@classmethod
diff --git a/tempest/tests/test_compute_xml_common.py b/tempest/tests/test_compute_xml_common.py
new file mode 100644
index 0000000..bfa6a10
--- /dev/null
+++ b/tempest/tests/test_compute_xml_common.py
@@ -0,0 +1,67 @@
+# Copyright 2013 IBM Corp.
+#
+# 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 lxml import etree
+
+from tempest.services.compute.xml import common
+from tempest.tests import base
+
+
+class TestXMLParser(base.TestCase):
+
+ def test_xml_to_json_parser_bool_value(self):
+ node = etree.fromstring('''<health_monitor
+ xmlns="http://openstack.org/quantum/api/v2.0"
+ xmlns:quantum="http://openstack.org/quantum/api/v2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <admin_state_up quantum:type="bool">False</admin_state_up>
+ <fake_state_up quantum:type="bool">True</fake_state_up>
+ </health_monitor>''')
+ body = common.xml_to_json(node)
+ self.assertEqual(body['admin_state_up'], False)
+ self.assertEqual(body['fake_state_up'], True)
+
+ def test_xml_to_json_parser_int_value(self):
+ node = etree.fromstring('''<health_monitor
+ xmlns="http://openstack.org/quantum/api/v2.0"
+ xmlns:quantum="http://openstack.org/quantum/api/v2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <delay quantum:type="long">4</delay>
+ <max_retries quantum:type="int">3</max_retries>
+ </health_monitor>''')
+ body = common.xml_to_json(node)
+ self.assertEqual(body['delay'], 4L)
+ self.assertEqual(body['max_retries'], 3)
+
+ def test_xml_to_json_parser_text_value(self):
+ node = etree.fromstring('''<health_monitor
+ xmlns="http://openstack.org/quantum/api/v2.0"
+ xmlns:quantum="http://openstack.org/quantum/api/v2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <status>ACTIVE</status>
+ </health_monitor>''')
+ body = common.xml_to_json(node)
+ self.assertEqual(body['status'], 'ACTIVE')
+
+ def test_xml_to_json_parser_list_as_value(self):
+ node = etree.fromstring('''<health_monitor
+ xmlns="http://openstack.org/quantum/api/v2.0"
+ xmlns:quantum="http://openstack.org/quantum/api/v2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <elements>
+ <element>first_element</element>
+ <element>second_element</element>
+ </elements>
+ </health_monitor>''')
+ body = common.xml_to_json(node, 'elements')
+ self.assertEqual(body['elements'], ['first_element', 'second_element'])
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index d484d94..b36e8c7 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -195,6 +195,7 @@
def setUpClass(cls):
super(BotoTestCase, cls).setUpClass()
cls.conclusion = decision_maker()
+ cls.os = cls.get_client_manager()
# The trash contains cleanup functions and paramaters in tuples
# (function, *args, **kwargs)
cls._resource_trash_bin = {}
@@ -259,6 +260,7 @@
LOG.exception("Cleanup failed %s" % func_name)
finally:
del cls._resource_trash_bin[key]
+ cls.clear_isolated_creds()
super(BotoTestCase, cls).tearDownClass()
# NOTE(afazekas): let the super called even on exceptions
# The real exceptions already logged, if the super throws another,
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 19ddd18..a6932bc 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -15,7 +15,6 @@
from boto import exception
-from tempest import clients
from tempest.common.utils import data_utils
from tempest.common.utils.linux.remote_client import RemoteClient
from tempest import config
@@ -41,7 +40,6 @@
if not cls.conclusion['A_I_IMAGES_READY']:
raise cls.skipException("".join(("EC2 ", cls.__name__,
": requires ami/aki/ari manifest")))
- cls.os = clients.Manager()
cls.s3_client = cls.os.s3_client
cls.ec2_client = cls.os.ec2api_client
cls.zone = cls.ec2_client.get_good_zone()
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index b4c1827..329ace3 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import clients
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest.test import skip_because
@@ -30,7 +29,6 @@
@classmethod
def setUpClass(cls):
super(EC2KeysTest, cls).setUpClass()
- cls.os = clients.Manager()
cls.client = cls.os.ec2api_client
cls.ec = cls.ec2_error_code
diff --git a/tempest/thirdparty/boto/test_ec2_network.py b/tempest/thirdparty/boto/test_ec2_network.py
index 3c3c74d..4b2f01f 100644
--- a/tempest/thirdparty/boto/test_ec2_network.py
+++ b/tempest/thirdparty/boto/test_ec2_network.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import clients
from tempest.test import attr
from tempest.test import skip_because
from tempest.thirdparty.boto.test import BotoTestCase
@@ -24,7 +23,6 @@
@classmethod
def setUpClass(cls):
super(EC2NetworkTest, cls).setUpClass()
- cls.os = clients.Manager()
cls.client = cls.os.ec2api_client
# Note(afazekas): these tests for things duable without an instance
diff --git a/tempest/thirdparty/boto/test_ec2_security_groups.py b/tempest/thirdparty/boto/test_ec2_security_groups.py
index 75dd254..9b58603 100644
--- a/tempest/thirdparty/boto/test_ec2_security_groups.py
+++ b/tempest/thirdparty/boto/test_ec2_security_groups.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import clients
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest.thirdparty.boto.test import BotoTestCase
@@ -24,7 +23,6 @@
@classmethod
def setUpClass(cls):
super(EC2SecurityGroupTest, cls).setUpClass()
- cls.os = clients.Manager()
cls.client = cls.os.ec2api_client
@attr(type='smoke')
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
index 3e7e2de..04671c5 100644
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ b/tempest/thirdparty/boto/test_ec2_volumes.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import clients
from tempest.openstack.common import log as logging
from tempest.test import attr
from tempest.thirdparty.boto.test import BotoTestCase
@@ -31,7 +30,6 @@
@classmethod
def setUpClass(cls):
super(EC2VolumesTest, cls).setUpClass()
- cls.os = clients.Manager()
cls.client = cls.os.ec2api_client
cls.zone = cls.client.get_good_zone()
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
index f8948fd..f34faac 100644
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ b/tempest/thirdparty/boto/test_s3_buckets.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import clients
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest.test import skip_because
@@ -25,7 +24,6 @@
@classmethod
def setUpClass(cls):
super(S3BucketsTest, cls).setUpClass()
- cls.os = clients.Manager()
cls.client = cls.os.s3_client
@skip_because(bug="1076965")
diff --git a/tempest/thirdparty/boto/test_s3_ec2_images.py b/tempest/thirdparty/boto/test_s3_ec2_images.py
index 722577b..9607a92 100644
--- a/tempest/thirdparty/boto/test_s3_ec2_images.py
+++ b/tempest/thirdparty/boto/test_s3_ec2_images.py
@@ -15,7 +15,6 @@
import os
-from tempest import clients
from tempest.common.utils import data_utils
from tempest import config
from tempest.test import attr
@@ -33,7 +32,6 @@
if not cls.conclusion['A_I_IMAGES_READY']:
raise cls.skipException("".join(("EC2 ", cls.__name__,
": requires ami/aki/ari manifest")))
- cls.os = clients.Manager()
cls.s3_client = cls.os.s3_client
cls.images_client = cls.os.ec2api_client
cls.materials_path = CONF.boto.s3_materials_path
diff --git a/tempest/thirdparty/boto/test_s3_objects.py b/tempest/thirdparty/boto/test_s3_objects.py
index f355899..a102a22 100644
--- a/tempest/thirdparty/boto/test_s3_objects.py
+++ b/tempest/thirdparty/boto/test_s3_objects.py
@@ -17,7 +17,6 @@
import boto.s3.key
-from tempest import clients
from tempest.common.utils import data_utils
from tempest.test import attr
from tempest.thirdparty.boto.test import BotoTestCase
@@ -28,7 +27,6 @@
@classmethod
def setUpClass(cls):
super(S3BucketsTest, cls).setUpClass()
- cls.os = clients.Manager()
cls.client = cls.os.s3_client
@attr(type='smoke')
diff --git a/test-requirements.txt b/test-requirements.txt
index d7340f3..3fe2f27 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,7 +2,7 @@
# needed for doc build
docutils==0.9.1
sphinx>=1.1.2,<1.2
-python-subunit
+python-subunit>=0.0.18
oslo.sphinx
mox>=0.5.3
mock>=1.0