Merge "Remove skip decorator for volume scenario test"
diff --git a/doc/source/plugin.rst b/doc/source/plugin.rst
index f92f63e..a41038c 100644
--- a/doc/source/plugin.rst
+++ b/doc/source/plugin.rst
@@ -20,32 +20,26 @@
to tempest-lib. In that situation, file a bug, push a migration patch, etc. to
expedite providing the interface in a reliable manner.
-Plugin Class
-------------
+Plugin Cookiecutter
+-------------------
-To provide tempest with all the required information it needs to be able to run
-your plugin you need to create a plugin class which tempest will load and call
-to get information when it needs. To simplify creating this tempest provides an
-abstract class that should be used as the parent for your plugin. To use this
-you would do something like the following::
+In order to create the basic structure with base classes and test directories
+you can use the tempest-plugin-cookiecutter project::
- from tempest.test_discover import plugin
+ > cookiecutter https://git.openstack.org/openstack/tempest-plugin-cookiecutter
- class MyPlugin(plugin.TempestPlugin):
+ Cloning into 'tempest-plugin-cookiecutter'...
+ remote: Counting objects: 17, done.
+ remote: Compressing objects: 100% (13/13), done.
+ remote: Total 17 (delta 1), reused 14 (delta 1)
+ Unpacking objects: 100% (17/17), done.
+ Checking connectivity... done.
+ project (default is "sample")? foo
+ testclass (default is "SampleTempestPlugin")? FooTempestPlugin
-Then you need to ensure you locally define all of the methods in the abstract
-class, you can refer to the api doc below for a reference of what that entails.
-
-Also, note eventually this abstract class will likely live in tempest-lib, when
-that migration occurs a deprecation shim will be added to tempest so as to not
-break any existing plugins. But, when that occurs migrating to using tempest-lib
-as the source for the abstract class will be prudent.
-
-Abstract Plugin Class
-^^^^^^^^^^^^^^^^^^^^^
-
-.. autoclass:: tempest.test_discover.plugins.TempestPlugin
- :members:
+This would create a folder called ``foo_tempest_plugin/`` with all necessary
+basic classes. You only need to move/create your test in
+``foo_tempest_plugin/tests``.
Entry Point
-----------
@@ -61,9 +55,35 @@
tempest.test_plugins =
plugin_name = module.path:PluginClass
-Plugin Structure
-----------------
+Plugin Class
+============
+To provide tempest with all the required information it needs to be able to run
+your plugin you need to create a plugin class which tempest will load and call
+to get information when it needs. To simplify creating this tempest provides an
+abstract class that should be used as the parent for your plugin. To use this
+you would do something like the following::
+
+ from tempest.test_discover import plugins
+
+ class MyPlugin(plugins.TempestPlugin):
+
+Then you need to ensure you locally define all of the methods in the abstract
+class, you can refer to the api doc below for a reference of what that entails.
+
+Also, note eventually this abstract class will likely live in tempest-lib, when
+that migration occurs a deprecation shim will be added to tempest so as to not
+break any existing plugins. But, when that occurs migrating to using tempest-lib
+as the source for the abstract class will be prudent.
+
+Abstract Plugin Class
+---------------------
+
+.. autoclass:: tempest.test_discover.plugins.TempestPlugin
+ :members:
+
+Plugin Structure
+================
While there are no hard and fast rules for the structure a plugin, there are
basically no constraints on what the plugin looks like as long as the 2 steps
above are done. However, there are some recommended patterns to follow to make
@@ -92,7 +112,7 @@
being added in the plugin act and behave like the rest of tempest.
Dealing with configuration options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+----------------------------------
Historically Tempest didn't provide external guarantees on its configuration
options. However, with the introduction of the plugin interface this is no
diff --git a/requirements.txt b/requirements.txt
index c0a9254..59d6856 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -13,11 +13,11 @@
testrepository>=0.0.18
pyOpenSSL>=0.14
oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=2.3.0 # Apache-2.0
+oslo.config>=2.6.0 # Apache-2.0
oslo.i18n>=1.5.0 # Apache-2.0
oslo.log>=1.8.0 # Apache-2.0
-oslo.serialization>=1.4.0 # Apache-2.0
-oslo.utils>=2.0.0 # Apache-2.0
+oslo.serialization>=1.10.0 # Apache-2.0
+oslo.utils!=2.6.0,>=2.4.0 # Apache-2.0
six>=1.9.0
iso8601>=0.1.9
fixtures>=1.3.1
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 34ec78d..f186a7d 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -14,8 +14,6 @@
# under the License.
-from collections import namedtuple
-
import testtools
from tempest.api.compute import base
@@ -26,9 +24,6 @@
CONF = config.CONF
-CreatedServer = namedtuple('CreatedServer', 'server_id, volume_backed')
-
-
class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
_host_key = 'OS-EXT-SRV-ATTR:host'
@@ -39,14 +34,6 @@
cls.admin_servers_client = cls.os_adm.servers_client
cls.admin_migration_client = cls.os_adm.migrations_client
- @classmethod
- def resource_setup(cls):
- super(LiveBlockMigrationTestJSON, cls).resource_setup()
-
- # list of CreatedServer namedtuples
- # TODO(mriedem): Remove the instance variable and shared server re-use
- cls.created_servers = []
-
def _get_compute_hostnames(self):
body = self.admin_hosts_client.list_hosts()['hosts']
return [
@@ -62,18 +49,12 @@
def _get_host_for_server(self, server_id):
return self._get_server_details(server_id)[self._host_key]
- def _migrate_server_to(self, server_id, dest_host):
- # volume backed instances shouldn't be block migrated
- for id, volume_backed in self.created_servers:
- if server_id == id:
- use_block_migration = not volume_backed
- break
- else:
- raise ValueError('Server with id %s not found.' % server_id)
- bmflm = (CONF.compute_feature_enabled.
- block_migration_for_live_migration and use_block_migration)
+ def _migrate_server_to(self, server_id, dest_host, volume_backed):
+ block_migration = (CONF.compute_feature_enabled.
+ block_migration_for_live_migration and
+ not volume_backed)
body = self.admin_servers_client.live_migrate_server(
- server_id, host=dest_host, block_migration=bmflm,
+ server_id, host=dest_host, block_migration=block_migration,
disk_over_commit=False)
return body
@@ -85,19 +66,10 @@
def _get_server_status(self, server_id):
return self._get_server_details(server_id)['status']
- def _get_an_active_server(self, volume_backed=False):
- for server_id, vol_backed in self.created_servers:
- if ('ACTIVE' == self._get_server_status(server_id) and
- volume_backed == vol_backed):
- return server_id
- else:
+ def _create_server(self, volume_backed=False):
server = self.create_test_server(wait_until="ACTIVE",
volume_backed=volume_backed)
- server_id = server['id']
- new_server = CreatedServer(server_id=server_id,
- volume_backed=volume_backed)
- self.created_servers.append(new_server)
- return server_id
+ return server['id']
def _volume_clean_up(self, server_id, volume_id):
body = self.volumes_client.show_volume(volume_id)['volume']
@@ -117,11 +89,11 @@
:param volume_backed: If the instance is volume backed or not. If
volume_backed, *block* migration is not used.
"""
- # Live block migrate an instance to another host
+ # Live migrate an instance to another host
if len(self._get_compute_hostnames()) < 2:
raise self.skipTest(
"Less than 2 compute nodes, skipping migration test.")
- server_id = self._get_an_active_server(volume_backed=volume_backed)
+ server_id = self._create_server(volume_backed=volume_backed)
actual_host = self._get_host_for_server(server_id)
target_host = self._get_host_other_than(actual_host)
@@ -130,7 +102,7 @@
waiters.wait_for_server_status(self.admin_servers_client,
server_id, state)
- self._migrate_server_to(server_id, target_host)
+ self._migrate_server_to(server_id, target_host, volume_backed)
waiters.wait_for_server_status(self.servers_client, server_id, state)
migration_list = (self.admin_migration_client.list_migrations()
['migrations'])
@@ -178,11 +150,10 @@
block_migrate_cinder_iscsi,
'Block Live migration not configured for iSCSI')
def test_iscsi_volume(self):
- # Live block migrate an instance to another host
if len(self._get_compute_hostnames()) < 2:
raise self.skipTest(
"Less than 2 compute nodes, skipping migration test.")
- server_id = self._get_an_active_server()
+ server_id = self._create_server()
actual_host = self._get_host_for_server(server_id)
target_host = self._get_host_other_than(actual_host)
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 2fd7520..902b72c 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import base64
-
import netaddr
import testtools
@@ -42,6 +40,7 @@
cls.client = cls.servers_client
cls.network_client = cls.os.network_client
cls.networks_client = cls.os.networks_client
+ cls.subnets_client = cls.os.subnets_client
@classmethod
def resource_setup(cls):
@@ -51,9 +50,6 @@
cls.accessIPv4 = '1.1.1.1'
cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
cls.name = data_utils.rand_name('server')
- file_contents = 'This is a test file.'
- personality = [{'path': '/test.txt',
- 'contents': base64.b64encode(file_contents)}]
disk_config = cls.disk_config
cls.server_initial = cls.create_test_server(
validatable=True,
@@ -62,7 +58,6 @@
metadata=cls.meta,
accessIPv4=cls.accessIPv4,
accessIPv6=cls.accessIPv6,
- personality=personality,
disk_config=disk_config)
cls.password = cls.server_initial['adminPass']
cls.server = (cls.client.show_server(cls.server_initial['id'])
@@ -74,11 +69,11 @@
self.addCleanup(self.networks_client.delete_network,
net['network']['id'])
- subnet = self.network_client.create_subnet(
+ subnet = self.subnets_client.create_subnet(
network_id=net['network']['id'],
cidr=cidr,
ip_version=4)
- self.addCleanup(self.network_client.delete_subnet,
+ self.addCleanup(self.subnets_client.delete_subnet,
subnet['subnet']['id'])
return net
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f0cd2a1..a59cb16 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import base64
import logging
from six.moves.urllib import parse as urlparse
@@ -145,16 +144,12 @@
# The server should be rebuilt using the provided image and data
meta = {'rebuild': 'server'}
new_name = data_utils.rand_name('server')
- file_contents = 'Test server rebuild.'
- personality = [{'path': 'rebuild.txt',
- 'contents': base64.b64encode(file_contents)}]
password = 'rebuildPassw0rd'
rebuilt_server = self.client.rebuild_server(
self.server_id,
self.image_ref_alt,
name=new_name,
metadata=meta,
- personality=personality,
adminPass=password)['server']
# If the server was rebuilt on a different image, restore it to the
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index a7fc235..77af509 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -17,17 +17,42 @@
from tempest_lib import exceptions as lib_exc
from tempest.api.compute import base
+from tempest import config
from tempest import test
+CONF = config.CONF
+
class ServerPersonalityTestJSON(base.BaseV2ComputeTest):
@classmethod
+ def skip_checks(cls):
+ super(ServerPersonalityTestJSON, cls).skip_checks()
+ if not CONF.compute_feature_enabled.personality:
+ raise cls.skipException("Nova personality feature disabled")
+
+ @classmethod
def setup_clients(cls):
super(ServerPersonalityTestJSON, cls).setup_clients()
cls.client = cls.servers_client
cls.user_client = cls.limits_client
+ @test.idempotent_id('3cfe87fd-115b-4a02-b942-7dc36a337fdf')
+ def test_create_server_with_personality(self):
+ file_contents = 'This is a test file.'
+ personality = [{'path': '/test.txt',
+ 'contents': base64.b64encode(file_contents)}]
+ self.create_test_server(personality=personality)
+
+ @test.idempotent_id('128966d8-71fc-443c-8cab-08e24114ecc9')
+ def test_rebuild_server_with_personality(self):
+ server_id = self.rebuild_server(None)
+ file_contents = 'Test server rebuild.'
+ personality = [{'path': 'rebuild.txt',
+ 'contents': base64.b64encode(file_contents)}]
+ self.client.rebuild_server(server_id, self.image_ref_alt,
+ personality=personality)
+
@test.idempotent_id('176cd8c9-b9e8-48ee-a480-180beab292bf')
def test_personality_files_exceed_limit(self):
# Server creation should fail if greater than the maximum allowed
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 6946be4..98b292a 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -66,6 +66,8 @@
@test.attr(type=['negative'])
@test.idempotent_id('b8a7235e-5246-4a8f-a08e-b34877c6586f')
+ @testtools.skipUnless(CONF.compute_feature_enabled.personality,
+ 'Nova personality feature disabled')
def test_personality_file_contents_not_encoded(self):
# Use an unencoded file when creating a server with personality
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 484c156..f8d0cca 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -186,6 +186,14 @@
@test.idempotent_id('acf8724b-142b-4044-82c3-78d31a533f24')
def test_create_server_fails_when_tenant_incorrect(self):
+ # BUG(sdague): this test should fail because of bad auth url,
+ # which means that when we run with a service catalog without
+ # project_id in the urls, it should fail to fail, and thus
+ # fail the test. It does not.
+ #
+ # The 400 BadRequest is clearly ambiguous, and something else
+ # is wrong about this request. This should be fixed.
+ #
# A create server request should fail if the tenant id does not match
# the current user
# Change the base URL to impersonate another user
@@ -199,9 +207,22 @@
@test.idempotent_id('f03d1ded-7fd4-4d29-bc13-e2391f29c625')
def test_create_keypair_in_analt_user_tenant(self):
- # A create keypair request should fail if the tenant id does not match
- # the current user
- # POST keypair with other user tenant
+ """create keypair should not function for alternate tenant
+
+ POST {alt_service_url}/os-keypairs
+
+ Attempt to create a keypair against an alternate tenant by
+ changing using a different tenant's service url. This should
+ return a BadRequest. This tests basic tenant isolation protections.
+
+ NOTE(sdague): if the environment does not use project_id in
+ the service urls, this test is not valid. Skip under these
+ conditions.
+
+ """
+ if self.alt_keypairs_client.base_url == self.keypairs_client.base_url:
+ raise self.skipException("Service urls don't include project_id")
+
k_name = data_utils.rand_name('keypair')
try:
# Change the base URL to impersonate another user
@@ -250,9 +271,23 @@
@test.idempotent_id('752c917e-83be-499d-a422-3559127f7d3c')
def test_create_security_group_in_analt_user_tenant(self):
- # A create security group request should fail if the tenant id does not
- # match the current user
- # POST security group with other user tenant
+ """create security group should not function for alternate tenant
+
+ POST {alt_service_url}/os-security-groups
+
+ Attempt to create a security group against an alternate tenant
+ by changing using a different tenant's service url. This
+ should return a BadRequest. This tests basic tenant isolation
+ protections.
+
+ NOTE(sdague): if the environment does not use project_id in
+ the service urls, this test is not valid. Skip under these
+ conditions.
+
+ """
+ if self.alt_security_client.base_url == self.security_client.base_url:
+ raise self.skipException("Service urls don't include project_id")
+
s_name = data_utils.rand_name('security')
s_description = data_utils.rand_name('security')
try:
@@ -289,9 +324,23 @@
@test.idempotent_id('b2b76de0-210a-4089-b921-591c9ec552f6')
def test_create_security_group_rule_in_analt_user_tenant(self):
- # A create security group rule request should fail if the tenant id
- # does not match the current user
- # POST security group rule with other user tenant
+ """create security group rule should not function for alternate tenant
+
+ POST {alt_service_url}/os-security-group-rules
+
+ Attempt to create a security group rule against an alternate
+ tenant by changing using a different tenant's service
+ url. This should return a BadRequest. This tests basic tenant
+ isolation protections.
+
+ NOTE(sdague): if the environment does not use project_id in
+ the service urls, this test is not valid. Skip under these
+ conditions.
+
+ """
+ if self.alt_security_client.base_url == self.security_client.base_url:
+ raise self.skipException("Service urls don't include project_id")
+
parent_group_id = self.security_group['id']
ip_protocol = 'icmp'
from_port = -1
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 62aa18e..ac53587 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -103,8 +103,9 @@
self.addCleanup(self._try_delete_resource,
self.admin_networks_client.delete_network,
external_network['id'])
- subnet = self.create_subnet(external_network, client=client,
- enable_dhcp=False)
+ subnet = self.create_subnet(
+ external_network, client=self.admin_subnets_client,
+ enable_dhcp=False)
body = client.create_floatingip(
floating_network_id=external_network['id'])
created_floating_ip = body['floatingip']
@@ -121,7 +122,7 @@
self.assertNotIn(created_floating_ip['id'],
(f['id'] for f in floatingip_list['floatingips']))
# Verifies subnet is deleted
- subnet_list = client.list_subnets()
+ subnet_list = self.admin_subnets_client.list_subnets()
self.assertNotIn(subnet['id'],
(s['id'] for s in subnet_list))
# Removes subnet from the cleanup list
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 39bdcff..17adfa5 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -74,6 +74,7 @@
super(BaseNetworkTest, cls).setup_clients()
cls.client = cls.os.network_client
cls.networks_client = cls.os.networks_client
+ cls.subnets_client = cls.os.subnets_client
@classmethod
def resource_setup(cls):
@@ -115,7 +116,7 @@
router)
# Clean up subnets
for subnet in cls.subnets:
- cls._try_delete_resource(cls.client.delete_subnet,
+ cls._try_delete_resource(cls.subnets_client.delete_subnet,
subnet['id'])
# Clean up networks
for network in cls.networks:
@@ -160,7 +161,7 @@
# allow tests to use admin client
if not client:
- client = cls.client
+ client = cls.subnets_client
# The cidr and mask_bits depend on the ip version.
ip_version = ip_version if ip_version is not None else cls._ip_version
@@ -220,7 +221,7 @@
ext_gw_info = {}
if external_network_id:
ext_gw_info['network_id'] = external_network_id
- if enable_snat:
+ if enable_snat is not None:
ext_gw_info['enable_snat'] = enable_snat
body = cls.client.create_router(
router_name, external_gateway_info=ext_gw_info,
@@ -267,6 +268,7 @@
super(BaseAdminNetworkTest, cls).setup_clients()
cls.admin_client = cls.os_adm.network_client
cls.admin_networks_client = cls.os_adm.networks_client
+ cls.admin_subnets_client = cls.os_adm.subnets_client
@classmethod
def create_metering_label(cls, name, description):
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index f362f85..631a38b 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -75,11 +75,11 @@
if port['id'] in [p['id'] for p in self.ports]:
self.client.delete_port(port['id'])
self._remove_from_list_by_index(self.ports, port)
- body = self.client.list_subnets()
+ body = self.subnets_client.list_subnets()
subnets = body['subnets']
for subnet in subnets:
if subnet['id'] in [s['id'] for s in self.subnets]:
- self.client.delete_subnet(subnet['id'])
+ self.subnets_client.delete_subnet(subnet['id'])
self._remove_from_list_by_index(self.subnets, subnet)
body = self.client.list_routers()
routers = body['routers']
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index a4ab43a..c5b2080 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -194,7 +194,7 @@
subnet_id = subnet['id']
# Verify subnet update
new_name = "New_subnet"
- body = self.client.update_subnet(subnet_id, name=new_name)
+ body = self.subnets_client.update_subnet(subnet_id, name=new_name)
updated_subnet = body['subnet']
self.assertEqual(updated_subnet['name'], new_name)
@@ -241,7 +241,7 @@
@test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
def test_show_subnet(self):
# Verify the details of a subnet
- body = self.client.show_subnet(self.subnet['id'])
+ body = self.subnets_client.show_subnet(self.subnet['id'])
subnet = body['subnet']
self.assertNotEmpty(subnet, "Subnet returned has no fields")
for key in ['id', 'cidr']:
@@ -252,8 +252,8 @@
def test_show_subnet_fields(self):
# Verify specific fields of a subnet
fields = ['id', 'network_id']
- body = self.client.show_subnet(self.subnet['id'],
- fields=fields)
+ body = self.subnets_client.show_subnet(self.subnet['id'],
+ fields=fields)
subnet = body['subnet']
self.assertEqual(sorted(subnet.keys()), sorted(fields))
for field_name in fields:
@@ -263,7 +263,7 @@
@test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
def test_list_subnets(self):
# Verify the subnet exists in the list of all subnets
- body = self.client.list_subnets()
+ body = self.subnets_client.list_subnets()
subnets = [subnet['id'] for subnet in body['subnets']
if subnet['id'] == self.subnet['id']]
self.assertNotEmpty(subnets, "Created subnet not found in the list")
@@ -272,7 +272,7 @@
def test_list_subnets_fields(self):
# Verify specific fields of subnets
fields = ['id', 'network_id']
- body = self.client.list_subnets(fields=fields)
+ body = self.subnets_client.list_subnets(fields=fields)
subnets = body['subnets']
self.assertNotEmpty(subnets, "Subnet list returned is empty")
for subnet in subnets:
@@ -303,7 +303,7 @@
body = self.networks_client.delete_network(net_id)
# Verify that the subnet got automatically deleted.
- self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
+ self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
subnet_id)
# Since create_subnet adds the subnet to the delete list, and it is
@@ -362,8 +362,8 @@
'gateway_ip': new_gateway, 'enable_dhcp': True}
new_name = "New_subnet"
- body = self.client.update_subnet(subnet_id, name=new_name,
- **kwargs)
+ body = self.subnets_client.update_subnet(subnet_id, name=new_name,
+ **kwargs)
updated_subnet = body['subnet']
kwargs['name'] = new_name
self.assertEqual(sorted(updated_subnet['dns_nameservers']),
@@ -398,7 +398,7 @@
# subnets_iter is a list (iterator) of lists. This flattens it to a
# list of UUIDs
public_subnets_iter = itertools.chain(*subnets_iter)
- body = self.client.list_subnets()
+ body = self.subnets_client.list_subnets()
subnets = [sub['id'] for sub in body['subnets']
if sub['id'] in public_subnets_iter]
self.assertEmpty(subnets, "Public subnets visible")
@@ -435,9 +435,9 @@
def _delete_subnets(self, created_subnets):
for n in created_subnets:
- self.client.delete_subnet(n['id'])
+ self.subnets_client.delete_subnet(n['id'])
# Asserting that the subnets are not found in the list after deletion
- body = self.client.list_subnets()
+ body = self.subnets_client.list_subnets()
subnets_list = [subnet['id'] for subnet in body['subnets']]
for n in created_subnets:
self.assertNotIn(n['id'], subnets_list)
@@ -496,7 +496,7 @@
created_subnets = body['subnets']
self.addCleanup(self._delete_subnets, created_subnets)
# Asserting that the subnets are found in the list after creation
- body = self.client.list_subnets()
+ body = self.subnets_client.list_subnets()
subnets_list = [subnet['id'] for subnet in body['subnets']]
for n in created_subnets:
self.assertIsNotNone(n['id'])
@@ -576,7 +576,7 @@
# Verifies Subnet GW is None in IPv4
self.assertEqual(subnet2['gateway_ip'], None)
# Verifies all 2 subnets in the same network
- body = self.client.list_subnets()
+ body = self.subnets_client.list_subnets()
subnets = [sub['id'] for sub in body['subnets']
if sub['network_id'] == network['id']]
test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
@@ -621,9 +621,9 @@
'ipv6_address_mode': mode})
port = self.create_port(slaac_network)
self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
- self.client.delete_subnet(subnet_slaac['id'])
+ self.subnets_client.delete_subnet(subnet_slaac['id'])
self.subnets.pop()
- subnets = self.client.list_subnets()
+ subnets = self.subnets_client.list_subnets()
subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
self.assertNotIn(subnet_slaac['id'], subnet_ids,
"Subnet wasn't deleted")
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index 4d1971f..4fe31cf 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -34,7 +34,7 @@
@test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
def test_show_non_existent_subnet(self):
non_exist_id = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
+ self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
non_exist_id)
@test.attr(type=['negative'])
@@ -64,7 +64,7 @@
@test.idempotent_id('1cc47884-ac52-4415-a31c-e7ce5474a868')
def test_update_non_existent_subnet(self):
non_exist_id = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound, self.client.update_subnet,
+ self.assertRaises(lib_exc.NotFound, self.subnets_client.update_subnet,
non_exist_id, name='new_name')
@test.attr(type=['negative'])
@@ -72,7 +72,7 @@
def test_delete_non_existent_subnet(self):
non_exist_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound,
- self.client.delete_subnet, non_exist_id)
+ self.subnets_client.delete_subnet, non_exist_id)
@test.attr(type=['negative'])
@test.idempotent_id('13d3b106-47e6-4b9b-8d53-dae947f092fe')
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 321473c..6f58075 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -106,7 +106,7 @@
allocation_pools = {'allocation_pools': [{'start': str(address + 4),
'end': str(address + 6)}]}
subnet = self.create_subnet(network, **allocation_pools)
- self.addCleanup(self.client.delete_subnet, subnet['id'])
+ self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
body = self.client.create_port(network_id=net_id)
self.addCleanup(self.client.delete_port, body['port']['id'])
port = body['port']
@@ -155,7 +155,7 @@
# Create network and subnet
network = self.create_network()
subnet = self.create_subnet(network)
- self.addCleanup(self.client.delete_subnet, subnet['id'])
+ self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
# Create two ports
port_1 = self.client.create_port(network_id=network['id'])
self.addCleanup(self.client.delete_port, port_1['port']['id'])
@@ -187,7 +187,7 @@
network = self.create_network()
self.addCleanup(self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(network)
- self.addCleanup(self.client.delete_subnet, subnet['id'])
+ self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
router = self.create_router(data_utils.rand_name('router-'))
self.addCleanup(self.client.delete_router, router['id'])
port = self.client.create_port(network_id=network['id'])
@@ -220,9 +220,9 @@
network = self.create_network()
self.addCleanup(self.networks_client.delete_network, network['id'])
subnet_1 = self.create_subnet(network)
- self.addCleanup(self.client.delete_subnet, subnet_1['id'])
+ self.addCleanup(self.subnets_client.delete_subnet, subnet_1['id'])
subnet_2 = self.create_subnet(network)
- self.addCleanup(self.client.delete_subnet, subnet_2['id'])
+ self.addCleanup(self.subnets_client.delete_subnet, subnet_2['id'])
fixed_ip_1 = [{'subnet_id': subnet_1['id']}]
fixed_ip_2 = [{'subnet_id': subnet_2['id']}]
@@ -247,7 +247,7 @@
def _update_port_with_security_groups(self, security_groups_names):
subnet_1 = self.create_subnet(self.network)
- self.addCleanup(self.client.delete_subnet, subnet_1['id'])
+ self.addCleanup(self.subnets_client.delete_subnet, subnet_1['id'])
fixed_ip_1 = [{'subnet_id': subnet_1['id']}]
security_groups_list = list()
@@ -328,7 +328,7 @@
network = self.create_network()
self.addCleanup(self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(network)
- self.addCleanup(self.client.delete_subnet, subnet['id'])
+ self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
port = self.create_port(network, security_groups=[])
self.addCleanup(self.client.delete_port, port['id'])
self.assertIsNotNone(port['security_groups'])
diff --git a/tempest/api/object_storage/test_container_staticweb.py b/tempest/api/object_storage/test_container_staticweb.py
index 4b4b499..18593f3 100644
--- a/tempest/api/object_storage/test_container_staticweb.py
+++ b/tempest/api/object_storage/test_container_staticweb.py
@@ -28,7 +28,7 @@
cls.container_name = data_utils.rand_name(name="TestContainer")
# This header should be posted on the container before every test
- cls.headers_public_read_acl = {'Read': '.r:*'}
+ cls.headers_public_read_acl = {'Read': '.r:*,.rlistings'}
# Create test container and create one object in it
cls.container_client.create_container(cls.container_name)
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 99c2a97..070150d 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -44,6 +44,7 @@
def setup_clients(cls):
super(NeutronResourcesTestJSON, cls).setup_clients()
cls.network_client = cls.os.network_client
+ cls.subnets_client = cls.os.subnets_client
@classmethod
def resource_setup(cls):
@@ -130,7 +131,7 @@
def test_created_subnet(self):
"""Verifies created subnet."""
subnet_id = self.test_resources.get('Subnet')['physical_resource_id']
- body = self.network_client.show_subnet(subnet_id)
+ body = self.subnets_client.show_subnet(subnet_id)
subnet = body['subnet']
network_id = self.test_resources.get('Network')['physical_resource_id']
self.assertEqual(subnet_id, subnet['id'])
diff --git a/tempest/api_schema/response/compute/v2_1/fixed_ips.py b/tempest/api_schema/response/compute/v2_1/fixed_ips.py
deleted file mode 100644
index 229860e..0000000
--- a/tempest/api_schema/response/compute/v2_1/fixed_ips.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# 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_schema.response.compute.v2_1 import parameter_types
-
-get_fixed_ip = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'fixed_ip': {
- 'type': 'object',
- 'properties': {
- 'address': parameter_types.ip_address,
- 'cidr': {'type': 'string'},
- 'host': {'type': 'string'},
- 'hostname': {'type': 'string'}
- },
- 'additionalProperties': False,
- 'required': ['address', 'cidr', 'host', 'hostname']
- }
- },
- 'additionalProperties': False,
- 'required': ['fixed_ip']
- }
-}
-
-reserve_unreserve_fixed_ip = {
- 'status_code': [202]
-}
diff --git a/tempest/api_schema/response/compute/v2_1/flavors.py b/tempest/api_schema/response/compute/v2_1/flavors.py
deleted file mode 100644
index 5f5b2e3..0000000
--- a/tempest/api_schema/response/compute/v2_1/flavors.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# 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_schema.response.compute.v2_1 import parameter_types
-
-list_flavors = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'flavors': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'name': {'type': 'string'},
- 'links': parameter_types.links,
- 'id': {'type': 'string'}
- },
- 'additionalProperties': False,
- 'required': ['name', 'links', 'id']
- }
- },
- 'flavors_links': parameter_types.links
- },
- 'additionalProperties': False,
- # NOTE(gmann): flavors_links attribute is not necessary
- # to be present always So it is not 'required'.
- 'required': ['flavors']
- }
-}
-
-common_flavor_info = {
- 'type': 'object',
- 'properties': {
- 'name': {'type': 'string'},
- 'links': parameter_types.links,
- 'ram': {'type': 'integer'},
- 'vcpus': {'type': 'integer'},
- # 'swap' attributes comes as integer value but if it is empty
- # it comes as "". So defining type of as string and integer.
- 'swap': {'type': ['integer', 'string']},
- 'disk': {'type': 'integer'},
- 'id': {'type': 'string'},
- 'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
- 'os-flavor-access:is_public': {'type': 'boolean'},
- 'rxtx_factor': {'type': 'number'},
- 'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'}
- },
- 'additionalProperties': False,
- # 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and
- # 'OS-FLV-EXT-DATA' are API extensions. So they are not 'required'.
- 'required': ['name', 'links', 'ram', 'vcpus', 'swap', 'disk', 'id']
-}
-
-list_flavors_details = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'flavors': {
- 'type': 'array',
- 'items': common_flavor_info
- },
- # NOTE(gmann): flavors_links attribute is not necessary
- # to be present always So it is not 'required'.
- 'flavors_links': parameter_types.links
- },
- 'additionalProperties': False,
- 'required': ['flavors']
- }
-}
-
-unset_flavor_extra_specs = {
- 'status_code': [200]
-}
-
-create_get_flavor_details = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'flavor': common_flavor_info
- },
- 'additionalProperties': False,
- 'required': ['flavor']
- }
-}
-
-delete_flavor = {
- 'status_code': [202]
-}
diff --git a/tempest/api_schema/response/compute/v2_1/flavors_access.py b/tempest/api_schema/response/compute/v2_1/flavors_access.py
deleted file mode 100644
index a4d6af0..0000000
--- a/tempest/api_schema/response/compute/v2_1/flavors_access.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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.
-
-add_remove_list_flavor_access = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'flavor_access': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'flavor_id': {'type': 'string'},
- 'tenant_id': {'type': 'string'},
- },
- 'additionalProperties': False,
- 'required': ['flavor_id', 'tenant_id'],
- }
- }
- },
- 'additionalProperties': False,
- 'required': ['flavor_access']
- }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py b/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
deleted file mode 100644
index a438d48..0000000
--- a/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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.
-
-set_get_flavor_extra_specs = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'extra_specs': {
- 'type': 'object',
- 'patternProperties': {
- '^[a-zA-Z0-9_\-\. :]+$': {'type': 'string'}
- }
- }
- },
- 'additionalProperties': False,
- 'required': ['extra_specs']
- }
-}
-
-set_get_flavor_extra_specs_key = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'patternProperties': {
- '^[a-zA-Z0-9_\-\. :]+$': {'type': 'string'}
- }
- }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/hosts.py b/tempest/api_schema/response/compute/v2_1/hosts.py
deleted file mode 100644
index ae70ff1..0000000
--- a/tempest/api_schema/response/compute/v2_1/hosts.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# 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.
-
-import copy
-
-
-list_hosts = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'hosts': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'host_name': {'type': 'string'},
- 'service': {'type': 'string'},
- 'zone': {'type': 'string'}
- },
- 'additionalProperties': False,
- 'required': ['host_name', 'service', 'zone']
- }
- }
- },
- 'additionalProperties': False,
- 'required': ['hosts']
- }
-}
-
-get_host_detail = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'host': {
- 'type': 'array',
- 'item': {
- 'type': 'object',
- 'properties': {
- 'resource': {
- 'type': 'object',
- 'properties': {
- 'cpu': {'type': 'integer'},
- 'disk_gb': {'type': 'integer'},
- 'host': {'type': 'string'},
- 'memory_mb': {'type': 'integer'},
- 'project': {'type': 'string'}
- },
- 'additionalProperties': False,
- 'required': ['cpu', 'disk_gb', 'host',
- 'memory_mb', 'project']
- }
- },
- 'additionalProperties': False,
- 'required': ['resource']
- }
- }
- },
- 'additionalProperties': False,
- 'required': ['host']
- }
-}
-
-startup_host = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'host': {'type': 'string'},
- 'power_action': {'enum': ['startup']}
- },
- 'additionalProperties': False,
- 'required': ['host', 'power_action']
- }
-}
-
-# The 'power_action' attribute of 'shutdown_host' API is 'shutdown'
-shutdown_host = copy.deepcopy(startup_host)
-
-shutdown_host['response_body']['properties']['power_action'] = {
- 'enum': ['shutdown']
-}
-
-# The 'power_action' attribute of 'reboot_host' API is 'reboot'
-reboot_host = copy.deepcopy(startup_host)
-
-reboot_host['response_body']['properties']['power_action'] = {
- 'enum': ['reboot']
-}
-
-update_host = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'host': {'type': 'string'},
- 'maintenance_mode': {'enum': ['on_maintenance',
- 'off_maintenance']},
- 'status': {'enum': ['enabled', 'disabled']}
- },
- 'additionalProperties': False,
- 'required': ['host', 'maintenance_mode', 'status']
- }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/hypervisors.py b/tempest/api_schema/response/compute/v2_1/hypervisors.py
deleted file mode 100644
index 05901b6..0000000
--- a/tempest/api_schema/response/compute/v2_1/hypervisors.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# 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.
-
-import copy
-
-from tempest.api_schema.response.compute.v2_1 import parameter_types
-
-get_hypervisor_statistics = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'hypervisor_statistics': {
- 'type': 'object',
- 'properties': {
- 'count': {'type': 'integer'},
- 'current_workload': {'type': 'integer'},
- 'disk_available_least': {'type': ['integer', 'null']},
- 'free_disk_gb': {'type': 'integer'},
- 'free_ram_mb': {'type': 'integer'},
- 'local_gb': {'type': 'integer'},
- 'local_gb_used': {'type': 'integer'},
- 'memory_mb': {'type': 'integer'},
- 'memory_mb_used': {'type': 'integer'},
- 'running_vms': {'type': 'integer'},
- 'vcpus': {'type': 'integer'},
- 'vcpus_used': {'type': 'integer'}
- },
- 'additionalProperties': False,
- 'required': ['count', 'current_workload',
- 'disk_available_least', 'free_disk_gb',
- 'free_ram_mb', 'local_gb', 'local_gb_used',
- 'memory_mb', 'memory_mb_used', 'running_vms',
- 'vcpus', 'vcpus_used']
- }
- },
- 'additionalProperties': False,
- 'required': ['hypervisor_statistics']
- }
-}
-
-
-hypervisor_detail = {
- 'type': 'object',
- 'properties': {
- 'status': {'type': 'string'},
- 'state': {'type': 'string'},
- 'cpu_info': {'type': 'string'},
- 'current_workload': {'type': 'integer'},
- 'disk_available_least': {'type': ['integer', 'null']},
- 'host_ip': parameter_types.ip_address,
- 'free_disk_gb': {'type': 'integer'},
- 'free_ram_mb': {'type': 'integer'},
- 'hypervisor_hostname': {'type': 'string'},
- 'hypervisor_type': {'type': 'string'},
- 'hypervisor_version': {'type': 'integer'},
- 'id': {'type': ['integer', 'string']},
- 'local_gb': {'type': 'integer'},
- 'local_gb_used': {'type': 'integer'},
- 'memory_mb': {'type': 'integer'},
- 'memory_mb_used': {'type': 'integer'},
- 'running_vms': {'type': 'integer'},
- 'service': {
- 'type': 'object',
- 'properties': {
- 'host': {'type': 'string'},
- 'id': {'type': ['integer', 'string']},
- 'disabled_reason': {'type': ['string', 'null']}
- },
- 'additionalProperties': False,
- 'required': ['host', 'id']
- },
- 'vcpus': {'type': 'integer'},
- 'vcpus_used': {'type': 'integer'}
- },
- 'additionalProperties': False,
- # NOTE: When loading os-hypervisor-status extension,
- # a response contains status and state. So these params
- # should not be required.
- 'required': ['cpu_info', 'current_workload',
- 'disk_available_least', 'host_ip',
- 'free_disk_gb', 'free_ram_mb',
- 'hypervisor_hostname', 'hypervisor_type',
- 'hypervisor_version', 'id', 'local_gb',
- 'local_gb_used', 'memory_mb', 'memory_mb_used',
- 'running_vms', 'service', 'vcpus', 'vcpus_used']
-}
-
-list_hypervisors_detail = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'hypervisors': {
- 'type': 'array',
- 'items': hypervisor_detail
- }
- },
- 'additionalProperties': False,
- 'required': ['hypervisors']
- }
-}
-
-get_hypervisor = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'hypervisor': hypervisor_detail
- },
- 'additionalProperties': False,
- 'required': ['hypervisor']
- }
-}
-
-list_search_hypervisors = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'hypervisors': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'status': {'type': 'string'},
- 'state': {'type': 'string'},
- 'id': {'type': ['integer', 'string']},
- 'hypervisor_hostname': {'type': 'string'}
- },
- 'additionalProperties': False,
- # NOTE: When loading os-hypervisor-status extension,
- # a response contains status and state. So these params
- # should not be required.
- 'required': ['id', 'hypervisor_hostname']
- }
- }
- },
- 'additionalProperties': False,
- 'required': ['hypervisors']
- }
-}
-
-get_hypervisor_uptime = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'hypervisor': {
- 'type': 'object',
- 'properties': {
- 'status': {'type': 'string'},
- 'state': {'type': 'string'},
- 'id': {'type': ['integer', 'string']},
- 'hypervisor_hostname': {'type': 'string'},
- 'uptime': {'type': 'string'}
- },
- 'additionalProperties': False,
- # NOTE: When loading os-hypervisor-status extension,
- # a response contains status and state. So these params
- # should not be required.
- 'required': ['id', 'hypervisor_hostname', 'uptime']
- }
- },
- 'additionalProperties': False,
- 'required': ['hypervisor']
- }
-}
-
-get_hypervisors_servers = copy.deepcopy(list_search_hypervisors)
-get_hypervisors_servers['response_body']['properties']['hypervisors']['items'][
- 'properties']['servers'] = {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'uuid': {'type': 'string'},
- 'name': {'type': 'string'}
- },
- 'additionalProperties': False,
- }
- }
-# In V2 API, if there is no servers (VM) on the Hypervisor host then 'servers'
-# attribute will not be present in response body So it is not 'required'.
diff --git a/tempest/clients.py b/tempest/clients.py
index b593089..84e8544 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -26,6 +26,15 @@
CertificatesClient
from tempest_lib.services.compute.extensions_client import \
ExtensionsClient
+from tempest_lib.services.compute.fixed_ips_client import FixedIPsClient
+from tempest_lib.services.compute.flavors_client import FlavorsClient
+from tempest_lib.services.compute.floating_ip_pools_client import \
+ FloatingIPPoolsClient
+from tempest_lib.services.compute.floating_ips_bulk_client import \
+ FloatingIPsBulkClient
+from tempest_lib.services.compute.hosts_client import HostsClient
+from tempest_lib.services.compute.hypervisor_client import \
+ HypervisorClient
from tempest_lib.services.identity.v2.token_client import TokenClient
from tempest_lib.services.identity.v3.token_client import V3TokenClient
@@ -37,17 +46,8 @@
from tempest.services.baremetal.v1.json.baremetal_client import \
BaremetalClient
from tempest.services import botoclients
-from tempest.services.compute.json.fixed_ips_client import FixedIPsClient
-from tempest.services.compute.json.flavors_client import FlavorsClient
-from tempest.services.compute.json.floating_ip_pools_client import \
- FloatingIPPoolsClient
-from tempest.services.compute.json.floating_ips_bulk_client import \
- FloatingIPsBulkClient
from tempest.services.compute.json.floating_ips_client import \
FloatingIPsClient
-from tempest.services.compute.json.hosts_client import HostsClient
-from tempest.services.compute.json.hypervisor_client import \
- HypervisorClient
from tempest.services.compute.json.images_client import ImagesClient
from tempest.services.compute.json.instance_usage_audit_log_client import \
InstanceUsagesAuditLogClient
@@ -107,6 +107,7 @@
MessagingClient
from tempest.services.network.json.network_client import NetworkClient
from tempest.services.network.json.networks_client import NetworksClient
+from tempest.services.network.json.subnets_client import SubnetsClient
from tempest.services.object_storage.account_client import AccountClient
from tempest.services.object_storage.container_client import ContainerClient
from tempest.services.object_storage.object_client import ObjectClient
@@ -204,6 +205,14 @@
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**self.default_params)
+ self.subnets_client = SubnetsClient(
+ self.auth_provider,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type=CONF.network.endpoint_type,
+ build_interval=CONF.network.build_interval,
+ build_timeout=CONF.network.build_timeout,
+ **self.default_params)
self.messaging_client = MessagingClient(
self.auth_provider,
CONF.messaging.catalog_type,
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 02c6e7f..a90b0ce 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -94,6 +94,7 @@
from tempest.services.identity.v2.json import identity_client
from tempest.services.network.json import network_client
from tempest.services.network.json import networks_client
+from tempest.services.network.json import subnets_client
import tempest_lib.auth
from tempest_lib.common.utils import data_utils
import tempest_lib.exceptions
@@ -138,6 +139,7 @@
)
network_admin = None
networks_admin = None
+ subnets_admin = None
neutron_iso_networks = False
if (CONF.service_available.neutron and
CONF.auth.create_isolated_networks):
@@ -154,12 +156,19 @@
CONF.network.region or CONF.identity.region,
endpoint_type='adminURL',
**params)
- return identity_admin, neutron_iso_networks, network_admin, networks_admin
+ subnets_admin = subnets_client.SubnetsClient(
+ _auth,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type='adminURL',
+ **params)
+ return (identity_admin, neutron_iso_networks, network_admin,
+ networks_admin, subnets_admin)
def create_resources(opts, resources):
(identity_admin, neutron_iso_networks,
- network_admin, networks_admin) = get_admin_clients(opts)
+ network_admin, networks_admin, subnets_admin) = get_admin_clients(opts)
roles = identity_admin.list_roles()['roles']
for u in resources['users']:
u['role_ids'] = []
@@ -202,7 +211,8 @@
for u in resources['users']:
tenant = identity_admin.get_tenant_by_name(u['tenant'])
network_name, router_name = create_network_resources(
- network_admin, networks_admin, tenant['id'], u['name'])
+ network_admin, networks_admin, subnets_admin, tenant['id'],
+ u['name'])
u['network'] = network_name
u['router'] = router_name
LOG.info('Networks created')
@@ -229,7 +239,7 @@
def create_network_resources(network_admin_client, networks_admin_client,
- tenant_id, name):
+ subnets_admin_client, tenant_id, name):
def _create_network(name):
resp_body = networks_admin_client.create_network(
@@ -241,7 +251,7 @@
mask_bits = CONF.network.tenant_network_mask_bits
for subnet_cidr in base_cidr.subnet(mask_bits):
try:
- resp_body = network_admin_client.\
+ resp_body = subnets_admin_client.\
create_subnet(
network_id=network_id, cidr=str(subnet_cidr),
name=subnet_name,
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 6c79abc..64e1303 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -382,6 +382,7 @@
super(NetworkService, self).__init__(kwargs)
self.client = manager.network_client
self.networks_client = manager.networks_client
+ self.subnets_client = manager.subnets_client
def _filter_by_conf_networks(self, item_list):
if not item_list or not all(('network_id' in i for i in item_list)):
@@ -676,7 +677,7 @@
class NetworkSubnetService(NetworkService):
def list(self):
- client = self.client
+ client = self.subnets_client
subnets = client.list_subnets(**self.tenant_filter)
subnets = subnets['subnets']
if self.is_preserve:
@@ -685,7 +686,7 @@
return subnets
def delete(self):
- client = self.client
+ client = self.subnets_client
subnets = self.list()
for subnet in subnets:
try:
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 2dbcd98..f57e757 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -117,11 +117,11 @@
import six
from tempest_lib import auth
from tempest_lib import exceptions as lib_exc
+from tempest_lib.services.compute import flavors_client
import yaml
from tempest.common import waiters
from tempest import config
-from tempest.services.compute.json import flavors_client
from tempest.services.compute.json import floating_ips_client
from tempest.services.compute.json import security_group_rules_client
from tempest.services.compute.json import security_groups_client
@@ -129,6 +129,7 @@
from tempest.services.identity.v2.json import identity_client
from tempest.services.image.v2.json import image_client
from tempest.services.network.json import network_client
+from tempest.services.network.json import subnets_client
from tempest.services.object_storage import container_client
from tempest.services.object_storage import object_client
from tempest.services.telemetry.json import telemetry_client
@@ -240,6 +241,14 @@
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**default_params)
+ self.subnets = subnets_client.SubnetsClient(
+ _auth,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type=CONF.network.endpoint_type,
+ build_interval=CONF.network.build_interval,
+ build_timeout=CONF.network.build_timeout,
+ **default_params)
def load_resources(fname):
@@ -769,9 +778,9 @@
LOG.info("Destroying subnets")
for subnet in subnets:
client = client_for_user(subnet['owner'])
- subnet_id = _get_resource_by_name(client.networks,
+ subnet_id = _get_resource_by_name(client.subnets,
'subnets', subnet['name'])['id']
- client.networks.delete_subnet(subnet_id)
+ client.subnets.delete_subnet(subnet_id)
def create_routers(routers):
diff --git a/tempest/cmd/main.py b/tempest/cmd/main.py
index 762e982..577df9b 100644
--- a/tempest/cmd/main.py
+++ b/tempest/cmd/main.py
@@ -16,8 +16,7 @@
from cliff import app
from cliff import commandmanager
-
-TEMPEST_CLI_VERSION = '0.1'
+from pbr import version
class Main(app.App):
@@ -27,7 +26,7 @@
def __init__(self):
super(Main, self).__init__(
description='Tempest cli application',
- version=TEMPEST_CLI_VERSION,
+ version=version.VersionInfo('tempest').version_string(),
command_manager=commandmanager.CommandManager('tempest.cm'),
)
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 4d391d0..79a502a 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -14,14 +14,11 @@
from oslo_log import log as logging
import six
+from tempest_lib import auth
from tempest_lib import exceptions as lib_exc
-from tempest.common import cred_provider
-from tempest import config
-from tempest import exceptions
from tempest.services.identity.v2.json import identity_client as v2_identity
-CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -36,7 +33,6 @@
def __init__(self, identity_client):
# The client implies version and credentials
self.identity_client = identity_client
- self.credentials = self.identity_client.auth_provider.credentials
def create_user(self, username, password, project, email):
user = self.identity_client.create_user(
@@ -75,6 +71,13 @@
@abc.abstractmethod
def get_credentials(self, user, project, password):
+ """Produces a Credentials object from the details provided
+
+ :param user: a user dict
+ :param project: a project dict
+ :param password: the password as a string
+ :return: a Credentials object with all the available credential details
+ """
pass
def delete_user(self, user_id):
@@ -93,7 +96,11 @@
return tenant
def get_credentials(self, user, project, password):
- return cred_provider.get_credentials(
+ # User and project already include both ID and name here,
+ # so there's no need to use the fill_in mode
+ return auth.get_credentials(
+ auth_url=None,
+ fill_in=False,
identity_version='v2',
username=user['name'], user_id=user['id'],
tenant_name=project['name'], tenant_id=project['id'],
@@ -114,8 +121,8 @@
params={'name': domain_name})['domains'][0]
except lib_exc.NotFound:
# TODO(andrea) we could probably create the domain on the fly
- msg = "Configured domain %s could not be found" % domain_name
- raise exceptions.InvalidConfiguration(msg)
+ msg = "Requested domain %s could not be found" % domain_name
+ raise lib_exc.InvalidCredentials(msg)
def create_project(self, name, description):
project = self.identity_client.create_project(
@@ -124,11 +131,16 @@
return project
def get_credentials(self, user, project, password):
- return cred_provider.get_credentials(
+ # User, project and domain already include both ID and name here,
+ # so there's no need to use the fill_in mode.
+ return auth.get_credentials(
+ auth_url=None,
+ fill_in=False,
identity_version='v3',
username=user['name'], user_id=user['id'],
project_name=project['name'], project_id=project['id'],
password=password,
+ project_domain_id=self.creds_domain['id'],
project_domain_name=self.creds_domain['name'])
def delete_project(self, project_id):
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 1221fc7..3575998 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -98,19 +98,22 @@
@six.add_metaclass(abc.ABCMeta)
class CredentialProvider(object):
- def __init__(self, identity_version=None, name=None,
- network_resources=None):
+ def __init__(self, identity_version, name=None, network_resources=None,
+ credentials_domain=None, admin_role=None):
"""A CredentialProvider supplies credentials to test classes.
- :param identity_version: If specified it will return credentials of the
- corresponding identity version, otherwise it
- uses auth_version from configuration
+ :param identity_version: Identity version of the credentials provided
:param name: Name of the calling test. Included in provisioned
credentials when credentials are provisioned on the fly
:param network_resources: Network resources required for the
credentials
+ :param credentials_domain: Domain credentials belong to
+ :param admin_role: Name of the role of the admin account
"""
+ self.identity_version = identity_version
self.name = name or "test_creds"
- self.identity_version = identity_version or CONF.identity.auth_version
+ self.network_resources = network_resources
+ self.credentials_domain = credentials_domain or 'Default'
+ self.admin_role = admin_role
if not auth.is_identity_version_supported(self.identity_version):
raise exceptions.InvalidIdentityVersion(
identity_version=self.identity_version)
diff --git a/tempest/common/credentials.py b/tempest/common/credentials.py
index 28e95e9..76f8afe 100644
--- a/tempest/common/credentials.py
+++ b/tempest/common/credentials.py
@@ -32,26 +32,34 @@
# dynamic credentials. A new account will be produced only for that test.
# In case admin credentials are not available for the account creation,
# the test should be skipped else it would fail.
+ identity_version = identity_version or CONF.identity.auth_version
if CONF.auth.use_dynamic_credentials or force_tenant_isolation:
return dynamic_creds.DynamicCredentialProvider(
name=name,
network_resources=network_resources,
- identity_version=identity_version)
+ identity_version=identity_version,
+ credentials_domain=CONF.auth.default_credentials_domain_name,
+ admin_role=CONF.identity.admin_role)
else:
if (CONF.auth.test_accounts_file and
os.path.isfile(CONF.auth.test_accounts_file)):
# Most params are not relevant for pre-created accounts
return preprov_creds.PreProvisionedCredentialProvider(
- name=name, identity_version=identity_version)
+ name=name, identity_version=identity_version,
+ credentials_domain=CONF.auth.default_credentials_domain_name,
+ admin_role=CONF.identity.admin_role)
else:
return preprov_creds.NonLockingCredentialProvider(
- name=name, identity_version=identity_version)
+ name=name, identity_version=identity_version,
+ admin_role=CONF.identity.admin_role)
# We want a helper function here to check and see if admin credentials
# are available so we can do a single call from skip_checks if admin
-# creds area vailable.
-def is_admin_available():
+# creds area available.
+# This depends on identity_version as there may be admin credentials
+# available for v2 but not for v3.
+def is_admin_available(identity_version):
is_admin = True
# If dynamic credentials is enabled admin will be available
if CONF.auth.use_dynamic_credentials:
@@ -60,13 +68,15 @@
elif (CONF.auth.test_accounts_file and
os.path.isfile(CONF.auth.test_accounts_file)):
check_accounts = preprov_creds.PreProvisionedCredentialProvider(
- name='check_admin')
+ identity_version=identity_version, name='check_admin',
+ admin_role=CONF.identity.admin_role)
if not check_accounts.admin_available():
is_admin = False
else:
try:
- cred_provider.get_configured_credentials('identity_admin',
- fill_in=False)
+ cred_provider.get_configured_credentials(
+ 'identity_admin', fill_in=False,
+ identity_version=identity_version)
except exceptions.InvalidConfiguration:
is_admin = False
return is_admin
@@ -74,19 +84,23 @@
# We want a helper function here to check and see if alt credentials
# are available so we can do a single call from skip_checks if alt
-# creds area vailable.
-def is_alt_available():
- # If dynamic credentials is enabled admin will be available
+# creds area available.
+# This depends on identity_version as there may be alt credentials
+# available for v2 but not for v3.
+def is_alt_available(identity_version):
+ # If dynamic credentials is enabled alt will be available
if CONF.auth.use_dynamic_credentials:
return True
# Check whether test accounts file has the admin specified or not
if (CONF.auth.test_accounts_file and
os.path.isfile(CONF.auth.test_accounts_file)):
check_accounts = preprov_creds.PreProvisionedCredentialProvider(
- name='check_alt')
+ identity_version=identity_version, name='check_alt',
+ admin_role=CONF.identity.admin_role)
else:
check_accounts = preprov_creds.NonLockingCredentialProvider(
- name='check_alt')
+ identity_version=identity_version, name='check_alt',
+ admin_role=CONF.identity.admin_role)
try:
if not check_accounts.is_multi_user():
return False
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index f0b6625..e2df560 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -30,25 +30,27 @@
class DynamicCredentialProvider(cred_provider.CredentialProvider):
- def __init__(self, identity_version=None, name=None,
- network_resources=None):
+ def __init__(self, identity_version, name=None, network_resources=None,
+ credentials_domain=None, admin_role=None):
super(DynamicCredentialProvider, self).__init__(
- identity_version, name, network_resources)
- self.network_resources = network_resources
+ identity_version=identity_version, name=name,
+ network_resources=network_resources,
+ credentials_domain=credentials_domain, admin_role=admin_role)
self._creds = {}
self.ports = []
self.default_admin_creds = cred_provider.get_configured_credentials(
'identity_admin', fill_in=True,
identity_version=self.identity_version)
(self.identity_admin_client, self.network_admin_client,
- self.networks_admin_client) = self._get_admin_clients()
- # Domain where dynamic credentials are provisioned (v3 only).
+ self.networks_admin_client,
+ self.subnets_admin_client) = self._get_admin_clients()
+ # Domain where isolated credentials are provisioned (v3 only).
# Use that of the admin account is None is configured.
self.creds_domain_name = None
if self.identity_version == 'v3':
self.creds_domain_name = (
self.default_admin_creds.project_domain_name or
- CONF.auth.default_credentials_domain_name)
+ self.credentials_domain)
self.creds_client = cred_client.get_creds_client(
self.identity_admin_client, self.creds_domain_name)
@@ -61,9 +63,11 @@
"""
os = clients.Manager(self.default_admin_creds)
if self.identity_version == 'v2':
- return os.identity_client, os.network_client, os.networks_client
+ return (os.identity_client, os.network_client, os.networks_client,
+ os.subnets_client)
else:
- return os.identity_v3_client, os.network_client, os.networks_client
+ return (os.identity_v3_client, os.network_client,
+ os.networks_client, os.subnets_client)
def _create_creds(self, suffix="", admin=False, roles=None):
"""Create random credentials under the following schema.
@@ -95,7 +99,7 @@
role_assigned = False
if admin:
self.creds_client.assign_user_role(user, project,
- CONF.identity.admin_role)
+ self.admin_role)
role_assigned = True
# Add roles specified in config file
for conf_role in CONF.auth.tempest_roles:
@@ -168,7 +172,7 @@
for subnet_cidr in base_cidr.subnet(mask_bits):
try:
if self.network_resources:
- resp_body = self.network_admin_client.\
+ resp_body = self.subnets_admin_client.\
create_subnet(
network_id=network_id, cidr=str(subnet_cidr),
name=subnet_name,
@@ -176,7 +180,7 @@
enable_dhcp=self.network_resources['dhcp'],
ip_version=4)
else:
- resp_body = self.network_admin_client.\
+ resp_body = self.subnets_admin_client.\
create_subnet(network_id=network_id,
cidr=str(subnet_cidr),
name=subnet_name,
@@ -260,9 +264,9 @@
router_name)
def _clear_isolated_subnet(self, subnet_id, subnet_name):
- net_client = self.network_admin_client
+ client = self.subnets_admin_client
try:
- net_client.delete_subnet(subnet_id)
+ client.delete_subnet(subnet_id)
except lib_exc.NotFound:
LOG.warn('subnet with name: %s not found for delete' %
subnet_name)
diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py
index eac7f4e..dd27f08 100644
--- a/tempest/common/preprov_creds.py
+++ b/tempest/common/preprov_creds.py
@@ -18,6 +18,7 @@
from oslo_concurrency import lockutils
from oslo_log import log as logging
import six
+from tempest_lib import auth
import yaml
from tempest import clients
@@ -38,9 +39,11 @@
class PreProvisionedCredentialProvider(cred_provider.CredentialProvider):
- def __init__(self, identity_version=None, name=None):
+ def __init__(self, identity_version, name=None, credentials_domain=None,
+ admin_role=None):
super(PreProvisionedCredentialProvider, self).__init__(
- identity_version=identity_version, name=name)
+ identity_version=identity_version, name=name,
+ credentials_domain=credentials_domain, admin_role=admin_role)
if (CONF.auth.test_accounts_file and
os.path.isfile(CONF.auth.test_accounts_file)):
accounts = read_accounts_yaml(CONF.auth.test_accounts_file)
@@ -48,7 +51,7 @@
else:
accounts = {}
self.use_default_creds = True
- self.hash_dict = self.get_hash_dict(accounts)
+ self.hash_dict = self.get_hash_dict(accounts, admin_role)
self.accounts_dir = os.path.join(lockutils.get_lock_path(CONF),
'test_accounts')
self._creds = {}
@@ -62,7 +65,7 @@
return hash_dict
@classmethod
- def get_hash_dict(cls, accounts):
+ def get_hash_dict(cls, accounts, admin_role):
hash_dict = {'roles': {}, 'creds': {}, 'networks': {}}
# Loop over the accounts read from the yaml file
for account in accounts:
@@ -86,8 +89,8 @@
# subdict with the hash
for type in types:
if type == 'admin':
- hash_dict = cls._append_role(CONF.identity.admin_role,
- temp_hash_key, hash_dict)
+ hash_dict = cls._append_role(admin_role, temp_hash_key,
+ hash_dict)
elif type == 'operator':
hash_dict = cls._append_role(
CONF.object_storage.operator_role, temp_hash_key,
@@ -172,9 +175,9 @@
# privlege set which could potentially cause issues on tests where that
# is not expected. So unless the admin role isn't specified do not
# allocate admin.
- admin_hashes = self.hash_dict['roles'].get(CONF.identity.admin_role,
+ admin_hashes = self.hash_dict['roles'].get(self.admin_role,
None)
- if ((not roles or CONF.identity.admin_role not in roles) and
+ if ((not roles or self.admin_role not in roles) and
admin_hashes):
useable_hashes = [x for x in hashes if x not in admin_hashes]
else:
@@ -216,7 +219,7 @@
if ('user_domain_name' in init_attributes and 'user_domain_name'
not in hash_attributes):
# Allow for the case of domain_name populated from config
- domain_name = CONF.auth.default_credentials_domain_name
+ domain_name = self.credentials_domain
hash_attributes['user_domain_name'] = domain_name
if all([getattr(creds, k) == hash_attributes[k] for
k in init_attributes]):
@@ -265,7 +268,7 @@
self.remove_credentials(creds)
def get_admin_creds(self):
- return self.get_creds_by_roles([CONF.identity.admin_role])
+ return self.get_creds_by_roles([self.admin_role])
def is_role_available(self, role):
if self.use_default_creds:
@@ -276,11 +279,16 @@
return False
def admin_available(self):
- return self.is_role_available(CONF.identity.admin_role)
+ return self.is_role_available(self.admin_role)
def _wrap_creds_with_network(self, hash):
creds_dict = self.hash_dict['creds'][hash]
- credential = cred_provider.get_credentials(
+ # Make sure a domain scope if defined for users in case of V3
+ creds_dict = self._extend_credentials(creds_dict)
+ # This just builds a Credentials object, it does not validate
+ # nor fill with missing fields.
+ credential = auth.get_credentials(
+ auth_url=None, fill_in=False,
identity_version=self.identity_version, **creds_dict)
net_creds = cred_provider.TestResources(credential)
net_clients = clients.Manager(credentials=credential)
@@ -294,6 +302,15 @@
net_creds.set_resources(network=network)
return net_creds
+ def _extend_credentials(self, creds_dict):
+ # In case of v3, adds a user_domain_name field to the creds
+ # dict if not defined
+ if self.identity_version == 'v3':
+ user_domain_fields = set(['user_domain_name', 'user_domain_id'])
+ if not user_domain_fields.intersection(set(creds_dict.keys())):
+ creds_dict['user_domain_name'] = self.credentials_domain
+ return creds_dict
+
class NonLockingCredentialProvider(PreProvisionedCredentialProvider):
"""Credentials provider which always returns the first and second
@@ -323,7 +340,8 @@
if self._creds.get('primary'):
return self._creds.get('primary')
primary_credential = cred_provider.get_configured_credentials(
- credential_type='user', identity_version=self.identity_version)
+ fill_in=False, credential_type='user',
+ identity_version=self.identity_version)
self._creds['primary'] = cred_provider.TestResources(
primary_credential)
return self._creds['primary']
@@ -332,7 +350,7 @@
if self._creds.get('alt'):
return self._creds.get('alt')
alt_credential = cred_provider.get_configured_credentials(
- credential_type='alt_user',
+ fill_in=False, credential_type='alt_user',
identity_version=self.identity_version)
self._creds['alt'] = cred_provider.TestResources(
alt_credential)
diff --git a/tempest/config.py b/tempest/config.py
index b2bc931..0cda018 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -425,6 +425,9 @@
cfg.BoolOpt('nova_cert',
default=True,
help='Does the test environment have the nova cert running?'),
+ cfg.BoolOpt('personality',
+ default=True,
+ help='Does the test environment support server personality'),
# TODO(mriedem): Remove preserve_ports once juno-eol happens.
cfg.BoolOpt('preserve_ports',
default=False,
@@ -1306,9 +1309,7 @@
class TempestConfigPrivate(object):
"""Provides OpenStack configuration information."""
- DEFAULT_CONFIG_DIR = os.path.join(
- os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
- "etc")
+ DEFAULT_CONFIG_DIR = os.path.join(os.getcwd(), "etc")
DEFAULT_CONFIG_FILE = "tempest.conf"
diff --git a/tempest/manager.py b/tempest/manager.py
index 6a003bc..d7c3128 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -54,7 +54,7 @@
else:
creds = self.credentials
# Creates an auth provider for the credentials
- self.auth_provider = get_auth_provider(creds)
+ self.auth_provider = get_auth_provider(creds, pre_auth=True)
# FIXME(andreaf) unused
self.client_attr_names = []
@@ -66,7 +66,7 @@
return auth.KeystoneV2AuthProvider, CONF.identity.uri
-def get_auth_provider(credentials):
+def get_auth_provider(credentials, pre_auth=False):
default_params = {
'disable_ssl_certificate_validation':
CONF.identity.disable_ssl_certificate_validation,
@@ -78,4 +78,8 @@
'Credentials must be specified')
auth_provider_class, auth_url = get_auth_provider_class(
credentials)
- return auth_provider_class(credentials, auth_url, **default_params)
+ _auth_provider = auth_provider_class(credentials, auth_url,
+ **default_params)
+ if pre_auth:
+ _auth_provider.set_auth()
+ return _auth_provider
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 738282f..a10dc83 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -62,6 +62,7 @@
# Neutron network client
cls.network_client = cls.manager.network_client
cls.networks_client = cls.manager.networks_client
+ cls.subnets_client = cls.manager.subnets_client
# Heat client
cls.orchestration_client = cls.manager.orchestration_client
@@ -449,21 +450,21 @@
image_name, server['name'])
return snapshot_image
- def nova_volume_attach(self):
+ def nova_volume_attach(self, server, volume_to_attach):
volume = self.servers_client.attach_volume(
- self.server['id'], volumeId=self.volume['id'], device='/dev/%s'
+ server['id'], volumeId=volume_to_attach['id'], device='/dev/%s'
% CONF.compute.volume_device_name)['volumeAttachment']
- self.assertEqual(self.volume['id'], volume['id'])
+ self.assertEqual(volume_to_attach['id'], volume['id'])
self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
- # Refresh the volume after the attachment
- self.volume = self.volumes_client.show_volume(volume['id'])['volume']
- def nova_volume_detach(self):
- self.servers_client.detach_volume(self.server['id'], self.volume['id'])
- self.volumes_client.wait_for_volume_status(self.volume['id'],
- 'available')
+ # Return the updated volume after the attachment
+ return self.volumes_client.show_volume(volume['id'])['volume']
- volume = self.volumes_client.show_volume(self.volume['id'])['volume']
+ def nova_volume_detach(self, server, volume):
+ self.servers_client.detach_volume(server['id'], volume['id'])
+ self.volumes_client.wait_for_volume_status(volume['id'], 'available')
+
+ volume = self.volumes_client.show_volume(volume['id'])['volume']
self.assertEqual('available', volume['status'])
def rebuild_server(self, server_id, image=None,
@@ -572,8 +573,10 @@
floating_ip['ip'], thing['id'])
return floating_ip
- def create_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt'):
- ssh_client = self.get_remote_client(server_or_ip)
+ def create_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
+ private_key=None):
+ ssh_client = self.get_remote_client(server_or_ip,
+ private_key=private_key)
if dev_name is not None:
ssh_client.make_fs(dev_name)
ssh_client.mount(dev_name, mount_path)
@@ -585,8 +588,10 @@
ssh_client.umount(mount_path)
return timestamp
- def get_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt'):
- ssh_client = self.get_remote_client(server_or_ip)
+ def get_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
+ private_key=None):
+ ssh_client = self.get_remote_client(server_or_ip,
+ private_key=private_key)
if dev_name is not None:
ssh_client.mount(dev_name, mount_path)
timestamp = ssh_client.exec_command('sudo cat %s/timestamp'
@@ -644,7 +649,7 @@
def _list_subnets(self, *args, **kwargs):
"""List subnets using admin creds """
- subnets_list = self.admin_manager.network_client.list_subnets(
+ subnets_list = self.admin_manager.subnets_client.list_subnets(
*args, **kwargs)
return subnets_list['subnets']
@@ -666,14 +671,16 @@
*args, **kwargs)
return agents_list['agents']
- def _create_subnet(self, network, client=None, namestart='subnet-smoke',
- **kwargs):
+ def _create_subnet(self, network, client=None, subnets_client=None,
+ namestart='subnet-smoke', **kwargs):
"""
Create a subnet for the given network within the cidr block
configured for tenant networks.
"""
if not client:
client = self.network_client
+ if not subnets_client:
+ subnets_client = self.subnets_client
def cidr_in_use(cidr, tenant_id):
"""
@@ -711,15 +718,16 @@
**kwargs
)
try:
- result = client.create_subnet(**subnet)
+ result = subnets_client.create_subnet(**subnet)
break
except lib_exc.Conflict as e:
is_overlapping_cidr = 'overlaps with another subnet' in str(e)
if not is_overlapping_cidr:
raise
self.assertIsNotNone(result, 'Unable to allocate tenant network')
- subnet = net_resources.DeletableSubnet(client=client,
- **result['subnet'])
+ subnet = net_resources.DeletableSubnet(
+ network_client=client, subnets_client=subnets_client,
+ **result['subnet'])
self.assertEqual(subnet.cidr, str_cidr)
self.addCleanup(self.delete_wrapper, subnet.delete)
return subnet
@@ -1076,7 +1084,8 @@
self.assertEqual(admin_state_up, router.admin_state_up)
def create_networks(self, client=None, networks_client=None,
- tenant_id=None, dns_nameservers=None):
+ subnets_client=None, tenant_id=None,
+ dns_nameservers=None):
"""Create a network with a subnet connected to a router.
The baremetal driver is a special case since all nodes are
@@ -1106,7 +1115,8 @@
tenant_id=tenant_id)
router = self._get_router(client=client, tenant_id=tenant_id)
- subnet_kwargs = dict(network=network, client=client)
+ subnet_kwargs = dict(network=network, client=client,
+ subnets_client=subnets_client)
# use explicit check because empty list is a valid option
if dns_nameservers is not None:
subnet_kwargs['dns_nameservers'] = dns_nameservers
diff --git a/tempest/scenario/test_encrypted_cinder_volumes.py b/tempest/scenario/test_encrypted_cinder_volumes.py
index b66eb59..3f0123d 100644
--- a/tempest/scenario/test_encrypted_cinder_volumes.py
+++ b/tempest/scenario/test_encrypted_cinder_volumes.py
@@ -54,8 +54,8 @@
self.volume = self.create_volume(volume_type=volume_type['name'])
def attach_detach_volume(self):
- self.nova_volume_attach()
- self.nova_volume_detach()
+ self.volume = self.nova_volume_attach(self.server, self.volume)
+ self.nova_volume_detach(self.server, self.volume)
@test.idempotent_id('79165fb4-5534-4b9d-8429-97ccffb8f86e')
@test.services('compute', 'volume', 'image')
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index eac8311..22aa06c 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -40,66 +40,61 @@
"""
- def _wait_for_server_status(self, status):
- server_id = self.server['id']
+ def _wait_for_server_status(self, server, status):
+ server_id = server['id']
# Raise on error defaults to True, which is consistent with the
# original function from scenario tests here
waiters.wait_for_server_status(self.servers_client,
server_id, status)
- def nova_keypair_add(self):
- self.keypair = self.create_keypair()
-
- def nova_boot(self):
- create_kwargs = {'key_name': self.keypair['name']}
- self.server = self.create_server(image=self.image,
- create_kwargs=create_kwargs)
+ def nova_boot(self, keypair):
+ create_kwargs = {'key_name': keypair['name']}
+ return self.create_server(image=self.image,
+ create_kwargs=create_kwargs)
def nova_list(self):
servers = self.servers_client.list_servers()
# The list servers in the compute client is inconsistent...
- servers = servers['servers']
- self.assertIn(self.server['id'], [x['id'] for x in servers])
+ return servers['servers']
- def nova_show(self):
- got_server = (self.servers_client.show_server(self.server['id'])
+ def nova_show(self, server):
+ got_server = (self.servers_client.show_server(server['id'])
['server'])
excluded_keys = ['OS-EXT-AZ:availability_zone']
# Exclude these keys because of LP:#1486475
excluded_keys.extend(['OS-EXT-STS:power_state', 'updated'])
self.assertThat(
- self.server, custom_matchers.MatchesDictExceptForKeys(
+ server, custom_matchers.MatchesDictExceptForKeys(
got_server, excluded_keys=excluded_keys))
def cinder_create(self):
- self.volume = self.create_volume()
+ return self.create_volume()
def cinder_list(self):
- volumes = self.volumes_client.list_volumes()['volumes']
- self.assertIn(self.volume['id'], [x['id'] for x in volumes])
+ return self.volumes_client.list_volumes()['volumes']
- def cinder_show(self):
- volume = self.volumes_client.show_volume(self.volume['id'])['volume']
- self.assertEqual(self.volume, volume)
+ def cinder_show(self, volume):
+ got_volume = self.volumes_client.show_volume(volume['id'])['volume']
+ self.assertEqual(volume, got_volume)
- def nova_reboot(self):
- self.servers_client.reboot_server(self.server['id'], 'SOFT')
- self._wait_for_server_status('ACTIVE')
+ def nova_reboot(self, server):
+ self.servers_client.reboot_server(server['id'], 'SOFT')
+ self._wait_for_server_status(server, 'ACTIVE')
def check_partitions(self):
# NOTE(andreaf) The device name may be different on different guest OS
partitions = self.linux_client.get_partitions()
self.assertEqual(1, partitions.count(CONF.compute.volume_device_name))
- def create_and_add_security_group(self):
+ def create_and_add_security_group_to_server(self, server):
secgroup = self._create_security_group()
- self.servers_client.add_security_group(self.server['id'],
+ self.servers_client.add_security_group(server['id'],
secgroup['name'])
self.addCleanup(self.servers_client.remove_security_group,
- self.server['id'], secgroup['name'])
+ server['id'], secgroup['name'])
def wait_for_secgroup_add():
- body = (self.servers_client.show_server(self.server['id'])
+ body = (self.servers_client.show_server(server['id'])
['server'])
return {'name': secgroup['name']} in body['security_groups']
@@ -107,29 +102,39 @@
CONF.compute.build_timeout,
CONF.compute.build_interval):
msg = ('Timed out waiting for adding security group %s to server '
- '%s' % (secgroup['id'], self.server['id']))
+ '%s' % (secgroup['id'], server['id']))
raise exceptions.TimeoutException(msg)
@test.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
@test.services('compute', 'volume', 'image', 'network')
def test_minimum_basic_scenario(self):
self.glance_image_create()
- self.nova_keypair_add()
- self.nova_boot()
- self.nova_list()
- self.nova_show()
- self.cinder_create()
- self.cinder_list()
- self.cinder_show()
- self.nova_volume_attach()
- self.addCleanup(self.nova_volume_detach)
- self.cinder_show()
- self.floating_ip = self.create_floating_ip(self.server)
- self.create_and_add_security_group()
+ keypair = self.create_keypair()
- self.linux_client = self.get_remote_client(self.floating_ip['ip'])
- self.nova_reboot()
+ server = self.nova_boot(keypair)
+ servers = self.nova_list()
+ self.assertIn(server['id'], [x['id'] for x in servers])
- self.linux_client = self.get_remote_client(self.floating_ip['ip'])
+ self.nova_show(server)
+
+ volume = self.cinder_create()
+ volumes = self.cinder_list()
+ self.assertIn(volume['id'], [x['id'] for x in volumes])
+
+ self.cinder_show(volume)
+
+ volume = self.nova_volume_attach(server, volume)
+ self.addCleanup(self.nova_volume_detach, server, volume)
+ self.cinder_show(volume)
+
+ floating_ip = self.create_floating_ip(server)
+ self.create_and_add_security_group_to_server(server)
+
+ self.linux_client = self.get_remote_client(
+ floating_ip['ip'], private_key=keypair['private_key'])
+ self.nova_reboot(server)
+
+ self.linux_client = self.get_remote_client(
+ floating_ip['ip'], private_key=keypair['private_key'])
self.check_partitions()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 62b2976..704342f 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -56,7 +56,7 @@
super(TestNetworkAdvancedServerOps, cls).setup_credentials()
def _setup_network_and_servers(self):
- self.keypair = self.create_keypair()
+ keypair = self.create_keypair()
security_group = self._create_security_group()
network, subnet, router = self.create_networks()
public_network_id = CONF.network.public_network_id
@@ -64,91 +64,103 @@
'networks': [
{'uuid': network.id},
],
- 'key_name': self.keypair['name'],
+ 'key_name': keypair['name'],
'security_groups': [{'name': security_group['name']}],
}
server_name = data_utils.rand_name('server-smoke')
- self.server = self.create_server(name=server_name,
- create_kwargs=create_kwargs)
- self.floating_ip = self.create_floating_ip(self.server,
- public_network_id)
+ server = self.create_server(name=server_name,
+ create_kwargs=create_kwargs)
+ floating_ip = self.create_floating_ip(server, public_network_id)
# Verify that we can indeed connect to the server before we mess with
# it's state
- self._wait_server_status_and_check_network_connectivity()
+ self._wait_server_status_and_check_network_connectivity(
+ server, keypair, floating_ip)
- def _check_network_connectivity(self, should_connect=True):
+ return server, keypair, floating_ip
+
+ def _check_network_connectivity(self, server, keypair, floating_ip,
+ should_connect=True):
username = CONF.compute.image_ssh_user
- private_key = self.keypair['private_key']
+ private_key = keypair['private_key']
self._check_tenant_network_connectivity(
- self.server, username, private_key,
+ server, username, private_key,
should_connect=should_connect,
- servers_for_debug=[self.server])
- floating_ip = self.floating_ip.floating_ip_address
+ servers_for_debug=[server])
+ floating_ip_addr = floating_ip.floating_ip_address
# Check FloatingIP status before checking the connectivity
- self.check_floating_ip_status(self.floating_ip, 'ACTIVE')
- self.check_public_network_connectivity(floating_ip, username,
+ self.check_floating_ip_status(floating_ip, 'ACTIVE')
+ self.check_public_network_connectivity(floating_ip_addr, username,
private_key, should_connect,
- servers=[self.server])
+ servers=[server])
- def _wait_server_status_and_check_network_connectivity(self):
- waiters.wait_for_server_status(self.servers_client,
- self.server['id'], 'ACTIVE')
- self._check_network_connectivity()
+ def _wait_server_status_and_check_network_connectivity(self, server,
+ keypair,
+ floating_ip):
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'ACTIVE')
+ self._check_network_connectivity(server, keypair, floating_ip)
@test.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
@test.stresstest(class_setup_per='process')
@test.services('compute', 'network')
def test_server_connectivity_stop_start(self):
- self._setup_network_and_servers()
- self.servers_client.stop_server(self.server['id'])
- waiters.wait_for_server_status(self.servers_client,
- self.server['id'], 'SHUTOFF')
- self._check_network_connectivity(should_connect=False)
- self.servers_client.start_server(self.server['id'])
- self._wait_server_status_and_check_network_connectivity()
+ server, keypair, floating_ip = self._setup_network_and_servers()
+ self.servers_client.stop_server(server['id'])
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'SHUTOFF')
+ self._check_network_connectivity(server, keypair, floating_ip,
+ should_connect=False)
+ self.servers_client.start_server(server['id'])
+ self._wait_server_status_and_check_network_connectivity(
+ server, keypair, floating_ip)
@test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
@test.services('compute', 'network')
def test_server_connectivity_reboot(self):
- self._setup_network_and_servers()
- self.servers_client.reboot_server(self.server['id'],
- reboot_type='SOFT')
- self._wait_server_status_and_check_network_connectivity()
+ server, keypair, floating_ip = self._setup_network_and_servers()
+ self.servers_client.reboot_server(server['id'], reboot_type='SOFT')
+ self._wait_server_status_and_check_network_connectivity(
+ server, keypair, floating_ip)
@test.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
@test.services('compute', 'network')
def test_server_connectivity_rebuild(self):
- self._setup_network_and_servers()
+ server, keypair, floating_ip = self._setup_network_and_servers()
image_ref_alt = CONF.compute.image_ref_alt
- self.servers_client.rebuild_server(self.server['id'],
+ self.servers_client.rebuild_server(server['id'],
image_ref=image_ref_alt)
- self._wait_server_status_and_check_network_connectivity()
+ self._wait_server_status_and_check_network_connectivity(
+ server, keypair, floating_ip)
@test.idempotent_id('2b2642db-6568-4b35-b812-eceed3fa20ce')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
@test.services('compute', 'network')
def test_server_connectivity_pause_unpause(self):
- self._setup_network_and_servers()
- self.servers_client.pause_server(self.server['id'])
- waiters.wait_for_server_status(self.servers_client,
- self.server['id'], 'PAUSED')
- self._check_network_connectivity(should_connect=False)
- self.servers_client.unpause_server(self.server['id'])
- self._wait_server_status_and_check_network_connectivity()
+ server, keypair, floating_ip = self._setup_network_and_servers()
+ self.servers_client.pause_server(server['id'])
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'PAUSED')
+ self._check_network_connectivity(server, keypair, floating_ip,
+ should_connect=False)
+ self.servers_client.unpause_server(server['id'])
+ self._wait_server_status_and_check_network_connectivity(
+ server, keypair, floating_ip)
@test.idempotent_id('5cdf9499-541d-4923-804e-b9a60620a7f0')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
@test.services('compute', 'network')
def test_server_connectivity_suspend_resume(self):
- self._setup_network_and_servers()
- self.servers_client.suspend_server(self.server['id'])
- waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ server, keypair, floating_ip = self._setup_network_and_servers()
+ self.servers_client.suspend_server(server['id'])
+ waiters.wait_for_server_status(self.servers_client, server['id'],
'SUSPENDED')
- self._check_network_connectivity(should_connect=False)
- self.servers_client.resume_server(self.server['id'])
- self._wait_server_status_and_check_network_connectivity()
+ self._check_network_connectivity(server, keypair, floating_ip,
+ should_connect=False)
+ self.servers_client.resume_server(server['id'])
+ self._wait_server_status_and_check_network_connectivity(
+ server, keypair, floating_ip)
@test.idempotent_id('719eb59d-2f42-4b66-b8b1-bb1254473967')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
@@ -159,10 +171,11 @@
if resize_flavor == CONF.compute.flavor_ref:
msg = "Skipping test - flavor_ref and flavor_ref_alt are identical"
raise self.skipException(msg)
- self._setup_network_and_servers()
- self.servers_client.resize_server(self.server['id'],
+ server, keypair, floating_ip = self._setup_network_and_servers()
+ self.servers_client.resize_server(server['id'],
flavor_ref=resize_flavor)
- waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ waiters.wait_for_server_status(self.servers_client, server['id'],
'VERIFY_RESIZE')
- self.servers_client.confirm_resize_server(self.server['id'])
- self._wait_server_status_and_check_network_connectivity()
+ self.servers_client.confirm_resize_server(server['id'])
+ self._wait_server_status_and_check_network_connectivity(
+ server, keypair, floating_ip)
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index a35c0b2..3c11c22 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -291,7 +291,8 @@
def _create_tenant_network(self, tenant):
network, subnet, router = self.create_networks(
client=tenant.manager.network_client,
- networks_client=tenant.manager.networks_client)
+ networks_client=tenant.manager.networks_client,
+ subnets_client=tenant.manager.subnets_client)
tenant.set_network(network, subnet, router)
def _set_compute_context(self, tenant):
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index dbc9bbb..bc80412 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -55,12 +55,12 @@
'ACTIVE')
def _create_server_then_shelve_and_unshelve(self, boot_from_volume=False):
- self.keypair = self.create_keypair()
+ keypair = self.create_keypair()
- self.security_group = self._create_security_group()
- security_groups = [{'name': self.security_group['name']}]
+ security_group = self._create_security_group()
+ security_groups = [{'name': security_group['name']}]
create_kwargs = {
- 'key_name': self.keypair['name'],
+ 'key_name': keypair['name'],
'security_groups': security_groups
}
@@ -86,18 +86,22 @@
floating_ip['id'])
self.floating_ips_client.associate_floating_ip_to_server(
floating_ip['ip'], server['id'])
- timestamp = self.create_timestamp(floating_ip['ip'])
+ timestamp = self.create_timestamp(
+ floating_ip['ip'], private_key=keypair['private_key'])
else:
- timestamp = self.create_timestamp(server)
+ timestamp = self.create_timestamp(
+ server, private_key=keypair['private_key'])
# Prevent bug #1257594 from coming back
# Unshelve used to boot the instance with the original image, not
# with the instance snapshot
self._shelve_then_unshelve_server(server)
if CONF.compute.use_floatingip_for_ssh:
- timestamp2 = self.get_timestamp(floating_ip['ip'])
+ timestamp2 = self.get_timestamp(floating_ip['ip'],
+ private_key=keypair['private_key'])
else:
- timestamp2 = self.get_timestamp(server)
+ timestamp2 = self.get_timestamp(server,
+ private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp2)
@test.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 79b809f..5ac3a7e 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -36,44 +36,47 @@
"""
- def _boot_image(self, image_id):
- security_groups = [{'name': self.security_group['name']}]
+ def _boot_image(self, image_id, keypair, security_group):
+ security_groups = [{'name': security_group['name']}]
create_kwargs = {
- 'key_name': self.keypair['name'],
+ 'key_name': keypair['name'],
'security_groups': security_groups
}
return self.create_server(image=image_id, create_kwargs=create_kwargs)
- def _add_keypair(self):
- self.keypair = self.create_keypair()
-
@test.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
@test.services('compute', 'network', 'image')
def test_snapshot_pattern(self):
# prepare for booting an instance
- self._add_keypair()
- self.security_group = self._create_security_group()
+ keypair = self.create_keypair()
+ security_group = self._create_security_group()
# boot an instance and create a timestamp file in it
- server = self._boot_image(CONF.compute.image_ref)
+ server = self._boot_image(CONF.compute.image_ref, keypair,
+ security_group)
if CONF.compute.use_floatingip_for_ssh:
fip_for_server = self.create_floating_ip(server)
- timestamp = self.create_timestamp(fip_for_server['ip'])
+ timestamp = self.create_timestamp(
+ fip_for_server['ip'], private_key=keypair['private_key'])
else:
- timestamp = self.create_timestamp(server)
+ timestamp = self.create_timestamp(
+ server, private_key=keypair['private_key'])
# snapshot the instance
snapshot_image = self.create_server_snapshot(server=server)
# boot a second instance from the snapshot
- server_from_snapshot = self._boot_image(snapshot_image['id'])
+ server_from_snapshot = self._boot_image(snapshot_image['id'],
+ keypair, security_group)
# check the existence of the timestamp file in the second instance
if CONF.compute.use_floatingip_for_ssh:
fip_for_snapshot = self.create_floating_ip(server_from_snapshot)
- timestamp2 = self.get_timestamp(fip_for_snapshot['ip'])
+ timestamp2 = self.get_timestamp(fip_for_snapshot['ip'],
+ private_key=keypair['private_key'])
else:
- timestamp2 = self.get_timestamp(server_from_snapshot)
+ timestamp2 = self.get_timestamp(server_from_snapshot,
+ private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp2)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index a4f9896..6eceeb2 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -63,20 +63,17 @@
self.snapshots_client.wait_for_snapshot_status(volume_snapshot['id'],
status)
- def _boot_image(self, image_id):
- security_groups = [{'name': self.security_group['name']}]
+ def _boot_image(self, image_id, keypair, security_group):
+ security_groups = [{'name': security_group['name']}]
create_kwargs = {
- 'key_name': self.keypair['name'],
+ 'key_name': keypair['name'],
'security_groups': security_groups
}
return self.create_server(image=image_id, create_kwargs=create_kwargs)
- def _add_keypair(self):
- self.keypair = self.create_keypair()
-
def _create_volume_snapshot(self, volume):
snapshot_name = data_utils.rand_name('scenario-snapshot')
- _, snapshot = self.snapshots_client.create_snapshot(
+ snapshot = self.snapshots_client.create_snapshot(
volume['id'], display_name=snapshot_name)['snapshot']
def cleaner():
@@ -111,8 +108,9 @@
self.servers_client.detach_volume(server['id'], volume['id'])
self._wait_for_volume_status(volume, 'available')
- def _wait_for_volume_available_on_the_system(self, server_or_ip):
- ssh = self.get_remote_client(server_or_ip)
+ def _wait_for_volume_available_on_the_system(self, server_or_ip,
+ private_key):
+ ssh = self.get_remote_client(server_or_ip, private_key=private_key)
def _func():
part = ssh.get_partitions()
@@ -131,12 +129,13 @@
@tempest.test.services('compute', 'network', 'volume', 'image')
def test_stamp_pattern(self):
# prepare for booting an instance
- self._add_keypair()
- self.security_group = self._create_security_group()
+ keypair = self.create_keypair()
+ security_group = self._create_security_group()
# boot an instance and create a timestamp file in it
volume = self._create_volume()
- server = self._boot_image(CONF.compute.image_ref)
+ server = self._boot_image(CONF.compute.image_ref, keypair,
+ security_group)
# create and add floating IP to server1
if CONF.compute.use_floatingip_for_ssh:
@@ -146,9 +145,11 @@
ip_for_server = server
self._attach_volume(server, volume)
- self._wait_for_volume_available_on_the_system(ip_for_server)
+ self._wait_for_volume_available_on_the_system(ip_for_server,
+ keypair['private_key'])
timestamp = self.create_timestamp(ip_for_server,
- CONF.compute.volume_device_name)
+ CONF.compute.volume_device_name,
+ private_key=keypair['private_key'])
self._detach_volume(server, volume)
# snapshot the volume
@@ -162,7 +163,8 @@
snapshot_id=volume_snapshot['id'])
# boot second instance from the snapshot(instance2)
- server_from_snapshot = self._boot_image(snapshot_image['id'])
+ server_from_snapshot = self._boot_image(snapshot_image['id'],
+ keypair, security_group)
# create and add floating IP to server_from_snapshot
if CONF.compute.use_floatingip_for_ssh:
@@ -174,9 +176,11 @@
# attach volume2 to instance2
self._attach_volume(server_from_snapshot, volume_from_snapshot)
- self._wait_for_volume_available_on_the_system(ip_for_snapshot)
+ self._wait_for_volume_available_on_the_system(ip_for_snapshot,
+ keypair['private_key'])
# check the existence of the timestamp file in the volume2
timestamp2 = self.get_timestamp(ip_for_snapshot,
- CONF.compute.volume_device_name)
+ CONF.compute.volume_device_name,
+ private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp2)
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index 63847c3..12509f7 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -19,13 +19,13 @@
from oslo_serialization import jsonutils as json
from tempest_lib.common.utils import misc
+from tempest_lib import exceptions as exc_lib
import testscenarios
import testtools
from tempest import clients
from tempest.common import credentials
from tempest import config
-from tempest import exceptions
CONF = config.CONF
@@ -174,7 +174,7 @@
scenario_utils = InputScenarioUtils()
scenario_flavor = scenario_utils.scenario_flavors
scenario_image = scenario_utils.scenario_images
- except (exceptions.InvalidConfiguration, TypeError):
+ except (exc_lib.InvalidCredentials, TypeError):
output = standard_tests
finally:
if scenario_utils:
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
deleted file mode 100644
index 7b374aa..0000000
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2013 IBM Corp
-# 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 oslo_serialization import jsonutils as json
-
-from tempest.api_schema.response.compute.v2_1 import fixed_ips as schema
-from tempest.common import service_client
-
-
-class FixedIPsClient(service_client.ServiceClient):
-
- def show_fixed_ip(self, fixed_ip):
- url = "os-fixed-ips/%s" % fixed_ip
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.get_fixed_ip, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def reserve_fixed_ip(self, fixed_ip, **kwargs):
- """This reserves and unreserves fixed ips."""
- url = "os-fixed-ips/%s/action" % fixed_ip
- resp, body = self.post(url, json.dumps(kwargs))
- self.validate_response(schema.reserve_unreserve_fixed_ip, resp, body)
- return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
deleted file mode 100644
index 2c32d30..0000000
--- a/tempest/services/compute/json/flavors_client.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# Copyright 2012 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 oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.api_schema.response.compute.v2_1 import flavors as schema
-from tempest.api_schema.response.compute.v2_1 import flavors_access \
- as schema_access
-from tempest.api_schema.response.compute.v2_1 import flavors_extra_specs \
- as schema_extra_specs
-from tempest.common import service_client
-
-
-class FlavorsClient(service_client.ServiceClient):
-
- def list_flavors(self, detail=False, **params):
- url = 'flavors'
- _schema = schema.list_flavors
-
- if detail:
- url += '/detail'
- _schema = schema.list_flavors_details
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(_schema, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def show_flavor(self, flavor_id):
- resp, body = self.get("flavors/%s" % flavor_id)
- body = json.loads(body)
- self.validate_response(schema.create_get_flavor_details, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def create_flavor(self, **kwargs):
- """Creates a new flavor or instance type.
- Most parameters except the following are passed to the API without
- any changes.
- :param ephemeral: The name is changed to OS-FLV-EXT-DATA:ephemeral
- :param is_public: The name is changed to os-flavor-access:is_public
- """
- if kwargs.get('ephemeral'):
- kwargs['OS-FLV-EXT-DATA:ephemeral'] = kwargs.pop('ephemeral')
- if kwargs.get('is_public'):
- kwargs['os-flavor-access:is_public'] = kwargs.pop('is_public')
-
- post_body = json.dumps({'flavor': kwargs})
- resp, body = self.post('flavors', post_body)
-
- body = json.loads(body)
- self.validate_response(schema.create_get_flavor_details, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def delete_flavor(self, flavor_id):
- """Deletes the given flavor."""
- resp, body = self.delete("flavors/{0}".format(flavor_id))
- self.validate_response(schema.delete_flavor, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def is_resource_deleted(self, id):
- # Did not use show_flavor(id) for verification as it gives
- # 200 ok even for deleted id. LP #981263
- # we can remove the loop here and use get by ID when bug gets sortedout
- flavors = self.list_flavors(detail=True)['flavors']
- for flavor in flavors:
- if flavor['id'] == id:
- return False
- return True
-
- @property
- def resource_type(self):
- """Returns the primary type of resource this client works with."""
- return 'flavor'
-
- def set_flavor_extra_spec(self, flavor_id, **kwargs):
- """Sets extra Specs to the mentioned flavor."""
- post_body = json.dumps({'extra_specs': kwargs})
- resp, body = self.post('flavors/%s/os-extra_specs' % flavor_id,
- post_body)
- body = json.loads(body)
- self.validate_response(schema_extra_specs.set_get_flavor_extra_specs,
- resp, body)
- return service_client.ResponseBody(resp, body)
-
- def list_flavor_extra_specs(self, flavor_id):
- """Gets extra Specs details of the mentioned flavor."""
- resp, body = self.get('flavors/%s/os-extra_specs' % flavor_id)
- body = json.loads(body)
- self.validate_response(schema_extra_specs.set_get_flavor_extra_specs,
- resp, body)
- return service_client.ResponseBody(resp, body)
-
- def show_flavor_extra_spec(self, flavor_id, key):
- """Gets extra Specs key-value of the mentioned flavor and key."""
- resp, body = self.get('flavors/%s/os-extra_specs/%s' % (flavor_id,
- key))
- body = json.loads(body)
- self.validate_response(
- schema_extra_specs.set_get_flavor_extra_specs_key,
- resp, body)
- return service_client.ResponseBody(resp, body)
-
- def update_flavor_extra_spec(self, flavor_id, key, **kwargs):
- """Update specified extra Specs of the mentioned flavor and key."""
- resp, body = self.put('flavors/%s/os-extra_specs/%s' %
- (flavor_id, key), json.dumps(kwargs))
- body = json.loads(body)
- self.validate_response(
- schema_extra_specs.set_get_flavor_extra_specs_key,
- resp, body)
- return service_client.ResponseBody(resp, body)
-
- def unset_flavor_extra_spec(self, flavor_id, key):
- """Unsets extra Specs from the mentioned flavor."""
- resp, body = self.delete('flavors/%s/os-extra_specs/%s' %
- (flavor_id, key))
- self.validate_response(schema.unset_flavor_extra_specs, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def list_flavor_access(self, flavor_id):
- """Gets flavor access information given the flavor id."""
- resp, body = self.get('flavors/%s/os-flavor-access' % flavor_id)
- body = json.loads(body)
- self.validate_response(schema_access.add_remove_list_flavor_access,
- resp, body)
- return service_client.ResponseBody(resp, body)
-
- def add_flavor_access(self, flavor_id, tenant_id):
- """Add flavor access for the specified tenant."""
- post_body = {
- 'addTenantAccess': {
- 'tenant': tenant_id
- }
- }
- post_body = json.dumps(post_body)
- resp, body = self.post('flavors/%s/action' % flavor_id, post_body)
- body = json.loads(body)
- self.validate_response(schema_access.add_remove_list_flavor_access,
- resp, body)
- return service_client.ResponseBody(resp, body)
-
- def remove_flavor_access(self, flavor_id, tenant_id):
- """Remove flavor access from the specified tenant."""
- post_body = {
- 'removeTenantAccess': {
- 'tenant': tenant_id
- }
- }
- post_body = json.dumps(post_body)
- resp, body = self.post('flavors/%s/action' % flavor_id, post_body)
- body = json.loads(body)
- self.validate_response(schema_access.add_remove_list_flavor_access,
- resp, body)
- return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/floating_ip_pools_client.py b/tempest/services/compute/json/floating_ip_pools_client.py
deleted file mode 100644
index c83537a..0000000
--- a/tempest/services/compute/json/floating_ip_pools_client.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2012 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 oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
-from tempest.common import service_client
-
-
-class FloatingIPPoolsClient(service_client.ServiceClient):
-
- def list_floating_ip_pools(self, params=None):
- """Gets all floating IP Pools list."""
- url = 'os-floating-ip-pools'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_floating_ip_pools, resp, body)
- return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/floating_ips_bulk_client.py b/tempest/services/compute/json/floating_ips_bulk_client.py
deleted file mode 100644
index dfe69f0..0000000
--- a/tempest/services/compute/json/floating_ips_bulk_client.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2012 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 oslo_serialization import jsonutils as json
-
-from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
-from tempest.common import service_client
-
-
-class FloatingIPsBulkClient(service_client.ServiceClient):
-
- def create_floating_ips_bulk(self, ip_range, pool, interface):
- """Allocate floating IPs in bulk."""
- post_body = {
- 'ip_range': ip_range,
- 'pool': pool,
- 'interface': interface
- }
- post_body = json.dumps({'floating_ips_bulk_create': post_body})
- resp, body = self.post('os-floating-ips-bulk', post_body)
- body = json.loads(body)
- self.validate_response(schema.create_floating_ips_bulk, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def list_floating_ips_bulk(self):
- """Gets all floating IPs in bulk."""
- resp, body = self.get('os-floating-ips-bulk')
- body = json.loads(body)
- self.validate_response(schema.list_floating_ips_bulk, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def delete_floating_ips_bulk(self, ip_range):
- """Deletes the provided floating IPs in bulk."""
- post_body = json.dumps({'ip_range': ip_range})
- resp, body = self.put('os-floating-ips-bulk/delete', post_body)
- body = json.loads(body)
- self.validate_response(schema.delete_floating_ips_bulk, resp, body)
- return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
deleted file mode 100644
index 3d3cb18..0000000
--- a/tempest/services/compute/json/hosts_client.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.api_schema.response.compute.v2_1 import hosts as schema
-from tempest.common import service_client
-
-
-class HostsClient(service_client.ServiceClient):
-
- def list_hosts(self, **params):
- """Lists all hosts."""
-
- url = 'os-hosts'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_hosts, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def show_host(self, hostname):
- """Show detail information for the host."""
-
- resp, body = self.get("os-hosts/%s" % hostname)
- body = json.loads(body)
- self.validate_response(schema.get_host_detail, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def update_host(self, hostname, **kwargs):
- """Update a host."""
-
- request_body = {
- 'status': None,
- 'maintenance_mode': None,
- }
- request_body.update(**kwargs)
- request_body = json.dumps(request_body)
-
- resp, body = self.put("os-hosts/%s" % hostname, request_body)
- body = json.loads(body)
- self.validate_response(schema.update_host, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def startup_host(self, hostname):
- """Startup a host."""
-
- resp, body = self.get("os-hosts/%s/startup" % hostname)
- body = json.loads(body)
- self.validate_response(schema.startup_host, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def shutdown_host(self, hostname):
- """Shutdown a host."""
-
- resp, body = self.get("os-hosts/%s/shutdown" % hostname)
- body = json.loads(body)
- self.validate_response(schema.shutdown_host, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def reboot_host(self, hostname):
- """reboot a host."""
-
- resp, body = self.get("os-hosts/%s/reboot" % hostname)
- body = json.loads(body)
- self.validate_response(schema.reboot_host, resp, body)
- return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
deleted file mode 100644
index ba06f23..0000000
--- a/tempest/services/compute/json/hypervisor_client.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright 2013 IBM 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 oslo_serialization import jsonutils as json
-
-from tempest.api_schema.response.compute.v2_1 import hypervisors as schema
-from tempest.common import service_client
-
-
-class HypervisorClient(service_client.ServiceClient):
-
- def list_hypervisors(self, detail=False):
- """List hypervisors information."""
- url = 'os-hypervisors'
- _schema = schema.list_search_hypervisors
- if detail:
- url += '/detail'
- _schema = schema.list_hypervisors_detail
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(_schema, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def show_hypervisor(self, hypervisor_id):
- """Display the details of the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s' % hypervisor_id)
- body = json.loads(body)
- self.validate_response(schema.get_hypervisor, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def list_servers_on_hypervisor(self, hypervisor_name):
- """List instances belonging to the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/servers' % hypervisor_name)
- body = json.loads(body)
- self.validate_response(schema.get_hypervisors_servers, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def show_hypervisor_statistics(self):
- """Get hypervisor statistics over all compute nodes."""
- resp, body = self.get('os-hypervisors/statistics')
- body = json.loads(body)
- self.validate_response(schema.get_hypervisor_statistics, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def show_hypervisor_uptime(self, hypervisor_id):
- """Display the uptime of the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/uptime' % hypervisor_id)
- body = json.loads(body)
- self.validate_response(schema.get_hypervisor_uptime, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def search_hypervisor(self, hypervisor_name):
- """Search specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/search' % hypervisor_name)
- body = json.loads(body)
- self.validate_response(schema.list_search_hypervisors, resp, body)
- return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 1d2c7b2..e54cfe4 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -32,8 +32,8 @@
self.enable_instance_password = enable_instance_password
def create_server(self, **kwargs):
- """
- Creates an instance of a server.
+ """Create server
+
Most parameters except the following are passed to the API without
any changes.
:param disk_config: The name is changed to OS-DCF:diskConfig
@@ -69,7 +69,8 @@
return service_client.ResponseBody(resp, body)
def update_server(self, server_id, **kwargs):
- """Updates the properties of an existing server.
+ """Update server
+
Most parameters except the following are passed to the API without
any changes.
:param disk_config: The name is changed to OS-DCF:diskConfig
@@ -84,20 +85,20 @@
return service_client.ResponseBody(resp, body)
def show_server(self, server_id):
- """Returns the details of an existing server."""
+ """Get server details"""
resp, body = self.get("servers/%s" % server_id)
body = json.loads(body)
self.validate_response(schema.get_server, resp, body)
return service_client.ResponseBody(resp, body)
def delete_server(self, server_id):
- """Deletes the given server."""
+ """Delete server"""
resp, body = self.delete("servers/%s" % server_id)
self.validate_response(schema.delete_server, resp, body)
return service_client.ResponseBody(resp, body)
def list_servers(self, detail=False, **params):
- """Lists all servers for a user."""
+ """List servers"""
url = 'servers'
_schema = schema.list_servers
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index d766aa5..7821f37 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -34,28 +34,6 @@
quotas
"""
- def create_subnet(self, **kwargs):
- uri = '/subnets'
- post_data = {'subnet': kwargs}
- return self.create_resource(uri, post_data)
-
- def update_subnet(self, subnet_id, **kwargs):
- uri = '/subnets/%s' % subnet_id
- post_data = {'subnet': kwargs}
- return self.update_resource(uri, post_data)
-
- def show_subnet(self, subnet_id, **fields):
- uri = '/subnets/%s' % subnet_id
- return self.show_resource(uri, **fields)
-
- def delete_subnet(self, subnet_id):
- uri = '/subnets/%s' % subnet_id
- return self.delete_resource(uri)
-
- def list_subnets(self, **filters):
- uri = '/subnets'
- return self.list_resources(uri, **filters)
-
def create_port(self, **kwargs):
uri = '/ports'
post_data = {'port': kwargs}
diff --git a/tempest/services/network/json/subnets_client.py b/tempest/services/network/json/subnets_client.py
new file mode 100644
index 0000000..957b606
--- /dev/null
+++ b/tempest/services/network/json/subnets_client.py
@@ -0,0 +1,38 @@
+# 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.network.json import base
+
+
+class SubnetsClient(base.BaseNetworkClient):
+
+ def create_subnet(self, **kwargs):
+ uri = '/subnets'
+ post_data = {'subnet': kwargs}
+ return self.create_resource(uri, post_data)
+
+ def update_subnet(self, subnet_id, **kwargs):
+ uri = '/subnets/%s' % subnet_id
+ post_data = {'subnet': kwargs}
+ return self.update_resource(uri, post_data)
+
+ def show_subnet(self, subnet_id, **fields):
+ uri = '/subnets/%s' % subnet_id
+ return self.show_resource(uri, **fields)
+
+ def delete_subnet(self, subnet_id):
+ uri = '/subnets/%s' % subnet_id
+ return self.delete_resource(uri)
+
+ def list_subnets(self, **filters):
+ uri = '/subnets'
+ return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 23d936e..16d9823 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -41,7 +41,9 @@
def __init__(self, *args, **kwargs):
self.client = kwargs.pop('client', None)
+ self.network_client = kwargs.pop('network_client', None)
self.networks_client = kwargs.pop('networks_client', None)
+ self.subnets_client = kwargs.pop('subnets_client', None)
super(DeletableResource, self).__init__(*args, **kwargs)
def __str__(self):
@@ -83,23 +85,23 @@
self._router_ids = set()
def update(self, *args, **kwargs):
- result = self.client.update_subnet(self.id,
- *args,
- **kwargs)
+ result = self.subnets_client.update_subnet(self.id,
+ *args,
+ **kwargs)
return super(DeletableSubnet, self).update(**result['subnet'])
def add_to_router(self, router_id):
self._router_ids.add(router_id)
- self.client.add_router_interface_with_subnet_id(router_id,
- subnet_id=self.id)
+ self.network_client.add_router_interface_with_subnet_id(
+ router_id, subnet_id=self.id)
def delete(self):
for router_id in self._router_ids.copy():
- self.client.remove_router_interface_with_subnet_id(
+ self.network_client.remove_router_interface_with_subnet_id(
router_id,
subnet_id=self.id)
self._router_ids.remove(router_id)
- self.client.delete_subnet(self.id)
+ self.subnets_client.delete_subnet(self.id)
class DeletableRouter(DeletableResource):
diff --git a/tempest/test.py b/tempest/test.py
index 490ee82..b8ba5f4 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -323,10 +323,13 @@
If one is really needed it may be implemented either in the
resource_setup or at test level.
"""
- if 'admin' in cls.credentials and not credentials.is_admin_available():
+ identity_version = cls.get_identity_version()
+ if 'admin' in cls.credentials and not credentials.is_admin_available(
+ identity_version=identity_version):
msg = "Missing Identity Admin API credentials in configuration."
raise cls.skipException(msg)
- if 'alt' in cls.credentials and not credentials.is_alt_available():
+ if 'alt' in cls.credentials and not credentials.is_alt_available(
+ identity_version=identity_version):
msg = "Missing a 2nd set of API credentials in configuration."
raise cls.skipException(msg)
if hasattr(cls, 'identity_version'):
@@ -454,6 +457,12 @@
return cred_client.get_creds_client(client, domain)
@classmethod
+ def get_identity_version(cls):
+ """Returns the identity version used by the test class"""
+ identity_version = getattr(cls, 'identity_version', None)
+ return identity_version or CONF.identity.auth_version
+
+ @classmethod
def _get_credentials_provider(cls):
"""Returns a credentials provider
@@ -464,13 +473,11 @@
not cls._creds_provider.name == cls.__name__):
force_tenant_isolation = getattr(cls, 'force_tenant_isolation',
False)
- identity_version = getattr(cls, 'identity_version', None)
- identity_version = identity_version or CONF.identity.auth_version
cls._creds_provider = credentials.get_credentials_provider(
name=cls.__name__, network_resources=cls.network_resources,
force_tenant_isolation=force_tenant_isolation,
- identity_version=identity_version)
+ identity_version=cls.get_identity_version())
return cls._creds_provider
@classmethod
@@ -597,7 +604,8 @@
# for their servers, so using an admin network client to validate
# the network name
if (not CONF.service_available.neutron and
- credentials.is_admin_available()):
+ credentials.is_admin_available(
+ identity_version=cls.get_identity_version())):
admin_creds = cred_provider.get_admin_creds()
admin_manager = clients.Manager(admin_creds)
networks_client = admin_manager.compute_networks_client
@@ -747,7 +755,8 @@
"mechanism")
if "admin_client" in description and description["admin_client"]:
- if not credentials.is_admin_available():
+ if not credentials.is_admin_available(
+ identity_version=self.get_identity_version()):
msg = ("Missing Identity Admin API credentials in"
"configuration.")
raise self.skipException(msg)
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 4a8f729..fc3d984 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -380,7 +380,7 @@
javelin.destroy_subnets([self.fake_object])
- mocked_function = self.fake_client.networks.delete_subnet
+ mocked_function = self.fake_client.subnets.delete_subnet
mocked_function.assert_called_once_with(fake_subnet_id)
def test_destroy_routers(self):
diff --git a/tempest/tests/common/test_admin_available.py b/tempest/tests/common/test_admin_available.py
index 8490c4d..a53ed5f 100644
--- a/tempest/tests/common/test_admin_available.py
+++ b/tempest/tests/common/test_admin_available.py
@@ -23,15 +23,17 @@
class TestAdminAvailable(base.TestCase):
+ identity_version = 'v2'
+
def setUp(self):
super(TestAdminAvailable, self).setUp()
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
- def run_test(self, tenant_isolation, use_accounts_file, admin_creds):
+ def run_test(self, dynamic_creds, use_accounts_file, admin_creds):
cfg.CONF.set_default('use_dynamic_credentials',
- tenant_isolation, group='auth')
+ dynamic_creds, group='auth')
if use_accounts_file:
accounts = [{'username': 'u1',
'tenant_name': 't1',
@@ -60,45 +62,58 @@
self.useFixture(mockpatch.Patch('os.path.isfile',
return_value=False))
if admin_creds:
- (u, t, p) = ('u', 't', 'p')
+ username = 'u'
+ tenant = 't'
+ password = 'p'
+ domain = 'd'
else:
- (u, t, p) = (None, None, None)
+ username = None
+ tenant = None
+ password = None
+ domain = None
- cfg.CONF.set_default('admin_username', u, group='auth')
- cfg.CONF.set_default('admin_tenant_name', t, group='auth')
- cfg.CONF.set_default('admin_password', p, group='auth')
+ cfg.CONF.set_default('admin_username', username, group='auth')
+ cfg.CONF.set_default('admin_tenant_name', tenant, group='auth')
+ cfg.CONF.set_default('admin_password', password, group='auth')
+ cfg.CONF.set_default('admin_domain_name', domain, group='auth')
- expected = admin_creds is not None or tenant_isolation
- observed = credentials.is_admin_available()
+ expected = admin_creds is not None or dynamic_creds
+ observed = credentials.is_admin_available(
+ identity_version=self.identity_version)
self.assertEqual(expected, observed)
- # Tenant isolation implies admin so only one test case for True
- def test__tenant_isolation__accounts_file__no_admin(self):
- self.run_test(tenant_isolation=True,
+ # Dynamic credentials implies admin so only one test case for True
+ def test__dynamic_creds__accounts_file__no_admin(self):
+ self.run_test(dynamic_creds=True,
use_accounts_file=True,
admin_creds=None)
- def test__no_tenant_isolation__accounts_file__no_admin(self):
- self.run_test(tenant_isolation=False,
+ def test__no_dynamic_creds__accounts_file__no_admin(self):
+ self.run_test(dynamic_creds=False,
use_accounts_file=True,
admin_creds=None)
- def test__no_tenant_isolation__accounts_file__admin_role(self):
- self.run_test(tenant_isolation=False,
+ def test__no_dynamic_creds__accounts_file__admin_role(self):
+ self.run_test(dynamic_creds=False,
use_accounts_file=True,
admin_creds='role')
- def test__no_tenant_isolation__accounts_file__admin_type(self):
- self.run_test(tenant_isolation=False,
+ def test__no_dynamic_creds__accounts_file__admin_type(self):
+ self.run_test(dynamic_creds=False,
use_accounts_file=True,
admin_creds='type')
- def test__no_tenant_isolation__no_accounts_file__no_admin(self):
- self.run_test(tenant_isolation=False,
+ def test__no_dynamic_creds__no_accounts_file__no_admin(self):
+ self.run_test(dynamic_creds=False,
use_accounts_file=False,
admin_creds=None)
- def test__no_tenant_isolation__no_accounts_file__admin(self):
- self.run_test(tenant_isolation=False,
+ def test__no_dynamic_creds__no_accounts_file__admin(self):
+ self.run_test(dynamic_creds=False,
use_accounts_file=False,
admin_creds='role')
+
+
+class TestAdminAvailableV3(TestAdminAvailable):
+
+ identity_version = 'v3'
diff --git a/tempest/tests/common/test_alt_available.py b/tempest/tests/common/test_alt_available.py
new file mode 100644
index 0000000..6a86f73
--- /dev/null
+++ b/tempest/tests/common/test_alt_available.py
@@ -0,0 +1,117 @@
+# Copyright 2015 Red Hat, Inc.
+#
+# 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 oslo_config import cfg
+from oslotest import mockpatch
+
+from tempest.common import credentials
+from tempest import config
+from tempest.tests import base
+from tempest.tests import fake_config
+
+
+class TestAltAvailable(base.TestCase):
+
+ identity_version = 'v2'
+
+ def setUp(self):
+ super(TestAltAvailable, self).setUp()
+ self.useFixture(fake_config.ConfigFixture())
+ self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
+
+ def run_test(self, dynamic_creds, use_accounts_file, creds):
+
+ cfg.CONF.set_default('use_dynamic_credentials',
+ dynamic_creds, group='auth')
+ if use_accounts_file:
+ accounts = [dict(username="u%s" % ii,
+ tenant_name="t%s" % ii,
+ password="p") for ii in creds]
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.preprov_creds.read_accounts_yaml',
+ return_value=accounts))
+ cfg.CONF.set_default('test_accounts_file',
+ use_accounts_file, group='auth')
+ self.useFixture(mockpatch.Patch('os.path.isfile',
+ return_value=True))
+ else:
+ self.useFixture(mockpatch.Patch('os.path.isfile',
+ return_value=False))
+ cred_prefix = ['', 'alt_']
+ for ii in range(0, 2):
+ if len(creds) > ii:
+ username = 'u%s' % creds[ii]
+ tenant = 't%s' % creds[ii]
+ password = 'p'
+ domain = 'd'
+ else:
+ username = None
+ tenant = None
+ password = None
+ domain = None
+
+ cfg.CONF.set_default('%susername' % cred_prefix[ii], username,
+ group='identity')
+ cfg.CONF.set_default('%stenant_name' % cred_prefix[ii], tenant,
+ group='identity')
+ cfg.CONF.set_default('%spassword' % cred_prefix[ii], password,
+ group='identity')
+ cfg.CONF.set_default('%sdomain_name' % cred_prefix[ii], domain,
+ group='identity')
+
+ expected = len(set(creds)) > 1 or dynamic_creds
+ observed = credentials.is_alt_available(
+ identity_version=self.identity_version)
+ self.assertEqual(expected, observed)
+
+ # Dynamic credentials implies alt so only one test case for True
+ def test__dynamic_creds__accounts_file__one_user(self):
+ self.run_test(dynamic_creds=True,
+ use_accounts_file=False,
+ creds=['1', '2'])
+
+ def test__no_dynamic_creds__accounts_file__one_user(self):
+ self.run_test(dynamic_creds=False,
+ use_accounts_file=True,
+ creds=['1'])
+
+ def test__no_dynamic_creds__accounts_file__two_users(self):
+ self.run_test(dynamic_creds=False,
+ use_accounts_file=True,
+ creds=['1', '2'])
+
+ def test__no_dynamic_creds__accounts_file__two_users_identical(self):
+ self.run_test(dynamic_creds=False,
+ use_accounts_file=True,
+ creds=['1', '1'])
+
+ def test__no_dynamic_creds__no_accounts_file__one_user(self):
+ self.run_test(dynamic_creds=False,
+ use_accounts_file=False,
+ creds=['1'])
+
+ def test__no_dynamic_creds__no_accounts_file__two_users(self):
+ self.run_test(dynamic_creds=False,
+ use_accounts_file=False,
+ creds=['1', '2'])
+
+ def test__no_dynamic_creds__no_accounts_file__two_users_identical(self):
+ self.run_test(dynamic_creds=False,
+ use_accounts_file=False,
+ creds=['1', '1'])
+
+
+class TestAltAvailableV3(TestAltAvailable):
+
+ identity_version = 'v3'
diff --git a/tempest/tests/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
similarity index 93%
rename from tempest/tests/test_dynamic_creds.py
rename to tempest/tests/common/test_dynamic_creds.py
index 5f57268..59a5523 100644
--- a/tempest/tests/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -32,6 +32,10 @@
class TestDynamicCredentialProvider(base.TestCase):
+ fixed_params = {'name': 'test class',
+ 'identity_version': 'v2',
+ 'admin_role': 'admin'}
+
def setUp(self):
super(TestDynamicCredentialProvider, self).setUp()
self.useFixture(fake_config.ConfigFixture())
@@ -44,7 +48,7 @@
self._mock_list_ec2_credentials('fake_user_id', 'fake_tenant_id')
def test_tempest_client(self):
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self.assertTrue(isinstance(creds.identity_admin_client,
json_iden_client.IdentityClient))
self.assertTrue(isinstance(creds.network_admin_client,
@@ -127,7 +131,7 @@
def _mock_subnet_create(self, iso_creds, id, name):
subnet_fix = self.useFixture(mockpatch.PatchObject(
- iso_creds.network_admin_client,
+ iso_creds.subnets_admin_client,
'create_subnet',
return_value={'subnet': {'id': id, 'name': name}}))
return subnet_fix
@@ -142,7 +146,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_primary_creds(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_tenant_create('1234', 'fake_prim_tenant')
@@ -157,7 +161,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_admin_creds(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_list_roles('1234', 'admin')
self._mock_user_create('1234', 'fake_admin_user')
self._mock_tenant_create('1234', 'fake_admin_tenant')
@@ -180,7 +184,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_role_creds(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
- creds = dynamic_creds.DynamicCredentialProvider('v2', 'test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_list_2_roles()
self._mock_user_create('1234', 'fake_role_user')
self._mock_tenant_create('1234', 'fake_role_tenant')
@@ -209,7 +213,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_all_cred_cleanup(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_tenant_create('1234', 'fake_prim_tenant')
@@ -249,7 +253,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_alt_creds(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_alt_user')
@@ -264,7 +268,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_no_network_creation_with_config_set(self, MockRestClient):
cfg.CONF.set_default('create_isolated_networks', False, group='auth')
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
@@ -272,7 +276,7 @@
net = mock.patch.object(creds.networks_admin_client,
'delete_network')
net_mock = net.start()
- subnet = mock.patch.object(creds.network_admin_client,
+ subnet = mock.patch.object(creds.subnets_admin_client,
'delete_subnet')
subnet_mock = subnet.start()
router = mock.patch.object(creds.network_admin_client,
@@ -292,7 +296,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_creation(self, MockRestClient):
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
@@ -323,7 +327,7 @@
"description": args['name'],
"security_group_rules": [],
"id": "sg-%s" % args['tenant_id']}]}
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
# Create primary tenant and network
self._mock_assign_user_role()
self._mock_list_role()
@@ -362,7 +366,7 @@
net = mock.patch.object(creds.networks_admin_client,
'delete_network')
net_mock = net.start()
- subnet = mock.patch.object(creds.network_admin_client,
+ subnet = mock.patch.object(creds.subnets_admin_client,
'delete_subnet')
subnet_mock = subnet.start()
router = mock.patch.object(creds.network_admin_client,
@@ -431,7 +435,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_alt_creation(self, MockRestClient):
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_alt_user')
@@ -456,7 +460,7 @@
@mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_admin_creation(self, MockRestClient):
- creds = dynamic_creds.DynamicCredentialProvider(name='test class')
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
self._mock_user_create('1234', 'fake_admin_user')
self._mock_tenant_create('1234', 'fake_admin_tenant')
@@ -488,7 +492,8 @@
'dhcp': False,
}
creds = dynamic_creds.DynamicCredentialProvider(
- name='test class', network_resources=net_dict)
+ network_resources=net_dict,
+ **self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
@@ -496,7 +501,7 @@
net = mock.patch.object(creds.networks_admin_client,
'delete_network')
net_mock = net.start()
- subnet = mock.patch.object(creds.network_admin_client,
+ subnet = mock.patch.object(creds.subnets_admin_client,
'delete_subnet')
subnet_mock = subnet.start()
router = mock.patch.object(creds.network_admin_client,
@@ -523,7 +528,8 @@
'dhcp': False,
}
creds = dynamic_creds.DynamicCredentialProvider(
- name='test class', network_resources=net_dict)
+ network_resources=net_dict,
+ **self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
@@ -540,7 +546,8 @@
'dhcp': False,
}
creds = dynamic_creds.DynamicCredentialProvider(
- name='test class', network_resources=net_dict)
+ network_resources=net_dict,
+ **self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
@@ -557,7 +564,8 @@
'dhcp': True,
}
creds = dynamic_creds.DynamicCredentialProvider(
- name='test class', network_resources=net_dict)
+ network_resources=net_dict,
+ **self.fixed_params)
self._mock_assign_user_role()
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index cb7240b..8a014af 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -36,6 +36,10 @@
class TestPreProvisionedCredentials(base.TestCase):
+ fixed_params = {'name': 'test class',
+ 'identity_version': 'v2',
+ 'admin_role': 'admin'}
+
def setUp(self):
super(TestPreProvisionedCredentials, self).setUp()
self.useFixture(fake_config.ConfigFixture())
@@ -89,7 +93,7 @@
self.stubs.Set(token_client.TokenClient, 'raw_request',
fake_identity._fake_v2_response)
test_account_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
hash_list = self._get_hash_list(self.test_accounts)
test_cred_dict = self.test_accounts[3]
test_creds = auth.get_credentials(fake_identity.FAKE_AUTH_URL,
@@ -99,8 +103,9 @@
def test_get_hash_dict(self):
test_account_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
- hash_dict = test_account_class.get_hash_dict(self.test_accounts)
+ **self.fixed_params)
+ hash_dict = test_account_class.get_hash_dict(
+ self.test_accounts, self.fixed_params['admin_role'])
hash_list = self._get_hash_list(self.test_accounts)
for hash in hash_list:
self.assertIn(hash, hash_dict['creds'].keys())
@@ -113,7 +118,7 @@
create=True):
test_account_class = (
preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name'))
+ **self.fixed_params))
res = test_account_class._create_hash_file('12345')
self.assertFalse(res, "_create_hash_file should return False if the "
"pseudo-lock file already exists")
@@ -125,7 +130,7 @@
create=True):
test_account_class = (
preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name'))
+ **self.fixed_params))
res = test_account_class._create_hash_file('12345')
self.assertTrue(res, "_create_hash_file should return True if the "
"pseudo-lock doesn't already exist")
@@ -138,7 +143,7 @@
mkdir_mock = self.useFixture(mockpatch.Patch('os.mkdir'))
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
test_account_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
with mock.patch('six.moves.builtins.open', mock.mock_open(),
create=True) as open_mock:
test_account_class._get_free_hash(hash_list)
@@ -157,7 +162,7 @@
# Emulate all lcoks in list are in use
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
test_account_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
with mock.patch('six.moves.builtins.open', mock.mock_open(),
create=True):
self.assertRaises(exceptions.InvalidConfiguration,
@@ -169,7 +174,7 @@
self.useFixture(mockpatch.Patch('os.path.isdir', return_value=True))
hash_list = self._get_hash_list(self.test_accounts)
test_account_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
def _fake_is_file(path):
# Fake isfile() to return that the path exists unless a specific
@@ -195,7 +200,7 @@
# Pretend the lock dir is empty
self.useFixture(mockpatch.Patch('os.listdir', return_value=[]))
test_account_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
test_account_class.remove_hash(hash_list[2])
@@ -216,7 +221,7 @@
self.useFixture(mockpatch.Patch('os.listdir', return_value=[
hash_list[1], hash_list[4]]))
test_account_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
test_account_class.remove_hash(hash_list[2])
@@ -228,7 +233,7 @@
def test_is_multi_user(self):
test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
self.assertTrue(test_accounts_class.is_multi_user())
def test_is_not_multi_user(self):
@@ -237,7 +242,7 @@
'tempest.common.preprov_creds.read_accounts_yaml',
return_value=self.test_accounts))
test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
self.assertFalse(test_accounts_class.is_multi_user())
def test__get_creds_by_roles_one_role(self):
@@ -245,7 +250,7 @@
'tempest.common.preprov_creds.read_accounts_yaml',
return_value=self.test_accounts))
test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
hashes = test_accounts_class.hash_dict['roles']['role4']
temp_hash = hashes[0]
get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
@@ -263,7 +268,7 @@
'tempest.common.preprov_creds.read_accounts_yaml',
return_value=self.test_accounts))
test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
hashes = test_accounts_class.hash_dict['roles']['role4']
hashes2 = test_accounts_class.hash_dict['roles']['role2']
hashes = list(set(hashes) & set(hashes2))
@@ -283,7 +288,7 @@
'tempest.common.preprov_creds.read_accounts_yaml',
return_value=self.test_accounts))
test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
hashes = list(test_accounts_class.hash_dict['creds'].keys())
admin_hashes = test_accounts_class.hash_dict['roles'][
cfg.CONF.identity.admin_role]
@@ -310,7 +315,7 @@
'tempest.common.preprov_creds.read_accounts_yaml',
return_value=test_accounts))
test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
with mock.patch('tempest.services.compute.json.networks_client.'
'NetworksClient.list_networks',
return_value={'networks': [{'name': 'network-2',
@@ -328,6 +333,10 @@
class TestNotLockingAccount(base.TestCase):
+ fixed_params = {'name': 'test class',
+ 'identity_version': 'v2',
+ 'admin_role': 'admin'}
+
def setUp(self):
super(TestNotLockingAccount, self).setUp()
self.useFixture(fake_config.ConfigFixture())
@@ -349,7 +358,7 @@
def test_get_creds_roles_nonlocking_invalid(self):
test_accounts_class = preprov_creds.NonLockingCredentialProvider(
- 'v2', 'test_name')
+ **self.fixed_params)
self.assertRaises(exceptions.InvalidConfiguration,
test_accounts_class.get_creds_by_roles,
['fake_role'])
diff --git a/tempest/tests/services/compute/test_fixedIPs_client.py b/tempest/tests/services/compute/test_fixedIPs_client.py
deleted file mode 100644
index b537baa..0000000
--- a/tempest/tests/services/compute/test_fixedIPs_client.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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_lib.tests import fake_auth_provider
-
-from tempest.services.compute.json import fixed_ips_client
-from tempest.tests.services.compute import base
-
-
-class TestFixedIPsClient(base.BaseComputeServiceTest):
- FIXED_IP_INFO = {"fixed_ip": {"address": "10.0.0.1",
- "cidr": "10.11.12.0/24",
- "host": "localhost",
- "hostname": "OpenStack"}}
-
- def setUp(self):
- super(TestFixedIPsClient, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.fixedIPsClient = (fixed_ips_client.
- FixedIPsClient
- (fake_auth, 'compute',
- 'regionOne'))
-
- def _test_show_fixed_ip(self, bytes_body=False):
- self.check_service_client_function(
- self.fixedIPsClient.show_fixed_ip,
- 'tempest.common.service_client.ServiceClient.get',
- self.FIXED_IP_INFO, bytes_body,
- status=200, fixed_ip='Identifier')
-
- def test_show_fixed_ip_with_str_body(self):
- self._test_show_fixed_ip()
-
- def test_show_fixed_ip_with_bytes_body(self):
- self._test_show_fixed_ip(True)
-
- def _test_reserve_fixed_ip(self, bytes_body=False):
- self.check_service_client_function(
- self.fixedIPsClient.reserve_fixed_ip,
- 'tempest.common.service_client.ServiceClient.post',
- {}, bytes_body,
- status=202, fixed_ip='Identifier')
-
- def test_reserve_fixed_ip_with_str_body(self):
- self._test_reserve_fixed_ip()
-
- def test_reserve_fixed_ip_with_bytes_body(self):
- self._test_reserve_fixed_ip(True)
diff --git a/tempest/tests/services/compute/test_flavors_client.py b/tempest/tests/services/compute/test_flavors_client.py
deleted file mode 100644
index 6c0edb8..0000000
--- a/tempest/tests/services/compute/test_flavors_client.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# Copyright 2015 IBM Corp.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
-from tempest.services.compute.json import flavors_client
-from tempest.tests import fake_auth_provider
-from tempest.tests.services.compute import base
-
-
-class TestFlavorsClient(base.BaseComputeServiceTest):
-
- FAKE_FLAVOR = {
- "disk": 1,
- "id": "1",
- "links": [{
- "href": "http://openstack.example.com/v2/openstack/flavors/1",
- "rel": "self"}, {
- "href": "http://openstack.example.com/openstack/flavors/1",
- "rel": "bookmark"}],
- "name": "m1.tiny",
- "ram": 512,
- "swap": 1,
- "vcpus": 1
- }
-
- EXTRA_SPECS = {"extra_specs": {
- "key1": "value1",
- "key2": "value2"}
- }
-
- FAKE_FLAVOR_ACCESS = {
- "flavor_id": "10",
- "tenant_id": "1a951d988e264818afe520e78697dcbf"
- }
-
- def setUp(self):
- super(TestFlavorsClient, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = flavors_client.FlavorsClient(fake_auth,
- 'compute', 'regionOne')
-
- def _test_list_flavors(self, bytes_body=False):
- flavor = copy.deepcopy(TestFlavorsClient.FAKE_FLAVOR)
- # Remove extra attributes
- for attribute in ('disk', 'vcpus', 'ram', 'swap'):
- del flavor[attribute]
- expected = {'flavors': [flavor]}
- self.check_service_client_function(
- self.client.list_flavors,
- 'tempest.common.service_client.ServiceClient.get',
- expected,
- bytes_body)
-
- def test_list_flavors_str_body(self):
- self._test_list_flavors(bytes_body=False)
-
- def test_list_flavors_byte_body(self):
- self._test_list_flavors(bytes_body=True)
-
- def _test_show_flavor(self, bytes_body=False):
- expected = {"flavor": TestFlavorsClient.FAKE_FLAVOR}
- self.check_service_client_function(
- self.client.show_flavor,
- 'tempest.common.service_client.ServiceClient.get',
- expected,
- bytes_body,
- flavor_id='fake-id')
-
- def test_show_flavor_str_body(self):
- self._test_show_flavor(bytes_body=False)
-
- def test_show_flavor_byte_body(self):
- self._test_show_flavor(bytes_body=True)
-
- def _test_create_flavor(self, bytes_body=False):
- expected = {"flavor": TestFlavorsClient.FAKE_FLAVOR}
- request = copy.deepcopy(TestFlavorsClient.FAKE_FLAVOR)
- # The 'links' parameter should not be passed in
- del request['links']
- self.check_service_client_function(
- self.client.create_flavor,
- 'tempest.common.service_client.ServiceClient.post',
- expected,
- bytes_body,
- **request)
-
- def test_create_flavor_str_body(self):
- self._test_create_flavor(bytes_body=False)
-
- def test_create_flavor__byte_body(self):
- self._test_create_flavor(bytes_body=True)
-
- def test_delete_flavor(self):
- self.check_service_client_function(
- self.client.delete_flavor,
- 'tempest.common.service_client.ServiceClient.delete',
- {}, status=202, flavor_id='c782b7a9-33cd-45f0-b795-7f87f456408b')
-
- def _test_is_resource_deleted(self, flavor_id, is_deleted=True,
- bytes_body=False):
- body = json.dumps({'flavors': [TestFlavorsClient.FAKE_FLAVOR]})
- if bytes_body:
- body = body.encode('utf-8')
- response = (httplib2.Response({'status': 200}), body)
- self.useFixture(mockpatch.Patch(
- 'tempest.common.service_client.ServiceClient.get',
- return_value=response))
- self.assertEqual(is_deleted,
- self.client.is_resource_deleted(flavor_id))
-
- def test_is_resource_deleted_true_str_body(self):
- self._test_is_resource_deleted('2', bytes_body=False)
-
- def test_is_resource_deleted_true_byte_body(self):
- self._test_is_resource_deleted('2', bytes_body=True)
-
- def test_is_resource_deleted_false_str_body(self):
- self._test_is_resource_deleted('1', is_deleted=False, bytes_body=False)
-
- def test_is_resource_deleted_false_byte_body(self):
- self._test_is_resource_deleted('1', is_deleted=False, bytes_body=True)
-
- def _test_set_flavor_extra_spec(self, bytes_body=False):
- self.check_service_client_function(
- self.client.set_flavor_extra_spec,
- 'tempest.common.service_client.ServiceClient.post',
- TestFlavorsClient.EXTRA_SPECS,
- bytes_body,
- flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
- **TestFlavorsClient.EXTRA_SPECS)
-
- def test_set_flavor_extra_spec_str_body(self):
- self._test_set_flavor_extra_spec(bytes_body=False)
-
- def test_set_flavor_extra_spec_byte_body(self):
- self._test_set_flavor_extra_spec(bytes_body=True)
-
- def _test_list_flavor_extra_specs(self, bytes_body=False):
- self.check_service_client_function(
- self.client.list_flavor_extra_specs,
- 'tempest.common.service_client.ServiceClient.get',
- TestFlavorsClient.EXTRA_SPECS,
- bytes_body,
- flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6')
-
- def test_list_flavor_extra_specs_str_body(self):
- self._test_list_flavor_extra_specs(bytes_body=False)
-
- def test_list_flavor_extra_specs__byte_body(self):
- self._test_list_flavor_extra_specs(bytes_body=True)
-
- def _test_show_flavor_extra_spec(self, bytes_body=False):
- expected = {"key": "value"}
- self.check_service_client_function(
- self.client.show_flavor_extra_spec,
- 'tempest.common.service_client.ServiceClient.get',
- expected,
- bytes_body,
- flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
- key='key')
-
- def test_show_flavor_extra_spec_str_body(self):
- self._test_show_flavor_extra_spec(bytes_body=False)
-
- def test_show_flavor_extra_spec__byte_body(self):
- self._test_show_flavor_extra_spec(bytes_body=True)
-
- def _test_update_flavor_extra_spec(self, bytes_body=False):
- expected = {"key1": "value"}
- self.check_service_client_function(
- self.client.update_flavor_extra_spec,
- 'tempest.common.service_client.ServiceClient.put',
- expected,
- bytes_body,
- flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
- key='key1', **expected)
-
- def test_update_flavor_extra_spec_str_body(self):
- self._test_update_flavor_extra_spec(bytes_body=False)
-
- def test_update_flavor_extra_spec_byte_body(self):
- self._test_update_flavor_extra_spec(bytes_body=True)
-
- def test_unset_flavor_extra_spec(self):
- self.check_service_client_function(
- self.client.unset_flavor_extra_spec,
- 'tempest.common.service_client.ServiceClient.delete', {},
- flavor_id='c782b7a9-33cd-45f0-b795-7f87f456408b', key='key')
-
- def _test_list_flavor_access(self, bytes_body=False):
- expected = {'flavor_access': [TestFlavorsClient.FAKE_FLAVOR_ACCESS]}
- self.check_service_client_function(
- self.client.list_flavor_access,
- 'tempest.common.service_client.ServiceClient.get',
- expected,
- bytes_body,
- flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6')
-
- def test_list_flavor_access_str_body(self):
- self._test_list_flavor_access(bytes_body=False)
-
- def test_list_flavor_access_byte_body(self):
- self._test_list_flavor_access(bytes_body=True)
-
- def _test_add_flavor_access(self, bytes_body=False):
- expected = {
- "flavor_access": [TestFlavorsClient.FAKE_FLAVOR_ACCESS]
- }
- self.check_service_client_function(
- self.client.add_flavor_access,
- 'tempest.common.service_client.ServiceClient.post',
- expected,
- bytes_body,
- flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
- tenant_id='1a951d988e264818afe520e78697dcbf')
-
- def test_add_flavor_access_str_body(self):
- self._test_add_flavor_access(bytes_body=False)
-
- def test_add_flavor_access_byte_body(self):
- self._test_add_flavor_access(bytes_body=True)
-
- def _test_remove_flavor_access(self, bytes_body=False):
- expected = {
- "flavor_access": [TestFlavorsClient.FAKE_FLAVOR_ACCESS]
- }
- self.check_service_client_function(
- self.client.remove_flavor_access,
- 'tempest.common.service_client.ServiceClient.post',
- expected,
- bytes_body,
- flavor_id='10',
- tenant_id='a6edd4d66ad04245b5d2d8716ecc91e3')
-
- def test_remove_flavor_access_str_body(self):
- self._test_remove_flavor_access(bytes_body=False)
-
- def test_remove_flavor_access_byte_body(self):
- self._test_remove_flavor_access(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_floating_ip_pools_client.py b/tempest/tests/services/compute/test_floating_ip_pools_client.py
deleted file mode 100644
index 1cb4bf3..0000000
--- a/tempest/tests/services/compute/test_floating_ip_pools_client.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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_lib.tests import fake_auth_provider
-
-from tempest.services.compute.json import floating_ip_pools_client
-from tempest.tests.services.compute import base
-
-
-class TestFloatingIPPoolsClient(base.BaseComputeServiceTest):
-
- FAKE_FLOATING_IP_POOLS = {
- "floating_ip_pools":
- [
- {"name": u'\u3042'},
- {"name": u'\u3044'}
- ]
- }
-
- def setUp(self):
- super(TestFloatingIPPoolsClient, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = floating_ip_pools_client.FloatingIPPoolsClient(
- fake_auth, 'compute', 'regionOne')
-
- def test_list_floating_ip_pools_with_str_body(self):
- self.check_service_client_function(
- self.client.list_floating_ip_pools,
- 'tempest.common.service_client.ServiceClient.get',
- self.FAKE_FLOATING_IP_POOLS)
-
- def test_list_floating_ip_pools_with_bytes_body(self):
- self.check_service_client_function(
- self.client.list_floating_ip_pools,
- 'tempest.common.service_client.ServiceClient.get',
- self.FAKE_FLOATING_IP_POOLS, to_utf=True)
diff --git a/tempest/tests/services/compute/test_floating_ips_bulk_client.py b/tempest/tests/services/compute/test_floating_ips_bulk_client.py
deleted file mode 100644
index 600985b..0000000
--- a/tempest/tests/services/compute/test_floating_ips_bulk_client.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# 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_lib.tests import fake_auth_provider
-
-from tempest.services.compute.json import floating_ips_bulk_client
-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_hosts_client.py b/tempest/tests/services/compute/test_hosts_client.py
deleted file mode 100644
index 2b7fdb5..0000000
--- a/tempest/tests/services/compute/test_hosts_client.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# 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 hosts_client
-from tempest.tests import fake_auth_provider
-from tempest.tests.services.compute import base
-
-
-class TestHostsClient(base.BaseComputeServiceTest):
- FAKE_HOST_DATA = {
- "host": {
- "resource": {
- "cpu": 1,
- "disk_gb": 1028,
- "host": "c1a7de0ac9d94e4baceae031d05caae3",
- "memory_mb": 8192,
- "project": "(total)"
- }
- },
- "hosts": {
- "host_name": "c1a7de0ac9d94e4baceae031d05caae3",
- "service": "conductor",
- "zone": "internal"
- },
- "enable_hosts": {
- "host": "65c5d5b7e3bd44308e67fc50f362aee6",
- "maintenance_mode": "off_maintenance",
- "status": "enabled"
- }
- }
-
- FAKE_CONTROL_DATA = {
- "shutdown": {
- "host": "c1a7de0ac9d94e4baceae031d05caae3",
- "power_action": "shutdown"
- },
- "startup": {
- "host": "c1a7de0ac9d94e4baceae031d05caae3",
- "power_action": "startup"
- },
- "reboot": {
- "host": "c1a7de0ac9d94e4baceae031d05caae3",
- "power_action": "reboot"
- }}
-
- HOST_DATA = {'host': [FAKE_HOST_DATA['host']]}
- HOSTS_DATA = {'hosts': [FAKE_HOST_DATA['hosts']]}
- ENABLE_HOST_DATA = FAKE_HOST_DATA['enable_hosts']
- HOST_ID = "c1a7de0ac9d94e4baceae031d05caae3"
- TEST_HOST_DATA = {
- "status": "enable",
- "maintenance_mode": "disable"
- }
-
- def setUp(self):
- super(TestHostsClient, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = hosts_client.HostsClient(fake_auth, 'compute',
- 'regionOne')
- self.params = {'hostname': self.HOST_ID}
- self.func2mock = {
- 'get': 'tempest.common.service_client.ServiceClient.get',
- 'put': 'tempest.common.service_client.ServiceClient.put'}
-
- def _test_host_data(self, test_type='list', bytes_body=False):
- expected_resp = self.HOST_DATA
- if test_type != 'list':
- function_call = self.client.show_host
- else:
- expected_resp = self.HOSTS_DATA
- function_call = self.client.list_hosts
- self.params = {'host_name': self.HOST_ID}
-
- self.check_service_client_function(
- function_call, self.func2mock['get'],
- expected_resp, bytes_body,
- 200, **self.params)
-
- def _test_update_hosts(self, bytes_body=False):
- expected_resp = self.ENABLE_HOST_DATA
- self.check_service_client_function(
- self.client.update_host, self.func2mock['put'],
- expected_resp, bytes_body,
- 200, **self.params)
-
- def _test_control_host(self, control_op='reboot', bytes_body=False):
- if control_op == 'start':
- expected_resp = self.FAKE_CONTROL_DATA['startup']
- function_call = self.client.startup_host
- elif control_op == 'stop':
- expected_resp = self.FAKE_CONTROL_DATA['shutdown']
- function_call = self.client.shutdown_host
- else:
- expected_resp = self.FAKE_CONTROL_DATA['reboot']
- function_call = self.client.reboot_host
-
- self.check_service_client_function(
- function_call, self.func2mock['get'],
- expected_resp, bytes_body,
- 200, **self.params)
-
- def test_show_host_with_str_body(self):
- self._test_host_data('show')
-
- def test_show_host_with_bytes_body(self):
- self._test_host_data('show', True)
-
- def test_list_host_with_str_body(self):
- self._test_host_data()
-
- def test_list_host_with_bytes_body(self):
- self._test_host_data(bytes_body=True)
-
- def test_start_host_with_str_body(self):
- self._test_control_host('start')
-
- def test_start_host_with_bytes_body(self):
- self._test_control_host('start', True)
-
- def test_stop_host_with_str_body(self):
- self._test_control_host('stop')
-
- def test_stop_host_with_bytes_body(self):
- self._test_control_host('stop', True)
-
- def test_reboot_host_with_str_body(self):
- self._test_control_host('reboot')
-
- def test_reboot_host_with_bytes_body(self):
- self._test_control_host('reboot', True)
-
- def test_update_host_with_str_body(self):
- self._test_update_hosts()
-
- def test_update_host_with_bytes_body(self):
- self._test_update_hosts(True)
diff --git a/tempest/tests/services/compute/test_hypervisor_client.py b/tempest/tests/services/compute/test_hypervisor_client.py
deleted file mode 100644
index 441e7e6..0000000
--- a/tempest/tests/services/compute/test_hypervisor_client.py
+++ /dev/null
@@ -1,167 +0,0 @@
-# Copyright 2015 IBM Corp.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.services.compute.json import hypervisor_client
-from tempest.tests import fake_auth_provider
-from tempest.tests.services.compute import base
-
-
-class TestHypervisorClient(base.BaseComputeServiceTest):
-
- hypervisor_id = "1"
- hypervisor_name = "hyper.hostname.com"
-
- def setUp(self):
- super(TestHypervisorClient, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = hypervisor_client.HypervisorClient(
- fake_auth, 'compute', 'regionOne')
-
- def test_list_hypervisor_str_body(self):
- self._test_list_hypervisor(bytes_body=False)
-
- def test_list_hypervisor_byte_body(self):
- self._test_list_hypervisor(bytes_body=True)
-
- def _test_list_hypervisor(self, bytes_body=False):
- expected = {"hypervisors": [{
- "id": 1,
- "hypervisor_hostname": "hypervisor1.hostname.com"},
- {
- "id": 2,
- "hypervisor_hostname": "hypervisor2.hostname.com"}]}
- self.check_service_client_function(
- self.client.list_hypervisors,
- 'tempest.common.service_client.ServiceClient.get',
- expected, bytes_body)
-
- def test_show_hypervisor_str_body(self):
- self._test_show_hypervisor(bytes_body=False)
-
- def test_show_hypervisor_byte_body(self):
- self._test_show_hypervisor(bytes_body=True)
-
- def _test_show_hypervisor(self, bytes_body=False):
- expected = {"hypervisor": {
- "cpu_info": "?",
- "current_workload": 0,
- "disk_available_least": 1,
- "host_ip": "10.10.10.10",
- "free_disk_gb": 1028,
- "free_ram_mb": 7680,
- "hypervisor_hostname": "fake-mini",
- "hypervisor_type": "fake",
- "hypervisor_version": 1,
- "id": 1,
- "local_gb": 1028,
- "local_gb_used": 0,
- "memory_mb": 8192,
- "memory_mb_used": 512,
- "running_vms": 0,
- "service": {
- "host": "fake_host",
- "id": 2},
- "vcpus": 1,
- "vcpus_used": 0}}
- self.check_service_client_function(
- self.client.show_hypervisor,
- 'tempest.common.service_client.ServiceClient.get',
- expected, bytes_body,
- hypervisor_id=self.hypervisor_id)
-
- def test_list_servers_on_hypervisor_str_body(self):
- self._test_list_servers_on_hypervisor(bytes_body=False)
-
- def test_list_servers_on_hypervisor_byte_body(self):
- self._test_list_servers_on_hypervisor(bytes_body=True)
-
- def _test_list_servers_on_hypervisor(self, bytes_body=False):
- expected = {"hypervisors": [{
- "id": 1,
- "hypervisor_hostname": "hyper.hostname.com",
- "servers": [{
- "uuid": "e1ae8fc4-b72d-4c2f-a427-30dd420b6277",
- "name": "instance-00000001"},
- {
- "uuid": "e1ae8fc4-b72d-4c2f-a427-30dd42066666",
- "name": "instance-00000002"}
- ]}
- ]}
- self.check_service_client_function(
- self.client.list_servers_on_hypervisor,
- 'tempest.common.service_client.ServiceClient.get',
- expected, bytes_body,
- hypervisor_name=self.hypervisor_name)
-
- def test_show_hypervisor_statistics_str_body(self):
- self._test_show_hypervisor_statistics(bytes_body=False)
-
- def test_show_hypervisor_statistics_byte_body(self):
- self._test_show_hypervisor_statistics(bytes_body=True)
-
- def _test_show_hypervisor_statistics(self, bytes_body=False):
- expected = {
- "hypervisor_statistics": {
- "count": 1,
- "current_workload": 0,
- "disk_available_least": 0,
- "free_disk_gb": 1028,
- "free_ram_mb": 7680,
- "local_gb": 1028,
- "local_gb_used": 0,
- "memory_mb": 8192,
- "memory_mb_used": 512,
- "running_vms": 0,
- "vcpus": 1,
- "vcpus_used": 0}}
- self.check_service_client_function(
- self.client.show_hypervisor_statistics,
- 'tempest.common.service_client.ServiceClient.get',
- expected, bytes_body)
-
- def test_show_hypervisor_uptime_str_body(self):
- self._test_show_hypervisor_uptime(bytes_body=False)
-
- def test_show_hypervisor_uptime_byte_body(self):
- self._test_show_hypervisor_uptime(bytes_body=True)
-
- def _test_show_hypervisor_uptime(self, bytes_body=False):
- expected = {
- "hypervisor": {
- "hypervisor_hostname": "fake-mini",
- "id": 1,
- "uptime": (" 08:32:11 up 93 days, 18:25, 12 users, "
- " load average: 0.20, 0.12, 0.14")
- }}
- self.check_service_client_function(
- self.client.show_hypervisor_uptime,
- 'tempest.common.service_client.ServiceClient.get',
- expected, bytes_body,
- hypervisor_id=self.hypervisor_id)
-
- def test_search_hypervisor_str_body(self):
- self._test_search_hypervisor(bytes_body=False)
-
- def test_search_hypervisor_byte_body(self):
- self._test_search_hypervisor(bytes_body=True)
-
- def _test_search_hypervisor(self, bytes_body=False):
- expected = {"hypervisors": [{
- "id": 2,
- "hypervisor_hostname": "hyper.hostname.com"}]}
- self.check_service_client_function(
- self.client.search_hypervisor,
- 'tempest.common.service_client.ServiceClient.get',
- expected, bytes_body,
- hypervisor_name=self.hypervisor_name)