blob: 73c7614a594e954280ec440ebabe524d157dd02b [file] [log] [blame]
Matt Riedemannbc8dbd32013-08-02 14:02:12 -07001# Copyright 2013 IBM Corp.
Dan Smithc18d8c62012-07-02 08:09:26 -07002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Anusha Raminenif3eb9472017-01-13 08:54:01 +053016from oslo_log import log as logging
ivan-zhu1feeb382013-01-24 10:14:39 +080017import testtools
Dan Smithc18d8c62012-07-02 08:09:26 -070018
Sean Dague1937d092013-05-17 16:36:38 -040019from tempest.api.compute import base
lanoux2746ba02016-03-16 17:41:01 +090020from tempest.common import compute
Masayuki Igawa209fd502014-02-17 14:46:43 +090021from tempest.common.utils.linux import remote_client
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000022from tempest.common import waiters
Sean Dague86bd8422013-12-20 09:56:44 -050023from tempest import config
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -080024from tempest.lib import decorators
Dan Smithc18d8c62012-07-02 08:09:26 -070025
Sean Dague86bd8422013-12-20 09:56:44 -050026CONF = config.CONF
27
Benny Kopilov5c5f7d82016-09-13 14:19:53 +030028LOG = logging.getLogger(__name__)
29
Dan Smithc18d8c62012-07-02 08:09:26 -070030
ivan-zhuf2b00502013-10-18 10:06:52 +080031class AttachVolumeTestJSON(base.BaseV2ComputeTest):
lanoux2746ba02016-03-16 17:41:01 +090032 max_microversion = '2.19'
Dan Smithc18d8c62012-07-02 08:09:26 -070033
Attila Fazekas19044d52013-02-16 07:35:06 +010034 @classmethod
Emily Hugenbruch8284a342014-12-11 22:04:55 +000035 def skip_checks(cls):
36 super(AttachVolumeTestJSON, cls).skip_checks()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000037 if not CONF.service_available.cinder:
Matthew Treinish4c412922013-07-16 15:27:42 -040038 skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
39 raise cls.skipException(skip_msg)
Dan Smithc18d8c62012-07-02 08:09:26 -070040
Emily Hugenbruch8284a342014-12-11 22:04:55 +000041 @classmethod
42 def setup_credentials(cls):
43 cls.prepare_instance_network()
44 super(AttachVolumeTestJSON, cls).setup_credentials()
45
46 @classmethod
47 def resource_setup(cls):
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000048 cls.set_validation_resources()
Emily Hugenbruch8284a342014-12-11 22:04:55 +000049 super(AttachVolumeTestJSON, cls).resource_setup()
50 cls.device = CONF.compute.volume_device_name
51
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020052 def _create_server(self):
Dan Smithc18d8c62012-07-02 08:09:26 -070053 # Start a server and wait for it to become ready
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020054 server = self.create_test_server(
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000055 validatable=True,
56 wait_until='ACTIVE',
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020057 adminPass=self.image_ssh_password)
Dan Smithc18d8c62012-07-02 08:09:26 -070058 # Record addresses so that we can ssh later
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020059 server['addresses'] = self.servers_client.list_addresses(
60 server['id'])['addresses']
61 return server
Dan Smithc18d8c62012-07-02 08:09:26 -070062
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -080063 @decorators.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
Dan Smithc18d8c62012-07-02 08:09:26 -070064 def test_attach_detach_volume(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050065 # Stop and Start a server with an attached volume, ensuring that
66 # the volume remains attached.
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020067 server = self._create_server()
Benny Kopilov5c5f7d82016-09-13 14:19:53 +030068 volume = self.create_volume()
zhufl36f0a972017-02-28 15:43:33 +080069 attachment = self.attach_volume(server, volume,
70 device=('/dev/%s' % self.device))
ivan-zhu2f54b282013-03-11 16:39:25 +080071
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020072 self.servers_client.stop_server(server['id'])
73 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000074 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -070075
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020076 self.servers_client.start_server(server['id'])
77 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000078 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -070079
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +010080 if CONF.validation.run_validation:
81 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020082 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +010083 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020084 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +010085 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020086 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +010087 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000088
Evgeny Antyshev4894a912016-11-21 12:17:18 +000089 disks = linux_client.get_disks()
90 device_name_to_match = '\n' + self.device + ' '
91 self.assertIn(device_name_to_match, disks)
Dan Smithc18d8c62012-07-02 08:09:26 -070092
zhufl36f0a972017-02-28 15:43:33 +080093 self.servers_client.detach_volume(server['id'], attachment['volumeId'])
94 waiters.wait_for_volume_resource_status(
95 self.volumes_client, attachment['volumeId'], 'available')
96
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020097 self.servers_client.stop_server(server['id'])
98 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000099 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -0700100
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200101 self.servers_client.start_server(server['id'])
102 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000103 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700104
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100105 if CONF.validation.run_validation:
106 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200107 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100108 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200109 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100110 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200111 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100112 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000113
Evgeny Antyshev4894a912016-11-21 12:17:18 +0000114 disks = linux_client.get_disks()
115 self.assertNotIn(device_name_to_match, disks)
Dan Smith1ced8422012-08-16 10:35:19 -0700116
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -0800117 @decorators.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
Ghanshyam5c2a5582014-04-14 17:16:57 +0900118 def test_list_get_volume_attachments(self):
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300119 # List volume attachment of the server
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200120 server = self._create_server()
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300121 volume = self.create_volume()
zhufl36f0a972017-02-28 15:43:33 +0800122 attachment = self.attach_volume(server, volume,
123 device=('/dev/%s' % self.device))
David Kranz3ebc7212015-02-10 12:19:19 -0500124 body = self.servers_client.list_volume_attachments(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200125 server['id'])['volumeAttachments']
Ghanshyam5c2a5582014-04-14 17:16:57 +0900126 self.assertEqual(1, len(body))
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300127 self.assertIn(attachment, body)
Ghanshyam5c2a5582014-04-14 17:16:57 +0900128
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300129 # Get volume attachment of the server
Ken'ichi Ohmichi277d1882015-11-20 00:44:06 +0000130 body = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200131 server['id'],
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300132 attachment['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200133 self.assertEqual(server['id'], body['serverId'])
Anna Babich506efe22016-09-08 18:14:22 +0300134 self.assertEqual(volume['id'], body['volumeId'])
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300135 self.assertEqual(attachment['id'], body['id'])
lanoux2746ba02016-03-16 17:41:01 +0900136
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -0800137 @decorators.idempotent_id('757d488b-a951-4bc7-b3cd-f417028da08a')
Ken'ichi Ohmichi09139282016-12-01 14:36:22 -0800138 def test_list_get_two_volume_attachments(self):
139 # NOTE: This test is using the volume device auto-assignment
140 # without specifying the device ("/dev/sdb", etc). The feature
141 # is supported since Nova Liberty release or later. So this should
142 # be skipped on older clouds.
143 server = self._create_server()
144 volume_1st = self.create_volume()
145 volume_2nd = self.create_volume()
zhufl36f0a972017-02-28 15:43:33 +0800146 attachment_1st = self.attach_volume(server, volume_1st)
147 attachment_2nd = self.attach_volume(server, volume_2nd)
Ken'ichi Ohmichi09139282016-12-01 14:36:22 -0800148
149 body = self.servers_client.list_volume_attachments(
150 server['id'])['volumeAttachments']
151 self.assertEqual(2, len(body))
152
153 body = self.servers_client.show_volume_attachment(
154 server['id'],
155 attachment_1st['id'])['volumeAttachment']
156 self.assertEqual(server['id'], body['serverId'])
157 self.assertEqual(attachment_1st['volumeId'], body['volumeId'])
158 self.assertEqual(attachment_1st['id'], body['id'])
159
160 body = self.servers_client.show_volume_attachment(
161 server['id'],
162 attachment_2nd['id'])['volumeAttachment']
163 self.assertEqual(server['id'], body['serverId'])
164 self.assertEqual(attachment_2nd['volumeId'], body['volumeId'])
165 self.assertEqual(attachment_2nd['id'], body['id'])
166
lanoux2746ba02016-03-16 17:41:01 +0900167
168class AttachVolumeShelveTestJSON(AttachVolumeTestJSON):
169 """Testing volume with shelved instance.
170
171 This test checks the attaching and detaching volumes from
Tianbiao Qi0d1d24e2016-09-28 14:17:12 +0800172 a shelved or shelved offload instance.
lanoux2746ba02016-03-16 17:41:01 +0900173 """
174
175 min_microversion = '2.20'
176 max_microversion = 'latest'
177
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200178 def _count_volumes(self, server):
179 # Count number of volumes on an instance
180 volumes = 0
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100181 if CONF.validation.run_validation:
182 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200183 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100184 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200185 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100186 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200187 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100188 servers_client=self.servers_client)
lanoux2746ba02016-03-16 17:41:01 +0900189
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200190 command = 'grep -c -E [vs]d.$ /proc/partitions'
191 volumes = int(linux_client.exec_command(command).strip())
192 return volumes
193
194 def _shelve_server(self, server):
195 # NOTE(andreaf) If we are going to shelve a server, we should
196 # check first whether the server is ssh-able. Otherwise we
197 # won't be able to distinguish failures introduced by shelve
198 # from pre-existing ones. Also it's good to wait for cloud-init
199 # to be done and sshd server to be running before shelving to
200 # avoid breaking the VM
201 if CONF.validation.run_validation:
202 linux_client = remote_client.RemoteClient(
203 self.get_server_ip(server),
204 self.image_ssh_user,
205 self.image_ssh_password,
206 self.validation_resources['keypair']['private_key'],
207 server=server,
208 servers_client=self.servers_client)
209 linux_client.validate_authentication()
210
211 # If validation went ok, or it was skipped, shelve the server
212 compute.shelve_server(self.servers_client, server['id'])
213
214 def _unshelve_server_and_check_volumes(self, server, number_of_volumes):
215 # Unshelve the instance and check that there are expected volumes
216 self.servers_client.unshelve_server(server['id'])
217 waiters.wait_for_server_status(self.servers_client,
218 server['id'],
219 'ACTIVE')
220 if CONF.validation.run_validation:
221 counted_volumes = self._count_volumes(server)
222 self.assertEqual(number_of_volumes, counted_volumes)
lanoux2746ba02016-03-16 17:41:01 +0900223
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -0800224 @decorators.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
lanoux2746ba02016-03-16 17:41:01 +0900225 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
226 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900227 def test_attach_volume_shelved_or_offload_server(self):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200228 # Create server, count number of volumes on it, shelve
229 # server and attach pre-created volume to shelved server
230 server = self._create_server()
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300231 volume = self.create_volume()
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200232 num_vol = self._count_volumes(server)
233 self._shelve_server(server)
zhufl36f0a972017-02-28 15:43:33 +0800234 attachment = self.attach_volume(server, volume,
235 device=('/dev/%s' % self.device))
lanoux2746ba02016-03-16 17:41:01 +0900236
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200237 # Unshelve the instance and check that attached volume exists
238 self._unshelve_server_and_check_volumes(server, num_vol + 1)
lanoux2746ba02016-03-16 17:41:01 +0900239
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300240 # Get volume attachment of the server
lanoux2746ba02016-03-16 17:41:01 +0900241 volume_attachment = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200242 server['id'],
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300243 attachment['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200244 self.assertEqual(server['id'], volume_attachment['serverId'])
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300245 self.assertEqual(attachment['id'], volume_attachment['id'])
lanoux2746ba02016-03-16 17:41:01 +0900246 # Check the mountpoint is not None after unshelve server even in
247 # case of shelved_offloaded.
248 self.assertIsNotNone(volume_attachment['device'])
249
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -0800250 @decorators.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
lanoux2746ba02016-03-16 17:41:01 +0900251 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
252 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900253 def test_detach_volume_shelved_or_offload_server(self):
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300254 # Count number of volumes on instance, shelve
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200255 # server and attach pre-created volume to shelved server
256 server = self._create_server()
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300257 volume = self.create_volume()
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200258 num_vol = self._count_volumes(server)
259 self._shelve_server(server)
zhufl36f0a972017-02-28 15:43:33 +0800260
261 # Attach and then detach the volume
262 self.attach_volume(server, volume, device=('/dev/%s' % self.device))
263 self.servers_client.detach_volume(server['id'], volume['id'])
264 waiters.wait_for_volume_resource_status(self.volumes_client,
265 volume['id'], 'available')
lanoux2746ba02016-03-16 17:41:01 +0900266
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200267 # Unshelve the instance and check that we have the expected number of
268 # volume(s)
269 self._unshelve_server_and_check_volumes(server, num_vol)