blob: 065e1836503e7ee6c573f1e35ea5bc497ff1a683 [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
Masayuki Igawa209fd502014-02-17 14:46:43 +090020from tempest.common.utils.linux import remote_client
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000021from tempest.common import waiters
Sean Dague86bd8422013-12-20 09:56:44 -050022from tempest import config
Masayuki Igawa209fd502014-02-17 14:46:43 +090023from tempest import test
Dan Smithc18d8c62012-07-02 08:09:26 -070024
Sean Dague86bd8422013-12-20 09:56:44 -050025CONF = config.CONF
26
Dan Smithc18d8c62012-07-02 08:09:26 -070027
ivan-zhuf2b00502013-10-18 10:06:52 +080028class AttachVolumeTestJSON(base.BaseV2ComputeTest):
lanoux2746ba02016-03-16 17:41:01 +090029 max_microversion = '2.19'
Dan Smithc18d8c62012-07-02 08:09:26 -070030
ivan-zhu2f54b282013-03-11 16:39:25 +080031 def __init__(self, *args, **kwargs):
32 super(AttachVolumeTestJSON, self).__init__(*args, **kwargs)
Ghanshyam5c2a5582014-04-14 17:16:57 +090033 self.attachment = None
ivan-zhu2f54b282013-03-11 16:39:25 +080034
Attila Fazekas19044d52013-02-16 07:35:06 +010035 @classmethod
Emily Hugenbruch8284a342014-12-11 22:04:55 +000036 def skip_checks(cls):
37 super(AttachVolumeTestJSON, cls).skip_checks()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000038 if not CONF.service_available.cinder:
Matthew Treinish4c412922013-07-16 15:27:42 -040039 skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
40 raise cls.skipException(skip_msg)
Dan Smithc18d8c62012-07-02 08:09:26 -070041
Emily Hugenbruch8284a342014-12-11 22:04:55 +000042 @classmethod
43 def setup_credentials(cls):
44 cls.prepare_instance_network()
45 super(AttachVolumeTestJSON, cls).setup_credentials()
46
47 @classmethod
48 def resource_setup(cls):
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000049 cls.set_validation_resources()
50
Emily Hugenbruch8284a342014-12-11 22:04:55 +000051 super(AttachVolumeTestJSON, cls).resource_setup()
52 cls.device = CONF.compute.volume_device_name
53
Dan Smithc18d8c62012-07-02 08:09:26 -070054 def _detach(self, server_id, volume_id):
Ghanshyam5c2a5582014-04-14 17:16:57 +090055 if self.attachment:
Matt Riedemannbc8dbd32013-08-02 14:02:12 -070056 self.servers_client.detach_volume(server_id, volume_id)
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050057 waiters.wait_for_volume_status(self.volumes_client,
58 volume_id, 'available')
Dan Smithc18d8c62012-07-02 08:09:26 -070059
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020060 def _create_server(self):
Dan Smithc18d8c62012-07-02 08:09:26 -070061 # Start a server and wait for it to become ready
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020062 server = self.create_test_server(
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000063 validatable=True,
64 wait_until='ACTIVE',
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020065 adminPass=self.image_ssh_password)
Dan Smithc18d8c62012-07-02 08:09:26 -070066
67 # Record addresses so that we can ssh later
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020068 server['addresses'] = self.servers_client.list_addresses(
69 server['id'])['addresses']
70 return server
Dan Smithc18d8c62012-07-02 08:09:26 -070071
Ken'ichi Ohmichi2b74f102016-11-22 17:18:36 -080072 def _create_and_attach_volume(self, server, device=None):
Dan Smithc18d8c62012-07-02 08:09:26 -070073 # Create a volume and wait for it to become ready
zhufl49134ed2016-10-17 14:41:35 +080074 volume = self.create_volume()
Anna Babich506efe22016-09-08 18:14:22 +030075 self.addCleanup(self.delete_volume, volume['id'])
Dan Smithc18d8c62012-07-02 08:09:26 -070076
77 # Attach the volume to the server
Ken'ichi Ohmichi2b74f102016-11-22 17:18:36 -080078 kwargs = {'volumeId': volume['id']}
79 if device:
80 kwargs.update({'device': '/dev/%s' % device})
David Kranz3ebc7212015-02-10 12:19:19 -050081 self.attachment = self.servers_client.attach_volume(
Ken'ichi Ohmichi2b74f102016-11-22 17:18:36 -080082 server['id'], **kwargs)['volumeAttachment']
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050083 waiters.wait_for_volume_status(self.volumes_client,
Anna Babich506efe22016-09-08 18:14:22 +030084 volume['id'], 'in-use')
Dan Smithc18d8c62012-07-02 08:09:26 -070085
Anna Babich506efe22016-09-08 18:14:22 +030086 self.addCleanup(self._detach, server['id'], volume['id'])
87 return volume
Dan Smithc18d8c62012-07-02 08:09:26 -070088
Chris Hoge7579c1a2015-02-26 14:12:15 -080089 @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
Dan Smithc18d8c62012-07-02 08:09:26 -070090 def test_attach_detach_volume(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050091 # Stop and Start a server with an attached volume, ensuring that
92 # the volume remains attached.
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020093 server = self._create_server()
Ken'ichi Ohmichi2b74f102016-11-22 17:18:36 -080094 volume = self._create_and_attach_volume(server, device=self.device)
ivan-zhu2f54b282013-03-11 16:39:25 +080095
Fabian Zimmermannbbef2762016-06-23 14:05:33 +020096 self.servers_client.stop_server(server['id'])
97 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000098 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -070099
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200100 self.servers_client.start_server(server['id'])
101 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000102 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700103
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100104 if CONF.validation.run_validation:
105 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200106 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100107 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200108 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100109 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200110 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100111 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000112
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100113 partitions = linux_client.get_partitions()
Emily Hugenbruchfe757e32016-09-02 15:10:52 -0400114 device_name_to_match = ' ' + self.device + '\n'
115 self.assertIn(device_name_to_match, partitions)
Dan Smithc18d8c62012-07-02 08:09:26 -0700116
Anna Babich506efe22016-09-08 18:14:22 +0300117 self._detach(server['id'], volume['id'])
Ghanshyam5c2a5582014-04-14 17:16:57 +0900118 self.attachment = None
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200119 self.servers_client.stop_server(server['id'])
120 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000121 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -0700122
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200123 self.servers_client.start_server(server['id'])
124 waiters.wait_for_server_status(self.servers_client, server['id'],
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000125 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700126
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100127 if CONF.validation.run_validation:
128 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200129 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100130 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200131 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100132 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200133 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100134 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000135
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100136 partitions = linux_client.get_partitions()
Emily Hugenbruchfe757e32016-09-02 15:10:52 -0400137 self.assertNotIn(device_name_to_match, partitions)
Dan Smith1ced8422012-08-16 10:35:19 -0700138
Chris Hoge7579c1a2015-02-26 14:12:15 -0800139 @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
Ghanshyam5c2a5582014-04-14 17:16:57 +0900140 def test_list_get_volume_attachments(self):
141 # Create Server, Volume and attach that Volume to Server
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200142 server = self._create_server()
Ken'ichi Ohmichi2b74f102016-11-22 17:18:36 -0800143 volume = self._create_and_attach_volume(server, device=self.device)
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200144
Ghanshyam5c2a5582014-04-14 17:16:57 +0900145 # List Volume attachment of the server
David Kranz3ebc7212015-02-10 12:19:19 -0500146 body = self.servers_client.list_volume_attachments(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200147 server['id'])['volumeAttachments']
Ghanshyam5c2a5582014-04-14 17:16:57 +0900148 self.assertEqual(1, len(body))
149 self.assertIn(self.attachment, body)
150
151 # Get Volume attachment of the server
Ken'ichi Ohmichi277d1882015-11-20 00:44:06 +0000152 body = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200153 server['id'],
ghanshyam0f825252015-08-25 16:02:50 +0900154 self.attachment['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200155 self.assertEqual(server['id'], body['serverId'])
Anna Babich506efe22016-09-08 18:14:22 +0300156 self.assertEqual(volume['id'], body['volumeId'])
Ghanshyam5c2a5582014-04-14 17:16:57 +0900157 self.assertEqual(self.attachment['id'], body['id'])
lanoux2746ba02016-03-16 17:41:01 +0900158
159
160class AttachVolumeShelveTestJSON(AttachVolumeTestJSON):
161 """Testing volume with shelved instance.
162
163 This test checks the attaching and detaching volumes from
Tianbiao Qi0d1d24e2016-09-28 14:17:12 +0800164 a shelved or shelved offload instance.
lanoux2746ba02016-03-16 17:41:01 +0900165 """
166
167 min_microversion = '2.20'
168 max_microversion = 'latest'
169
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200170 def _count_volumes(self, server):
171 # Count number of volumes on an instance
172 volumes = 0
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100173 if CONF.validation.run_validation:
174 linux_client = remote_client.RemoteClient(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200175 self.get_server_ip(server),
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100176 self.image_ssh_user,
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200177 self.image_ssh_password,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100178 self.validation_resources['keypair']['private_key'],
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200179 server=server,
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100180 servers_client=self.servers_client)
lanoux2746ba02016-03-16 17:41:01 +0900181
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200182 command = 'grep -c -E [vs]d.$ /proc/partitions'
183 volumes = int(linux_client.exec_command(command).strip())
184 return volumes
185
186 def _shelve_server(self, server):
187 # NOTE(andreaf) If we are going to shelve a server, we should
188 # check first whether the server is ssh-able. Otherwise we
189 # won't be able to distinguish failures introduced by shelve
190 # from pre-existing ones. Also it's good to wait for cloud-init
191 # to be done and sshd server to be running before shelving to
192 # avoid breaking the VM
193 if CONF.validation.run_validation:
194 linux_client = remote_client.RemoteClient(
195 self.get_server_ip(server),
196 self.image_ssh_user,
197 self.image_ssh_password,
198 self.validation_resources['keypair']['private_key'],
199 server=server,
200 servers_client=self.servers_client)
201 linux_client.validate_authentication()
202
203 # If validation went ok, or it was skipped, shelve the server
204 compute.shelve_server(self.servers_client, server['id'])
205
206 def _unshelve_server_and_check_volumes(self, server, number_of_volumes):
207 # 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:
213 counted_volumes = self._count_volumes(server)
214 self.assertEqual(number_of_volumes, counted_volumes)
lanoux2746ba02016-03-16 17:41:01 +0900215
216 @test.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
217 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
218 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900219 def test_attach_volume_shelved_or_offload_server(self):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200220 # Create server, count number of volumes on it, shelve
221 # server and attach pre-created volume to shelved server
222 server = self._create_server()
223 num_vol = self._count_volumes(server)
224 self._shelve_server(server)
Ken'ichi Ohmichi2b74f102016-11-22 17:18:36 -0800225 self._create_and_attach_volume(server, device=self.device)
lanoux2746ba02016-03-16 17:41:01 +0900226
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200227 # Unshelve the instance and check that attached volume exists
228 self._unshelve_server_and_check_volumes(server, num_vol + 1)
lanoux2746ba02016-03-16 17:41:01 +0900229
230 # Get Volume attachment of the server
231 volume_attachment = self.servers_client.show_volume_attachment(
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200232 server['id'],
lanoux2746ba02016-03-16 17:41:01 +0900233 self.attachment['id'])['volumeAttachment']
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200234 self.assertEqual(server['id'], volume_attachment['serverId'])
lanoux2746ba02016-03-16 17:41:01 +0900235 self.assertEqual(self.attachment['id'], volume_attachment['id'])
236 # Check the mountpoint is not None after unshelve server even in
237 # case of shelved_offloaded.
238 self.assertIsNotNone(volume_attachment['device'])
239
240 @test.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
241 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
242 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900243 def test_detach_volume_shelved_or_offload_server(self):
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200244 # Create server, count number of volumes on it, shelve
245 # server and attach pre-created volume to shelved server
246 server = self._create_server()
247 num_vol = self._count_volumes(server)
248 self._shelve_server(server)
Ken'ichi Ohmichi2b74f102016-11-22 17:18:36 -0800249 volume = self._create_and_attach_volume(server, device=self.device)
lanoux2746ba02016-03-16 17:41:01 +0900250
251 # Detach the volume
Anna Babich506efe22016-09-08 18:14:22 +0300252 self._detach(server['id'], volume['id'])
lanoux2746ba02016-03-16 17:41:01 +0900253 self.attachment = None
254
Fabian Zimmermannbbef2762016-06-23 14:05:33 +0200255 # Unshelve the instance and check that we have the expected number of
256 # volume(s)
257 self._unshelve_server_and_check_volumes(server, num_vol)