Migrate test_volume_boot_pattern to tempest client
Migrate the test and all shared or necessary functions from
OfficialClientTest to ScenarioTest. Create and update as well all
needed functions:
- server api schema
- servers_client
Partially implements: bp:tempest-client-scenarios
Change-Id: Ib9e70b6ce3814031d1b4b8987a24eb0992624204
diff --git a/tempest/api_schema/response/compute/servers.py b/tempest/api_schema/response/compute/servers.py
index d6c2ddb..f9c957b 100644
--- a/tempest/api_schema/response/compute/servers.py
+++ b/tempest/api_schema/response/compute/servers.py
@@ -54,14 +54,15 @@
'id': {'type': 'string'},
'name': {'type': 'string'},
'status': {'type': 'string'},
- 'image': {
- 'type': 'object',
- 'properties': {
- 'id': {'type': 'string'},
- 'links': parameter_types.links
- },
- 'required': ['id', 'links']
- },
+ 'image': {'oneOf': [
+ {'type': 'object',
+ 'properties': {
+ 'id': {'type': 'string'},
+ 'links': parameter_types.links
+ },
+ 'required': ['id', 'links']},
+ {'type': ['string', 'null']}
+ ]},
'flavor': {
'type': 'object',
'properties': {
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 54f0256..d1af4bc 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -87,6 +87,7 @@
cls.security_groups_client = cls.manager.security_groups_client
cls.servers_client = cls.manager.servers_client
cls.volumes_client = cls.manager.volumes_client
+ cls.snapshots_client = cls.manager.snapshots_client
@classmethod
def _get_credentials(cls, get_creds, ctype):
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index bf5d1f6..ec8575a 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from cinderclient import exceptions as cinder_exc
-
from tempest.common.utils import data_utils
from tempest import config
from tempest.openstack.common import log
@@ -23,7 +21,7 @@
LOG = log.getLogger(__name__)
-class TestVolumeBootPattern(manager.OfficialClientTest):
+class TestVolumeBootPattern(manager.ScenarioTest):
"""
This test case attempts to reproduce the following steps:
@@ -54,28 +52,32 @@
# dev_name=id:type:size:delete_on_terminate
# where type needs to be "snap" if the server is booted
# from a snapshot, size instead can be safely left empty
- bd_map = {
- 'vda': vol_id + ':::0'
- }
- security_groups = [self.security_group.name]
+ bd_map = [{
+ 'device_name': 'vda',
+ 'volume_id': vol_id,
+ 'delete_on_termination': '0'}]
+ self.security_group = self._create_security_group_nova()
+ security_groups = [{'name': self.security_group['name']}]
create_kwargs = {
'block_device_mapping': bd_map,
- 'key_name': keypair.name,
+ 'key_name': keypair['name'],
'security_groups': security_groups
}
return self.create_server(image='', create_kwargs=create_kwargs)
def _create_snapshot_from_volume(self, vol_id):
- volume_snapshots = self.volume_client.volume_snapshots
snap_name = data_utils.rand_name('snapshot')
- snap = volume_snapshots.create(volume_id=vol_id,
- force=True,
- display_name=snap_name)
- self.addCleanup_with_wait(self.volume_client.volume_snapshots, snap.id,
- exc_type=cinder_exc.NotFound)
- self.status_timeout(volume_snapshots,
- snap.id,
- 'available')
+ _, snap = self.snapshots_client.create_snapshot(
+ volume_id=vol_id,
+ force=True,
+ display_name=snap_name)
+ self.addCleanup_with_wait(
+ waiter_callable=self.snapshots_client.wait_for_resource_deletion,
+ thing_id=snap['id'], thing_id_param='id',
+ cleanup_callable=self.delete_wrapper,
+ cleanup_args=[self.snapshots_client.delete_snapshot, snap['id']])
+ self.snapshots_client.wait_for_snapshot_status(snap['id'], 'available')
+ self.assertEqual(snap_name, snap['display_name'])
return snap
def _create_volume_from_snapshot(self, snap_id):
@@ -85,27 +87,26 @@
def _stop_instances(self, instances):
# NOTE(gfidente): two loops so we do not wait for the status twice
for i in instances:
- self.compute_client.servers.stop(i)
+ self.servers_client.stop(i['id'])
for i in instances:
- self.status_timeout(self.compute_client.servers,
- i.id,
- 'SHUTOFF')
+ self.servers_client.wait_for_server_status(i['id'], 'SHUTOFF')
def _detach_volumes(self, volumes):
# NOTE(gfidente): two loops so we do not wait for the status twice
for v in volumes:
- self.volume_client.volumes.detach(v)
+ self.volumes_client.detach_volume(v['id'])
for v in volumes:
- self.status_timeout(self.volume_client.volumes,
- v.id,
- 'available')
+ self.volumes_client.wait_for_volume_status(v['id'], 'available')
def _ssh_to_server(self, server, keypair):
if CONF.compute.use_floatingip_for_ssh:
- floating_ip = self.compute_client.floating_ips.create()
- self.addCleanup(self.delete_wrapper, floating_ip)
- server.add_floating_ip(floating_ip)
- ip = floating_ip.ip
+ _, floating_ip = self.floating_ips_client.create_floating_ip()
+ self.addCleanup(self.delete_wrapper,
+ self.floating_ips_client.delete_floating_ip,
+ floating_ip['id'])
+ self.floating_ips_client.associate_floating_ip_to_server(
+ floating_ip['ip'], server['id'])
+ ip = floating_ip['ip']
else:
network_name_for_ssh = CONF.compute.network_for_ssh
ip = server.networks[network_name_for_ssh][0]
@@ -113,10 +114,10 @@
try:
return self.get_remote_client(
ip,
- private_key=keypair.private_key)
+ private_key=keypair['private_key'])
except Exception:
LOG.exception('ssh to server failed')
- self._log_console_output()
+ self._log_console_output(self)
raise
def _get_content(self, ssh_client):
@@ -129,8 +130,8 @@
return self._get_content(ssh_client)
def _delete_server(self, server):
- self.compute_client.servers.delete(server)
- self.delete_timeout(self.compute_client.servers, server.id)
+ self.servers_client.delete_server(server['id'])
+ self.servers_client.wait_for_server_termination(server['id'])
def _check_content_of_written_file(self, ssh_client, expected):
actual = self._get_content(ssh_client)
@@ -143,7 +144,7 @@
# create an instance from volume
volume_origin = self._create_volume_from_image()
- instance_1st = self._boot_instance_from_volume(volume_origin.id,
+ instance_1st = self._boot_instance_from_volume(volume_origin['id'],
keypair)
# write content to volume on instance
@@ -155,7 +156,7 @@
self._delete_server(instance_1st)
# create a 2nd instance from volume
- instance_2nd = self._boot_instance_from_volume(volume_origin.id,
+ instance_2nd = self._boot_instance_from_volume(volume_origin['id'],
keypair)
# check the content of written file
@@ -164,11 +165,11 @@
self._check_content_of_written_file(ssh_client_for_instance_2nd, text)
# snapshot a volume
- snapshot = self._create_snapshot_from_volume(volume_origin.id)
+ snapshot = self._create_snapshot_from_volume(volume_origin['id'])
# create a 3rd instance from snapshot
- volume = self._create_volume_from_snapshot(snapshot.id)
- instance_from_snapshot = self._boot_instance_from_volume(volume.id,
+ volume = self._create_volume_from_snapshot(snapshot['id'])
+ instance_from_snapshot = self._boot_instance_from_volume(volume['id'],
keypair)
# check the content of written file
@@ -186,10 +187,11 @@
bdms = [{'uuid': vol_id, 'source_type': 'volume',
'destination_type': 'volume', 'boot_index': 0,
'delete_on_termination': False}]
- security_groups = [self.security_group.name]
+ self.security_group = self._create_security_group_nova()
+ security_groups = [{'name': self.security_group['name']}]
create_kwargs = {
'block_device_mapping_v2': bdms,
- 'key_name': keypair.name,
+ 'key_name': keypair['name'],
'security_groups': security_groups
}
return self.create_server(image='', create_kwargs=create_kwargs)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index f44be29..88b68d3 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -58,6 +58,7 @@
disk_config: Determines if user or admin controls disk configuration.
return_reservation_id: Enable/Disable the return of reservation id
block_device_mapping: Block device mapping for the server.
+ block_device_mapping_v2: Block device mapping V2 for the server.
"""
post_body = {
'name': name,
@@ -70,7 +71,8 @@
'availability_zone', 'accessIPv4', 'accessIPv6',
'min_count', 'max_count', ('metadata', 'meta'),
('OS-DCF:diskConfig', 'disk_config'),
- 'return_reservation_id', 'block_device_mapping']:
+ 'return_reservation_id', 'block_device_mapping',
+ 'block_device_mapping_v2']:
if isinstance(option, tuple):
post_param = option[0]
key = option[1]
@@ -80,6 +82,7 @@
value = kwargs.get(key)
if value is not None:
post_body[post_param] = value
+
post_body = {'server': post_body}
if 'sched_hints' in kwargs: