blob: 4624249011d9d6e02a6158cbd32ef961fc570b11 [file] [log] [blame]
scottda61f68ac2016-06-07 12:07:55 -06001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from oslo_log import log as logging
14
Andrea Frittolicd368412017-08-14 21:37:56 +010015from tempest.common import utils
scottda61f68ac2016-06-07 12:07:55 -060016from tempest.common import waiters
17from tempest import config
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -080018from tempest.lib import decorators
scottda61f68ac2016-06-07 12:07:55 -060019from tempest.scenario import manager
scottda61f68ac2016-06-07 12:07:55 -060020
21CONF = config.CONF
22LOG = logging.getLogger(__name__)
23
24
25class TestVolumeMigrateRetypeAttached(manager.ScenarioTest):
26
27 """This test case attempts to reproduce the following steps:
28
29 * Create 2 volume types representing 2 different backends
30 * Create in Cinder some bootable volume importing a Glance image using
31 * volume_type_1
32 * Boot an instance from the bootable volume
33 * Write to the volume
34 * Perform a cinder retype --on-demand of the volume to type of backend #2
35 * Check written content of migrated volume
36 """
37
38 credentials = ['primary', 'admin']
39
40 @classmethod
Mohammed Naser65e4f9b2017-12-29 21:22:24 +000041 def setup_clients(cls):
42 super(TestVolumeMigrateRetypeAttached, cls).setup_clients()
43 cls.admin_volumes_client = cls.os_admin.volumes_v2_client
44
45 @classmethod
scottda61f68ac2016-06-07 12:07:55 -060046 def skip_checks(cls):
47 super(TestVolumeMigrateRetypeAttached, cls).skip_checks()
48 if not CONF.volume_feature_enabled.multi_backend:
49 raise cls.skipException("Cinder multi-backend feature disabled")
50
51 if len(set(CONF.volume.backend_names)) < 2:
52 raise cls.skipException("Requires at least two different "
53 "backend names")
54
55 def _boot_instance_from_volume(self, vol_id, keypair, security_group):
56
57 key_name = keypair['name']
58 security_groups = [{'name': security_group['name']}]
59 block_device_mapping = [{'device_name': 'vda', 'volume_id': vol_id,
60 'delete_on_termination': False}]
61
zhufl13c9c892017-02-10 12:04:07 +080062 return self.create_server(image_id='',
scottda61f68ac2016-06-07 12:07:55 -060063 key_name=key_name,
64 security_groups=security_groups,
65 block_device_mapping=block_device_mapping)
66
67 def _create_volume_types(self):
68 backend_names = CONF.volume.backend_names
69
70 backend_source = backend_names[0]
71 backend_dest = backend_names[1]
72
73 source_body = self.create_volume_type(backend_name=backend_source)
74 dest_body = self.create_volume_type(backend_name=backend_dest)
75
76 LOG.info("Created Volume types: %(src)s -> %(src_backend)s, %(dst)s "
77 "-> %(dst_backend)s", {'src': source_body['name'],
78 'src_backend': backend_source,
79 'dst': dest_body['name'],
80 'dst_backend': backend_dest})
81 return source_body['name'], dest_body['name']
82
83 def _volume_retype_with_migration(self, volume_id, new_volume_type):
Ken'ichi Ohmichid513a7f2018-01-04 12:55:08 -080084 # NOTE: The 'on-demand' migration requires admin operation, so
85 # admin_volumes_client() should be used here.
scottda61f68ac2016-06-07 12:07:55 -060086 migration_policy = 'on-demand'
Mohammed Naser65e4f9b2017-12-29 21:22:24 +000087 self.admin_volumes_client.retype_volume(
scottda61f68ac2016-06-07 12:07:55 -060088 volume_id, new_type=new_volume_type,
89 migration_policy=migration_policy)
90 waiters.wait_for_volume_retype(self.volumes_client,
91 volume_id, new_volume_type)
92
Jordan Pittier3b46d272017-04-12 16:17:28 +020093 @decorators.attr(type='slow')
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -080094 @decorators.idempotent_id('deadd2c2-beef-4dce-98be-f86765ff311b')
Andrea Frittolicd368412017-08-14 21:37:56 +010095 @utils.services('compute', 'volume')
scottda61f68ac2016-06-07 12:07:55 -060096 def test_volume_migrate_attached(self):
97 LOG.info("Creating keypair and security group")
98 keypair = self.create_keypair()
99 security_group = self._create_security_group()
100
101 # create volume types
102 LOG.info("Creating Volume types")
103 source_type, dest_type = self._create_volume_types()
104
105 # create an instance from volume
106 LOG.info("Booting instance from volume")
107 volume_origin = self.create_volume(imageRef=CONF.compute.image_ref,
108 volume_type=source_type)
109
110 instance = self._boot_instance_from_volume(volume_origin['id'],
111 keypair, security_group)
112
113 # write content to volume on instance
114 LOG.info("Setting timestamp in instance %s", instance['id'])
115 ip_instance = self.get_server_ip(instance)
116 timestamp = self.create_timestamp(ip_instance,
Slawek Kaplonski79d8b0f2018-07-30 22:43:41 +0200117 private_key=keypair['private_key'],
118 server=instance)
scottda61f68ac2016-06-07 12:07:55 -0600119
120 # retype volume with migration from backend #1 to backend #2
121 LOG.info("Retyping Volume %s to new type %s", volume_origin['id'],
122 dest_type)
123 self._volume_retype_with_migration(volume_origin['id'], dest_type)
124
125 # check the content of written file
126 LOG.info("Getting timestamp in postmigrated instance %s",
127 instance['id'])
128 timestamp2 = self.get_timestamp(ip_instance,
Slawek Kaplonski79d8b0f2018-07-30 22:43:41 +0200129 private_key=keypair['private_key'],
130 server=instance)
scottda61f68ac2016-06-07 12:07:55 -0600131 self.assertEqual(timestamp, timestamp2)