Merge "XML endpoint client use correct string for enabled"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 1d571c0..ee2da40 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -105,6 +105,10 @@
# value)
#catalog_type=baremetal
+# The endpoint type to use for the baremetal provisioning
+# service. (string value)
+#endpoint_type=publicURL
+
[boto]
@@ -355,6 +359,10 @@
# iSCSI volumes (boolean value)
#block_migrate_cinder_iscsi=false
+# Enable VNC console. This configuration value should be same
+# as [nova.vnc]->vnc_enabled in nova.conf (boolean value)
+#vnc_console=false
+
[dashboard]
@@ -378,6 +386,10 @@
# Catalog type of the data processing service. (string value)
#catalog_type=data_processing
+# The endpoint type to use for the data processing service.
+# (string value)
+#endpoint_type=publicURL
+
[debug]
@@ -627,6 +639,9 @@
# creating containers (string value)
#operator_role=Member
+# User role that has reseller admin (string value)
+#reseller_admin_role=ResellerAdmin
+
[object-storage-feature-enabled]
@@ -816,6 +831,10 @@
# Catalog type of the Telemetry service. (string value)
#catalog_type=metering
+# The endpoint type to use for the telemetry service. (string
+# value)
+#endpoint_type=publicURL
+
[volume]
diff --git a/requirements.txt b/requirements.txt
index a08a437..0bddca3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-pbr>=0.5.21,<1.0
+pbr>=0.6,<1.0
anyjson>=0.3.3
httplib2>=0.7.5
jsonschema>=2.0.0,<3.0.0
@@ -8,18 +8,18 @@
paramiko>=1.9.0
netaddr>=0.7.6
python-glanceclient>=0.9.0
-python-keystoneclient>=0.4.2
+python-keystoneclient>=0.6.0
python-novaclient>=2.15.0
-python-neutronclient>=2.3.3,<3
+python-neutronclient>=2.3.4,<3
python-cinderclient>=1.0.6
python-heatclient>=0.2.3
-python-savannaclient>=0.4.1
-python-swiftclient>=1.5
+python-savannaclient>=0.5.0
+python-swiftclient>=1.6
testresources>=0.2.4
keyring>=1.6.1,<2.0,>=2.1
-testrepository>=0.0.17
+testrepository>=0.0.18
oslo.config>=1.2.0
-six>=1.4.1
+six>=1.5.2
iso8601>=0.1.8
fixtures>=0.3.14
testscenarios>=0.4
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 08d8a0d..4818aa6 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -47,7 +47,7 @@
resp, aggregate = self.client.create_aggregate(name=aggregate_name)
self.assertEqual(200, resp.status)
self.assertEqual(aggregate_name, aggregate['name'])
- self.assertEqual(None, aggregate['availability_zone'])
+ self.assertIsNone(aggregate['availability_zone'])
resp, _ = self.client.delete_aggregate(aggregate['id'])
self.assertEqual(200, resp.status)
@@ -175,7 +175,7 @@
self.assertEqual(1, len(aggs))
agg = aggs[0]
self.assertEqual(aggregate_name, agg['name'])
- self.assertEqual(None, agg['availability_zone'])
+ self.assertIsNone(agg['availability_zone'])
self.assertIn(self.host, agg['hosts'])
@attr(type='gate')
@@ -190,7 +190,7 @@
resp, body = self.client.get_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, body['name'])
- self.assertEqual(None, body['availability_zone'])
+ self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
@attr(type='gate')
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 8a5f1a5..3b7f221 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -175,6 +175,16 @@
rebuilt_image_id = server['image']['id']
self.assertEqual(self.image_ref_alt, rebuilt_image_id)
+ @test.attr(type='gate')
+ def test_reset_network_inject_network_info(self):
+ # Reset Network of a Server
+ resp, server = self.create_test_server(wait_until='ACTIVE')
+ resp, server_body = self.client.reset_network(server['id'])
+ self.assertEqual(202, resp.status)
+ # Inject the Network Info into Server
+ resp, server_body = self.client.inject_network_info(server['id'])
+ self.assertEqual(202, resp.status)
+
class ServersAdminTestXML(ServersAdminTestJSON):
_host_key = (
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 72bb723..9162926 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -303,6 +303,8 @@
class BaseV3ComputeTest(BaseComputeTest):
+ _interface = "json"
+
@classmethod
def setUpClass(cls):
# By default compute tests do not create network resources
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index 680bc2f..9c9e72c 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import testtools
-
from tempest.api.compute.security_groups import base
from tempest.common.utils import data_utils
from tempest import config
@@ -24,6 +22,13 @@
CONF = config.CONF
+def not_existing_id():
+ if CONF.service_available.neutron:
+ return data_utils.rand_uuid()
+ else:
+ return data_utils.rand_int_id(start=999)
+
+
class SecurityGroupRulesNegativeTestJSON(base.BaseSecurityGroupsTest):
_interface = 'json'
@@ -32,14 +37,12 @@
super(SecurityGroupRulesNegativeTestJSON, cls).setUpClass()
cls.client = cls.security_groups_client
- @test.skip_because(bug="1182384",
- condition=CONF.service_available.neutron)
@test.attr(type=['negative', 'smoke'])
def test_create_security_group_rule_with_non_existent_id(self):
# Negative test: Creation of Security Group rule should FAIL
# with non existent Parent group id
# Adding rules to the non existent Security Group id
- parent_group_id = data_utils.rand_int_id(start=999)
+ parent_group_id = not_existing_id()
ip_protocol = 'tcp'
from_port = 22
to_port = 22
@@ -47,8 +50,6 @@
self.client.create_security_group_rule,
parent_group_id, ip_protocol, from_port, to_port)
- @testtools.skipIf(CONF.service_available.neutron,
- "Neutron not check the security_group_id")
@test.attr(type=['negative', 'smoke'])
def test_create_security_group_rule_with_invalid_id(self):
# Negative test: Creation of Security Group rule should FAIL
@@ -146,13 +147,11 @@
self.client.create_security_group_rule,
secgroup_id, ip_protocol, from_port, to_port)
- @test.skip_because(bug="1182384",
- condition=CONF.service_available.neutron)
@test.attr(type=['negative', 'smoke'])
def test_delete_security_group_rule_with_non_existent_id(self):
# Negative test: Deletion of Security Group rule should be FAIL
# with non existent id
- non_existent_rule_id = data_utils.rand_int_id(start=999)
+ non_existent_rule_id = not_existing_id()
self.assertRaises(exceptions.NotFound,
self.client.delete_security_group_rule,
non_existent_rule_id)
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 9cdac55..f02cd93 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -123,6 +123,33 @@
_ifs = self._test_delete_interface(server, ifs)
self.assertEqual(len(ifs) - 1, len(_ifs))
+ @attr(type='gate')
+ def test_add_remove_fixed_ip(self):
+ # Add and Remove the fixed IP to server.
+ server, ifs = self._create_server_get_interfaces()
+ interface_count = len(ifs)
+ self.assertTrue(interface_count > 0)
+ self._check_interface(ifs[0])
+ network_id = ifs[0]['net_id']
+ resp, body = self.client.add_fixed_ip(server['id'],
+ network_id)
+ self.assertEqual(202, resp.status)
+ # Remove the fixed IP from server.
+ server_resp, server_detail = self.os.servers_client.get_server(
+ server['id'])
+ # Get the Fixed IP from server.
+ fixed_ip = None
+ for ip_set in server_detail['addresses']:
+ for ip in server_detail['addresses'][ip_set]:
+ if ip['OS-EXT-IPS:type'] == 'fixed':
+ fixed_ip = ip['addr']
+ break
+ if fixed_ip is not None:
+ break
+ resp, body = self.client.remove_fixed_ip(server['id'],
+ fixed_ip)
+ self.assertEqual(202, resp.status)
+
class AttachInterfacesTestXML(AttachInterfacesTestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index ec40ce0..6c0e37c 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -36,6 +36,7 @@
resp, server = self.create_test_server(wait_until='BUILD')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_active_server(self):
@@ -43,6 +44,7 @@
resp, server = self.create_test_server(wait_until='ACTIVE')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_server_while_in_shutoff_state(self):
@@ -52,6 +54,7 @@
self.client.wait_for_server_status(server['id'], 'SHUTOFF')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_server_while_in_pause_state(self):
@@ -61,6 +64,7 @@
self.client.wait_for_server_status(server['id'], 'PAUSED')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_server_while_in_shelved_state(self):
@@ -79,6 +83,7 @@
'SHELVED')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
class DeleteServersAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -103,6 +108,8 @@
self.assertEqual(server['status'], 'ERROR')
resp, _ = self.non_admin_client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.servers_client.wait_for_server_termination(server['id'],
+ ignore_error=True)
@test.attr(type='gate')
def test_admin_delete_servers_of_others(self):
diff --git a/tempest/api/compute/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index da0e4c4..e1a264e 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -38,7 +38,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/v3/admin/test_aggregates.py b/tempest/api/compute/v3/admin/test_aggregates.py
index 20093e4..e5ec08b 100644
--- a/tempest/api/compute/v3/admin/test_aggregates.py
+++ b/tempest/api/compute/v3/admin/test_aggregates.py
@@ -26,7 +26,6 @@
"""
_host_key = 'os-extended-server-attributes:host'
- _interface = 'json'
@classmethod
def setUpClass(cls):
@@ -47,7 +46,7 @@
resp, aggregate = self.client.create_aggregate(name=aggregate_name)
self.assertEqual(201, resp.status)
self.assertEqual(aggregate_name, aggregate['name'])
- self.assertEqual(None, aggregate['availability_zone'])
+ self.assertIsNone(aggregate['availability_zone'])
resp, _ = self.client.delete_aggregate(aggregate['id'])
self.assertEqual(204, resp.status)
@@ -176,7 +175,7 @@
self.assertEqual(1, len(aggs))
agg = aggs[0]
self.assertEqual(aggregate_name, agg['name'])
- self.assertEqual(None, agg['availability_zone'])
+ self.assertIsNone(agg['availability_zone'])
self.assertIn(self.host, agg['hosts'])
@test.attr(type='gate')
@@ -191,7 +190,7 @@
resp, body = self.client.get_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, body['name'])
- self.assertEqual(None, body['availability_zone'])
+ self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
@test.attr(type='gate')
diff --git a/tempest/api/compute/v3/admin/test_aggregates_negative.py b/tempest/api/compute/v3/admin/test_aggregates_negative.py
index 5700460..1505f74 100644
--- a/tempest/api/compute/v3/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/v3/admin/test_aggregates_negative.py
@@ -26,8 +26,6 @@
Tests Aggregates API that require admin privileges
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(AggregatesAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_availability_zone.py b/tempest/api/compute/v3/admin/test_availability_zone.py
index 176751f..9ca8953 100644
--- a/tempest/api/compute/v3/admin/test_availability_zone.py
+++ b/tempest/api/compute/v3/admin/test_availability_zone.py
@@ -23,8 +23,6 @@
Tests Availability Zone API List
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(AZAdminV3Test, cls).setUpClass()
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 180f298..f3af6df 100644
--- a/tempest/api/compute/v3/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
@@ -24,8 +24,6 @@
Tests Availability Zone API List
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(AZAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors.py b/tempest/api/compute/v3/admin/test_flavors.py
index 597c99b..401eb85 100644
--- a/tempest/api/compute/v3/admin/test_flavors.py
+++ b/tempest/api/compute/v3/admin/test_flavors.py
@@ -27,8 +27,6 @@
Tests Flavors API Create and Delete that require admin privileges
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(FlavorsAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors_access.py b/tempest/api/compute/v3/admin/test_flavors_access.py
index 43dc726..03305ff 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access.py
@@ -25,8 +25,6 @@
Add and remove Flavor Access require admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(FlavorsAccessV3Test, cls).setUpClass()
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 6a2e826..334d124 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
@@ -28,8 +28,6 @@
Add and remove Flavor Access require admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(FlavorsAccessNegativeV3Test, cls).setUpClass()
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 4d22027..29cd8db 100644
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
@@ -26,8 +26,6 @@
GET Flavor Extra specs can be performed even by without admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(FlavorsExtraSpecsV3Test, cls).setUpClass()
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 98e6e3d..e9c04a3 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
@@ -27,8 +27,6 @@
SET, UNSET, UPDATE Flavor Extra specs require admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(FlavorsExtraSpecsNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors_negative.py b/tempest/api/compute/v3/admin/test_flavors_negative.py
index f54de79..3f8a2da 100644
--- a/tempest/api/compute/v3/admin/test_flavors_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_negative.py
@@ -27,8 +27,6 @@
Tests Flavors API Create and Delete that require admin privileges
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(FlavorsAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hosts.py b/tempest/api/compute/v3/admin/test_hosts.py
index 2c9369f..8cb1f23 100644
--- a/tempest/api/compute/v3/admin/test_hosts.py
+++ b/tempest/api/compute/v3/admin/test_hosts.py
@@ -23,8 +23,6 @@
Tests hosts API using admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(HostsAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hosts_negative.py b/tempest/api/compute/v3/admin/test_hosts_negative.py
index ac5d7de..79cd97f 100644
--- a/tempest/api/compute/v3/admin/test_hosts_negative.py
+++ b/tempest/api/compute/v3/admin/test_hosts_negative.py
@@ -24,8 +24,6 @@
Tests hosts API using admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(HostsAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hypervisor.py b/tempest/api/compute/v3/admin/test_hypervisor.py
index 0f96bba..93d4441 100644
--- a/tempest/api/compute/v3/admin/test_hypervisor.py
+++ b/tempest/api/compute/v3/admin/test_hypervisor.py
@@ -23,8 +23,6 @@
Tests Hypervisors API that require admin privileges
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(HypervisorAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hypervisor_negative.py b/tempest/api/compute/v3/admin/test_hypervisor_negative.py
index aee354a..45642b7 100644
--- a/tempest/api/compute/v3/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/v3/admin/test_hypervisor_negative.py
@@ -27,8 +27,6 @@
Tests Hypervisors API that require admin privileges
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(HypervisorAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_quotas.py b/tempest/api/compute/v3/admin/test_quotas.py
index b388b70..0c138bb 100644
--- a/tempest/api/compute/v3/admin/test_quotas.py
+++ b/tempest/api/compute/v3/admin/test_quotas.py
@@ -22,7 +22,6 @@
class QuotasAdminV3Test(base.BaseV3ComputeAdminTest):
- _interface = 'json'
force_tenant_isolation = True
@classmethod
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
index 0dc3dbc..7787770 100644
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ b/tempest/api/compute/v3/admin/test_servers.py
@@ -25,7 +25,6 @@
"""
_host_key = 'os-extended-server-attributes:host'
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/admin/test_servers_negative.py b/tempest/api/compute/v3/admin/test_servers_negative.py
index a6a5736..cc1be4e 100644
--- a/tempest/api/compute/v3/admin/test_servers_negative.py
+++ b/tempest/api/compute/v3/admin/test_servers_negative.py
@@ -26,8 +26,6 @@
Tests Servers API using admin privileges
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(ServersAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_services.py b/tempest/api/compute/v3/admin/test_services.py
index 8d6e549..914a2a4 100644
--- a/tempest/api/compute/v3/admin/test_services.py
+++ b/tempest/api/compute/v3/admin/test_services.py
@@ -24,8 +24,6 @@
Tests Services API. List and Enable/Disable require admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(ServicesAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_services_negative.py b/tempest/api/compute/v3/admin/test_services_negative.py
index c270842..3168af2 100644
--- a/tempest/api/compute/v3/admin/test_services_negative.py
+++ b/tempest/api/compute/v3/admin/test_services_negative.py
@@ -25,8 +25,6 @@
Tests Services API. List and Enable/Disable require admin privileges.
"""
- _interface = 'json'
-
@classmethod
def setUpClass(cls):
super(ServicesAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/certificates/test_certificates.py b/tempest/api/compute/v3/certificates/test_certificates.py
index 5c980c0..ce025fc 100644
--- a/tempest/api/compute/v3/certificates/test_certificates.py
+++ b/tempest/api/compute/v3/certificates/test_certificates.py
@@ -18,7 +18,6 @@
class CertificatesV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@attr(type='gate')
def test_create_and_get_root_certificate(self):
diff --git a/tempest/api/compute/v3/flavors/test_flavors.py b/tempest/api/compute/v3/flavors/test_flavors.py
index 812358f..a0bbba6 100644
--- a/tempest/api/compute/v3/flavors/test_flavors.py
+++ b/tempest/api/compute/v3/flavors/test_flavors.py
@@ -18,7 +18,6 @@
class FlavorsV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/flavors/test_flavors_negative.py b/tempest/api/compute/v3/flavors/test_flavors_negative.py
index 3d4100a..346f6d6 100644
--- a/tempest/api/compute/v3/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/v3/flavors/test_flavors_negative.py
@@ -24,7 +24,6 @@
class FlavorsListNegativeV3Test(base.BaseV3ComputeTest,
test.NegativeAutoTest):
- _interface = 'json'
_service = 'computev3'
_schema_file = 'compute/flavors/flavors_list_v3.json'
@@ -37,7 +36,6 @@
class FlavorDetailsNegativeV3Test(base.BaseV3ComputeTest,
test.NegativeAutoTest):
- _interface = 'json'
_service = 'computev3'
_schema_file = 'compute/flavors/flavor_details_v3.json'
diff --git a/tempest/api/compute/v3/images/test_images.py b/tempest/api/compute/v3/images/test_images.py
index b045630..656f7ba 100644
--- a/tempest/api/compute/v3/images/test_images.py
+++ b/tempest/api/compute/v3/images/test_images.py
@@ -22,7 +22,6 @@
class ImagesV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/images/test_images_oneserver.py b/tempest/api/compute/v3/images/test_images_oneserver.py
index 1ded4e4..48a885e 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver.py
@@ -26,7 +26,6 @@
class ImagesOneServerV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
def setUp(self):
# NOTE(afazekas): Normally we use the same server with all test cases,
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 8d2517e..7679eee 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver_negative.py
@@ -27,7 +27,6 @@
class ImagesOneServerNegativeV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
def tearDown(self):
"""Terminate test instances created after a test is executed."""
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs.py b/tempest/api/compute/v3/keypairs/test_keypairs.py
index 8eef811..668a295 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs.py
@@ -19,7 +19,6 @@
class KeyPairsV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
index ae22ccc..e426b85 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
@@ -21,7 +21,6 @@
class KeyPairsNegativeV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index 272cb53..f6068de 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -24,7 +24,6 @@
class AttachInterfacesV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
@@ -122,3 +121,30 @@
_ifs = self._test_delete_interface(server, ifs)
self.assertEqual(len(ifs) - 1, len(_ifs))
+
+ @attr(type='gate')
+ def test_add_remove_fixed_ip(self):
+ # Add and Remove the fixed IP to server.
+ server, ifs = self._create_server_get_interfaces()
+ interface_count = len(ifs)
+ self.assertGreater(interface_count, 0)
+ self._check_interface(ifs[0])
+ network_id = ifs[0]['net_id']
+ resp, body = self.client.add_fixed_ip(server['id'],
+ network_id)
+ self.assertEqual(202, resp.status)
+ server_resp, server_detail = self.servers_client.get_server(
+ server['id'])
+ # Get the Fixed IP from server.
+ fixed_ip = None
+ for ip_set in server_detail['addresses']:
+ for ip in server_detail['addresses'][ip_set]:
+ if ip['type'] == 'fixed':
+ fixed_ip = ip['addr']
+ break
+ if fixed_ip is not None:
+ break
+ # Remove the fixed IP from server.
+ resp, body = self.client.remove_fixed_ip(server['id'],
+ fixed_ip)
+ self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/v3/servers/test_attach_volume.py b/tempest/api/compute/v3/servers/test_attach_volume.py
index 2edf934..8577aab 100644
--- a/tempest/api/compute/v3/servers/test_attach_volume.py
+++ b/tempest/api/compute/v3/servers/test_attach_volume.py
@@ -24,7 +24,6 @@
class AttachVolumeV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
run_ssh = CONF.compute.run_ssh
def __init__(self, *args, **kwargs):
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
index 0825381..a212ca5 100644
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ b/tempest/api/compute/v3/servers/test_create_server.py
@@ -28,7 +28,6 @@
class ServersV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
run_ssh = CONF.compute.run_ssh
disk_config = 'AUTO'
@@ -119,7 +118,6 @@
class ServersWithSpecificFlavorV3Test(base.BaseV3ComputeAdminTest):
- _interface = 'json'
run_ssh = CONF.compute.run_ssh
disk_config = 'AUTO'
diff --git a/tempest/api/compute/v3/servers/test_delete_server.py b/tempest/api/compute/v3/servers/test_delete_server.py
index f53ab6e..0dfe60e 100644
--- a/tempest/api/compute/v3/servers/test_delete_server.py
+++ b/tempest/api/compute/v3/servers/test_delete_server.py
@@ -35,6 +35,7 @@
resp, server = self.create_test_server(wait_until='BUILD')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_active_server(self):
@@ -42,6 +43,7 @@
resp, server = self.create_test_server(wait_until='ACTIVE')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_server_while_in_shutoff_state(self):
@@ -51,6 +53,7 @@
self.client.wait_for_server_status(server['id'], 'SHUTOFF')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_server_while_in_pause_state(self):
@@ -60,6 +63,7 @@
self.client.wait_for_server_status(server['id'], 'PAUSED')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
@test.attr(type='gate')
def test_delete_server_while_in_shelved_state(self):
@@ -79,6 +83,7 @@
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.client.wait_for_server_termination(server['id'])
class DeleteServersAdminV3Test(base.BaseV3ComputeAdminTest):
@@ -103,6 +108,8 @@
self.assertEqual(server['status'], 'ERROR')
resp, _ = self.non_admin_client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
+ self.servers_client.wait_for_server_termination(server['id'],
+ ignore_error=True)
@test.attr(type='gate')
def test_admin_delete_servers_of_others(self):
diff --git a/tempest/api/compute/v3/servers/test_instance_actions.py b/tempest/api/compute/v3/servers/test_instance_actions.py
index 5a8465c..7d25100 100644
--- a/tempest/api/compute/v3/servers/test_instance_actions.py
+++ b/tempest/api/compute/v3/servers/test_instance_actions.py
@@ -18,7 +18,6 @@
class InstanceActionsV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
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 e08125b..ec31e8e 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -24,7 +24,6 @@
class ListServerFiltersV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
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 09e1bb6..9a46193 100644
--- a/tempest/api/compute/v3/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_list_servers_negative.py
@@ -21,7 +21,6 @@
class ListServersNegativeV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
force_tenant_isolation = True
@classmethod
diff --git a/tempest/api/compute/v3/servers/test_multiple_create.py b/tempest/api/compute/v3/servers/test_multiple_create.py
index dee4407..23e0854 100644
--- a/tempest/api/compute/v3/servers/test_multiple_create.py
+++ b/tempest/api/compute/v3/servers/test_multiple_create.py
@@ -19,7 +19,6 @@
class MultipleCreateV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
_name = 'multiple-create-test'
def _generate_name(self):
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 6584b93..406c45a 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -28,7 +28,6 @@
class ServerActionsV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
resize_available = CONF.compute_feature_enabled.resize
run_ssh = CONF.compute.run_ssh
@@ -411,3 +410,16 @@
resp, server = self.servers_client.start(self.server_id)
self.assertEqual(202, resp.status)
self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+
+ @testtools.skipUnless(CONF.compute_feature_enabled.vnc_console,
+ 'VNC Console feature is disabled')
+ @test.attr(type='gate')
+ def test_get_vnc_console(self):
+ # Get the VNC console
+ console_types = ['novnc', 'xvpvnc']
+ for console_type in console_types:
+ resp, body = self.servers_client.get_vnc_console(self.server_id,
+ console_type)
+ self.assertEqual(200, resp.status)
+ self.assertEqual(console_type, body['type'])
+ self.assertNotEqual('', body['url'])
diff --git a/tempest/api/compute/v3/servers/test_server_addresses.py b/tempest/api/compute/v3/servers/test_server_addresses.py
index 038e254..335bd3d 100644
--- a/tempest/api/compute/v3/servers/test_server_addresses.py
+++ b/tempest/api/compute/v3/servers/test_server_addresses.py
@@ -22,7 +22,6 @@
class ServerAddressesV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_metadata.py b/tempest/api/compute/v3/servers/test_server_metadata.py
index 13c82dd..0e4ef07 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata.py
@@ -18,7 +18,6 @@
class ServerMetadataV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_metadata_negative.py b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
index ce6c340..ec2bc8c 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
@@ -19,7 +19,6 @@
class ServerMetadataV3NegativeTest(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_password.py b/tempest/api/compute/v3/servers/test_server_password.py
index 579a8a5..fc0b145 100644
--- a/tempest/api/compute/v3/servers/test_server_password.py
+++ b/tempest/api/compute/v3/servers/test_server_password.py
@@ -19,7 +19,6 @@
class ServerPasswordV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_rescue.py b/tempest/api/compute/v3/servers/test_server_rescue.py
index fa7def0..5d7f91d 100644
--- a/tempest/api/compute/v3/servers/test_server_rescue.py
+++ b/tempest/api/compute/v3/servers/test_server_rescue.py
@@ -20,7 +20,6 @@
class ServerRescueV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_servers.py b/tempest/api/compute/v3/servers/test_servers.py
index 5480e31..426ee8d 100644
--- a/tempest/api/compute/v3/servers/test_servers.py
+++ b/tempest/api/compute/v3/servers/test_servers.py
@@ -19,7 +19,6 @@
class ServersV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index 12e0ad8..cb5e93d 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -27,7 +27,6 @@
class ServersNegativeV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
def setUp(self):
super(ServersNegativeV3Test, self).setUp()
diff --git a/tempest/api/compute/v3/test_extensions.py b/tempest/api/compute/v3/test_extensions.py
index 09f5ab4..3c612df 100644
--- a/tempest/api/compute/v3/test_extensions.py
+++ b/tempest/api/compute/v3/test_extensions.py
@@ -25,7 +25,6 @@
class ExtensionsV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@test.attr(type='gate')
def test_list_extensions(self):
diff --git a/tempest/api/compute/v3/test_live_block_migration.py b/tempest/api/compute/v3/test_live_block_migration.py
index 43b4e2b..33d2bd9 100644
--- a/tempest/api/compute/v3/test_live_block_migration.py
+++ b/tempest/api/compute/v3/test_live_block_migration.py
@@ -24,7 +24,6 @@
class LiveBlockMigrationV3Test(base.BaseV3ComputeAdminTest):
_host_key = 'os-extended-server-attributes:host'
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/test_live_block_migration_negative.py b/tempest/api/compute/v3/test_live_block_migration_negative.py
index 4d820d8..b4ec505 100644
--- a/tempest/api/compute/v3/test_live_block_migration_negative.py
+++ b/tempest/api/compute/v3/test_live_block_migration_negative.py
@@ -25,7 +25,6 @@
class LiveBlockMigrationV3NegativeTest(base.BaseV3ComputeAdminTest):
_host_key = 'os-extended-server-attributes:host'
- _interface = 'json'
@classmethod
def setUpClass(cls):
@@ -39,7 +38,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/v3/test_quotas.py b/tempest/api/compute/v3/test_quotas.py
index 33b90ff..b53d9be 100644
--- a/tempest/api/compute/v3/test_quotas.py
+++ b/tempest/api/compute/v3/test_quotas.py
@@ -18,7 +18,6 @@
class QuotasV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/compute/v3/test_version.py b/tempest/api/compute/v3/test_version.py
index 9161d4d..1a74e35 100644
--- a/tempest/api/compute/v3/test_version.py
+++ b/tempest/api/compute/v3/test_version.py
@@ -19,7 +19,6 @@
class VersionV3Test(base.BaseV3ComputeTest):
- _interface = 'json'
@test.attr(type='gate')
def test_version(self):
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 2a5401f..759c4a9 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -70,7 +70,7 @@
@attr(type='gate')
def test_delete_image(self):
- # Deletes a image by image_id
+ # Deletes an image by image_id
# Create image
image_name = data_utils.rand_name('image')
@@ -90,6 +90,43 @@
self.assertEqual(resp.status, 200)
self.assertNotIn(image_id, images)
+ @attr(type='gate')
+ def test_update_image(self):
+ # Updates an image by image_id
+
+ # Create image
+ image_name = data_utils.rand_name('image')
+ resp, body = self.client.create_image(name=image_name,
+ container_format='bare',
+ disk_format='iso',
+ visibility='public')
+ self.assertEqual(201, resp.status)
+ self.assertEqual('queued', body['status'])
+ image_id = body['id']
+
+ # Now try uploading an image file
+ file_content = '*' * 1024
+ image_file = StringIO.StringIO(file_content)
+ resp, body = self.client.store_image(image_id, image_file)
+ self.assertEqual(204, resp.status)
+
+ # Update Image
+ new_image_name = data_utils.rand_name('new-image')
+ new_visibility = 'private'
+ resp, body = self.client.update_image(image_id, [
+ dict(replace='/name', value=new_image_name),
+ dict(replace='/visibility', value=new_visibility)])
+
+ self.assertEqual(200, resp.status)
+
+ # Verifying updating
+
+ resp, body = self.client.get_image(image_id)
+ self.assertEqual(200, resp.status)
+ self.assertEqual(image_id, body['id'])
+ self.assertEqual(new_image_name, body['name'])
+ self.assertEqual(new_visibility, body['visibility'])
+
class ListImagesTest(base.BaseV2ImageTest):
"""
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index 41fc49d..530262f 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -22,6 +22,7 @@
image_id = self._create_image()
resp, member = self.os_img_client.add_member(image_id,
self.alt_tenant_id)
+ self.assertEqual(200, resp.status)
self.assertEqual(member['member_id'], self.alt_tenant_id)
self.assertEqual(member['image_id'], image_id)
self.assertEqual(member['status'], 'pending')
@@ -30,7 +31,8 @@
self.alt_tenant_id,
'accepted')
self.assertIn(image_id, self._list_image_ids_as_alt())
- _, body = self.os_img_client.get_image_membership(image_id)
+ resp, body = self.os_img_client.get_image_membership(image_id)
+ self.assertEqual(200, resp.status)
members = body['members']
member = members[0]
self.assertEqual(len(members), 1, str(members))
@@ -43,11 +45,44 @@
image_id = self._create_image()
resp, member = self.os_img_client.add_member(image_id,
self.alt_tenant_id)
+ self.assertEqual(200, resp.status)
self.assertEqual(member['member_id'], self.alt_tenant_id)
self.assertEqual(member['image_id'], image_id)
self.assertEqual(member['status'], 'pending')
self.assertNotIn(image_id, self._list_image_ids_as_alt())
+ resp, _ = self.alt_img_client.update_member_status(image_id,
+ self.alt_tenant_id,
+ 'rejected')
+ self.assertEqual(200, resp.status)
+ self.assertNotIn(image_id, self._list_image_ids_as_alt())
+
+ @attr(type='gate')
+ def test_get_image_member(self):
+ image_id = self._create_image()
+ self.os_img_client.add_member(image_id,
+ self.alt_tenant_id)
self.alt_img_client.update_member_status(image_id,
self.alt_tenant_id,
- 'rejected')
+ 'accepted')
+
+ self.assertIn(image_id, self._list_image_ids_as_alt())
+ resp, member = self.os_img_client.get_member(image_id,
+ self.alt_tenant_id)
+ self.assertEqual(200, resp.status)
+ self.assertEqual(self.alt_tenant_id, member['member_id'])
+ self.assertEqual(image_id, member['image_id'])
+ self.assertEqual('accepted', member['status'])
+
+ @attr(type='gate')
+ def test_remove_image_member(self):
+ image_id = self._create_image()
+ self.os_img_client.add_member(image_id,
+ self.alt_tenant_id)
+ self.alt_img_client.update_member_status(image_id,
+ self.alt_tenant_id,
+ 'accepted')
+
+ self.assertIn(image_id, self._list_image_ids_as_alt())
+ resp = self.os_img_client.remove_member(image_id, self.alt_tenant_id)
+ self.assertEqual(204, resp.status)
self.assertNotIn(image_id, self._list_image_ids_as_alt())
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index 304b2ca..b278002 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -38,11 +38,13 @@
self.assertNotIn(router_id, routers_list)
def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
- resp, _ = self.client.remove_router_interface_with_subnet_id(
+ resp, body = self.client.remove_router_interface_with_subnet_id(
router_id, subnet_id)
self.assertEqual('200', resp['status'])
+ self.assertEqual(subnet_id, body['subnet_id'])
def _remove_router_interface_with_port_id(self, router_id, port_id):
- resp, _ = self.client.remove_router_interface_with_port_id(
+ resp, body = self.client.remove_router_interface_with_port_id(
router_id, port_id)
self.assertEqual('200', resp['status'])
+ self.assertEqual(port_id, body['port_id'])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 0ff91ab..2657031 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -256,3 +256,48 @@
def _delete_extra_routes(self, router_id):
resp, _ = self.client.delete_extra_routes(router_id)
+
+ @test.attr(type='smoke')
+ def test_update_router_admin_state(self):
+ self.router = self.create_router(data_utils.rand_name('router-'))
+ self.assertFalse(self.router['admin_state_up'])
+ # Update router admin state
+ resp, update_body = self.client.update_router(self.router['id'],
+ admin_state_up=True)
+ self.assertEqual('200', resp['status'])
+ self.assertTrue(update_body['router']['admin_state_up'])
+ resp, show_body = self.client.show_router(self.router['id'])
+ self.assertEqual('200', resp['status'])
+ self.assertTrue(show_body['router']['admin_state_up'])
+
+ @test.attr(type='smoke')
+ def test_add_multiple_router_interfaces(self):
+ network = self.create_network()
+ subnet01 = self.create_subnet(network)
+ subnet02 = self.create_subnet(network)
+ router = self.create_router(data_utils.rand_name('router-'))
+ interface01 = self._add_router_interface_with_subnet_id(router['id'],
+ subnet01['id'])
+ self._verify_router_interface(router['id'], subnet01['id'],
+ interface01['port_id'])
+ interface02 = self._add_router_interface_with_subnet_id(router['id'],
+ subnet02['id'])
+ self._verify_router_interface(router['id'], subnet02['id'],
+ interface02['port_id'])
+
+ def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
+ resp, interface = self.client.add_router_interface_with_subnet_id(
+ router_id, subnet_id)
+ self.assertEqual('200', resp['status'])
+ self.addCleanup(self._remove_router_interface_with_subnet_id,
+ router_id, subnet_id)
+ self.assertEqual(subnet_id, interface['subnet_id'])
+ return interface
+
+ def _verify_router_interface(self, router_id, subnet_id, port_id):
+ resp, show_port_body = self.client.show_port(port_id)
+ self.assertEqual('200', resp['status'])
+ interface_port = show_port_body['port']
+ self.assertEqual(router_id, interface_port['device_id'])
+ self.assertEqual(subnet_id,
+ interface_port['fixed_ips'][0]['subnet_id'])
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 788292d..b14adc0 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -17,9 +17,12 @@
from tempest.api.object_storage 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 AccountQuotasTest(base.BaseObjectTest):
@@ -41,7 +44,7 @@
try:
_, roles = cls.os_admin.identity_client.list_roles()
reseller_role_id = next(r['id'] for r in roles if r['name']
- == 'ResellerAdmin')
+ == CONF.object_storage.reseller_admin_role)
except StopIteration:
msg = "No ResellerAdmin role found"
raise exceptions.NotFound(msg)
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index cab307d..402cd90 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -17,9 +17,12 @@
from tempest.api.object_storage 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 AccountQuotasNegativeTest(base.BaseObjectTest):
@@ -41,7 +44,7 @@
try:
_, roles = cls.os_admin.identity_client.list_roles()
reseller_role_id = next(r['id'] for r in roles if r['name']
- == 'ResellerAdmin')
+ == CONF.object_storage.reseller_admin_role)
except StopIteration:
msg = "No ResellerAdmin role found"
raise exceptions.NotFound(msg)
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 3e621f4..291f0d1 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -135,7 +135,7 @@
# the cause of the server not signalling the waitcondition
# to heat.
resp, body = cls.client.get_resource(cls.stack_identifier,
- 'SmokeServerNeutron')
+ 'Server')
server_id = body['physical_resource_id']
LOG.debug('Console output for %s', server_id)
resp, output = cls.servers_client.get_console_output(
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
new file mode 100644
index 0000000..5921a7a
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
+#
+# Author: Chmouel Boudjnah <chmouel@enovance.com>
+#
+# 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 clients
+from tempest.common.utils import data_utils
+from tempest import config
+
+
+CONF = config.CONF
+
+
+class SwiftResourcesTestJSON(base.BaseOrchestrationTest):
+ _interface = 'json'
+ template = """
+heat_template_version: 2013-05-23
+description: Template which creates a Swift container ressource
+
+resources:
+ SwiftContainerWebsite:
+ DeletionPolicy: "Delete"
+ Type: OS::Swift::Container
+ Properties:
+ X-Container-Read: ".r:*"
+ X-Container-Meta:
+ web-index: "index.html"
+ web-error: "error.html"
+
+ SwiftContainer:
+ Type: OS::Swift::Container
+
+outputs:
+ WebsiteURL:
+ description: "URL for website hosted on S3"
+ value: { get_attr: [SwiftContainer, WebsiteURL] }
+ DomainName:
+ description: "Domain of Swift host"
+ value: { get_attr: [SwiftContainer, DomainName] }
+
+"""
+
+ @classmethod
+ def setUpClass(cls):
+ super(SwiftResourcesTestJSON, cls).setUpClass()
+ cls.client = cls.orchestration_client
+ cls.stack_name = data_utils.rand_name('heat')
+ os = clients.Manager()
+ if not CONF.service_available.swift:
+ raise cls.skipException("Swift support is required")
+ cls.account_client = os.account_client
+ cls.container_client = os.container_client
+ # create the stack
+ cls.stack_identifier = cls.create_stack(
+ cls.stack_name,
+ cls.template)
+ cls.stack_id = cls.stack_identifier.split('/')[1]
+ cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
+ cls.test_resources = {}
+ _, resources = cls.client.list_resources(cls.stack_identifier)
+ for resource in resources:
+ cls.test_resources[resource['logical_resource_id']] = resource
+
+ def test_created_resources(self):
+ """Created stack should be on the list of existing stacks."""
+ resources = [('SwiftContainer', 'OS::Swift::Container'),
+ ('SwiftContainerWebsite', 'OS::Swift::Container')]
+ for resource_name, resource_type in resources:
+ resource = self.test_resources.get(resource_name)
+ self.assertIsInstance(resource, dict)
+ self.assertEqual(resource_type, resource['resource_type'])
+ self.assertEqual(resource_name, resource['logical_resource_id'])
+ self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
+
+ def test_created_containers(self):
+ params = {'format': 'json'}
+ resp, container_list = \
+ self.account_client.list_account_containers(params=params)
+ self.assertEqual('200', resp['status'])
+ self.assertEqual(2, len(container_list))
+ for cont in container_list:
+ self.assertTrue(cont['name'].startswith(self.stack_name))
+
+ def test_acl(self):
+ acl_headers = ('x-container-meta-web-index', 'x-container-read')
+
+ swcont = self.test_resources.get(
+ 'SwiftContainer')['physical_resource_id']
+ swcont_website = self.test_resources.get(
+ 'SwiftContainerWebsite')['physical_resource_id']
+
+ headers, _ = self.container_client.list_container_metadata(swcont)
+ for h in acl_headers:
+ self.assertNotIn(h, headers)
+ headers, _ = self.container_client.list_container_metadata(
+ swcont_website)
+ for h in acl_headers:
+ self.assertIn(h, headers)
+
+ def test_metadata(self):
+ metadatas = {
+ "web-index": "index.html",
+ "web-error": "error.html"
+ }
+ swcont_website = self.test_resources.get(
+ 'SwiftContainerWebsite')['physical_resource_id']
+ headers, _ = self.container_client.list_container_metadata(
+ swcont_website)
+
+ for meta in metadatas:
+ header_meta = "x-container-meta-%s" % meta
+ self.assertIn(header_meta, headers)
+ self.assertEqual(headers[header_meta], metadatas[meta])
diff --git a/tempest/auth.py b/tempest/auth.py
index e1ba13b..8cb3b2c 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -382,7 +382,7 @@
path = "/" + filters['api_version']
noversion_path = "/".join(parts.path.split("/")[2:])
if noversion_path != "":
- path += noversion_path
+ path += "/" + noversion_path
_base_url = _base_url.replace(parts.path, path)
if filters.get('skip_path', None) is not None:
_base_url = _base_url.replace(parts.path, "/")
diff --git a/tempest/config.py b/tempest/config.py
index ad91494..887bac3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -263,7 +263,11 @@
cfg.BoolOpt('block_migrate_cinder_iscsi',
default=False,
help="Does the test environment block migration support "
- "cinder iSCSI volumes")
+ "cinder iSCSI volumes"),
+ cfg.BoolOpt('vnc_console',
+ default=False,
+ help='Enable VNC console. This configuration value should '
+ 'be same as [nova.vnc]->vnc_enabled in nova.conf')
]
@@ -472,6 +476,9 @@
default='Member',
help="Role to add to users created for swift tests to "
"enable creating containers"),
+ cfg.StrOpt('reseller_admin_role',
+ default='ResellerAdmin',
+ help="User role that has reseller admin"),
]
object_storage_feature_group = cfg.OptGroup(
@@ -541,6 +548,11 @@
cfg.StrOpt('catalog_type',
default='metering',
help="Catalog type of the Telemetry service."),
+ cfg.StrOpt('endpoint_type',
+ default='publicURL',
+ choices=['public', 'admin', 'internal',
+ 'publicURL', 'adminURL', 'internalURL'],
+ help="The endpoint type to use for the telemetry service."),
]
@@ -563,7 +575,13 @@
DataProcessingGroup = [
cfg.StrOpt('catalog_type',
default='data_processing',
- help="Catalog type of the data processing service.")
+ help="Catalog type of the data processing service."),
+ cfg.StrOpt('endpoint_type',
+ default='publicURL',
+ choices=['public', 'admin', 'internal',
+ 'publicURL', 'adminURL', 'internalURL'],
+ help="The endpoint type to use for the data processing "
+ "service."),
]
@@ -761,6 +779,12 @@
cfg.StrOpt('catalog_type',
default='baremetal',
help="Catalog type of the baremetal provisioning service."),
+ cfg.StrOpt('endpoint_type',
+ default='publicURL',
+ choices=['public', 'admin', 'internal',
+ 'publicURL', 'adminURL', 'internalURL'],
+ help="The endpoint type to use for the baremetal provisioning "
+ "service."),
]
cli_group = cfg.OptGroup(name='cli', title="cli Configuration Options")
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 56fdcc8..1b1ddab 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -225,8 +225,9 @@
# so case sensitive comparisons can really mess things
# up.
if new_status.lower() == error_status.lower():
- message = ("%s failed to get to expected status. "
- "In %s state.") % (thing, new_status)
+ message = ("%s failed to get to expected status (%s). "
+ "In %s state.") % (thing, expected_status,
+ new_status)
raise exceptions.BuildErrorException(message,
server_id=thing_id)
elif new_status == expected_status and expected_status is not None:
@@ -605,7 +606,7 @@
:param floating_ip: type DeletableFloatingIp
"""
floating_ip.update(port_id=None)
- self.assertEqual(None, floating_ip.port_id)
+ self.assertIsNone(floating_ip.port_id)
return floating_ip
def _ping_ip_address(self, ip_address, should_succeed=True):
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index f4c4c64..de3aa19 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -80,3 +80,25 @@
raise exceptions.TimeoutException(message)
return resp, body
+
+ def add_fixed_ip(self, server_id, network_id):
+ """Add a fixed IP to input server instance."""
+ post_body = json.dumps({
+ 'addFixedIp': {
+ 'networkId': network_id
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
+
+ def remove_fixed_ip(self, server_id, ip_address):
+ """Remove input fixed IP from input server instance."""
+ post_body = json.dumps({
+ 'removeFixedIp': {
+ 'address': ip_address
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 025c4e5..deb78ee 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -428,3 +428,11 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def reset_network(self, server_id, **kwargs):
+ """Resets the Network of a server"""
+ return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+ def inject_network_info(self, server_id, **kwargs):
+ """Inject the Network Info into server"""
+ return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/compute/v3/json/interfaces_client.py b/tempest/services/compute/v3/json/interfaces_client.py
index c167520..f8b9d09 100644
--- a/tempest/services/compute/v3/json/interfaces_client.py
+++ b/tempest/services/compute/v3/json/interfaces_client.py
@@ -81,3 +81,25 @@
raise exceptions.TimeoutException(message)
return resp, body
+
+ def add_fixed_ip(self, server_id, network_id):
+ """Add a fixed IP to input server instance."""
+ post_body = json.dumps({
+ 'add_fixed_ip': {
+ 'network_id': network_id
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
+
+ def remove_fixed_ip(self, server_id, ip_address):
+ """Remove input fixed IP from input server instance."""
+ post_body = json.dumps({
+ 'remove_fixed_ip': {
+ 'address': ip_address
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 840e914..819e366 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -423,3 +423,15 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def get_vnc_console(self, server_id, type):
+ """Get URL of VNC console."""
+ post_body = json.dumps({
+ "get_vnc_console": {
+ "type": type
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ body = json.loads(body)
+ return resp, body['console']
diff --git a/tempest/services/compute/xml/interfaces_client.py b/tempest/services/compute/xml/interfaces_client.py
index 5df6187..8d4bfcc 100644
--- a/tempest/services/compute/xml/interfaces_client.py
+++ b/tempest/services/compute/xml/interfaces_client.py
@@ -24,6 +24,7 @@
from tempest.services.compute.xml.common import Element
from tempest.services.compute.xml.common import Text
from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml.common import XMLNS_11
CONF = config.CONF
@@ -104,3 +105,21 @@
(port_id, status, self.build_timeout))
raise exceptions.TimeoutException(message)
return resp, body
+
+ def add_fixed_ip(self, server_id, network_id):
+ """Add a fixed IP to input server instance."""
+ post_body = Element("addFixedIp",
+ xmlns=XMLNS_11,
+ networkId=network_id)
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ str(Document(post_body)))
+ return resp, body
+
+ def remove_fixed_ip(self, server_id, ip_address):
+ """Remove input fixed IP from input server instance."""
+ post_body = Element("removeFixedIp",
+ xmlns=XMLNS_11,
+ address=ip_address)
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ str(Document(post_body)))
+ return resp, body
diff --git a/tempest/services/compute/xml/quotas_client.py b/tempest/services/compute/xml/quotas_client.py
index eb287c2..b8b759f 100644
--- a/tempest/services/compute/xml/quotas_client.py
+++ b/tempest/services/compute/xml/quotas_client.py
@@ -44,9 +44,6 @@
return quota
- def _parse_array(self, node):
- return [self._format_quota(xml_to_json(x)) for x in node]
-
def get_quota_set(self, tenant_id):
"""List the quota set for a tenant."""
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index da01b83..cd2cb06 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -633,3 +633,11 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def reset_network(self, server_id, **kwargs):
+ """Resets the Network of a server"""
+ return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+ def inject_network_info(self, server_id, **kwargs):
+ """Inject the Network Info into server"""
+ return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/identity/v3/xml/service_client.py b/tempest/services/identity/v3/xml/service_client.py
index d5476c4..d4a5877 100644
--- a/tempest/services/identity/v3/xml/service_client.py
+++ b/tempest/services/identity/v3/xml/service_client.py
@@ -35,12 +35,6 @@
self.endpoint_url = 'adminURL'
self.api_version = "v3"
- def _parse_array(self, node):
- array = []
- for child in node.getchildren():
- array.append(xml_to_json(child))
- return array
-
def _parse_body(self, body):
data = xml_to_json(body)
return data
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 58819d0..30c6ffc 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -68,6 +68,15 @@
self._http = self._get_http()
return self._http
+ def update_image(self, image_id, patch):
+ data = json.dumps(patch)
+ self._validate_schema(data)
+
+ headers = {"Content-Type": "application/openstack-images-v2.0"
+ "-json-patch"}
+ resp, body = self.patch('v2/images/%s' % image_id, data, headers)
+ return resp, self._parse_resp(body)
+
def create_image(self, name, container_format, disk_format, **kwargs):
params = {
"name": name,
@@ -163,3 +172,15 @@
body = json.loads(body)
self.expected_success(200, resp)
return resp, body
+
+ def get_member(self, image_id, member_id):
+ url = 'v2/images/%s/members/%s' % (image_id, member_id)
+ resp, body = self.get(url)
+ self.expected_success(200, resp)
+ return resp, json.loads(body)
+
+ def remove_member(self, image_id, member_id):
+ url = 'v2/images/%s/members/%s' % (image_id, member_id)
+ resp, _ = self.delete(url)
+ self.expected_success(204, resp)
+ return resp
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index 97d514f..c520018 100644
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -30,12 +30,6 @@
rc.TYPE = self.TYPE
return rc
- def _parse_array(self, node):
- array = []
- for child in node.getchildren():
- array.append(common.xml_to_json(child))
- return array
-
def deserialize_list(self, body):
return common.parse_array(etree.fromstring(body), self.PLURALS)
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
index ba43daf..9f07972 100644
--- a/tempest/tests/test_rest_client.py
+++ b/tempest/tests/test_rest_client.py
@@ -164,7 +164,7 @@
keys = ["fake_key1", "fake_key2"]
values = ["fake_value1", "fake_value2"]
- item_expected = {key: value for key, value in zip(keys, values)}
+ item_expected = dict((key, value) for (key, value) in zip(keys, values))
list_expected = {"body_list": [
{keys[0]: values[0]},
{keys[1]: values[1]},
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index 37484cf..dec0170 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -48,7 +48,7 @@
key_name = data_utils.rand_name("keypair-")
self.client.create_key_pair(key_name)
self.client.delete_key_pair(key_name)
- self.assertEqual(None, self.client.get_key_pair(key_name))
+ self.assertIsNone(self.client.get_key_pair(key_name))
@test.attr(type='smoke')
def test_get_ec2_keypair(self):
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
index a493fda..6a771e5 100644
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ b/tempest/thirdparty/boto/test_ec2_volumes.py
@@ -13,10 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest import config
from tempest.openstack.common import log as logging
from tempest import test
from tempest.thirdparty.boto import test as boto_test
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -30,6 +32,11 @@
@classmethod
def setUpClass(cls):
super(EC2VolumesTest, cls).setUpClass()
+
+ if not CONF.service_available.cinder:
+ skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
+ raise cls.skipException(skip_msg)
+
cls.client = cls.os.ec2api_client
cls.zone = cls.client.get_good_zone()
diff --git a/tox.ini b/tox.ini
index 69e9d57..4a625f8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -29,7 +29,7 @@
sitepackages = True
setenv = VIRTUAL_ENV={envdir}
commands =
- python setup.py testr --slowest --testr-args='{posargs}'
+ bash tools/pretty_tox.sh '{posargs}'
[testenv:full]
sitepackages = True