Merge "Updated from global requirements"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 441c87d..f8b0051 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -229,6 +229,18 @@
cls.password = server['adminPass']
return server['id']
+ @classmethod
+ def delete_volume(cls, volume_id):
+ """Deletes the given volume and waits for it to be gone."""
+ try:
+ resp, _ = cls.volumes_extensions_client.delete_volume(volume_id)
+ # TODO(mriedem): We should move the wait_for_resource_deletion
+ # into the delete_volume method as a convenience to the caller.
+ cls.volumes_extensions_client.wait_for_resource_deletion(volume_id)
+ except exceptions.NotFound:
+ LOG.warn("Unable to delete volume '%s' since it was not found. "
+ "Maybe it was already deleted?" % volume_id)
+
class BaseV2ComputeAdminTest(BaseV2ComputeTest):
"""Base test case class for Compute Admin V2 API tests."""
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 15b3faa..15b7b9e 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -143,6 +143,22 @@
# when _interface='xml', one element for servers_links in servers
self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
+ @attr(type='gate')
+ def test_list_servers_filter_by_zero_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 0}
+ resp, servers = self.client.list_servers(params)
+ self.assertEqual(0, len(servers['servers']))
+
+ @attr(type='gate')
+ def test_list_servers_filter_by_exceed_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 100000}
+ resp, servers = self.client.list_servers(params)
+ resp, all_servers = self.client.list_servers()
+ self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
+ len([x for x in servers['servers'] if 'id' in x]))
+
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@attr(type='gate')
def test_list_servers_detailed_filter_by_image(self):
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index 533a2c2..86ac497 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -125,6 +125,22 @@
resp, servers = self.client.list_servers(params)
self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
+ @attr(type='gate')
+ def test_list_servers_filter_by_zero_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 0}
+ resp, servers = self.client.list_servers(params)
+ self.assertEqual(0, len(servers['servers']))
+
+ @attr(type='gate')
+ def test_list_servers_filter_by_exceed_limit(self):
+ # Verify only the expected number of servers are returned
+ params = {'limit': 100000}
+ resp, servers = self.client.list_servers(params)
+ resp, all_servers = self.client.list_servers()
+ self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
+ len([x for x in servers['servers'] if 'id' in x]))
+
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@attr(type='gate')
def test_list_servers_detailed_filter_by_image(self):
diff --git a/tempest/api/compute/v3/servers/test_server_metadata.py b/tempest/api/compute/v3/servers/test_server_metadata.py
index 1758b0b..00549eb 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata.py
@@ -14,8 +14,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
class ServerMetadataV3TestJSON(base.BaseV3ComputeTest):
@@ -40,7 +39,7 @@
resp, _ = self.client.set_server_metadata(self.server_id, meta)
self.assertEqual(resp.status, 200)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_list_server_metadata(self):
# All metadata key/value pairs for a server should be returned
resp, resp_metadata = self.client.list_server_metadata(self.server_id)
@@ -50,7 +49,7 @@
expected = {'key1': 'value1', 'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_set_server_metadata(self):
# The server's metadata should be replaced with the provided values
# Create a new set of metadata for the server
@@ -64,22 +63,7 @@
resp, resp_metadata = self.client.list_server_metadata(self.server_id)
self.assertEqual(resp_metadata, req_metadata)
- @attr(type='gate')
- def test_server_create_metadata_key_too_long(self):
- # Attempt to start a server with a meta-data key that is > 255
- # characters
-
- # Try a few values
- for sz in [256, 257, 511, 1023]:
- key = "k" * sz
- meta = {key: 'data1'}
- self.assertRaises(exceptions.OverLimit,
- self.create_test_server,
- meta=meta)
-
- # no teardown - all creates should fail
-
- @attr(type='gate')
+ @test.attr(type='gate')
def test_update_server_metadata(self):
# The server's metadata values should be updated to the
# provided values
@@ -93,7 +77,7 @@
expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_update_metadata_empty_body(self):
# The original metadata should not be lost if empty metadata body is
# passed
@@ -103,14 +87,14 @@
expected = {'key1': 'value1', 'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_get_server_metadata_item(self):
# The value for a specific metadata key should be returned
resp, meta = self.client.get_server_metadata_item(self.server_id,
'key2')
self.assertEqual('value2', meta['key2'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_set_server_metadata_item(self):
# The item's value should be updated to the provided value
# Update the metadata value
@@ -124,7 +108,7 @@
expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
self.assertEqual(expected, resp_metadata)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_delete_server_metadata_item(self):
# The metadata value/key pair should be deleted from the server
resp, meta = self.client.delete_server_metadata_item(self.server_id,
@@ -135,77 +119,3 @@
resp, resp_metadata = self.client.list_server_metadata(self.server_id)
expected = {'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
-
- @attr(type=['negative', 'gate'])
- def test_server_metadata_negative(self):
- # Blank key should trigger an error.
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- meta=meta)
-
- # GET on a non-existent server should not succeed
- self.assertRaises(exceptions.NotFound,
- self.client.get_server_metadata_item, 999, 'test2')
-
- # List metadata on a non-existent server should not succeed
- self.assertRaises(exceptions.NotFound,
- self.client.list_server_metadata, 999)
-
- # Raise BadRequest if key in uri does not match
- # the key passed in body.
- meta = {'testkey': 'testvalue'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata_item,
- self.server_id, 'key', meta)
-
- # Set metadata on a non-existent server should not succeed
- meta = {'meta1': 'data1'}
- self.assertRaises(exceptions.NotFound,
- self.client.set_server_metadata, 999, meta)
-
- # An update should not happen for a non-existent image
- meta = {'key1': 'value1', 'key2': 'value2'}
- self.assertRaises(exceptions.NotFound,
- self.client.update_server_metadata, 999, meta)
-
- # Blank key should trigger an error
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.update_server_metadata,
- self.server_id, meta=meta)
-
- # Should not be able to delete metadata item from a non-existent server
- self.assertRaises(exceptions.NotFound,
- self.client.delete_server_metadata_item, 999, 'd')
-
- # Raise a 413 OverLimit exception while exceeding metadata items limit
- # for tenant.
- _, quota_set = self.quotas.get_quota_set(self.tenant_id)
- quota_metadata = quota_set['metadata_items']
- req_metadata = {}
- for num in range(1, quota_metadata + 2):
- req_metadata['key' + str(num)] = 'val' + str(num)
- self.assertRaises(exceptions.OverLimit,
- self.client.set_server_metadata,
- self.server_id, req_metadata)
-
- # Raise a 413 OverLimit exception while exceeding metadata items limit
- # for tenant (update).
- self.assertRaises(exceptions.OverLimit,
- self.client.update_server_metadata,
- self.server_id, req_metadata)
-
- # Raise a bad request error for blank key.
- # set_server_metadata will replace all metadata with new value
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata,
- self.server_id, meta=meta)
-
- # Raise a bad request error for a missing metadata field
- # set_server_metadata will replace all metadata with new value
- meta = {'meta1': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata,
- self.server_id, meta=meta, no_metadata_field=True)
diff --git a/tempest/api/compute/v3/servers/test_server_metadata_negative.py b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
new file mode 100644
index 0000000..4062696
--- /dev/null
+++ b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
@@ -0,0 +1,158 @@
+# Copyright 2014 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class ServerMetadataV3NegativeTestJSON(base.BaseV3ComputeTest):
+ _interface = 'json'
+
+ @classmethod
+ def setUpClass(cls):
+ super(ServerMetadataV3NegativeTestJSON, cls).setUpClass()
+ cls.client = cls.servers_client
+ cls.quotas = cls.quotas_client
+ cls.admin_client = cls._get_identity_admin_client()
+ resp, tenants = cls.admin_client.list_tenants()
+ cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+ cls.client.tenant_name][0]
+ resp, server = cls.create_test_server(meta={}, wait_until='ACTIVE')
+
+ cls.server_id = server['id']
+
+ @test.attr(type=['gate', 'negative'])
+ def test_server_create_metadata_key_too_long(self):
+ # Attempt to start a server with a meta-data key that is > 255
+ # characters
+
+ # Tryset_server_metadata_item a few values
+ for sz in [256, 257, 511, 1023]:
+ key = "k" * sz
+ meta = {key: 'data1'}
+ self.assertRaises(exceptions.OverLimit,
+ self.create_test_server,
+ meta=meta)
+
+ # no teardown - all creates should fail
+
+ @test.attr(type=['negative', 'gate'])
+ def test_create_server_metadata_blank_key(self):
+ # Blank key should trigger an error.
+ meta = {'': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.create_test_server,
+ meta=meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_server_metadata_non_existent_server(self):
+ # GET on a non-existent server should not succeed
+ non_existent_server_id = data_utils.rand_uuid()
+ self.assertRaises(exceptions.NotFound,
+ self.client.get_server_metadata_item,
+ non_existent_server_id,
+ 'test2')
+
+ @test.attr(type=['negative', 'gate'])
+ def test_list_server_metadata_non_existent_server(self):
+ # List metadata on a non-existent server should not succeed
+ non_existent_server_id = data_utils.rand_uuid()
+ self.assertRaises(exceptions.NotFound,
+ self.client.list_server_metadata,
+ non_existent_server_id)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_wrong_key_passed_in_body(self):
+ # Raise BadRequest if key in uri does not match
+ # the key passed in body.
+ meta = {'testkey': 'testvalue'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.set_server_metadata_item,
+ self.server_id, 'key', meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_set_metadata_non_existent_server(self):
+ # Set metadata on a non-existent server should not succeed
+ non_existent_server_id = data_utils.rand_uuid()
+ meta = {'meta1': 'data1'}
+ self.assertRaises(exceptions.NotFound,
+ self.client.set_server_metadata,
+ non_existent_server_id,
+ meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_update_metadata_non_existent_server(self):
+ # An update should not happen for a non-existent server
+ non_existent_server_id = data_utils.rand_uuid()
+ meta = {'key1': 'value1', 'key2': 'value2'}
+ self.assertRaises(exceptions.NotFound,
+ self.client.update_server_metadata,
+ non_existent_server_id,
+ meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_update_metadata_with_blank_key(self):
+ # Blank key should trigger an error
+ meta = {'': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.update_server_metadata,
+ self.server_id, meta=meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_delete_metadata_non_existent_server(self):
+ # Should not be able to delete metadata item from a non-existent server
+ non_existent_server_id = data_utils.rand_uuid()
+ self.assertRaises(exceptions.NotFound,
+ self.client.delete_server_metadata_item,
+ non_existent_server_id,
+ 'd')
+
+ @test.attr(type=['negative', 'gate'])
+ def test_metadata_items_limit(self):
+ # Raise a 413 OverLimit exception while exceeding metadata items limit
+ # for tenant.
+ _, quota_set = self.quotas.get_quota_set(self.tenant_id)
+ quota_metadata = quota_set['metadata_items']
+ req_metadata = {}
+ for num in range(1, quota_metadata + 2):
+ req_metadata['key' + str(num)] = 'val' + str(num)
+ self.assertRaises(exceptions.OverLimit,
+ self.client.set_server_metadata,
+ self.server_id, req_metadata)
+
+ # Raise a 413 OverLimit exception while exceeding metadata items limit
+ # for tenant (update).
+ self.assertRaises(exceptions.OverLimit,
+ self.client.update_server_metadata,
+ self.server_id, req_metadata)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_set_server_metadata_blank_key(self):
+ # Raise a bad request error for blank key.
+ # set_server_metadata will replace all metadata with new value
+ meta = {'': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.set_server_metadata,
+ self.server_id, meta=meta)
+
+ @test.attr(type=['negative', 'gate'])
+ def test_set_server_metadata_missing_metadata(self):
+ # Raise a bad request error for a missing metadata field
+ # set_server_metadata will replace all metadata with new value
+ meta = {'meta1': 'data1'}
+ self.assertRaises(exceptions.BadRequest,
+ self.client.set_server_metadata,
+ self.server_id, meta=meta, no_metadata_field=True)
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 3fc7c55..bcab891 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -44,7 +44,7 @@
resp, volume = self.client.create_volume(size=1,
display_name=v_name,
metadata=metadata)
- self.addCleanup(self._delete_volume, volume)
+ self.addCleanup(self.delete_volume, volume['id'])
self.assertEqual(200, resp.status)
self.assertIn('id', volume)
self.assertIn('displayName', volume)
@@ -72,16 +72,6 @@
'The fetched Volume metadata misses data '
'from the created Volume')
- def _delete_volume(self, volume):
- # Delete the Volume created in this method
- try:
- resp, _ = self.client.delete_volume(volume['id'])
- self.assertEqual(202, resp.status)
- # Checking if the deleted Volume still exists
- self.client.wait_for_resource_deletion(volume['id'])
- except KeyError:
- return
-
class VolumesGetTestXML(VolumesGetTestJSON):
_interface = "xml"
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index bec2ef4..48b1b7e 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -62,7 +62,7 @@
# too small. So, here, we clean up whatever we did manage
# to create and raise a SkipTest
for volume in cls.volume_list:
- cls.client.delete_volume(volume)
+ cls.delete_volume(volume['id'])
msg = ("Failed to create ALL necessary volumes to run "
"test. This typically means that the backing file "
"size of the nova-volumes group is too small to "
@@ -74,8 +74,7 @@
def tearDownClass(cls):
# Delete the created Volumes
for volume in cls.volume_list:
- resp, _ = cls.client.delete_volume(volume['id'])
- cls.client.wait_for_resource_deletion(volume['id'])
+ cls.delete_volume(volume['id'])
super(VolumesTestJSON, cls).tearDownClass()
@attr(type='gate')
diff --git a/tempest/common/commands.py b/tempest/common/commands.py
index af7a692..6405eaa 100644
--- a/tempest/common/commands.py
+++ b/tempest/common/commands.py
@@ -29,7 +29,8 @@
subprocess_args = {'stdout': subprocess.PIPE,
'stderr': subprocess.STDOUT}
try:
- proc = subprocess.Popen(['/usr/bin/sudo'] + args, **subprocess_args)
+ proc = subprocess.Popen(['/usr/bin/sudo', '-n'] + args,
+ **subprocess_args)
return proc.communicate()[0]
if proc.returncode != 0:
LOG.error(cmd + "returned with: " +
diff --git a/tempest/config.py b/tempest/config.py
index 704556f..66fbed3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -727,9 +727,7 @@
path = os.path.join(conf_dir, conf_file)
- if not (os.path.isfile(path) or
- 'TEMPEST_CONFIG_DIR' in os.environ or
- 'TEMPEST_CONFIG' in os.environ):
+ if not os.path.isfile(path):
path = failsafe_path
# only parse the config file if we expect one to exist. This is needed