blob: da7085fbc2fde379e1210ce7369925a9e07dab31 [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
ivan-zhu1feeb382013-01-24 10:14:39 +080016import testtools
Dan Smithc18d8c62012-07-02 08:09:26 -070017
Sean Dague1937d092013-05-17 16:36:38 -040018from tempest.api.compute import base
lanoux2746ba02016-03-16 17:41:01 +090019from tempest.common import compute
Anna Babich68f261d2016-09-13 11:32:13 +030020from tempest.common.utils import data_utils
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
Masayuki Igawa209fd502014-02-17 14:46:43 +090024from tempest import test
Dan Smithc18d8c62012-07-02 08:09:26 -070025
Sean Dague86bd8422013-12-20 09:56:44 -050026CONF = config.CONF
27
Dan Smithc18d8c62012-07-02 08:09:26 -070028
ivan-zhuf2b00502013-10-18 10:06:52 +080029class AttachVolumeTestJSON(base.BaseV2ComputeTest):
lanoux2746ba02016-03-16 17:41:01 +090030 max_microversion = '2.19'
Dan Smithc18d8c62012-07-02 08:09:26 -070031
ivan-zhu2f54b282013-03-11 16:39:25 +080032 def __init__(self, *args, **kwargs):
33 super(AttachVolumeTestJSON, self).__init__(*args, **kwargs)
Ghanshyam5c2a5582014-04-14 17:16:57 +090034 self.attachment = None
ivan-zhu2f54b282013-03-11 16:39:25 +080035
Attila Fazekas19044d52013-02-16 07:35:06 +010036 @classmethod
Emily Hugenbruch8284a342014-12-11 22:04:55 +000037 def skip_checks(cls):
38 super(AttachVolumeTestJSON, cls).skip_checks()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000039 if not CONF.service_available.cinder:
Matthew Treinish4c412922013-07-16 15:27:42 -040040 skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
41 raise cls.skipException(skip_msg)
Dan Smithc18d8c62012-07-02 08:09:26 -070042
Emily Hugenbruch8284a342014-12-11 22:04:55 +000043 @classmethod
44 def setup_credentials(cls):
45 cls.prepare_instance_network()
46 super(AttachVolumeTestJSON, cls).setup_credentials()
47
48 @classmethod
49 def resource_setup(cls):
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000050 cls.set_validation_resources()
51
Emily Hugenbruch8284a342014-12-11 22:04:55 +000052 super(AttachVolumeTestJSON, cls).resource_setup()
53 cls.device = CONF.compute.volume_device_name
54
Dan Smithc18d8c62012-07-02 08:09:26 -070055 def _detach(self, server_id, volume_id):
Ghanshyam5c2a5582014-04-14 17:16:57 +090056 if self.attachment:
Matt Riedemannbc8dbd32013-08-02 14:02:12 -070057 self.servers_client.detach_volume(server_id, volume_id)
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050058 waiters.wait_for_volume_status(self.volumes_client,
59 volume_id, 'available')
Dan Smithc18d8c62012-07-02 08:09:26 -070060
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020061 def _create_server(self):
Dan Smithc18d8c62012-07-02 08:09:26 -070062 # Start a server and wait for it to become ready
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020063 server = self.create_test_server(
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000064 validatable=True,
65 wait_until='ACTIVE',
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020066 adminPass=self.image_ssh_password)
Dan Smithc18d8c62012-07-02 08:09:26 -070067
68 # Record addresses so that we can ssh later
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020069 server['addresses'] = self.servers_client.list_addresses(
70 server['id'])['addresses']
71 return server
Dan Smithc18d8c62012-07-02 08:09:26 -070072
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020073 def _create_and_attach_volume(self, server):
Dan Smithc18d8c62012-07-02 08:09:26 -070074 # Create a volume and wait for it to become ready
Anna Babich68f261d2016-09-13 11:32:13 +030075 vol_name = data_utils.rand_name(self.__class__.__name__ + '-volume')
Anna Babich506efe22016-09-08 18:14:22 +030076 volume = self.volumes_client.create_volume(
Anna Babich68f261d2016-09-13 11:32:13 +030077 size=CONF.volume.volume_size, display_name=vol_name)['volume']
Anna Babich506efe22016-09-08 18:14:22 +030078 self.addCleanup(self.delete_volume, volume['id'])
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050079 waiters.wait_for_volume_status(self.volumes_client,
Anna Babich506efe22016-09-08 18:14:22 +030080 volume['id'], 'available')
Dan Smithc18d8c62012-07-02 08:09:26 -070081
82 # Attach the volume to the server
David Kranz3ebc7212015-02-10 12:19:19 -050083 self.attachment = self.servers_client.attach_volume(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020084 server['id'],
Anna Babich506efe22016-09-08 18:14:22 +030085 volumeId=volume['id'],
ghanshyam0f825252015-08-25 16:02:50 +090086 device='/dev/%s' % self.device)['volumeAttachment']
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050087 waiters.wait_for_volume_status(self.volumes_client,
Anna Babich506efe22016-09-08 18:14:22 +030088 volume['id'], 'in-use')
Dan Smithc18d8c62012-07-02 08:09:26 -070089
Anna Babich506efe22016-09-08 18:14:22 +030090 self.addCleanup(self._detach, server['id'], volume['id'])
91 return volume
Dan Smithc18d8c62012-07-02 08:09:26 -070092
Chris Hoge7579c1a2015-02-26 14:12:15 -080093 @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
Dan Smithc18d8c62012-07-02 08:09:26 -070094 def test_attach_detach_volume(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050095 # Stop and Start a server with an attached volume, ensuring that
96 # the volume remains attached.
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020097 server = self._create_server()
Anna Babich506efe22016-09-08 18:14:22 +030098 volume = self._create_and_attach_volume(server)
ivan-zhu2f54b282013-03-11 16:39:25 +080099
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200100 self.servers_client.stop_server(server['id'])
101 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000102 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -0700103
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200104 self.servers_client.start_server(server['id'])
105 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000106 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700107
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100108 if CONF.validation.run_validation:
109 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200110 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100111 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200112 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100113 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200114 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100115 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000116
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100117 partitions = linux_client.get_partitions()
Emily Hugenbruchfe757e32016-09-02 15:10:52 -0400118 device_name_to_match = ' ' + self.device + '\n'
119 self.assertIn(device_name_to_match, partitions)
Dan Smithc18d8c62012-07-02 08:09:26 -0700120
Anna Babich506efe22016-09-08 18:14:22 +0300121 self._detach(server['id'], volume['id'])
Ghanshyam5c2a5582014-04-14 17:16:57 +0900122 self.attachment = None
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200123 self.servers_client.stop_server(server['id'])
124 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000125 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -0700126
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200127 self.servers_client.start_server(server['id'])
128 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000129 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700130
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100131 if CONF.validation.run_validation:
132 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200133 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100134 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200135 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100136 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200137 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100138 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000139
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100140 partitions = linux_client.get_partitions()
Emily Hugenbruchfe757e32016-09-02 15:10:52 -0400141 self.assertNotIn(device_name_to_match, partitions)
Dan Smith1ced8422012-08-16 10:35:19 -0700142
Chris Hoge7579c1a2015-02-26 14:12:15 -0800143 @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
Ghanshyam5c2a5582014-04-14 17:16:57 +0900144 def test_list_get_volume_attachments(self):
145 # Create Server, Volume and attach that Volume to Server
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200146 server = self._create_server()
Anna Babich506efe22016-09-08 18:14:22 +0300147 volume = self._create_and_attach_volume(server)
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200148
Ghanshyam5c2a5582014-04-14 17:16:57 +0900149 # List Volume attachment of the server
David Kranz3ebc7212015-02-10 12:19:19 -0500150 body = self.servers_client.list_volume_attachments(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200151 server['id'])['volumeAttachments']
Ghanshyam5c2a5582014-04-14 17:16:57 +0900152 self.assertEqual(1, len(body))
153 self.assertIn(self.attachment, body)
154
155 # Get Volume attachment of the server
Ken'ichi Ohmichi277d1882015-11-20 00:44:06 +0000156 body = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200157 server['id'],
ghanshyam0f825252015-08-25 16:02:50 +0900158 self.attachment['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200159 self.assertEqual(server['id'], body['serverId'])
Anna Babich506efe22016-09-08 18:14:22 +0300160 self.assertEqual(volume['id'], body['volumeId'])
Ghanshyam5c2a5582014-04-14 17:16:57 +0900161 self.assertEqual(self.attachment['id'], body['id'])
lanoux2746ba02016-03-16 17:41:01 +0900162
163
164class AttachVolumeShelveTestJSON(AttachVolumeTestJSON):
165 """Testing volume with shelved instance.
166
167 This test checks the attaching and detaching volumes from
168 a shelved or shelved ofload instance.
169 """
170
171 min_microversion = '2.20'
172 max_microversion = 'latest'
173
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200174 def _count_volumes(self, server):
175 # Count number of volumes on an instance
176 volumes = 0
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100177 if CONF.validation.run_validation:
178 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200179 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100180 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200181 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100182 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200183 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100184 servers_client=self.servers_client)
lanoux2746ba02016-03-16 17:41:01 +0900185
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200186 command = 'grep -c -E [vs]d.$ /proc/partitions'
187 volumes = int(linux_client.exec_command(command).strip())
188 return volumes
189
190 def _shelve_server(self, server):
191 # NOTE(andreaf) If we are going to shelve a server, we should
192 # check first whether the server is ssh-able. Otherwise we
193 # won't be able to distinguish failures introduced by shelve
194 # from pre-existing ones. Also it's good to wait for cloud-init
195 # to be done and sshd server to be running before shelving to
196 # avoid breaking the VM
197 if CONF.validation.run_validation:
198 linux_client = remote_client.RemoteClient(
199 self.get_server_ip(server),
200 self.image_ssh_user,
201 self.image_ssh_password,
202 self.validation_resources['keypair']['private_key'],
203 server=server,
204 servers_client=self.servers_client)
205 linux_client.validate_authentication()
206
207 # If validation went ok, or it was skipped, shelve the server
208 compute.shelve_server(self.servers_client, server['id'])
209
210 def _unshelve_server_and_check_volumes(self, server, number_of_volumes):
211 # Unshelve the instance and check that there are expected volumes
212 self.servers_client.unshelve_server(server['id'])
213 waiters.wait_for_server_status(self.servers_client,
214 server['id'],
215 'ACTIVE')
216 if CONF.validation.run_validation:
217 counted_volumes = self._count_volumes(server)
218 self.assertEqual(number_of_volumes, counted_volumes)
lanoux2746ba02016-03-16 17:41:01 +0900219
220 @test.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
221 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
222 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900223 def test_attach_volume_shelved_or_offload_server(self):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200224 # Create server, count number of volumes on it, shelve
225 # server and attach pre-created volume to shelved server
226 server = self._create_server()
227 num_vol = self._count_volumes(server)
228 self._shelve_server(server)
229 self._create_and_attach_volume(server)
lanoux2746ba02016-03-16 17:41:01 +0900230
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200231 # Unshelve the instance and check that attached volume exists
232 self._unshelve_server_and_check_volumes(server, num_vol + 1)
lanoux2746ba02016-03-16 17:41:01 +0900233
234 # Get Volume attachment of the server
235 volume_attachment = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200236 server['id'],
lanoux2746ba02016-03-16 17:41:01 +0900237 self.attachment['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200238 self.assertEqual(server['id'], volume_attachment['serverId'])
lanoux2746ba02016-03-16 17:41:01 +0900239 self.assertEqual(self.attachment['id'], volume_attachment['id'])
240 # Check the mountpoint is not None after unshelve server even in
241 # case of shelved_offloaded.
242 self.assertIsNotNone(volume_attachment['device'])
243
244 @test.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
245 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
246 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900247 def test_detach_volume_shelved_or_offload_server(self):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200248 # Create server, count number of volumes on it, shelve
249 # server and attach pre-created volume to shelved server
250 server = self._create_server()
251 num_vol = self._count_volumes(server)
252 self._shelve_server(server)
Anna Babich506efe22016-09-08 18:14:22 +0300253 volume = self._create_and_attach_volume(server)
lanoux2746ba02016-03-16 17:41:01 +0900254
255 # Detach the volume
Anna Babich506efe22016-09-08 18:14:22 +0300256 self._detach(server['id'], volume['id'])
lanoux2746ba02016-03-16 17:41:01 +0900257 self.attachment = None
258
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200259 # Unshelve the instance and check that we have the expected number of
260 # volume(s)
261 self._unshelve_server_and_check_volumes(server, num_vol)