Merge "Remove list_security_group_rules wrapper method"
diff --git a/.gitignore b/.gitignore
index f584532..efba45e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,4 @@
.coverage*
!.coveragerc
cover/
-doc/source/_static/tempest.conf
+doc/source/_static/tempest.conf.sample
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 3ec25ea..f85899b 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -15,18 +15,6 @@
import os
import subprocess
-# Build a tempest sample config file:
-def build_sample_config(app):
- root_dir = os.path.dirname(
- os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- subprocess.call(["oslo-config-generator", "--config-file",
- "tools/config/config-generator.tempest.conf",
- "--output-file", "doc/source/_static/tempest.conf"],
- cwd=root_dir)
-
-def setup(app):
- app.connect('builder-inited', build_sample_config)
-
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -42,9 +30,13 @@
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.viewcode',
- 'oslosphinx'
+ 'oslosphinx',
+ 'oslo_config.sphinxconfiggen',
]
+config_generator_config_file = '../../tools/config/config-generator.tempest.conf'
+sample_config_basename = '_static/tempest'
+
todo_include_todos = True
# Add any paths that contain templates here, relative to this directory.
diff --git a/doc/source/sampleconf.rst b/doc/source/sampleconf.rst
index 2a72971..c290140 100644
--- a/doc/source/sampleconf.rst
+++ b/doc/source/sampleconf.rst
@@ -8,7 +8,6 @@
if you are having issues with an option, please compare your version of
Tempest with the version of this documentation.
-The sample configuration can also be viewed in `file form <_static/tempest.conf>`_.
+The sample configuration can also be viewed in `file form <_static/tempest.conf.sample>`_.
-.. include:: _static/tempest.conf
- :code:
+.. literalinclude:: _static/tempest.conf.sample
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index d7b4470..5d461ab 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -117,7 +117,8 @@
device = '/dev/%s' % CONF.compute.volume_device_name
server = self.create_test_server(wait_until='ACTIVE')
- volume = volumes_client.create_volume(size=CONF.volume.volume_size)
+ volume = (volumes_client.create_volume(size=CONF.volume.volume_size)
+ ['volume'])
self.addCleanup(volumes_client.delete_volume, volume['id'])
waiters.wait_for_volume_status(volumes_client,
volume['id'], 'available')
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 9d06188..f8567cf 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -62,7 +62,7 @@
def _create_volume(self):
volume = self.volumes_extensions_client.create_volume(
size=CONF.volume.volume_size, display_name=data_utils.rand_name(
- self.__class__.__name__ + '_volume'))
+ self.__class__.__name__ + '_volume'))['volume']
self.addCleanup(self.delete_volume, volume['id'])
waiters.wait_for_volume_status(self.volumes_extensions_client,
volume['id'], 'available')
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index f05a5a3..6074054 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -48,7 +48,7 @@
# Create volume
volume = self.client.create_volume(size=CONF.volume.volume_size,
display_name=v_name,
- metadata=metadata)
+ metadata=metadata)['volume']
self.addCleanup(self.delete_volume, volume['id'])
self.assertIn('id', volume)
self.assertIn('displayName', volume)
@@ -60,7 +60,7 @@
# Wait for Volume status to become ACTIVE
waiters.wait_for_volume_status(self.client, volume['id'], 'available')
# GET Volume
- fetched_volume = self.client.show_volume(volume['id'])
+ fetched_volume = self.client.show_volume(volume['id'])['volume']
# Verification of details of fetched Volume
self.assertEqual(v_name,
fetched_volume['displayName'],
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 421d96f..f0ed141 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -56,10 +56,10 @@
try:
volume = cls.client.create_volume(size=CONF.volume.volume_size,
display_name=v_name,
- metadata=metadata)
+ metadata=metadata)['volume']
waiters.wait_for_volume_status(cls.client,
volume['id'], 'available')
- volume = cls.client.show_volume(volume['id'])
+ volume = cls.client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
cls.volume_id_list.append(volume['id'])
except Exception:
@@ -89,7 +89,7 @@
def test_volume_list(self):
# Should return the list of Volumes
# Fetch all Volumes
- fetched_list = self.client.list_volumes()
+ fetched_list = self.client.list_volumes()['volumes']
# Now check if all the Volumes created in setup are in fetched list
missing_volumes = [
v for v in self.volume_list if v not in fetched_list
@@ -104,7 +104,7 @@
def test_volume_list_with_details(self):
# Should return the list of Volumes with details
# Fetch all Volumes
- fetched_list = self.client.list_volumes(detail=True)
+ fetched_list = self.client.list_volumes(detail=True)['volumes']
# Now check if all the Volumes created in setup are in fetched list
missing_volumes = [
v for v in self.volume_list if v not in fetched_list
@@ -119,7 +119,7 @@
def test_volume_list_param_limit(self):
# Return the list of volumes based on limit set
params = {'limit': 2}
- fetched_vol_list = self.client.list_volumes(**params)
+ fetched_vol_list = self.client.list_volumes(**params)['volumes']
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volumes by limit set")
@@ -128,7 +128,8 @@
def test_volume_list_with_detail_param_limit(self):
# Return the list of volumes with details based on limit set.
params = {'limit': 2}
- fetched_vol_list = self.client.list_volumes(detail=True, **params)
+ fetched_vol_list = self.client.list_volumes(detail=True,
+ **params)['volumes']
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volume details by limit set")
@@ -137,9 +138,9 @@
def test_volume_list_param_offset_and_limit(self):
# Return the list of volumes based on offset and limit set.
# get all volumes list
- all_vol_list = self.client.list_volumes()
+ all_vol_list = self.client.list_volumes()['volumes']
params = {'offset': 1, 'limit': 1}
- fetched_vol_list = self.client.list_volumes(**params)
+ fetched_vol_list = self.client.list_volumes(**params)['volumes']
# Validating length of the fetched volumes
self.assertEqual(len(fetched_vol_list), params['limit'],
@@ -154,9 +155,10 @@
def test_volume_list_with_detail_param_offset_and_limit(self):
# Return the list of volumes details based on offset and limit set.
# get all volumes list
- all_vol_list = self.client.list_volumes(detail=True)
+ all_vol_list = self.client.list_volumes(detail=True)['volumes']
params = {'offset': 1, 'limit': 1}
- fetched_vol_list = self.client.list_volumes(detail=True, **params)
+ fetched_vol_list = self.client.list_volumes(detail=True,
+ **params)['volumes']
# Validating length of the fetched volumes
self.assertEqual(len(fetched_vol_list), params['limit'],
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 5681ac6..b5f86da 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -92,7 +92,6 @@
token_id = token_auth.response['x-subject-token']
orig_expires_at = token_auth['token']['expires_at']
- orig_issued_at = token_auth['token']['issued_at']
orig_user = token_auth['token']['user']
self.assertIsInstance(token_auth['token']['expires_at'], unicode)
@@ -117,7 +116,6 @@
self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
'Expiration time should match original token')
self.assertIsInstance(token_auth['token']['issued_at'], unicode)
- self.assertNotEqual(orig_issued_at, token_auth['token']['issued_at'])
self.assertEqual(set(['password', 'token']),
set(token_auth['token']['methods']))
self.assertEqual(orig_user, token_auth['token']['user'],
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 49d5f8c..ce7728e 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -287,10 +287,13 @@
[CONF.object_storage.operator_role])}]
if CONF.service_available.swift:
spec.append({'number': 1,
- 'prefix': 'swift_admin',
+ 'prefix': 'swift_operator',
'roles': (CONF.auth.tempest_roles +
- [CONF.object_storage.operator_role,
- CONF.object_storage.reseller_admin_role])})
+ [CONF.object_storage.operator_role])})
+ spec.append({'number': 1,
+ 'prefix': 'swift_reseller_admin',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.reseller_admin_role])})
if CONF.service_available.heat:
spec.append({'number': 1,
'prefix': 'stack_owner',
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index b0afcc1..248513e 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -162,20 +162,13 @@
def wait_for_volume_status(client, volume_id, status):
"""Waits for a Volume to reach a given status."""
- body = client.show_volume(volume_id)
- if 'volume' in body:
- body = body['volume']
+ body = client.show_volume(volume_id)['volume']
volume_status = body['status']
start = int(time.time())
while volume_status != status:
time.sleep(client.build_interval)
- body = client.show_volume(volume_id)
- # TODO(jswarren) always extract 'volume' value
- # once the compute clients also return the full
- # response.
- if 'volume' in body:
- body = body['volume']
+ body = client.show_volume(volume_id)['volume']
volume_status = body['status']
if volume_status == 'error':
raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
diff --git a/tempest/config.py b/tempest/config.py
index 7655c75..295b74d 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -607,6 +607,12 @@
' validation resources to enable remote access',
deprecated_opts=[cfg.DeprecatedOpt('run_ssh',
group='compute')]),
+ cfg.BoolOpt('security_group',
+ default=True,
+ help='Enable/disable security groups.'),
+ cfg.BoolOpt('security_group_rules',
+ default=True,
+ help='Enable/disable security group rules.'),
cfg.StrOpt('connect_method',
default='floating',
choices=['fixed', 'floating'],
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index c86aaff..db92351 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -35,7 +35,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_volumes, resp, body)
- return service_client.ResponseBodyList(resp, body['volumes'])
+ return service_client.ResponseBody(resp, body)
def show_volume(self, volume_id):
"""Returns the details of a single volume."""
@@ -43,7 +43,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.create_get_volume, resp, body)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def create_volume(self, **kwargs):
"""
@@ -57,7 +57,7 @@
resp, body = self.post('os-volumes', post_body)
body = json.loads(body)
self.validate_response(schema.create_get_volume, resp, body)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def delete_volume(self, volume_id):
"""Deletes the Specified Volume."""
diff --git a/tempest/test.py b/tempest/test.py
index df6b30d..b664b47 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -530,9 +530,10 @@
else:
floating_ip = False
if security_group is None:
- security_group = True
+ security_group = CONF.validation.security_group
if security_group_rules is None:
- security_group_rules = True
+ security_group_rules = CONF.validation.security_group_rules
+
if not cls.validation_resources:
cls.validation_resources = {
'keypair': keypair,
diff --git a/tempest/tests/fake_tempest_plugin.py b/tempest/tests/fake_tempest_plugin.py
new file mode 100644
index 0000000..f718d0b
--- /dev/null
+++ b/tempest/tests/fake_tempest_plugin.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# 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.test_discover import plugins
+
+
+class FakePlugin(plugins.TempestPlugin):
+ expected_load_test = ["my/test/path", "/home/dir"]
+
+ def load_tests(self):
+ return self.expected_load_test
+
+ def register_opts(self, conf):
+ return
+
+ def get_opt_lists(self):
+ return []
+
+
+class FakeStevedoreObj(object):
+ obj = FakePlugin()
+
+ @property
+ def name(self):
+ return self._name
+
+ def __init__(self, name='Test1'):
+ self._name = name
diff --git a/tempest/tests/services/compute/test_floating_ips_bulk_client.py b/tempest/tests/services/compute/test_floating_ips_bulk_client.py
new file mode 100644
index 0000000..6cf1b17
--- /dev/null
+++ b/tempest/tests/services/compute/test_floating_ips_bulk_client.py
@@ -0,0 +1,87 @@
+# Copyright 2015 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.services.compute.json import floating_ips_bulk_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFloatingIPsBulkClient(base.BaseComputeServiceTest):
+
+ FAKE_FIP_BULK_LIST = {"floating_ip_info": [{
+ "address": "10.10.10.1",
+ "instance_uuid": None,
+ "fixed_ip": None,
+ "interface": "eth0",
+ "pool": "nova",
+ "project_id": None
+ },
+ {
+ "address": "10.10.10.2",
+ "instance_uuid": None,
+ "fixed_ip": None,
+ "interface": "eth0",
+ "pool": "nova",
+ "project_id": None
+ }]}
+
+ def setUp(self):
+ super(TestFloatingIPsBulkClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = floating_ips_bulk_client.FloatingIPsBulkClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_floating_ips_bulk(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_FIP_BULK_LIST,
+ to_utf=bytes_body)
+
+ def _test_create_floating_ips_bulk(self, bytes_body=False):
+ fake_fip_create_data = {"floating_ips_bulk_create": {
+ "ip_range": "192.168.1.0/24", "pool": "nova", "interface": "eth0"}}
+ self.check_service_client_function(
+ self.client.create_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.post',
+ fake_fip_create_data,
+ to_utf=bytes_body,
+ ip_range="192.168.1.0/24", pool="nova", interface="eth0")
+
+ def _test_delete_floating_ips_bulk(self, bytes_body=False):
+ fake_fip_delete_data = {"floating_ips_bulk_delete": "192.168.1.0/24"}
+ self.check_service_client_function(
+ self.client.delete_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.put',
+ fake_fip_delete_data,
+ to_utf=bytes_body,
+ ip_range="192.168.1.0/24")
+
+ def test_list_floating_ips_bulk_with_str_body(self):
+ self._test_list_floating_ips_bulk()
+
+ def test_list_floating_ips_bulk_with_bytes_body(self):
+ self._test_list_floating_ips_bulk(True)
+
+ def test_create_floating_ips_bulk_with_str_body(self):
+ self._test_create_floating_ips_bulk()
+
+ def test_create_floating_ips_bulk_with_bytes_body(self):
+ self._test_create_floating_ips_bulk(True)
+
+ def test_delete_floating_ips_bulk_with_str_body(self):
+ self._test_delete_floating_ips_bulk()
+
+ def test_delete_floating_ips_bulk_with_bytes_body(self):
+ self._test_delete_floating_ips_bulk(True)
diff --git a/tempest/tests/services/compute/test_security_group_default_rules_client.py b/tempest/tests/services/compute/test_security_group_default_rules_client.py
new file mode 100644
index 0000000..75fa1cb
--- /dev/null
+++ b/tempest/tests/services/compute/test_security_group_default_rules_client.py
@@ -0,0 +1,88 @@
+# Copyright 2015 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.services.compute.json import security_group_default_rules_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestSecurityGroupDefaultRulesClient(base.BaseComputeServiceTest):
+ FAKE_RULE = {
+ "from_port": 80,
+ "id": 1,
+ "ip_protocol": "TCP",
+ "ip_range": {
+ "cidr": "10.10.10.0/24"
+ },
+ "to_port": 80
+ }
+
+ def setUp(self):
+ super(TestSecurityGroupDefaultRulesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = (security_group_default_rules_client.
+ SecurityGroupDefaultRulesClient(fake_auth, 'compute',
+ 'regionOne'))
+
+ def _test_list_security_group_default_rules(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_security_group_default_rules,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group_default_rules": [self.FAKE_RULE]},
+ to_utf=bytes_body)
+
+ def test_list_security_group_default_rules_with_str_body(self):
+ self._test_list_security_group_default_rules()
+
+ def test_list_security_group_default_rules_with_bytes_body(self):
+ self._test_list_security_group_default_rules(bytes_body=True)
+
+ def _test_show_security_group_default_rule(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_security_group_default_rule,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group_default_rule": self.FAKE_RULE},
+ to_utf=bytes_body,
+ security_group_default_rule_id=1)
+
+ def test_show_security_group_default_rule_with_str_body(self):
+ self._test_show_security_group_default_rule()
+
+ def test_show_security_group_default_rule_with_bytes_body(self):
+ self._test_show_security_group_default_rule(bytes_body=True)
+
+ def _test_create_security_default_group_rule(self, bytes_body=False):
+ request_body = {
+ "to_port": 80,
+ "from_port": 80,
+ "ip_protocol": "TCP",
+ "cidr": "10.10.10.0/24"
+ }
+ self.check_service_client_function(
+ self.client.create_security_default_group_rule,
+ 'tempest.common.service_client.ServiceClient.post',
+ {"security_group_default_rule": self.FAKE_RULE},
+ to_utf=bytes_body, **request_body)
+
+ def test_create_security_default_group_rule_with_str_body(self):
+ self._test_create_security_default_group_rule()
+
+ def test_create_security_default_group_rule_with_bytes_body(self):
+ self._test_create_security_default_group_rule(bytes_body=True)
+
+ def test_delete_security_group_default_rule(self):
+ self.check_service_client_function(
+ self.client.delete_security_group_default_rule,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=204, security_group_default_rule_id=1)
diff --git a/tempest/tests/test_tempest_plugin.py b/tempest/tests/test_tempest_plugin.py
new file mode 100644
index 0000000..c07e98c
--- /dev/null
+++ b/tempest/tests/test_tempest_plugin.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# 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.test_discover import plugins
+from tempest.tests import base
+from tempest.tests import fake_tempest_plugin as fake_plugin
+
+
+class TestPluginDiscovery(base.TestCase):
+ def test_load_tests_with_one_plugin(self):
+ # we can't mock stevedore since it's a singleton and already executed
+ # during test discovery. So basically this test covers the plugin loop
+ # and the abstract plugin interface.
+ manager = plugins.TempestTestPluginManager()
+ fake_obj = fake_plugin.FakeStevedoreObj()
+ manager.ext_plugins = [fake_obj]
+ result = manager.get_plugin_load_tests_tuple()
+
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result[fake_obj.name])
+
+ def test_load_tests_with_two_plugins(self):
+ manager = plugins.TempestTestPluginManager()
+ obj1 = fake_plugin.FakeStevedoreObj('fake01')
+ obj2 = fake_plugin.FakeStevedoreObj('fake02')
+ manager.ext_plugins = [obj1, obj2]
+ result = manager.get_plugin_load_tests_tuple()
+
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result['fake01'])
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result['fake02'])