Merge "Change six to match global requirements"
diff --git a/run_tests.sh b/run_tests.sh
index 970da51..5c8ce7d 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -63,7 +63,7 @@
-l|--logging) logging=1;;
-L|--logging-config) logging_config=$2; shift;;
--) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no ;;
- *) testrargs="$testrargs $1"
+ *) testrargs="$testrargs $1"; noseargs+=" $1" ;;
esac
shift
done
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 8213839..5495778 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -144,7 +144,7 @@
# An exception should be raised when adding flavor access to the same
# tenant
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.client.add_flavor_access,
new_flavor['id'],
self.tenant_id)
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 5ca16f4..b7c3574 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -16,7 +16,6 @@
# under the License.
from tempest.api.compute import base
-from tempest import exceptions
from tempest.test import attr
@@ -32,7 +31,6 @@
def setUpClass(cls):
super(HypervisorAdminTestJSON, cls).setUpClass()
cls.client = cls.os_adm.hypervisor_client
- cls.non_adm_client = cls.hypervisor_client
def _list_hypervisors(self):
# List of hypervisors
@@ -93,19 +91,14 @@
self.assertEqual(200, resp.status)
self.assertTrue(len(uptime) > 0)
- @attr(type=['negative', 'gate'])
- def test_get_hypervisor_list_with_non_admin_user(self):
- # List of hypervisor and available services with non admin user
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_list)
-
- @attr(type=['negative', 'gate'])
- def test_get_hypervisor_list_details_with_non_admin_user(self):
- # List of hypervisor details and available services with non admin user
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_list_details)
+ @attr(type='gate')
+ def test_search_hypervisor(self):
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+ resp, hypers = self.client.search_hypervisor(
+ hypers[0]['hypervisor_hostname'])
+ self.assertEqual(200, resp.status)
+ self.assertTrue(len(hypers) > 0)
class HypervisorAdminTestXML(HypervisorAdminTestJSON):
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
new file mode 100644
index 0000000..69b8d9c
--- /dev/null
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -0,0 +1,144 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Huawei Technologies Co.,LTD.
+# 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.
+
+import uuid
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest.test import attr
+
+
+class HypervisorAdminNegativeTestJSON(base.BaseComputeAdminTest):
+
+ """
+ Tests Hypervisors API that require admin privileges
+ """
+
+ _interface = 'json'
+
+ @classmethod
+ def setUpClass(cls):
+ super(HypervisorAdminNegativeTestJSON, cls).setUpClass()
+ cls.client = cls.os_adm.hypervisor_client
+ cls.non_adm_client = cls.hypervisor_client
+
+ def _list_hypervisors(self):
+ # List of hypervisors
+ resp, hypers = self.client.get_hypervisor_list()
+ self.assertEqual(200, resp.status)
+ return hypers
+
+ @attr(type=['negative', 'gate'])
+ def test_show_nonexistent_hypervisor(self):
+ nonexistent_hypervisor_id = str(uuid.uuid4())
+
+ self.assertRaises(
+ exceptions.NotFound,
+ self.client.get_hypervisor_show_details,
+ nonexistent_hypervisor_id)
+
+ @attr(type=['negative', 'gate'])
+ def test_show_hypervisor_with_non_admin_user(self):
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_show_details,
+ hypers[0]['id'])
+
+ @attr(type=['negative', 'gate'])
+ def test_show_servers_with_non_admin_user(self):
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_servers,
+ hypers[0]['id'])
+
+ @attr(type=['negative', 'gate'])
+ def test_show_servers_with_nonexistent_hypervisor(self):
+ nonexistent_hypervisor_id = str(uuid.uuid4())
+
+ self.assertRaises(
+ exceptions.NotFound,
+ self.client.get_hypervisor_servers,
+ nonexistent_hypervisor_id)
+
+ @attr(type=['negative', 'gate'])
+ def test_get_hypervisor_stats_with_non_admin_user(self):
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_stats)
+
+ @attr(type=['negative', 'gate'])
+ def test_get_nonexistent_hypervisor_uptime(self):
+ nonexistent_hypervisor_id = str(uuid.uuid4())
+
+ self.assertRaises(
+ exceptions.NotFound,
+ self.client.get_hypervisor_uptime,
+ nonexistent_hypervisor_id)
+
+ @attr(type=['negative', 'gate'])
+ def test_get_hypervisor_uptime_with_non_admin_user(self):
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_uptime,
+ hypers[0]['id'])
+
+ @attr(type=['negative', 'gate'])
+ def test_get_hypervisor_list_with_non_admin_user(self):
+ # List of hypervisor and available services with non admin user
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_list)
+
+ @attr(type=['negative', 'gate'])
+ def test_get_hypervisor_list_details_with_non_admin_user(self):
+ # List of hypervisor details and available services with non admin user
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_list_details)
+
+ @attr(type=['negative', 'gate'])
+ def test_search_nonexistent_hypervisor(self):
+ nonexistent_hypervisor_name = data_utils.rand_name('test_hypervisor')
+
+ self.assertRaises(
+ exceptions.NotFound,
+ self.client.search_hypervisor,
+ nonexistent_hypervisor_name)
+
+ @attr(type=['negative', 'gate'])
+ def test_search_hypervisor_with_non_admin_user(self):
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.search_hypervisor,
+ hypers[0]['hypervisor_hostname'])
+
+
+class HypervisorAdminNegativeTestXML(HypervisorAdminNegativeTestJSON):
+ _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index f55f152..757dfc0 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -17,8 +17,10 @@
from tempest.api.compute import base
from tempest.common.utils.data_utils import rand_name
+from tempest import config
from tempest import exceptions
from tempest.test import attr
+from tempest.test import skip_because
class QuotasAdminTestJSON(base.BaseComputeAdminTest):
@@ -52,15 +54,6 @@
'instances', 'security_group_rules',
'cores', 'security_groups'))
- @classmethod
- def tearDownClass(cls):
- for server in cls.servers:
- try:
- cls.servers_client.delete_server(server['id'])
- except exceptions.NotFound:
- continue
- super(QuotasAdminTestJSON, cls).tearDownClass()
-
@attr(type='smoke')
def test_get_default_quotas(self):
# Admin can get the default resource quota set for a tenant
@@ -167,6 +160,8 @@
instances=default_instances_quota)
self.assertRaises(exceptions.OverLimit, self.create_server)
+ @skip_because(bug="1186354",
+ condition=config.TempestConfig().service_available.neutron)
@attr(type=['negative', 'gate'])
def test_security_groups_exceed_limit(self):
# Negative test: Creation Security Groups over limit should FAIL
@@ -189,6 +184,8 @@
self.sg_client.create_security_group,
"sg-overlimit", "sg-desc")
+ @skip_because(bug="1186354",
+ condition=config.TempestConfig().service_available.neutron)
@attr(type=['negative', 'gate'])
def test_security_groups_rules_exceed_limit(self):
# Negative test: Creation of Security Group Rules should FAIL
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 1b346f1..97e0e69 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -19,6 +19,7 @@
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.test import attr
+from tempest.test import skip_because
class ServersAdminTestJSON(base.BaseComputeAdminTest):
@@ -159,6 +160,7 @@
self.client.reset_state, '999')
@attr(type='gate')
+ @skip_because(bug="1240043")
def test_get_server_diagnostics_by_admin(self):
# Retrieve server diagnostics by admin user
resp, diagnostic = self.client.get_server_diagnostics(self.s1_id)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 0b527d9..885adcf 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -100,6 +100,19 @@
pass
@classmethod
+ def rebuild_server(cls, **kwargs):
+ # Destroy an existing server and creates a new one
+ try:
+ cls.servers_client.delete_server(cls.server_id)
+ cls.servers_client.wait_for_server_termination(cls.server_id)
+ except Exception as exc:
+ LOG.exception(exc)
+ pass
+ resp, server = cls.create_server(wait_until='ACTIVE', **kwargs)
+ cls.server_id = server['id']
+ cls.password = server['adminPass']
+
+ @classmethod
def clear_images(cls):
for image_id in cls.images:
try:
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index b747b46..a5a361e 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -15,8 +15,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+import uuid
+
from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
@@ -46,7 +48,9 @@
for i in range(len(body)):
cls.floating_ip_ids.append(body[i]['id'])
while True:
- cls.non_exist_id = rand_name('999')
+ cls.non_exist_id = data_utils.rand_int_id(start=999)
+ if cls.config.service_available.neutron:
+ cls.non_exist_id = str(uuid.uuid4())
if cls.non_exist_id not in cls.floating_ip_ids:
break
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 3c76069..fb9610a 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -15,8 +15,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+import uuid
+
from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
@@ -87,7 +89,9 @@
floating_ip_id.append(body[i]['id'])
# Creating a non-existent floatingIP id
while True:
- non_exist_id = rand_name('999')
+ non_exist_id = data_utils.rand_int_id(start=999)
+ if self.config.service_available.neutron:
+ non_exist_id = str(uuid.uuid4())
if non_exist_id not in floating_ip_id:
break
self.assertRaises(exceptions.NotFound,
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 800b2de..accfc35 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -23,9 +23,12 @@
from tempest.common.utils.data_utils import parse_image_id
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
+from tempest.openstack.common import log as logging
from tempest.test import attr
from tempest.test import skip_because
+LOG = logging.getLogger(__name__)
+
class ImagesOneServerTestJSON(base.BaseComputeTest):
_interface = 'json'
@@ -37,6 +40,19 @@
self.image_ids.remove(image_id)
super(ImagesOneServerTestJSON, 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()
+ # Check if the server is in a clean state after test
+ try:
+ self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ except Exception as exc:
+ LOG.exception(exc)
+ # Rebuild server if cannot reach the ACTIVE state
+ # Usually it means the server had a serius accident
+ self.rebuild_server()
+
@classmethod
def setUpClass(cls):
super(ImagesOneServerTestJSON, cls).setUpClass()
@@ -46,7 +62,8 @@
raise cls.skipException(skip_msg)
try:
- resp, cls.server = cls.create_server(wait_until='ACTIVE')
+ resp, server = cls.create_server(wait_until='ACTIVE')
+ cls.server_id = server['id']
except Exception:
cls.tearDownClass()
raise
@@ -71,7 +88,7 @@
# Return an error if the image name has multi-byte characters
snapshot_name = rand_name('\xef\xbb\xbf')
self.assertRaises(exceptions.BadRequest,
- self.client.create_image, self.server['id'],
+ self.client.create_image, self.server_id,
snapshot_name)
@attr(type=['negative', 'gate'])
@@ -80,7 +97,7 @@
snapshot_name = rand_name('test-snap-')
meta = {'': ''}
self.assertRaises(exceptions.BadRequest, self.client.create_image,
- self.server['id'], snapshot_name, meta)
+ self.server_id, snapshot_name, meta)
@attr(type=['negative', 'gate'])
def test_create_image_specify_metadata_over_limits(self):
@@ -88,7 +105,7 @@
snapshot_name = rand_name('test-snap-')
meta = {'a' * 260: 'b' * 260}
self.assertRaises(exceptions.BadRequest, self.client.create_image,
- self.server['id'], snapshot_name, meta)
+ self.server_id, snapshot_name, meta)
def _get_default_flavor_disk_size(self, flavor_id):
resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
@@ -102,7 +119,7 @@
# Create a new image
name = rand_name('image')
meta = {'image_type': 'test'}
- resp, body = self.client.create_image(self.server['id'], name, meta)
+ resp, body = self.client.create_image(self.server_id, name, meta)
self.assertEqual(202, resp.status)
image_id = parse_image_id(resp['location'])
self.client.wait_for_image_status(image_id, 'ACTIVE')
@@ -133,7 +150,7 @@
# Create first snapshot
snapshot_name = rand_name('test-snap-')
- resp, body = self.client.create_image(self.server['id'],
+ resp, body = self.client.create_image(self.server_id,
snapshot_name)
self.assertEqual(202, resp.status)
image_id = parse_image_id(resp['location'])
@@ -141,8 +158,8 @@
# Create second snapshot
alt_snapshot_name = rand_name('test-snap-')
- self.assertRaises(exceptions.Duplicate, self.client.create_image,
- self.server['id'], alt_snapshot_name)
+ self.assertRaises(exceptions.Conflict, self.client.create_image,
+ self.server_id, alt_snapshot_name)
self.client.wait_for_image_status(image_id, 'ACTIVE')
@attr(type=['negative', 'gate'])
@@ -151,14 +168,14 @@
snapshot_name = rand_name('a' * 260)
self.assertRaises(exceptions.BadRequest, self.client.create_image,
- self.server['id'], snapshot_name)
+ self.server_id, snapshot_name)
@attr(type=['negative', 'gate'])
def test_delete_image_that_is_not_yet_active(self):
# Return an error while trying to delete an image what is creating
snapshot_name = rand_name('test-snap-')
- resp, body = self.client.create_image(self.server['id'], snapshot_name)
+ resp, body = self.client.create_image(self.server_id, snapshot_name)
self.assertEqual(202, resp.status)
image_id = parse_image_id(resp['location'])
self.image_ids.append(image_id)
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index 807315a..9b2a1de 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -158,7 +158,7 @@
resp, _ = self.client.create_keypair(k_name)
self.assertEqual(200, resp.status)
# Now try the same keyname to create another key
- self.assertRaises(exceptions.Duplicate, self.client.create_keypair,
+ self.assertRaises(exceptions.Conflict, self.client.create_keypair,
k_name)
resp, _ = self.client.delete_keypair(k_name)
self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index cbc0080..5faa9a4 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -16,7 +16,7 @@
# under the License.
from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
from tempest.test import attr
@@ -36,8 +36,8 @@
# Positive test: Creation of Security Group rule
# should be successful
# Creating a Security Group to add rules to it
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = \
self.client.create_security_group(s_name, s_description)
securitygroup_id = securitygroup['id']
@@ -63,15 +63,15 @@
secgroup1 = None
secgroup2 = None
# Creating a Security Group to add rules to it
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = \
self.client.create_security_group(s_name, s_description)
secgroup1 = securitygroup['id']
self.addCleanup(self.client.delete_security_group, secgroup1)
# Creating a Security Group so as to assign group_id to the rule
- s_name2 = rand_name('securitygroup-')
- s_description2 = rand_name('description-')
+ s_name2 = data_utils.rand_name('securitygroup-')
+ s_description2 = data_utils.rand_name('description-')
resp, securitygroup = \
self.client.create_security_group(s_name2, s_description2)
secgroup2 = securitygroup['id']
@@ -100,7 +100,7 @@
# Negative test: Creation of Security Group rule should FAIL
# with invalid Parent group id
# Adding rules to the invalid Security Group id
- parent_group_id = rand_name('999')
+ parent_group_id = data_utils.rand_int_id(start=999)
ip_protocol = 'tcp'
from_port = 22
to_port = 22
@@ -113,13 +113,13 @@
# Negative test: Creation of Security Group rule should FAIL
# with invalid ip_protocol
# Creating a Security Group to add rule to it
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = self.client.create_security_group(s_name,
s_description)
# Adding rules to the created Security Group
parent_group_id = securitygroup['id']
- ip_protocol = rand_name('999')
+ ip_protocol = data_utils.rand_name('999')
from_port = 22
to_port = 22
@@ -133,14 +133,14 @@
# Negative test: Creation of Security Group rule should FAIL
# with invalid from_port
# Creating a Security Group to add rule to it
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = self.client.create_security_group(s_name,
s_description)
# Adding rules to the created Security Group
parent_group_id = securitygroup['id']
ip_protocol = 'tcp'
- from_port = rand_name('999')
+ from_port = data_utils.rand_int_id(start=999, end=65535)
to_port = 22
self.addCleanup(self.client.delete_security_group, securitygroup['id'])
self.assertRaises(exceptions.BadRequest,
@@ -150,17 +150,17 @@
@attr(type=['negative', 'gate'])
def test_security_group_rules_create_with_invalid_to_port(self):
# Negative test: Creation of Security Group rule should FAIL
- # with invalid from_port
+ # with invalid to_port
# Creating a Security Group to add rule to it
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = self.client.create_security_group(s_name,
s_description)
# Adding rules to the created Security Group
parent_group_id = securitygroup['id']
ip_protocol = 'tcp'
from_port = 22
- to_port = rand_name('999')
+ to_port = data_utils.rand_int_id(start=65536)
self.addCleanup(self.client.delete_security_group, securitygroup['id'])
self.assertRaises(exceptions.BadRequest,
self.client.create_security_group_rule,
@@ -171,8 +171,8 @@
# Negative test: Creation of Security Group rule should FAIL
# with invalid port range.
# Creating a Security Group to add rule to it.
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = self.client.create_security_group(s_name,
s_description)
# Adding a rule to the created Security Group
@@ -193,15 +193,15 @@
# with invalid rule id
self.assertRaises(exceptions.NotFound,
self.client.delete_security_group_rule,
- rand_name('999'))
+ data_utils.rand_int_id(start=999))
@attr(type='gate')
def test_security_group_rules_list(self):
# Positive test: Created Security Group rules should be
# in the list of all rules
# Creating a Security Group to add rules to it
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = \
self.client.create_security_group(s_name, s_description)
securitygroup_id = securitygroup['id']
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index fba2f53..2d9c62d 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -18,7 +18,7 @@
import testtools
from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
from tempest.test import attr
@@ -43,8 +43,8 @@
# Create 3 Security Groups
security_group_list = list()
for i in range(3):
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = \
self.client.create_security_group(s_name, s_description)
self.assertEqual(200, resp.status)
@@ -68,8 +68,8 @@
@attr(type='gate')
def test_security_group_create_delete(self):
# Security Group should be created, verified and deleted
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = \
self.client.create_security_group(s_name, s_description)
self.assertIn('id', securitygroup)
@@ -87,8 +87,8 @@
@attr(type='gate')
def test_security_group_create_get_delete(self):
# Security Group should be created, fetched and deleted
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, securitygroup = \
self.client.create_security_group(s_name, s_description)
self.addCleanup(self._delete_security_group,
@@ -120,7 +120,7 @@
security_group_id.append(body[i]['id'])
# Creating a non-existent Security Group id
while True:
- non_exist_id = rand_name('999')
+ non_exist_id = data_utils.rand_int_id(start=999)
if non_exist_id not in security_group_id:
break
self.assertRaises(exceptions.NotFound, self.client.get_security_group,
@@ -132,7 +132,7 @@
def test_security_group_create_with_invalid_group_name(self):
# Negative test: Security Group should not be created with group name
# as an empty string/with white spaces/chars more than 255
- s_description = rand_name('description-')
+ s_description = data_utils.rand_name('description-')
# Create Security Group with empty string as group name
self.assertRaises(exceptions.BadRequest,
self.client.create_security_group, "", s_description)
@@ -152,7 +152,7 @@
def test_security_group_create_with_invalid_group_description(self):
# Negative test:Security Group should not be created with description
# as an empty string/with white spaces/chars more than 255
- s_name = rand_name('securitygroup-')
+ s_name = data_utils.rand_name('securitygroup-')
# Create Security Group with empty string as description
self.assertRaises(exceptions.BadRequest,
self.client.create_security_group, s_name, "")
@@ -171,8 +171,8 @@
def test_security_group_create_with_duplicate_name(self):
# Negative test:Security Group with duplicate name should not
# be created
- s_name = rand_name('securitygroup-')
- s_description = rand_name('description-')
+ s_name = data_utils.rand_name('securitygroup-')
+ s_description = data_utils.rand_name('description-')
resp, security_group =\
self.client.create_security_group(s_name, s_description)
self.assertEqual(200, resp.status)
@@ -209,7 +209,7 @@
security_group_id.append(body[i]['id'])
# Creating non-existent Security Group
while True:
- non_exist_id = rand_name('999')
+ non_exist_id = data_utils.rand_int_id(start=999)
if non_exist_id not in security_group_id:
break
self.assertRaises(exceptions.NotFound,
@@ -228,19 +228,19 @@
# and not deleted if the server is active.
# Create a couple security groups that we will use
# for the server resource this test creates
- sg_name = rand_name('sg')
- sg_desc = rand_name('sg-desc')
+ sg_name = data_utils.rand_name('sg')
+ sg_desc = data_utils.rand_name('sg-desc')
resp, sg = self.client.create_security_group(sg_name, sg_desc)
sg_id = sg['id']
- sg2_name = rand_name('sg')
- sg2_desc = rand_name('sg-desc')
+ sg2_name = data_utils.rand_name('sg')
+ sg2_desc = data_utils.rand_name('sg-desc')
resp, sg2 = self.client.create_security_group(sg2_name, sg2_desc)
sg2_id = sg2['id']
# Create server and add the security group created
# above to the server we just created
- server_name = rand_name('server')
+ server_name = data_utils.rand_name('server')
resp, server = self.servers_client.create_server(server_name,
self.image_ref,
self.flavor_ref)
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 9abb86a..ffc8b6b 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -38,6 +38,7 @@
# A server should be rebuilt using the manual disk config option
resp, server = self.create_server(disk_config='AUTO',
wait_until='ACTIVE')
+ self.addCleanup(self.client.delete_server, server['id'])
# Verify the specified attributes are set correctly
resp, server = self.client.get_server(server['id'])
@@ -54,14 +55,12 @@
resp, server = self.client.get_server(server['id'])
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
- # Delete the server
- resp, body = self.client.delete_server(server['id'])
-
@attr(type='gate')
def test_rebuild_server_with_auto_disk_config(self):
# A server should be rebuilt using the auto disk config option
resp, server = self.create_server(disk_config='MANUAL',
wait_until='ACTIVE')
+ self.addCleanup(self.client.delete_server, server['id'])
# Verify the specified attributes are set correctly
resp, server = self.client.get_server(server['id'])
@@ -78,16 +77,13 @@
resp, server = self.client.get_server(server['id'])
self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
- # Delete the server
- resp, body = self.client.delete_server(server['id'])
-
@testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
@attr(type='gate')
def test_resize_server_from_manual_to_auto(self):
# A server should be resized from manual to auto disk config
resp, server = self.create_server(disk_config='MANUAL',
wait_until='ACTIVE')
-
+ self.addCleanup(self.client.delete_server, server['id'])
# Resize with auto option
self.client.resize(server['id'], self.flavor_ref_alt,
disk_config='AUTO')
@@ -98,15 +94,13 @@
resp, server = self.client.get_server(server['id'])
self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
- # Delete the server
- resp, body = self.client.delete_server(server['id'])
-
@testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
@attr(type='gate')
def test_resize_server_from_auto_to_manual(self):
# A server should be resized from auto to manual disk config
resp, server = self.create_server(disk_config='AUTO',
wait_until='ACTIVE')
+ self.addCleanup(self.client.delete_server, server['id'])
# Resize with manual option
self.client.resize(server['id'], self.flavor_ref_alt,
@@ -118,8 +112,26 @@
resp, server = self.client.get_server(server['id'])
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
- # Delete the server
- resp, body = self.client.delete_server(server['id'])
+ @attr(type='gate')
+ def test_update_server_from_auto_to_manual(self):
+ # A server should be updated from auto to manual disk config
+ resp, server = self.create_server(disk_config='AUTO',
+ wait_until='ACTIVE')
+ self.addCleanup(self.client.delete_server, server['id'])
+
+ # Verify the disk_config attribute is set correctly
+ resp, server = self.client.get_server(server['id'])
+ self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
+
+ # Update the disk_config attribute to manual
+ resp, server = self.client.update_server(server['id'],
+ disk_config='MANUAL')
+ self.assertEqual(200, resp.status)
+ self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+ # Verify the disk_config attribute is set correctly
+ resp, server = self.client.get_server(server['id'])
+ self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
class ServerDiskConfigTestXML(ServerDiskConfigTestJSON):
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 6f646b2..f073ebc 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -44,13 +44,13 @@
self.client.wait_for_server_status(self.server_id, 'ACTIVE')
except Exception:
# Rebuild server if something happened to it during a test
- self.rebuild_servers()
+ self.rebuild_server()
@classmethod
def setUpClass(cls):
super(ServerActionsTestJSON, cls).setUpClass()
cls.client = cls.servers_client
- cls.rebuild_servers()
+ cls.rebuild_server()
@testtools.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
'Change password not available.')
@@ -197,41 +197,6 @@
required time (%s s).' % (self.server_id, self.build_timeout)
raise exceptions.TimeoutException(message)
- @attr(type=['negative', 'gate'])
- def test_resize_server_using_nonexist_flavor(self):
- flavor_id = -1
- self.assertRaises(exceptions.BadRequest,
- self.client.resize, self.server_id, flavor_id)
-
- @attr(type=['negative', 'gate'])
- def test_resize_server_using_null_flavor(self):
- flavor_id = ""
- self.assertRaises(exceptions.BadRequest,
- self.client.resize, self.server_id, flavor_id)
-
- @attr(type=['negative', 'gate'])
- def test_reboot_nonexistent_server_soft(self):
- # Negative Test: The server reboot on non existent server should return
- # an error
- self.assertRaises(exceptions.NotFound, self.client.reboot, 999, 'SOFT')
-
- @attr(type=['negative', 'gate'])
- def test_rebuild_nonexistent_server(self):
- # Negative test: The server rebuild for a non existing server
- # should not be allowed
- meta = {'rebuild': 'server'}
- new_name = rand_name('server')
- file_contents = 'Test server rebuild.'
- personality = [{'path': '/etc/rebuild.txt',
- 'contents': base64.b64encode(file_contents)}]
- self.assertRaises(exceptions.NotFound,
- self.client.rebuild,
- 999, self.image_ref_alt,
- name=new_name,
- metadata=meta,
- personality=personality,
- adminPass='rebuild')
-
@attr(type='gate')
def test_get_console_output(self):
# Positive test:Should be able to GET the console output
@@ -245,14 +210,6 @@
self.assertEqual(lines, 10)
self.wait_for(get_output)
- @attr(type=['negative', 'gate'])
- def test_get_console_output_invalid_server_id(self):
- # Negative test: Should not be able to get the console output
- # for an invalid server_id
- self.assertRaises(exceptions.NotFound,
- self.servers_client.get_console_output,
- '!@#$%^&*()', 10)
-
@skip_because(bug="1014683")
@attr(type='gate')
def test_get_console_output_server_id_in_reboot_status(self):
@@ -286,14 +243,6 @@
self.assertEqual(202, resp.status)
self.client.wait_for_server_status(self.server_id, 'ACTIVE')
- @classmethod
- def rebuild_servers(cls):
- # Destroy any existing server and creates a new one
- cls.clear_servers()
- resp, server = cls.create_server(wait_until='ACTIVE')
- cls.server_id = server['id']
- cls.password = server['adminPass']
-
@attr(type='gate')
def test_stop_start_server(self):
resp, server = self.servers_client.stop(self.server_id)
@@ -303,6 +252,7 @@
self.assertEqual(202, resp.status)
self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+ @skip_because(bug="1233026")
@attr(type='gate')
def test_lock_unlock_server(self):
# Lock the server,try server stop(exceptions throw),unlock it and retry
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 5ea3cbf..15c3e6b 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -81,14 +81,6 @@
# no teardown - all creates should fail
- @attr(type=['negative', 'gate'])
- def test_create_metadata_key_error(self):
- # Blank key should trigger an error.
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.create_server,
- meta=meta)
-
@attr(type='gate')
def test_update_server_metadata(self):
# The server's metadata values should be updated to the
@@ -147,62 +139,48 @@
self.assertEqual(expected, resp_metadata)
@attr(type=['negative', 'gate'])
- def test_get_nonexistant_server_metadata_item(self):
- # Negative test: GET on a non-existent server should not succeed
+ def test_server_metadata_negative(self):
+ # Blank key should trigger an error.
+ meta = {'': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.create_server,
+ meta=meta)
+
+ # GET on a non-existent server should not succeed
self.assertRaises(exceptions.NotFound,
self.client.get_server_metadata_item, 999, 'test2')
- @attr(type=['negative', 'gate'])
- def test_list_nonexistant_server_metadata(self):
- # Negative test:List metadata on a non-existent server should
- # not succeed
+ # List metadata on a non-existent server should not succeed
self.assertRaises(exceptions.NotFound,
self.client.list_server_metadata, 999)
- @attr(type=['negative', 'gate'])
- def test_set_server_metadata_item_incorrect_uri_key(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)
- @attr(type=['negative', 'gate'])
- def test_set_nonexistant_server_metadata(self):
- # Negative test: Set metadata on a non-existent server should not
- # succeed
+ # Set metadata on a non-existent server should not succeed
meta = {'meta1': 'data1'}
self.assertRaises(exceptions.NotFound,
self.client.set_server_metadata, 999, meta)
- @attr(type=['negative', 'gate'])
- def test_update_nonexistant_server_metadata(self):
- # Negative test: An update should not happen for a non-existent image
+ # 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)
- @attr(type=['negative', 'gate'])
- def test_update_metadata_key_error(self):
- # Blank key should trigger an error.
+ # Blank key should trigger an error
meta = {'': 'data1'}
self.assertRaises(exceptions.BadRequest,
self.client.update_server_metadata,
self.server_id, meta=meta)
- @attr(type=['negative', 'gate'])
- def test_delete_nonexistant_server_metadata_item(self):
- # Negative test: Should not be able to delete metadata item from a
- # non-existent server
-
- # Delete the metadata item
+ # 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')
- @attr(type=['negative', 'gate'])
- def test_set_server_metadata_too_long(self):
# Raise a 413 OverLimit exception while exceeding metadata items limit
# for tenant.
_, quota_set = self.quotas.get_quota_set(self.tenant_id)
@@ -214,21 +192,12 @@
self.client.set_server_metadata,
self.server_id, req_metadata)
- @attr(type=['negative', 'gate'])
- def test_update_server_metadata_too_long(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)
+ # for tenant (update).
self.assertRaises(exceptions.OverLimit,
self.client.update_server_metadata,
self.server_id, req_metadata)
- @attr(type=['negative', 'gate'])
- def test_update_all_metadata_field_error(self):
# Raise a bad request error for blank key.
# set_server_metadata will replace all metadata with new value
meta = {'': 'data1'}
@@ -236,6 +205,13 @@
self.client.set_server_metadata,
self.server_id, meta=meta)
+ # Raise a bad request error for a missing metadata field
+ # set_server_metadata will replace all metadata with new value
+ meta = {'meta1': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.set_server_metadata,
+ self.server_id, meta=meta, no_metadata_field=True)
+
class ServerMetadataTestXML(ServerMetadataTestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 82559d5..3cbae56 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -133,13 +133,13 @@
self.addCleanup(self._unpause, self.server_id)
self.assertEqual(202, resp.status)
self.servers_client.wait_for_server_status(self.server_id, 'PAUSED')
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.servers_client.rescue_server,
self.server_id)
@attr(type=['negative', 'gate'])
def test_rescued_vm_reboot(self):
- self.assertRaises(exceptions.Duplicate, self.servers_client.reboot,
+ self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
self.rescue_id, 'HARD')
@attr(type=['negative', 'gate'])
@@ -151,7 +151,7 @@
@attr(type=['negative', 'gate'])
def test_rescued_vm_rebuild(self):
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.servers_client.rebuild,
self.rescue_id,
self.image_ref_alt)
@@ -164,7 +164,7 @@
self.addCleanup(self._unrescue, self.server_id)
# Attach the volume to the server
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.servers_client.attach_volume,
self.server_id,
self.volume_to_attach['id'],
@@ -188,7 +188,7 @@
self.addCleanup(self._unrescue, self.server_id)
# Detach the volume from the server expecting failure
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.servers_client.detach_volume,
self.server_id,
self.volume_to_detach['id'])
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 5d9a5ce..d2088fa 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -15,6 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import base64
import sys
import uuid
@@ -28,6 +29,13 @@
class ServersNegativeTestJSON(base.BaseComputeTest):
_interface = 'json'
+ def setUp(self):
+ super(ServersNegativeTestJSON, self).setUp()
+ try:
+ self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ except Exception:
+ self.rebuild_server()
+
@classmethod
def setUpClass(cls):
super(ServersNegativeTestJSON, cls).setUpClass()
@@ -35,6 +43,8 @@
cls.img_client = cls.images_client
cls.alt_os = clients.AltManager()
cls.alt_client = cls.alt_os.servers_client
+ resp, server = cls.create_server(wait_until='ACTIVE')
+ cls.server_id = server['id']
@attr(type=['negative', 'gate'])
def test_server_name_blank(self):
@@ -90,38 +100,65 @@
self.create_server, accessIPv6=IPv6)
@attr(type=['negative', 'gate'])
- def test_reboot_deleted_server(self):
- # Reboot a deleted server
- resp, server = self.create_server()
- self.server_id = server['id']
- self.client.delete_server(self.server_id)
- self.client.wait_for_server_termination(self.server_id)
+ def test_resize_server_with_non_existent_flavor(self):
+ # Resize a server with non-existent flavor
+ nonexistent_flavor = str(uuid.uuid4())
+ self.assertRaises(exceptions.BadRequest, self.client.resize,
+ self.server_id, flavor_ref=nonexistent_flavor)
+
+ @attr(type=['negative', 'gate'])
+ def test_resize_server_with_null_flavor(self):
+ # Resize a server with null flavor
+ self.assertRaises(exceptions.BadRequest, self.client.resize,
+ self.server_id, flavor_ref="")
+
+ @attr(type=['negative', 'gate'])
+ def test_reboot_non_existent_server(self):
+ # Reboot a non existent server
+ nonexistent_server = str(uuid.uuid4())
self.assertRaises(exceptions.NotFound, self.client.reboot,
- self.server_id, 'SOFT')
+ nonexistent_server, 'SOFT')
@attr(type=['negative', 'gate'])
def test_pause_paused_server(self):
# Pause a paused server.
- resp, server = self.create_server(wait_until='ACTIVE')
- self.server_id = server['id']
self.client.pause_server(self.server_id)
+ self.addCleanup(self.client.unpause_server,
+ self.server_id)
self.client.wait_for_server_status(self.server_id, 'PAUSED')
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.client.pause_server,
self.server_id)
@attr(type=['negative', 'gate'])
- def test_rebuild_deleted_server(self):
- # Rebuild a deleted server
-
- resp, server = self.create_server()
- self.server_id = server['id']
- self.client.delete_server(self.server_id)
- self.client.wait_for_server_termination(self.server_id)
+ def test_rebuild_reboot_deleted_server(self):
+ # Rebuild and Reboot a deleted server
+ _, server = self.create_server()
+ self.client.delete_server(server['id'])
+ self.client.wait_for_server_termination(server['id'])
self.assertRaises(exceptions.NotFound,
self.client.rebuild,
- self.server_id, self.image_ref_alt)
+ server['id'], self.image_ref_alt)
+ self.assertRaises(exceptions.NotFound, self.client.reboot,
+ server['id'], 'SOFT')
+
+ @attr(type=['negative', 'gate'])
+ def test_rebuild_non_existent_server(self):
+ # Rebuild a non existent server
+ nonexistent_server = str(uuid.uuid4())
+ meta = {'rebuild': 'server'}
+ new_name = rand_name('server')
+ file_contents = 'Test server rebuild.'
+ personality = [{'path': '/etc/rebuild.txt',
+ 'contents': base64.b64encode(file_contents)}]
+ self.assertRaises(exceptions.NotFound,
+ self.client.rebuild,
+ nonexistent_server,
+ self.image_ref_alt,
+ name=new_name, meta=meta,
+ personality=personality,
+ adminPass='rebuild')
@attr(type=['negative', 'gate'])
def test_create_numeric_server_name(self):
@@ -195,21 +232,19 @@
def test_update_server_of_another_tenant(self):
# Update name of a server that belongs to another tenant
- resp, server = self.create_server(wait_until='ACTIVE')
- new_name = server['id'] + '_new'
+ new_name = self.server_id + '_new'
self.assertRaises(exceptions.NotFound,
- self.alt_client.update_server, server['id'],
+ self.alt_client.update_server, self.server_id,
name=new_name)
@attr(type=['negative', 'gate'])
def test_update_server_name_length_exceeds_256(self):
# Update name of server exceed the name length limit
- resp, server = self.create_server(wait_until='ACTIVE')
new_name = 'a' * 256
self.assertRaises(exceptions.BadRequest,
self.client.update_server,
- server['id'],
+ self.server_id,
name=new_name)
@attr(type=['negative', 'gate'])
@@ -222,10 +257,9 @@
@attr(type=['negative', 'gate'])
def test_delete_a_server_of_another_tenant(self):
# Delete a server that belongs to another tenant
- resp, server = self.create_server(wait_until='ACTIVE')
self.assertRaises(exceptions.NotFound,
self.alt_client.delete_server,
- server['id'])
+ self.server_id)
@attr(type=['negative', 'gate'])
def test_delete_server_pass_negative_id(self):
@@ -259,66 +293,71 @@
@attr(type=['negative', 'gate'])
def test_stop_non_existent_server(self):
# Stop a non existent server
+ nonexistent_server = str(uuid.uuid4())
self.assertRaises(exceptions.NotFound, self.servers_client.stop,
- str(uuid.uuid4()))
+ nonexistent_server)
@attr(type=['negative', 'gate'])
def test_pause_non_existent_server(self):
# pause a non existent server
+ nonexistent_server = str(uuid.uuid4())
self.assertRaises(exceptions.NotFound, self.client.pause_server,
- str(uuid.uuid4()))
+ nonexistent_server)
@attr(type=['negative', 'gate'])
def test_unpause_non_existent_server(self):
# unpause a non existent server
+ nonexistent_server = str(uuid.uuid4())
self.assertRaises(exceptions.NotFound, self.client.unpause_server,
- str(uuid.uuid4()))
+ nonexistent_server)
@attr(type=['negative', 'gate'])
def test_unpause_server_invalid_state(self):
# unpause an active server.
- resp, server = self.create_server(wait_until='ACTIVE')
- server_id = server['id']
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.client.unpause_server,
- server_id)
+ self.server_id)
@attr(type=['negative', 'gate'])
def test_suspend_non_existent_server(self):
# suspend a non existent server
+ nonexistent_server = str(uuid.uuid4())
self.assertRaises(exceptions.NotFound, self.client.suspend_server,
- str(uuid.uuid4()))
+ nonexistent_server)
@attr(type=['negative', 'gate'])
def test_suspend_server_invalid_state(self):
- # create server.
- resp, server = self.create_server(wait_until='ACTIVE')
- server_id = server['id']
-
# suspend a suspended server.
- resp, _ = self.client.suspend_server(server_id)
+ resp, _ = self.client.suspend_server(self.server_id)
+ self.addCleanup(self.client.resume_server,
+ self.server_id)
self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(server_id, 'SUSPENDED')
- self.assertRaises(exceptions.Duplicate,
+ self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
+ self.assertRaises(exceptions.Conflict,
self.client.suspend_server,
- server_id)
+ self.server_id)
@attr(type=['negative', 'gate'])
def test_resume_non_existent_server(self):
# resume a non existent server
+ nonexistent_server = str(uuid.uuid4())
self.assertRaises(exceptions.NotFound, self.client.resume_server,
- str(uuid.uuid4()))
+ nonexistent_server)
@attr(type=['negative', 'gate'])
def test_resume_server_invalid_state(self):
- # create server.
- resp, server = self.create_server(wait_until='ACTIVE')
- server_id = server['id']
-
# resume an active server.
- self.assertRaises(exceptions.Duplicate,
+ self.assertRaises(exceptions.Conflict,
self.client.resume_server,
- server_id)
+ self.server_id)
+
+ @attr(type=['negative', 'gate'])
+ def test_get_console_output_of_non_existent_server(self):
+ # get the console output for a non existent server
+ nonexistent_server = str(uuid.uuid4())
+ self.assertRaises(exceptions.NotFound,
+ self.client.get_console_output,
+ nonexistent_server, 10)
class ServersNegativeTestXML(ServersNegativeTestJSON):
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index 9ca1380..90e6946 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -15,8 +15,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+import uuid
+
from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
from tempest import exceptions
from tempest.test import attr
@@ -36,39 +38,23 @@
def test_volume_get_nonexistant_volume_id(self):
# Negative: Should not be able to get details of nonexistant volume
# Creating a nonexistant volume id
- volume_id_list = list()
- resp, body = self.client.list_volumes()
- for i in range(len(body)):
- volume_id_list.append(body[i]['id'])
- while True:
- non_exist_id = rand_name('999')
- if non_exist_id not in volume_id_list:
- break
# Trying to GET a non existant volume
self.assertRaises(exceptions.NotFound, self.client.get_volume,
- non_exist_id)
+ str(uuid.uuid4()))
@attr(type=['negative', 'gate'])
def test_volume_delete_nonexistant_volume_id(self):
# Negative: Should not be able to delete nonexistant Volume
# Creating nonexistant volume id
- volume_id_list = list()
- resp, body = self.client.list_volumes()
- for i in range(len(body)):
- volume_id_list.append(body[i]['id'])
- while True:
- non_exist_id = rand_name('999')
- if non_exist_id not in volume_id_list:
- break
# Trying to DELETE a non existant volume
self.assertRaises(exceptions.NotFound, self.client.delete_volume,
- non_exist_id)
+ str(uuid.uuid4()))
@attr(type=['negative', 'gate'])
def test_create_volume_with_invalid_size(self):
# Negative: Should not be able to create volume with invalid size
# in request
- v_name = rand_name('Volume-')
+ v_name = data_utils.rand_name('Volume-')
metadata = {'Type': 'work'}
self.assertRaises(exceptions.BadRequest, self.client.create_volume,
size='#$%', display_name=v_name, metadata=metadata)
@@ -77,7 +63,7 @@
def test_create_volume_with_out_passing_size(self):
# Negative: Should not be able to create volume without passing size
# in request
- v_name = rand_name('Volume-')
+ v_name = data_utils.rand_name('Volume-')
metadata = {'Type': 'work'}
self.assertRaises(exceptions.BadRequest, self.client.create_volume,
size='', display_name=v_name, metadata=metadata)
@@ -85,7 +71,7 @@
@attr(type=['negative', 'gate'])
def test_create_volume_with_size_zero(self):
# Negative: Should not be able to create volume with size zero
- v_name = rand_name('Volume-')
+ v_name = data_utils.rand_name('Volume-')
metadata = {'Type': 'work'}
self.assertRaises(exceptions.BadRequest, self.client.create_volume,
size='0', display_name=v_name, metadata=metadata)
diff --git a/tempest/api/identity/admin/test_roles.py b/tempest/api/identity/admin/test_roles.py
index 690d14f..543cd91 100644
--- a/tempest/api/identity/admin/test_roles.py
+++ b/tempest/api/identity/admin/test_roles.py
@@ -103,7 +103,7 @@
self.assertIn('status', resp)
self.assertTrue(resp['status'].startswith('2'))
self.addCleanup(self.client.delete_role, role1_id)
- self.assertRaises(exceptions.Duplicate, self.client.create_role,
+ self.assertRaises(exceptions.Conflict, self.client.create_role,
role_name)
@attr(type='gate')
@@ -160,7 +160,7 @@
# Duplicate user role should not get assigned
(user, tenant, role) = self._get_role_params()
self.client.assign_user_role(tenant['id'], user['id'], role['id'])
- self.assertRaises(exceptions.Duplicate, self.client.assign_user_role,
+ self.assertRaises(exceptions.Conflict, self.client.assign_user_role,
tenant['id'], user['id'], role['id'])
@attr(type='gate')
diff --git a/tempest/api/identity/admin/test_tenant_negative.py b/tempest/api/identity/admin/test_tenant_negative.py
new file mode 100644
index 0000000..d10080b
--- /dev/null
+++ b/tempest/api/identity/admin/test_tenant_negative.py
@@ -0,0 +1,148 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Huawei Technologies Co.,LTD.
+# 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.
+
+import uuid
+
+from tempest.api.identity import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest.test import attr
+
+
+class TenantsNegativeTestJSON(base.BaseIdentityAdminTest):
+ _interface = 'json'
+
+ @attr(type=['negative', 'gate'])
+ def test_list_tenants_by_unauthorized_user(self):
+ # Non-administrator user should not be able to list tenants
+ self.assertRaises(exceptions.Unauthorized,
+ self.non_admin_client.list_tenants)
+
+ @attr(type=['negative', 'gate'])
+ def test_list_tenant_request_without_token(self):
+ # Request to list tenants without a valid token should fail
+ token = self.client.get_auth()
+ self.client.delete_token(token)
+ self.assertRaises(exceptions.Unauthorized, self.client.list_tenants)
+ self.client.clear_auth()
+
+ @attr(type=['negative', 'gate'])
+ def test_tenant_delete_by_unauthorized_user(self):
+ # Non-administrator user should not be able to delete a tenant
+ tenant_name = data_utils.rand_name(name='tenant-')
+ resp, tenant = self.client.create_tenant(tenant_name)
+ self.assertEqual(200, resp.status)
+ self.data.tenants.append(tenant)
+ self.assertRaises(exceptions.Unauthorized,
+ self.non_admin_client.delete_tenant, tenant['id'])
+
+ @attr(type=['negative', 'gate'])
+ def test_tenant_delete_request_without_token(self):
+ # Request to delete a tenant without a valid token should fail
+ tenant_name = data_utils.rand_name(name='tenant-')
+ resp, tenant = self.client.create_tenant(tenant_name)
+ self.assertEqual(200, resp.status)
+ self.data.tenants.append(tenant)
+ token = self.client.get_auth()
+ self.client.delete_token(token)
+ self.assertRaises(exceptions.Unauthorized, self.client.delete_tenant,
+ tenant['id'])
+ self.client.clear_auth()
+
+ @attr(type=['negative', 'gate'])
+ def test_delete_non_existent_tenant(self):
+ # Attempt to delete a non existent tenant should fail
+ self.assertRaises(exceptions.NotFound, self.client.delete_tenant,
+ str(uuid.uuid4().hex))
+
+ @attr(type=['negative', 'gate'])
+ def test_tenant_create_duplicate(self):
+ # Tenant names should be unique
+ tenant_name = data_utils.rand_name(name='tenant-')
+ resp, body = self.client.create_tenant(tenant_name)
+ self.assertEqual(200, resp.status)
+ tenant = body
+ self.data.tenants.append(tenant)
+ tenant1_id = body.get('id')
+
+ self.addCleanup(self.client.delete_tenant, tenant1_id)
+ self.addCleanup(self.data.tenants.remove, tenant)
+ self.assertRaises(exceptions.Conflict, self.client.create_tenant,
+ tenant_name)
+
+ @attr(type=['negative', 'gate'])
+ def test_create_tenant_by_unauthorized_user(self):
+ # Non-administrator user should not be authorized to create a tenant
+ tenant_name = data_utils.rand_name(name='tenant-')
+ self.assertRaises(exceptions.Unauthorized,
+ self.non_admin_client.create_tenant, tenant_name)
+
+ @attr(type=['negative', 'gate'])
+ def test_create_tenant_request_without_token(self):
+ # Create tenant request without a token should not be authorized
+ tenant_name = data_utils.rand_name(name='tenant-')
+ token = self.client.get_auth()
+ self.client.delete_token(token)
+ self.assertRaises(exceptions.Unauthorized, self.client.create_tenant,
+ tenant_name)
+ self.client.clear_auth()
+
+ @attr(type=['negative', 'gate'])
+ def test_create_tenant_with_empty_name(self):
+ # Tenant name should not be empty
+ self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
+ name='')
+
+ @attr(type=['negative', 'gate'])
+ def test_create_tenants_name_length_over_64(self):
+ # Tenant name length should not be greater than 64 characters
+ tenant_name = 'a' * 65
+ self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
+ tenant_name)
+
+ @attr(type=['negative', 'gate'])
+ def test_update_non_existent_tenant(self):
+ # Attempt to update a non existent tenant should fail
+ self.assertRaises(exceptions.NotFound, self.client.update_tenant,
+ str(uuid.uuid4().hex))
+
+ @attr(type=['negative', 'gate'])
+ def test_tenant_update_by_unauthorized_user(self):
+ # Non-administrator user should not be able to update a tenant
+ tenant_name = data_utils.rand_name(name='tenant-')
+ resp, tenant = self.client.create_tenant(tenant_name)
+ self.assertEqual(200, resp.status)
+ self.data.tenants.append(tenant)
+ self.assertRaises(exceptions.Unauthorized,
+ self.non_admin_client.update_tenant, tenant['id'])
+
+ @attr(type=['negative', 'gate'])
+ def test_tenant_update_request_without_token(self):
+ # Request to update a tenant without a valid token should fail
+ tenant_name = data_utils.rand_name(name='tenant-')
+ resp, tenant = self.client.create_tenant(tenant_name)
+ self.assertEqual(200, resp.status)
+ self.data.tenants.append(tenant)
+ token = self.client.get_auth()
+ self.client.delete_token(token)
+ self.assertRaises(exceptions.Unauthorized, self.client.update_tenant,
+ tenant['id'])
+ self.client.clear_auth()
+
+
+class TenantsNegativeTestXML(TenantsNegativeTestJSON):
+ _interface = 'xml'
diff --git a/tempest/api/identity/admin/test_tenants.py b/tempest/api/identity/admin/test_tenants.py
index 486b739..e36b543 100644
--- a/tempest/api/identity/admin/test_tenants.py
+++ b/tempest/api/identity/admin/test_tenants.py
@@ -16,8 +16,7 @@
# under the License.
from tempest.api.identity import base
-from tempest.common.utils.data_utils import rand_name
-from tempest import exceptions
+from tempest.common.utils import data_utils
from tempest.test import attr
@@ -25,25 +24,13 @@
_interface = 'json'
@attr(type='gate')
- def test_list_tenants_by_unauthorized_user(self):
- # Non-administrator user should not be able to list tenants
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.list_tenants)
-
- @attr(type='gate')
- def test_list_tenant_request_without_token(self):
- # Request to list tenants without a valid token should fail
- token = self.client.get_auth()
- self.client.delete_token(token)
- self.assertRaises(exceptions.Unauthorized, self.client.list_tenants)
- self.client.clear_auth()
-
- @attr(type='gate')
def test_tenant_list_delete(self):
# Create several tenants and delete them
tenants = []
for _ in xrange(3):
- resp, tenant = self.client.create_tenant(rand_name('tenant-new'))
+ tenant_name = data_utils.rand_name(name='tenant-new')
+ resp, tenant = self.client.create_tenant(tenant_name)
+ self.assertEqual(200, resp.status)
self.data.tenants.append(tenant)
tenants.append(tenant)
tenant_ids = map(lambda x: x['id'], tenants)
@@ -62,37 +49,10 @@
self.assertFalse(any(found), 'Tenants failed to delete')
@attr(type='gate')
- def test_tenant_delete_by_unauthorized_user(self):
- # Non-administrator user should not be able to delete a tenant
- tenant_name = rand_name('tenant-')
- resp, tenant = self.client.create_tenant(tenant_name)
- self.data.tenants.append(tenant)
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.delete_tenant, tenant['id'])
-
- @attr(type='gate')
- def test_tenant_delete_request_without_token(self):
- # Request to delete a tenant without a valid token should fail
- tenant_name = rand_name('tenant-')
- resp, tenant = self.client.create_tenant(tenant_name)
- self.data.tenants.append(tenant)
- token = self.client.get_auth()
- self.client.delete_token(token)
- self.assertRaises(exceptions.Unauthorized, self.client.delete_tenant,
- tenant['id'])
- self.client.clear_auth()
-
- @attr(type='gate')
- def test_delete_non_existent_tenant(self):
- # Attempt to delete a non existent tenant should fail
- self.assertRaises(exceptions.NotFound, self.client.delete_tenant,
- 'junk_tenant_123456abc')
-
- @attr(type='gate')
def test_tenant_create_with_description(self):
# Create tenant with a description
- tenant_name = rand_name('tenant-')
- tenant_desc = rand_name('desc-')
+ tenant_name = data_utils.rand_name(name='tenant-')
+ tenant_desc = data_utils.rand_name(name='desc-')
resp, body = self.client.create_tenant(tenant_name,
description=tenant_desc)
tenant = body
@@ -113,7 +73,7 @@
@attr(type='gate')
def test_tenant_create_enabled(self):
# Create a tenant that is enabled
- tenant_name = rand_name('tenant-')
+ tenant_name = data_utils.rand_name(name='tenant-')
resp, body = self.client.create_tenant(tenant_name, enabled=True)
tenant = body
self.data.tenants.append(tenant)
@@ -131,7 +91,7 @@
@attr(type='gate')
def test_tenant_create_not_enabled(self):
# Create a tenant that is not enabled
- tenant_name = rand_name('tenant-')
+ tenant_name = data_utils.rand_name(name='tenant-')
resp, body = self.client.create_tenant(tenant_name, enabled=False)
tenant = body
self.data.tenants.append(tenant)
@@ -149,61 +109,18 @@
self.data.tenants.remove(tenant)
@attr(type='gate')
- def test_tenant_create_duplicate(self):
- # Tenant names should be unique
- tenant_name = rand_name('tenant-dup-')
- resp, body = self.client.create_tenant(tenant_name)
- tenant = body
- self.data.tenants.append(tenant)
- tenant1_id = body.get('id')
-
- self.addCleanup(self.client.delete_tenant, tenant1_id)
- self.addCleanup(self.data.tenants.remove, tenant)
- self.assertRaises(exceptions.Duplicate, self.client.create_tenant,
- tenant_name)
-
- @attr(type='gate')
- def test_create_tenant_by_unauthorized_user(self):
- # Non-administrator user should not be authorized to create a tenant
- tenant_name = rand_name('tenant-')
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.create_tenant, tenant_name)
-
- @attr(type='gate')
- def test_create_tenant_request_without_token(self):
- # Create tenant request without a token should not be authorized
- tenant_name = rand_name('tenant-')
- token = self.client.get_auth()
- self.client.delete_token(token)
- self.assertRaises(exceptions.Unauthorized, self.client.create_tenant,
- tenant_name)
- self.client.clear_auth()
-
- @attr(type='gate')
- def test_create_tenant_with_empty_name(self):
- # Tenant name should not be empty
- self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
- name='')
-
- @attr(type='gate')
- def test_create_tenants_name_length_over_64(self):
- # Tenant name length should not be greater than 64 characters
- tenant_name = 'a' * 65
- self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
- tenant_name)
-
- @attr(type='gate')
def test_tenant_update_name(self):
# Update name attribute of a tenant
- t_name1 = rand_name('tenant-')
+ t_name1 = data_utils.rand_name(name='tenant-')
resp, body = self.client.create_tenant(t_name1)
+ self.assertEqual(200, resp.status)
tenant = body
self.data.tenants.append(tenant)
t_id = body['id']
resp1_name = body['name']
- t_name2 = rand_name('tenant2-')
+ t_name2 = data_utils.rand_name(name='tenant2-')
resp, body = self.client.update_tenant(t_id, name=t_name2)
st2 = resp['status']
resp2_name = body['name']
@@ -223,16 +140,17 @@
@attr(type='gate')
def test_tenant_update_desc(self):
# Update description attribute of a tenant
- t_name = rand_name('tenant-')
- t_desc = rand_name('desc-')
+ t_name = data_utils.rand_name(name='tenant-')
+ t_desc = data_utils.rand_name(name='desc-')
resp, body = self.client.create_tenant(t_name, description=t_desc)
+ self.assertEqual(200, resp.status)
tenant = body
self.data.tenants.append(tenant)
t_id = body['id']
resp1_desc = body['description']
- t_desc2 = rand_name('desc2-')
+ t_desc2 = data_utils.rand_name(name='desc2-')
resp, body = self.client.update_tenant(t_id, description=t_desc2)
st2 = resp['status']
resp2_desc = body['description']
@@ -252,9 +170,10 @@
@attr(type='gate')
def test_tenant_update_enable(self):
# Update the enabled attribute of a tenant
- t_name = rand_name('tenant-')
+ t_name = data_utils.rand_name(name='tenant-')
t_en = False
resp, body = self.client.create_tenant(t_name, enabled=t_en)
+ self.assertEqual(200, resp.status)
tenant = body
self.data.tenants.append(tenant)
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/test_tokens.py
new file mode 100644
index 0000000..334a5aa
--- /dev/null
+++ b/tempest/api/identity/admin/test_tokens.py
@@ -0,0 +1,58 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Huawei Technologies Co.,LTD.
+# 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.
+
+import json
+
+from tempest.api.identity import base
+from tempest.common.utils import data_utils
+from tempest.test import attr
+
+
+class TokensTestJSON(base.BaseIdentityAdminTest):
+ _interface = 'json'
+
+ @attr(type='gate')
+ def test_create_delete_token(self):
+ # get a token by username and password
+ user_name = data_utils.rand_name(name='user-')
+ user_password = data_utils.rand_name(name='pass-')
+ # first:create a tenant
+ tenant_name = data_utils.rand_name(name='tenant-')
+ resp, tenant = self.client.create_tenant(tenant_name)
+ self.assertEqual(200, resp.status)
+ self.data.tenants.append(tenant)
+ # second:create a user
+ resp, user = self.client.create_user(user_name, user_password,
+ tenant['id'], '')
+ self.assertEqual(200, resp.status)
+ self.data.users.append(user)
+ # then get a token for the user
+ rsp, body = self.token_client.auth(user_name,
+ user_password,
+ tenant['name'])
+ access_data = json.loads(body)['access']
+ self.assertEqual(rsp['status'], '200')
+ self.assertEqual(access_data['token']['tenant']['name'],
+ tenant['name'])
+ # then delete the token
+ token_id = access_data['token']['id']
+ resp, body = self.client.delete_token(token_id)
+ self.assertEqual(resp['status'], '204')
+
+
+class TokensTestXML(TokensTestJSON):
+ _interface = 'xml'
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/test_users.py
index 66d35cb..906fad3 100644
--- a/tempest/api/identity/admin/test_users.py
+++ b/tempest/api/identity/admin/test_users.py
@@ -18,7 +18,7 @@
from testtools.matchers import Contains
from tempest.api.identity import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
from tempest.test import attr
@@ -28,11 +28,11 @@
@classmethod
def setUpClass(cls):
super(UsersTestJSON, cls).setUpClass()
- cls.alt_user = rand_name('test_user_')
- cls.alt_password = rand_name('pass_')
+ cls.alt_user = data_utils.rand_name('test_user_')
+ cls.alt_password = data_utils.rand_name('pass_')
cls.alt_email = cls.alt_user + '@testmail.tm'
- cls.alt_tenant = rand_name('test_tenant_')
- cls.alt_description = rand_name('desc_')
+ cls.alt_tenant = data_utils.rand_name('test_tenant_')
+ cls.alt_description = data_utils.rand_name('desc_')
@attr(type='smoke')
def test_create_user(self):
@@ -49,7 +49,7 @@
def test_create_user_with_enabled(self):
# Create a user with enabled : False
self.data.setup_test_tenant()
- name = rand_name('test_user_')
+ name = data_utils.rand_name('test_user_')
resp, user = self.client.create_user(name, self.alt_password,
self.data.tenant['id'],
self.alt_email, enabled=False)
@@ -62,7 +62,7 @@
@attr(type='smoke')
def test_update_user(self):
# Test case to check if updating of user attributes is successful.
- test_user = rand_name('test_user_')
+ test_user = data_utils.rand_name('test_user_')
self.data.setup_test_tenant()
resp, user = self.client.create_user(test_user, self.alt_password,
self.data.tenant['id'],
@@ -70,7 +70,7 @@
# Delete the User at the end of this method
self.addCleanup(self.client.delete_user, user['id'])
# Updating user details with new values
- u_name2 = rand_name('user2-')
+ u_name2 = data_utils.rand_name('user2-')
u_email2 = u_name2 + '@testmail.tm'
resp, update_user = self.client.update_user(user['id'], name=u_name2,
email=u_email2,
@@ -90,7 +90,7 @@
@attr(type='smoke')
def test_delete_user(self):
# Delete a user
- test_user = rand_name('test_user_')
+ test_user = data_utils.rand_name('test_user_')
self.data.setup_test_tenant()
resp, user = self.client.create_user(test_user, self.alt_password,
self.data.tenant['id'],
@@ -144,7 +144,7 @@
self.data.setup_test_tenant()
user_ids = list()
fetched_user_ids = list()
- alt_tenant_user1 = rand_name('tenant_user1_')
+ alt_tenant_user1 = data_utils.rand_name('tenant_user1_')
resp, user1 = self.client.create_user(alt_tenant_user1, 'password1',
self.data.tenant['id'],
'user1@123')
@@ -152,7 +152,7 @@
user_ids.append(user1['id'])
self.data.users.append(user1)
- alt_tenant_user2 = rand_name('tenant_user2_')
+ alt_tenant_user2 = data_utils.rand_name('tenant_user2_')
resp, user2 = self.client.create_user(alt_tenant_user2, 'password2',
self.data.tenant['id'],
'user2@123')
@@ -187,7 +187,7 @@
role['id'])
self.assertEqual('200', resp['status'])
- alt_user2 = rand_name('second_user_')
+ alt_user2 = data_utils.rand_name('second_user_')
resp, second_user = self.client.create_user(alt_user2, 'password1',
self.data.tenant['id'],
'user2@123')
diff --git a/tempest/api/identity/admin/test_users_negative.py b/tempest/api/identity/admin/test_users_negative.py
index 7cb9aef..b29d155 100644
--- a/tempest/api/identity/admin/test_users_negative.py
+++ b/tempest/api/identity/admin/test_users_negative.py
@@ -63,7 +63,7 @@
def test_create_user_with_duplicate_name(self):
# Duplicate user should not be created
self.data.setup_test_user()
- self.assertRaises(exceptions.Duplicate, self.client.create_user,
+ self.assertRaises(exceptions.Conflict, self.client.create_user,
self.data.test_user, self.data.test_password,
self.data.tenant['id'], self.data.test_email)
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index 36ced70..ef9814a 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -212,7 +212,7 @@
self.v3data.projects.append(project)
self.assertRaises(
- exceptions.Duplicate, self.v3_client.create_project, project_name)
+ exceptions.Conflict, self.v3_client.create_project, project_name)
@attr(type=['negative', 'gate'])
def test_create_project_by_unauthorized_user(self):
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index e9c395e..9ea9a3d 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -28,21 +28,26 @@
@classmethod
def setUpClass(cls):
super(ImageMembersTests, cls).setUpClass()
- admin = clients.AdminManager(interface='json')
- cls.admin_client = admin.identity_client
- cls.tenants = cls._get_tenants()
+ if cls.config.compute.allow_tenant_isolation:
+ creds = cls.isolated_creds.get_alt_creds()
+ username, tenant_name, password = creds
+ cls.os_alt = clients.Manager(username=username,
+ password=password,
+ tenant_name=tenant_name)
+ else:
+ cls.os_alt = clients.AltManager()
- @classmethod
- def _get_tenants(cls):
- resp, tenants = cls.admin_client.list_tenants()
- tenants = map(lambda x: x['id'], tenants)
- return tenants
+ alt_tenant_name = cls.os_alt.tenant_name
+ identity_client = cls._get_identity_admin_client()
+ _, tenants = identity_client.list_tenants()
+ cls.alt_tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+ alt_tenant_name][0]
def _create_image(self):
image_file = StringIO.StringIO('*' * 1024)
resp, image = self.create_image(container_format='bare',
disk_format='raw',
- is_public=True,
+ is_public=False,
data=image_file)
self.assertEqual(201, resp.status)
image_id = image['id']
@@ -51,23 +56,23 @@
@attr(type='gate')
def test_add_image_member(self):
image = self._create_image()
- resp = self.client.add_member(self.tenants[0], image)
+ resp = self.client.add_member(self.alt_tenant_id, image)
self.assertEqual(204, resp.status)
resp, body = self.client.get_image_membership(image)
self.assertEqual(200, resp.status)
members = body['members']
members = map(lambda x: x['member_id'], members)
- self.assertIn(self.tenants[0], members)
+ self.assertIn(self.alt_tenant_id, members)
@attr(type='gate')
def test_get_shared_images(self):
image = self._create_image()
- resp = self.client.add_member(self.tenants[0], image)
+ resp = self.client.add_member(self.alt_tenant_id, image)
self.assertEqual(204, resp.status)
share_image = self._create_image()
- resp = self.client.add_member(self.tenants[0], share_image)
+ resp = self.client.add_member(self.alt_tenant_id, share_image)
self.assertEqual(204, resp.status)
- resp, body = self.client.get_shared_images(self.tenants[0])
+ resp, body = self.client.get_shared_images(self.alt_tenant_id)
self.assertEqual(200, resp.status)
images = body['shared_images']
images = map(lambda x: x['image_id'], images)
@@ -77,28 +82,28 @@
@attr(type='gate')
def test_remove_member(self):
image_id = self._create_image()
- resp = self.client.add_member(self.tenants[0], image_id)
+ resp = self.client.add_member(self.alt_tenant_id, image_id)
self.assertEqual(204, resp.status)
- resp = self.client.delete_member(self.tenants[0], image_id)
+ resp = self.client.delete_member(self.alt_tenant_id, image_id)
self.assertEqual(204, resp.status)
resp, body = self.client.get_image_membership(image_id)
self.assertEqual(200, resp.status)
members = body['members']
- self.assertEqual(0, len(members))
+ self.assertEqual(0, len(members), str(members))
@attr(type=['negative', 'gate'])
def test_add_member_with_non_existing_image(self):
# Add member with non existing image.
non_exist_image = rand_name('image_')
self.assertRaises(exceptions.NotFound, self.client.add_member,
- self.tenants[0], non_exist_image)
+ self.alt_tenant_id, non_exist_image)
@attr(type=['negative', 'gate'])
def test_delete_member_with_non_existing_image(self):
# Delete member with non existing image.
non_exist_image = rand_name('image_')
self.assertRaises(exceptions.NotFound, self.client.delete_member,
- self.tenants[0], non_exist_image)
+ self.alt_tenant_id, non_exist_image)
@attr(type=['negative', 'gate'])
def test_delete_member_with_non_existing_tenant(self):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index cfac257..b6c2679 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -20,8 +20,11 @@
from tempest import clients
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
+from tempest.openstack.common import log as logging
import tempest.test
+LOG = logging.getLogger(__name__)
+
class BaseNetworkTest(tempest.test.BaseTestCase):
@@ -56,28 +59,84 @@
cls.networks = []
cls.subnets = []
cls.ports = []
+ cls.routers = []
cls.pools = []
cls.vips = []
cls.members = []
cls.health_monitors = []
+ cls.vpnservices = []
@classmethod
def tearDownClass(cls):
+ has_exception = False
+ for vpnservice in cls.vpnservices:
+ try:
+ cls.client.delete_vpn_service(vpnservice['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+
+ for router in cls.routers:
+ try:
+ resp, body = cls.client.list_router_interfaces(router['id'])
+ interfaces = body['ports']
+ for i in interfaces:
+ cls.client.remove_router_interface_with_subnet_id(
+ router['id'], i['fixed_ips'][0]['subnet_id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+ try:
+ cls.client.delete_router(router['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
+
for health_monitor in cls.health_monitors:
- cls.client.delete_health_monitor(health_monitor['id'])
+ try:
+ cls.client.delete_health_monitor(health_monitor['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for member in cls.members:
- cls.client.delete_member(member['id'])
+ try:
+ cls.client.delete_member(member['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for vip in cls.vips:
- cls.client.delete_vip(vip['id'])
+ try:
+ cls.client.delete_vip(vip['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for pool in cls.pools:
- cls.client.delete_pool(pool['id'])
+ try:
+ cls.client.delete_pool(pool['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for port in cls.ports:
- cls.client.delete_port(port['id'])
+ try:
+ cls.client.delete_port(port['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for subnet in cls.subnets:
- cls.client.delete_subnet(subnet['id'])
+ try:
+ cls.client.delete_subnet(subnet['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
for network in cls.networks:
- cls.client.delete_network(network['id'])
+ try:
+ cls.client.delete_network(network['id'])
+ except Exception as exc:
+ LOG.exception(exc)
+ has_exception = True
super(BaseNetworkTest, cls).tearDownClass()
+ if has_exception:
+ raise exceptions.TearDownException()
@classmethod
def create_network(cls, network_name=None):
@@ -125,6 +184,21 @@
return port
@classmethod
+ def create_router(cls, router_name=None, admin_state_up=False,
+ external_network_id=None, enable_snat=None):
+ ext_gw_info = {}
+ if external_network_id:
+ ext_gw_info['network_id'] = external_network_id
+ if enable_snat:
+ ext_gw_info['enable_snat'] = enable_snat
+ resp, body = cls.client.create_router(
+ router_name, external_gateway_info=ext_gw_info,
+ admin_state_up=admin_state_up)
+ router = body['router']
+ cls.routers.append(router)
+ return router
+
+ @classmethod
def create_pool(cls, name, lb_method, protocol, subnet):
"""Wrapper utility that returns a test pool."""
resp, body = cls.client.create_pool(name, lb_method, protocol,
@@ -161,3 +235,19 @@
health_monitor = body['health_monitor']
cls.health_monitors.append(health_monitor)
return health_monitor
+
+ @classmethod
+ def create_router_interface(cls, router_id, subnet_id):
+ """Wrapper utility that returns a router interface."""
+ resp, interface = cls.client.add_router_interface_with_subnet_id(
+ router_id, subnet_id)
+
+ @classmethod
+ def create_vpnservice(cls, subnet_id, router_id):
+ """Wrapper utility that returns a test vpn service."""
+ resp, body = cls.client.create_vpn_service(
+ subnet_id, router_id, admin_state_up=True,
+ name=rand_name("vpnservice-"))
+ vpnservice = body['vpnservice']
+ cls.vpnservices.append(vpnservice)
+ return vpnservice
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index ca2c879..9acb6c5 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -47,11 +47,9 @@
# Create network, subnet, router and add interface
cls.network = cls.create_network()
cls.subnet = cls.create_subnet(cls.network)
- resp, router = cls.client.create_router(
+ cls.router = cls.create_router(
rand_name('router-'),
- external_gateway_info={"network_id":
- cls.network_cfg.public_network_id})
- cls.router = router['router']
+ external_network_id=cls.network_cfg.public_network_id)
resp, _ = cls.client.add_router_interface_with_subnet_id(
cls.router['id'], cls.subnet['id'])
cls.port = list()
@@ -66,7 +64,6 @@
cls.subnet['id'])
for i in range(2):
cls.client.delete_port(cls.port[i]['id'])
- cls.client.delete_router(cls.router['id'])
super(FloatingIPTestJSON, cls).tearDownClass()
def _delete_floating_ip(self, floating_ip_id):
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 8b939fe..2cfbf61 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -52,6 +52,8 @@
@attr(type='smoke')
def test_create_show_list_update_delete_router(self):
# Create a router
+ # NOTE(salv-orlando): Do not invoke self.create_router
+ # as we need to check the response code
name = rand_name('router-')
resp, create_body = self.client.create_router(
name, external_gateway_info={
@@ -94,41 +96,37 @@
def test_add_remove_router_interface_with_subnet_id(self):
network = self.create_network()
subnet = self.create_subnet(network)
- name = rand_name('router-')
- resp, create_body = self.client.create_router(name)
- self.addCleanup(self.client.delete_router, create_body['router']['id'])
+ router = self.create_router(rand_name('router-'))
# Add router interface with subnet id
resp, interface = self.client.add_router_interface_with_subnet_id(
- create_body['router']['id'], subnet['id'])
+ router['id'], subnet['id'])
self.assertEqual('200', resp['status'])
self.addCleanup(self._remove_router_interface_with_subnet_id,
- create_body['router']['id'], subnet['id'])
+ router['id'], subnet['id'])
self.assertTrue('subnet_id' in interface.keys())
self.assertTrue('port_id' in interface.keys())
# Verify router id is equal to device id in port details
resp, show_port_body = self.client.show_port(
interface['port_id'])
self.assertEqual(show_port_body['port']['device_id'],
- create_body['router']['id'])
+ router['id'])
@attr(type='smoke')
def test_add_remove_router_interface_with_port_id(self):
network = self.create_network()
self.create_subnet(network)
- name = rand_name('router-')
- resp, create_body = self.client.create_router(name)
- self.addCleanup(self.client.delete_router, create_body['router']['id'])
+ router = self.create_router(rand_name('router-'))
resp, port_body = self.client.create_port(network['id'])
# add router interface to port created above
resp, interface = self.client.add_router_interface_with_port_id(
- create_body['router']['id'], port_body['port']['id'])
+ router['id'], port_body['port']['id'])
self.assertEqual('200', resp['status'])
self.addCleanup(self._remove_router_interface_with_port_id,
- create_body['router']['id'], port_body['port']['id'])
+ router['id'], port_body['port']['id'])
self.assertTrue('subnet_id' in interface.keys())
self.assertTrue('port_id' in interface.keys())
# Verify router id is equal to device id in port details
resp, show_port_body = self.client.show_port(
interface['port_id'])
self.assertEqual(show_port_body['port']['device_id'],
- create_body['router']['id'])
+ router['id'])
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 60ca88a..9218f0c 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -16,8 +16,7 @@
# under the License.
from tempest.api.network import base
-from tempest.common.utils.data_utils import rand_name
-from tempest import exceptions
+from tempest.common.utils import data_utils
from tempest.test import attr
@@ -66,9 +65,9 @@
self.assertIsNotNone(found, msg)
@attr(type='smoke')
- def test_create_show_delete_security_group_and_rule(self):
+ def test_create_show_delete_security_group(self):
# Create a security group
- name = rand_name('secgroup-')
+ name = data_utils.rand_name('secgroup-')
resp, group_create_body = self.client.create_security_group(name)
self.assertEqual('201', resp['status'])
self.addCleanup(self._delete_security_group,
@@ -88,14 +87,29 @@
for secgroup in list_body['security_groups']:
secgroup_list.append(secgroup['id'])
self.assertIn(group_create_body['security_group']['id'], secgroup_list)
- # No Update in security group
- # Create rule
- resp, rule_create_body = self.client.create_security_group_rule(
- group_create_body['security_group']['id']
- )
+
+ @attr(type='smoke')
+ def test_create_show_delete_security_group_rule(self):
+ # Create a security group
+ name = data_utils.rand_name('secgroup-')
+ resp, group_create_body = self.client.create_security_group(name)
self.assertEqual('201', resp['status'])
- self.addCleanup(self._delete_security_group_rule,
- rule_create_body['security_group_rule']['id'])
+ self.addCleanup(self._delete_security_group,
+ group_create_body['security_group']['id'])
+ self.assertEqual(group_create_body['security_group']['name'], name)
+
+ # Create rules for each protocol
+ protocols = ['tcp', 'udp', 'icmp']
+ for protocol in protocols:
+ resp, rule_create_body = self.client.create_security_group_rule(
+ group_create_body['security_group']['id'],
+ protocol=protocol
+ )
+ self.assertEqual('201', resp['status'])
+ self.addCleanup(self._delete_security_group_rule,
+ rule_create_body['security_group_rule']['id']
+ )
+
# Show details of the created security rule
resp, show_rule_body = self.client.show_security_group_rule(
rule_create_body['security_group_rule']['id']
@@ -109,19 +123,6 @@
for rule in rule_list_body['security_group_rules']]
self.assertIn(rule_create_body['security_group_rule']['id'], rule_list)
- @attr(type=['negative', 'smoke'])
- def test_show_non_existent_security_group(self):
- non_exist_id = rand_name('secgroup-')
- self.assertRaises(exceptions.NotFound, self.client.show_security_group,
- non_exist_id)
-
- @attr(type=['negative', 'smoke'])
- def test_show_non_existent_security_group_rule(self):
- non_exist_id = rand_name('rule-')
- self.assertRaises(exceptions.NotFound,
- self.client.show_security_group_rule,
- non_exist_id)
-
class SecGroupTestXML(SecGroupTest):
_interface = 'xml'
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
new file mode 100644
index 0000000..d321e23
--- /dev/null
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -0,0 +1,42 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.network import test_security_groups as base
+from tempest import exceptions
+from tempest.test import attr
+import uuid
+
+
+class NegativeSecGroupTest(base.SecGroupTest):
+ _interface = 'json'
+
+ @attr(type=['negative', 'smoke'])
+ def test_show_non_existent_security_group(self):
+ non_exist_id = str(uuid.uuid4())
+ self.assertRaises(exceptions.NotFound, self.client.show_security_group,
+ non_exist_id)
+
+ @attr(type=['negative', 'smoke'])
+ def test_show_non_existent_security_group_rule(self):
+ non_exist_id = str(uuid.uuid4())
+ self.assertRaises(exceptions.NotFound,
+ self.client.show_security_group_rule,
+ non_exist_id)
+
+
+class NegativeSecGroupTestXML(NegativeSecGroupTest):
+ _interface = 'xml'
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
new file mode 100644
index 0000000..7a8128b
--- /dev/null
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -0,0 +1,96 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.network import base
+from tempest.common.utils.data_utils import rand_name
+from tempest.test import attr
+
+
+class VPNaaSJSON(base.BaseNetworkTest):
+ _interface = 'json'
+
+ """
+ Tests the following operations in the Neutron API using the REST client for
+ Neutron:
+
+ List VPN Services
+ Show VPN Services
+ Create VPN Services
+ Update VPN Services
+ Delete VPN Services
+ """
+
+ @classmethod
+ def setUpClass(cls):
+ super(VPNaaSJSON, cls).setUpClass()
+ cls.network = cls.create_network()
+ cls.subnet = cls.create_subnet(cls.network)
+ cls.router = cls.create_router(rand_name("router-"))
+ cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+ cls.vpnservice = cls.create_vpnservice(cls.subnet['id'],
+ cls.router['id'])
+
+ @attr(type='smoke')
+ def test_list_vpn_services(self):
+ # Verify the VPN service exists in the list of all VPN services
+ resp, body = self.client.list_vpn_services()
+ self.assertEqual('200', resp['status'])
+ vpnservices = body['vpnservices']
+ self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
+
+ @attr(type='smoke')
+ def test_create_update_delete_vpn_service(self):
+ # Creates a VPN service
+ name = rand_name('vpn-service-')
+ resp, body = self.client.create_vpn_service(self.subnet['id'],
+ self.router['id'],
+ name=name,
+ admin_state_up=True)
+ self.assertEqual('201', resp['status'])
+ vpnservice = body['vpnservice']
+ # Assert if created vpnservices are not found in vpnservices list
+ resp, body = self.client.list_vpn_services()
+ vpn_services = [vs['id'] for vs in body['vpnservices']]
+ self.assertIsNotNone(vpnservice['id'])
+ self.assertIn(vpnservice['id'], vpn_services)
+
+ # TODO(raies): implement logic to update vpnservice
+ # VPNaaS client function to update is implemented.
+ # But precondition is that current state of vpnservice
+ # should be "ACTIVE" not "PENDING*"
+
+ # Verification of vpn service delete
+ resp, body = self.client.delete_vpn_service(vpnservice['id'])
+ self.assertEqual('204', resp['status'])
+ # Asserting if vpn service is found in the list after deletion
+ resp, body = self.client.list_vpn_services()
+ vpn_services = [vs['id'] for vs in body['vpnservices']]
+ self.assertNotIn(vpnservice['id'], vpn_services)
+
+ @attr(type='smoke')
+ def test_show_vpn_service(self):
+ # Verifies the details of a vpn service
+ resp, body = self.client.show_vpn_service(self.vpnservice['id'])
+ self.assertEqual('200', resp['status'])
+ vpnservice = body['vpnservice']
+ self.assertEqual(self.vpnservice['id'], vpnservice['id'])
+ self.assertEqual(self.vpnservice['name'], vpnservice['name'])
+ self.assertEqual(self.vpnservice['description'],
+ vpnservice['description'])
+ self.assertEqual(self.vpnservice['router_id'], vpnservice['router_id'])
+ self.assertEqual(self.vpnservice['subnet_id'], vpnservice['subnet_id'])
+ self.assertEqual(self.vpnservice['tenant_id'], vpnservice['tenant_id'])
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 3e2b6ad..02adc5d 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -85,6 +85,33 @@
size='-1', display_name=v_name, metadata=metadata)
@attr(type=['negative', 'gate'])
+ def test_create_volume_with_nonexistant_volume_type(self):
+ # Should not be able to create volume with non-existant volume type
+ v_name = rand_name('Volume-')
+ metadata = {'Type': 'work'}
+ self.assertRaises(exceptions.NotFound, self.client.create_volume,
+ size='1', volume_type=str(uuid.uuid4()),
+ display_name=v_name, metadata=metadata)
+
+ @attr(type=['negative', 'gate'])
+ def test_create_volume_with_nonexistant_snapshot_id(self):
+ # Should not be able to create volume with non-existant snapshot
+ v_name = rand_name('Volume-')
+ metadata = {'Type': 'work'}
+ self.assertRaises(exceptions.NotFound, self.client.create_volume,
+ size='1', snapshot_id=str(uuid.uuid4()),
+ display_name=v_name, metadata=metadata)
+
+ @attr(type=['negative', 'gate'])
+ def test_create_volume_with_nonexistant_source_volid(self):
+ # Should not be able to create volume with non-existant source volume
+ v_name = rand_name('Volume-')
+ metadata = {'Type': 'work'}
+ self.assertRaises(exceptions.NotFound, self.client.create_volume,
+ size='1', source_volid=str(uuid.uuid4()),
+ display_name=v_name, metadata=metadata)
+
+ @attr(type=['negative', 'gate'])
def test_update_volume_with_nonexistant_volume_id(self):
v_name = rand_name('Volume-')
metadata = {'Type': 'work'}
diff --git a/tempest/cli/simple_read_only/test_neutron.py b/tempest/cli/simple_read_only/test_neutron.py
index 3c266be..9bd07d0 100644
--- a/tempest/cli/simple_read_only/test_neutron.py
+++ b/tempest/cli/simple_read_only/test_neutron.py
@@ -22,6 +22,7 @@
import tempest.cli
from tempest.openstack.common import log as logging
+from tempest import test
CONF = cfg.CONF
@@ -67,9 +68,11 @@
def test_neutron_floatingip_list(self):
self.neutron('floatingip-list')
+ @test.skip_because(bug="1240694")
def test_neutron_meter_label_list(self):
self.neutron('meter-label-list')
+ @test.skip_because(bug="1240694")
def test_neutron_meter_label_rule_list(self):
self.neutron('meter-label-rule-list')
diff --git a/tempest/cli/simple_read_only/test_compute.py b/tempest/cli/simple_read_only/test_nova.py
similarity index 100%
rename from tempest/cli/simple_read_only/test_compute.py
rename to tempest/cli/simple_read_only/test_nova.py
diff --git a/tempest/cli/simple_read_only/test_compute_manage.py b/tempest/cli/simple_read_only/test_nova_manage.py
similarity index 100%
rename from tempest/cli/simple_read_only/test_compute_manage.py
rename to tempest/cli/simple_read_only/test_nova_manage.py
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 4b5127a..9322f1b 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -488,7 +488,7 @@
if resp.status == 409:
if parse_resp:
resp_body = self._parse_resp(resp_body)
- raise exceptions.Duplicate(resp_body)
+ raise exceptions.Conflict(resp_body)
if resp.status == 413:
if parse_resp:
@@ -519,7 +519,7 @@
elif 'message' in resp_body:
message = resp_body['message']
- raise exceptions.ComputeFault(message)
+ raise exceptions.ServerFault(message)
if resp.status >= 400:
if parse_resp:
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index bbba235..3ab8fe0 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -24,7 +24,7 @@
def rand_name(name='test'):
- return name + str(random.randint(1, 0x7fffffff))
+ return name + "-tempest-" + str(random.randint(1, 0x7fffffff))
def rand_int_id(start=0, end=0x7fffffff):
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 158a216..8d05fd8 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -129,8 +129,8 @@
message = "Quota exceeded"
-class ComputeFault(TempestException):
- message = "Got compute fault"
+class ServerFault(TempestException):
+ message = "Got server fault"
class ImageFault(TempestException):
@@ -141,7 +141,7 @@
message = "Got identity error"
-class Duplicate(RestClientException):
+class Conflict(RestClientException):
message = "An object with that identifier already exists"
diff --git a/tempest/scenario/orchestration/test_autoscaling.py b/tempest/scenario/orchestration/test_autoscaling.py
index 658e9bb..e843793 100644
--- a/tempest/scenario/orchestration/test_autoscaling.py
+++ b/tempest/scenario/orchestration/test_autoscaling.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import heatclient.exc as heat_exceptions
import time
from tempest.scenario import manager
@@ -74,7 +75,8 @@
self.assertEqual('CREATE', self.stack.action)
# wait for create to complete.
- self.status_timeout(self.client.stacks, sid, 'COMPLETE')
+ self.status_timeout(self.client.stacks, sid, 'COMPLETE',
+ error_status='FAILED')
self.stack.get()
self.assertEqual('CREATE_COMPLETE', self.stack.stack_status)
@@ -96,8 +98,10 @@
call_until_true(lambda: server_count() == to_servers,
timeout, interval)
self.assertEqual(to_servers, self.server_count,
- 'Failed scaling from %d to %d servers' % (
- from_servers, to_servers))
+ 'Failed scaling from %d to %d servers. '
+ 'Current server count: %s' % (
+ from_servers, to_servers,
+ self.server_count))
# he marched them up to the top of the hill
assertScale(1, 2)
@@ -106,3 +110,15 @@
# and he marched them down again
assertScale(3, 2)
assertScale(2, 1)
+
+ # delete stack on completion
+ self.stack.delete()
+ self.status_timeout(self.client.stacks, sid, 'COMPLETE',
+ error_status='FAILED',
+ not_found_exception=heat_exceptions.NotFound)
+
+ try:
+ self.stack.get()
+ self.assertEqual('DELETE_COMPLETE', self.stack.stack_status)
+ except heat_exceptions.NotFound:
+ pass
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index e2e5c7b..fba5acb 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -63,3 +63,9 @@
resp, body = self.get('os-hypervisors/%s/uptime' % hyper_id)
body = json.loads(body)
return resp, body['hypervisor']
+
+ def search_hypervisor(self, hyper_name):
+ """Search specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s/search' % hyper_name)
+ body = json.loads(body)
+ return resp, body['hypervisors']
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index eda0ede..07bb6ce 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -89,7 +89,7 @@
return resp, body['server']
def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
- accessIPv6=None):
+ accessIPv6=None, disk_config=None):
"""
Updates the properties of an existing server.
server_id: The id of an existing server.
@@ -113,6 +113,9 @@
if accessIPv6 is not None:
post_body['accessIPv6'] = accessIPv6
+ if disk_config is not None:
+ post_body['OS-DCF:diskConfig'] = disk_config
+
post_body = json.dumps({'server': post_body})
resp, body = self.put("servers/%s" % str(server_id),
post_body, self.headers)
@@ -236,8 +239,11 @@
body = json.loads(body)
return resp, body['metadata']
- def set_server_metadata(self, server_id, meta):
- post_body = json.dumps({'metadata': meta})
+ def set_server_metadata(self, server_id, meta, no_metadata_field=False):
+ if no_metadata_field:
+ post_body = ""
+ else:
+ post_body = json.dumps({'metadata': meta})
resp, body = self.put('servers/%s/metadata' % str(server_id),
post_body, self.headers)
body = json.loads(body)
diff --git a/tempest/services/compute/xml/hypervisor_client.py b/tempest/services/compute/xml/hypervisor_client.py
index 3c4f2b8..c10fed9 100644
--- a/tempest/services/compute/xml/hypervisor_client.py
+++ b/tempest/services/compute/xml/hypervisor_client.py
@@ -70,3 +70,10 @@
self.headers)
uptime = xml_to_json(etree.fromstring(body))
return resp, uptime
+
+ def search_hypervisor(self, hyper_name):
+ """Search specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s/search' % hyper_name,
+ self.headers)
+ hypervisors = self._parse_array(etree.fromstring(body))
+ return resp, hypervisors
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index cb21c61..43de4ef 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -250,7 +250,7 @@
return resp, {"servers": servers}
def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
- accessIPv6=None):
+ accessIPv6=None, disk_config=None):
doc = Document()
server = Element("server")
doc.append(server)
@@ -261,6 +261,10 @@
server.add_attr("accessIPv4", accessIPv4)
if accessIPv6 is not None:
server.add_attr("accessIPv6", accessIPv6)
+ if disk_config is not None:
+ server.add_attr('xmlns:OS-DCF', "http://docs.openstack.org/"
+ "compute/ext/disk_config/api/v1.1")
+ server.add_attr("OS-DCF:diskConfig", disk_config)
if meta is not None:
metadata = Element("metadata")
server.append(metadata)
@@ -494,14 +498,15 @@
body = self._parse_key_value(etree.fromstring(body))
return resp, body
- def set_server_metadata(self, server_id, meta):
+ def set_server_metadata(self, server_id, meta, no_metadata_field=False):
doc = Document()
- metadata = Element("metadata")
- doc.append(metadata)
- for k, v in meta.items():
- meta_element = Element("meta", key=k)
- meta_element.append(Text(v))
- metadata.append(meta_element)
+ if not no_metadata_field:
+ metadata = Element("metadata")
+ doc.append(metadata)
+ for k, v in meta.items():
+ meta_element = Element("meta", key=k)
+ meta_element.append(Text(v))
+ metadata.append(meta_element)
resp, body = self.put('servers/%s/metadata' % str(server_id),
str(doc), self.headers)
return resp, xml_to_json(etree.fromstring(body))
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 4b87b91..92c1faf 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -600,3 +600,53 @@
resp, body = self.get(uri, headers=self.headers)
body = json.loads(body)
return resp, body
+
+ def list_vpn_services(self):
+ uri = '%s/vpn/vpnservices' % (self.uri_prefix)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def create_vpn_service(self, subnet_id, router_id, **kwargs):
+ post_body = {
+ "vpnservice": {
+ "subnet_id": subnet_id,
+ "router_id": router_id
+ }
+ }
+ for key, val in kwargs.items():
+ post_body['vpnservice'][key] = val
+ body = json.dumps(post_body)
+ uri = '%s/vpn/vpnservices' % (self.uri_prefix)
+ resp, body = self.post(uri, headers=self.headers, body=body)
+ body = json.loads(body)
+ return resp, body
+
+ def show_vpn_service(self, uuid):
+ uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def delete_vpn_service(self, uuid):
+ uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+ resp, body = self.delete(uri, self.headers)
+ return resp, body
+
+ def update_vpn_service(self, uuid, description):
+ put_body = {
+ "vpnservice": {
+ "description": description
+ }
+ }
+ body = json.dumps(put_body)
+ uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+ resp, body = self.put(uri, body=body, headers=self.headers)
+ body = json.loads(body)
+ return resp, body
+
+ def list_router_interfaces(self, uuid):
+ uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
+ resp, body = self.get(uri, self.headers)
+ body = json.loads(body)
+ return resp, body
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index cf8154a..04ad86f 100755
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -547,6 +547,13 @@
body = _root_tag_fetcher_and_xml_to_json_parse(body)
return resp, body
+ def list_router_interfaces(self, uuid):
+ uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
+ resp, body = self.get(uri, self.headers)
+ ports = self._parse_array(etree.fromstring(body))
+ ports = {"ports": ports}
+ return resp, ports
+
def _root_tag_fetcher_and_xml_to_json_parse(xml_returned_body):
body = ET.fromstring(xml_returned_body)
diff --git a/tempest/tests/test_wrappers.py b/tempest/tests/test_wrappers.py
index 1a5af00..dbe3420 100644
--- a/tempest/tests/test_wrappers.py
+++ b/tempest/tests/test_wrappers.py
@@ -20,8 +20,6 @@
import tempfile
import testtools
-from tempest.test import attr
-
DEVNULL = open(os.devnull, 'wb')
@@ -46,7 +44,6 @@
shutil.copy('tempest/tests/files/setup.cfg', self.setup_cfg_file)
shutil.copy('tempest/tests/files/__init__.py', self.init_file)
- @attr(type='smoke')
def test_pretty_tox(self):
# Copy wrapper script and requirements:
pretty_tox = os.path.join(self.directory, 'pretty_tox.sh')
@@ -62,7 +59,6 @@
shell=True, stdout=DEVNULL, stderr=DEVNULL)
self.assertEqual(exit_code, 0)
- @attr(type='smoke')
def test_pretty_tox_fails(self):
# Copy wrapper script and requirements:
pretty_tox = os.path.join(self.directory, 'pretty_tox.sh')
@@ -78,7 +74,6 @@
stdout=DEVNULL, stderr=DEVNULL)
self.assertEqual(exit_code, 1)
- @attr(type='smoke')
def test_pretty_tox_serial(self):
# Copy wrapper script and requirements:
pretty_tox = os.path.join(self.directory, 'pretty_tox_serial.sh')
@@ -90,7 +85,6 @@
shell=True, stdout=DEVNULL, stderr=DEVNULL)
self.assertEqual(exit_code, 0)
- @attr(type='smoke')
def test_pretty_tox_serial_fails(self):
# Copy wrapper script and requirements:
pretty_tox = os.path.join(self.directory, 'pretty_tox_serial.sh')
diff --git a/tox.ini b/tox.ini
index ff09b3f..d93112c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,11 +1,23 @@
[tox]
envlist = pep8
+minversion = 1.6
+skipsdist = True
[testenv]
setenv = VIRTUAL_ENV={envdir}
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_ALL=C
+usedevelop = True
+
+[testenv:py26]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
+
+[testenv:py33]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
+
+[testenv:py27]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
[testenv:all]
sitepackages = True
@@ -15,29 +27,25 @@
[testenv:full]
sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
# The regex below is used to select which tests to run and exclude the slow tag:
# See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
commands =
- sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests)) {posargs}'
+ sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
[testenv:testr-full]
sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
commands =
- sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests)) {posargs}'
+ sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
[testenv:heat-slow]
sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
- OS_TEST_TIMEOUT=1200
+setenv = OS_TEST_TIMEOUT=1200
# The regex below is used to select heat api/scenario tests tagged as slow.
commands =
sh tools/pretty_tox_serial.sh '(?=.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)\.orchestration) {posargs}'
[testenv:large-ops]
sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
commands =
python setup.py testr --slowest --testr-args='tempest.scenario.test_large_ops {posargs}'
@@ -53,7 +61,7 @@
NOSE_OPENSTACK_STDOUT=1
TEMPEST_PY26_NOSE_COMPAT=1
commands =
- nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --xunit-file=nosetests-full.xml tempest/api tempest/scenario tempest/thirdparty tempest/cli tempest/tests {posargs}
+ nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --xunit-file=nosetests-full.xml tempest/api tempest/scenario tempest/thirdparty tempest/cli {posargs}
[testenv:py26-smoke]
setenv = VIRTUAL_ENV={envdir}
@@ -69,7 +77,6 @@
[testenv:smoke]
sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
# This is still serial because neutron doesn't work with parallel. See:
# https://bugs.launchpad.net/tempest/+bug/1216076 so the neutron smoke
# job would fail if we moved it to parallel.
@@ -78,15 +85,13 @@
[testenv:coverage]
sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
commands =
python -m tools/tempest_coverage -c start --combine
- sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests))'
+ sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli))'
python -m tools/tempest_coverage -c report --html {posargs}
[testenv:stress]
sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
commands =
python -m tempest/stress/run_stress -a -d 3600 -S