blob: 297e8a8aa6a4b4a061f43cc5c491d0ec095cecdc [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
Sean Dague1937d092013-05-17 16:36:38 -040016from tempest.api.compute import base
lanoux2746ba02016-03-16 17:41:01 +090017from tempest.common import compute
Masayuki Igawa209fd502014-02-17 14:46:43 +090018from tempest.common.utils.linux import remote_client
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000019from tempest.common import waiters
Sean Dague86bd8422013-12-20 09:56:44 -050020from tempest import config
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -080021from tempest.lib import decorators
Dan Smithc18d8c62012-07-02 08:09:26 -070022
Sean Dague86bd8422013-12-20 09:56:44 -050023CONF = config.CONF
24
Dan Smithc18d8c62012-07-02 08:09:26 -070025
ivan-zhuf2b00502013-10-18 10:06:52 +080026class AttachVolumeTestJSON(base.BaseV2ComputeTest):
lanoux2746ba02016-03-16 17:41:01 +090027 max_microversion = '2.19'
Dan Smithc18d8c62012-07-02 08:09:26 -070028
Attila Fazekas19044d52013-02-16 07:35:06 +010029 @classmethod
Emily Hugenbruch8284a342014-12-11 22:04:55 +000030 def skip_checks(cls):
31 super(AttachVolumeTestJSON, cls).skip_checks()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000032 if not CONF.service_available.cinder:
Matthew Treinish4c412922013-07-16 15:27:42 -040033 skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
34 raise cls.skipException(skip_msg)
Dan Smithc18d8c62012-07-02 08:09:26 -070035
Emily Hugenbruch8284a342014-12-11 22:04:55 +000036 @classmethod
37 def setup_credentials(cls):
38 cls.prepare_instance_network()
39 super(AttachVolumeTestJSON, cls).setup_credentials()
40
41 @classmethod
42 def resource_setup(cls):
43 super(AttachVolumeTestJSON, cls).resource_setup()
44 cls.device = CONF.compute.volume_device_name
45
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020046 def _create_server(self):
Dan Smithc18d8c62012-07-02 08:09:26 -070047 # Start a server and wait for it to become ready
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010048 validation_resources = self.get_test_validation_resources(
49 self.os_primary)
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020050 server = self.create_test_server(
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000051 validatable=True,
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010052 validation_resources=validation_resources,
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000053 wait_until='ACTIVE',
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020054 adminPass=self.image_ssh_password)
Kevin_Zheng7a547df2017-04-27 18:00:13 +080055 self.addCleanup(self.delete_server, server['id'])
Dan Smithc18d8c62012-07-02 08:09:26 -070056 # Record addresses so that we can ssh later
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020057 server['addresses'] = self.servers_client.list_addresses(
58 server['id'])['addresses']
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010059 return server, validation_resources
Dan Smithc18d8c62012-07-02 08:09:26 -070060
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -080061 @decorators.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
Dan Smithc18d8c62012-07-02 08:09:26 -070062 def test_attach_detach_volume(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050063 # Stop and Start a server with an attached volume, ensuring that
64 # the volume remains attached.
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010065 server, validation_resources = self._create_server()
Andrea Frittolicec44942017-03-24 14:44:19 +000066
67 # NOTE(andreaf) Create one remote client used throughout the test.
68 if CONF.validation.run_validation:
69 linux_client = remote_client.RemoteClient(
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010070 self.get_server_ip(server, validation_resources),
Andrea Frittolicec44942017-03-24 14:44:19 +000071 self.image_ssh_user,
72 self.image_ssh_password,
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010073 validation_resources['keypair']['private_key'],
Andrea Frittolicec44942017-03-24 14:44:19 +000074 server=server,
75 servers_client=self.servers_client)
76 # NOTE(andreaf) We need to ensure the ssh key has been
77 # injected in the guest before we power cycle
78 linux_client.validate_authentication()
79
Benny Kopilov5c5f7d82016-09-13 14:19:53 +030080 volume = self.create_volume()
zhufl36f0a972017-02-28 15:43:33 +080081 attachment = self.attach_volume(server, volume,
82 device=('/dev/%s' % self.device))
ivan-zhu2f54b282013-03-11 16:39:25 +080083
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020084 self.servers_client.stop_server(server['id'])
85 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000086 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -070087
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020088 self.servers_client.start_server(server['id'])
89 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000090 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -070091
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +010092 if CONF.validation.run_validation:
Evgeny Antyshev4894a912016-11-21 12:17:18 +000093 disks = linux_client.get_disks()
94 device_name_to_match = '\n' + self.device + ' '
95 self.assertIn(device_name_to_match, disks)
Dan Smithc18d8c62012-07-02 08:09:26 -070096
zhufl36f0a972017-02-28 15:43:33 +080097 self.servers_client.detach_volume(server['id'], attachment['volumeId'])
98 waiters.wait_for_volume_resource_status(
99 self.volumes_client, attachment['volumeId'], 'available')
100
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200101 self.servers_client.stop_server(server['id'])
102 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000103 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -0700104
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200105 self.servers_client.start_server(server['id'])
106 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000107 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700108
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100109 if CONF.validation.run_validation:
Evgeny Antyshev4894a912016-11-21 12:17:18 +0000110 disks = linux_client.get_disks()
111 self.assertNotIn(device_name_to_match, disks)
Dan Smith1ced8422012-08-16 10:35:19 -0700112
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -0800113 @decorators.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
Ghanshyam5c2a5582014-04-14 17:16:57 +0900114 def test_list_get_volume_attachments(self):
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300115 # List volume attachment of the server
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100116 server, _ = self._create_server()
zhufl16dd62c2017-05-03 15:46:16 +0800117 volume_1st = self.create_volume()
118 attachment_1st = self.attach_volume(server, volume_1st,
119 device=('/dev/%s' % self.device))
David Kranz3ebc7212015-02-10 12:19:19 -0500120 body = self.servers_client.list_volume_attachments(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200121 server['id'])['volumeAttachments']
Ghanshyam5c2a5582014-04-14 17:16:57 +0900122 self.assertEqual(1, len(body))
zhufl16dd62c2017-05-03 15:46:16 +0800123 self.assertIn(attachment_1st, body)
Ghanshyam5c2a5582014-04-14 17:16:57 +0900124
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300125 # Get volume attachment of the server
Ken'ichi Ohmichi277d1882015-11-20 00:44:06 +0000126 body = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200127 server['id'],
zhufl16dd62c2017-05-03 15:46:16 +0800128 attachment_1st['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200129 self.assertEqual(server['id'], body['serverId'])
zhufl16dd62c2017-05-03 15:46:16 +0800130 self.assertEqual(volume_1st['id'], body['volumeId'])
131 self.assertEqual(attachment_1st['id'], body['id'])
lanoux2746ba02016-03-16 17:41:01 +0900132
zhufl16dd62c2017-05-03 15:46:16 +0800133 # attach one more volume to server
Ken'ichi Ohmichi09139282016-12-01 14:36:22 -0800134 volume_2nd = self.create_volume()
zhufl36f0a972017-02-28 15:43:33 +0800135 attachment_2nd = self.attach_volume(server, volume_2nd)
Ken'ichi Ohmichi09139282016-12-01 14:36:22 -0800136 body = self.servers_client.list_volume_attachments(
137 server['id'])['volumeAttachments']
138 self.assertEqual(2, len(body))
139
zhufl16dd62c2017-05-03 15:46:16 +0800140 for attachment in [attachment_1st, attachment_2nd]:
141 body = self.servers_client.show_volume_attachment(
142 server['id'], attachment['id'])['volumeAttachment']
143 self.assertEqual(server['id'], body['serverId'])
144 self.assertEqual(attachment['volumeId'], body['volumeId'])
145 self.assertEqual(attachment['id'], body['id'])
Steve Noyes5026c502017-08-10 11:12:31 -0400146 self.servers_client.detach_volume(server['id'],
147 attachment['volumeId'])
148 waiters.wait_for_volume_resource_status(
149 self.volumes_client, attachment['volumeId'], 'available')
Ken'ichi Ohmichi09139282016-12-01 14:36:22 -0800150
lanoux2746ba02016-03-16 17:41:01 +0900151
152class AttachVolumeShelveTestJSON(AttachVolumeTestJSON):
153 """Testing volume with shelved instance.
154
155 This test checks the attaching and detaching volumes from
Tianbiao Qi0d1d24e2016-09-28 14:17:12 +0800156 a shelved or shelved offload instance.
lanoux2746ba02016-03-16 17:41:01 +0900157 """
158
159 min_microversion = '2.20'
160 max_microversion = 'latest'
161
zhufl11289db2017-08-29 10:59:39 +0800162 @classmethod
163 def skip_checks(cls):
164 super(AttachVolumeShelveTestJSON, cls).skip_checks()
165 if not CONF.compute_feature_enabled.shelve:
166 raise cls.skipException('Shelve is not available.')
167
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100168 def _count_volumes(self, server, validation_resources):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200169 # Count number of volumes on an instance
170 volumes = 0
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100171 if CONF.validation.run_validation:
172 linux_client = remote_client.RemoteClient(
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100173 self.get_server_ip(server, validation_resources),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100174 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200175 self.image_ssh_password,
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100176 validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200177 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100178 servers_client=self.servers_client)
lanoux2746ba02016-03-16 17:41:01 +0900179
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200180 command = 'grep -c -E [vs]d.$ /proc/partitions'
181 volumes = int(linux_client.exec_command(command).strip())
182 return volumes
183
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100184 def _shelve_server(self, server, validation_resources):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200185 # NOTE(andreaf) If we are going to shelve a server, we should
186 # check first whether the server is ssh-able. Otherwise we
187 # won't be able to distinguish failures introduced by shelve
188 # from pre-existing ones. Also it's good to wait for cloud-init
189 # to be done and sshd server to be running before shelving to
190 # avoid breaking the VM
191 if CONF.validation.run_validation:
192 linux_client = remote_client.RemoteClient(
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100193 self.get_server_ip(server, validation_resources),
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200194 self.image_ssh_user,
195 self.image_ssh_password,
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100196 validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200197 server=server,
198 servers_client=self.servers_client)
199 linux_client.validate_authentication()
200
201 # If validation went ok, or it was skipped, shelve the server
202 compute.shelve_server(self.servers_client, server['id'])
203
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100204 def _unshelve_server_and_check_volumes(self, server,
205 validation_resources,
206 number_of_volumes):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200207 # Unshelve the instance and check that there are expected volumes
208 self.servers_client.unshelve_server(server['id'])
209 waiters.wait_for_server_status(self.servers_client,
210 server['id'],
211 'ACTIVE')
212 if CONF.validation.run_validation:
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100213 counted_volumes = self._count_volumes(
214 server, validation_resources)
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200215 self.assertEqual(number_of_volumes, counted_volumes)
lanoux2746ba02016-03-16 17:41:01 +0900216
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -0800217 @decorators.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
lanoux2746ba02016-03-16 17:41:01 +0900218 def test_attach_volume_shelved_or_offload_server(self):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200219 # Create server, count number of volumes on it, shelve
220 # server and attach pre-created volume to shelved server
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100221 server, validation_resources = self._create_server()
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300222 volume = self.create_volume()
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100223 num_vol = self._count_volumes(server, validation_resources)
224 self._shelve_server(server, validation_resources)
zhufl36f0a972017-02-28 15:43:33 +0800225 attachment = self.attach_volume(server, volume,
Matt Riedemannb36186b2017-12-04 17:54:08 +0000226 device=('/dev/%s' % self.device))
lanoux2746ba02016-03-16 17:41:01 +0900227
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200228 # Unshelve the instance and check that attached volume exists
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100229 self._unshelve_server_and_check_volumes(
230 server, validation_resources, num_vol + 1)
lanoux2746ba02016-03-16 17:41:01 +0900231
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300232 # Get volume attachment of the server
lanoux2746ba02016-03-16 17:41:01 +0900233 volume_attachment = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200234 server['id'],
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300235 attachment['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200236 self.assertEqual(server['id'], volume_attachment['serverId'])
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300237 self.assertEqual(attachment['id'], volume_attachment['id'])
lanoux2746ba02016-03-16 17:41:01 +0900238 # Check the mountpoint is not None after unshelve server even in
239 # case of shelved_offloaded.
240 self.assertIsNotNone(volume_attachment['device'])
241
Ken'ichi Ohmichi6c92edf2017-01-27 17:32:10 -0800242 @decorators.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
lanoux2746ba02016-03-16 17:41:01 +0900243 def test_detach_volume_shelved_or_offload_server(self):
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300244 # Count number of volumes on instance, shelve
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200245 # server and attach pre-created volume to shelved server
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100246 server, validation_resources = self._create_server()
Benny Kopilov5c5f7d82016-09-13 14:19:53 +0300247 volume = self.create_volume()
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100248 num_vol = self._count_volumes(server, validation_resources)
249 self._shelve_server(server, validation_resources)
zhufl36f0a972017-02-28 15:43:33 +0800250
251 # Attach and then detach the volume
Matt Riedemannb36186b2017-12-04 17:54:08 +0000252 self.attach_volume(server, volume, device=('/dev/%s' % self.device))
zhufl36f0a972017-02-28 15:43:33 +0800253 self.servers_client.detach_volume(server['id'], volume['id'])
254 waiters.wait_for_volume_resource_status(self.volumes_client,
255 volume['id'], 'available')
lanoux2746ba02016-03-16 17:41:01 +0900256
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200257 # Unshelve the instance and check that we have the expected number of
258 # volume(s)
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100259 self._unshelve_server_and_check_volumes(
260 server, validation_resources, num_vol)