blob: a5c303cd4f70821c9762e7368420b664f896bd94 [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
Matt Riedemannbc8dbd32013-08-02 14:02:12 -070060 def _delete_volume(self):
Ghanshyam5c2a5582014-04-14 17:16:57 +090061 # Delete the created Volumes
ivan-zhu2f54b282013-03-11 16:39:25 +080062 if self.volume:
63 self.volumes_client.delete_volume(self.volume['id'])
Ghanshyam5c2a5582014-04-14 17:16:57 +090064 self.volumes_client.wait_for_resource_deletion(self.volume['id'])
ivan-zhu2f54b282013-03-11 16:39:25 +080065 self.volume = None
Dan Smithc18d8c62012-07-02 08:09:26 -070066
lanoux2746ba02016-03-16 17:41:01 +090067 def _create_and_attach(self, shelve_server=False):
Dan Smithc18d8c62012-07-02 08:09:26 -070068 # Start a server and wait for it to become ready
Ghanshyam3390d9f2015-12-25 12:48:02 +090069 self.admin_pass = self.image_ssh_password
Joseph Lanouxffe09dd2015-03-18 16:45:33 +000070 self.server = self.create_test_server(
71 validatable=True,
72 wait_until='ACTIVE',
Ghanshyam3390d9f2015-12-25 12:48:02 +090073 adminPass=self.admin_pass)
Dan Smithc18d8c62012-07-02 08:09:26 -070074
75 # Record addresses so that we can ssh later
ghanshyam0f825252015-08-25 16:02:50 +090076 self.server['addresses'] = self.servers_client.list_addresses(
77 self.server['id'])['addresses']
Dan Smithc18d8c62012-07-02 08:09:26 -070078
79 # Create a volume and wait for it to become ready
Joseph Lanoux6809bab2014-12-18 14:57:18 +000080 self.volume = self.volumes_client.create_volume(
Ghanshyam8fc0ed22015-12-18 10:25:14 +090081 size=CONF.volume.volume_size, display_name='test')['volume']
Matt Riedemannbc8dbd32013-08-02 14:02:12 -070082 self.addCleanup(self._delete_volume)
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050083 waiters.wait_for_volume_status(self.volumes_client,
84 self.volume['id'], 'available')
Dan Smithc18d8c62012-07-02 08:09:26 -070085
lanoux2746ba02016-03-16 17:41:01 +090086 if shelve_server:
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +010087 if CONF.validation.run_validation:
88 # NOTE(andreaf) If we are going to shelve a server, we should
89 # check first whether the server is ssh-able. Otherwise we
90 # won't be able to distinguish failures introduced by shelve
91 # from pre-existing ones. Also it's good to wait for cloud-init
92 # to be done and sshd server to be running before shelving to
93 # avoid breaking the VM
94 linux_client = remote_client.RemoteClient(
95 self.get_server_ip(self.server),
96 self.image_ssh_user,
97 self.admin_pass,
98 self.validation_resources['keypair']['private_key'])
99 linux_client.validate_authentication()
100
101 # If validation went ok, or it was skipped, shelve the server
lanoux2746ba02016-03-16 17:41:01 +0900102 compute.shelve_server(self.servers_client, self.server['id'])
103
Dan Smithc18d8c62012-07-02 08:09:26 -0700104 # Attach the volume to the server
David Kranz3ebc7212015-02-10 12:19:19 -0500105 self.attachment = self.servers_client.attach_volume(
Ghanshyam5c2a5582014-04-14 17:16:57 +0900106 self.server['id'],
Ken'ichi Ohmichidfc88de2015-08-13 05:12:20 +0000107 volumeId=self.volume['id'],
ghanshyam0f825252015-08-25 16:02:50 +0900108 device='/dev/%s' % self.device)['volumeAttachment']
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -0500109 waiters.wait_for_volume_status(self.volumes_client,
110 self.volume['id'], 'in-use')
Dan Smithc18d8c62012-07-02 08:09:26 -0700111
Ghanshyam4adb7cd2014-06-03 12:32:46 +0900112 self.addCleanup(self._detach, self.server['id'], self.volume['id'])
Dan Smithc18d8c62012-07-02 08:09:26 -0700113
Chris Hoge7579c1a2015-02-26 14:12:15 -0800114 @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
Dan Smithc18d8c62012-07-02 08:09:26 -0700115 def test_attach_detach_volume(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500116 # Stop and Start a server with an attached volume, ensuring that
117 # the volume remains attached.
Matt Riedemannbc8dbd32013-08-02 14:02:12 -0700118 self._create_and_attach()
ivan-zhu2f54b282013-03-11 16:39:25 +0800119
Ken'ichi Ohmichib2631082015-08-27 01:31:00 +0000120 self.servers_client.stop_server(self.server['id'])
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000121 waiters.wait_for_server_status(self.servers_client, self.server['id'],
122 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -0700123
Ken'ichi Ohmichib2631082015-08-27 01:31:00 +0000124 self.servers_client.start_server(self.server['id'])
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000125 waiters.wait_for_server_status(self.servers_client, self.server['id'],
126 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700127
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100128 if CONF.validation.run_validation:
129 linux_client = remote_client.RemoteClient(
130 self.get_server_ip(self.server),
131 self.image_ssh_user,
132 self.admin_pass,
133 self.validation_resources['keypair']['private_key'],
134 server=self.server,
135 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000136
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100137 partitions = linux_client.get_partitions()
138 self.assertIn(self.device, partitions)
Dan Smithc18d8c62012-07-02 08:09:26 -0700139
Ghanshyam4adb7cd2014-06-03 12:32:46 +0900140 self._detach(self.server['id'], self.volume['id'])
Ghanshyam5c2a5582014-04-14 17:16:57 +0900141 self.attachment = None
Ken'ichi Ohmichib2631082015-08-27 01:31:00 +0000142 self.servers_client.stop_server(self.server['id'])
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000143 waiters.wait_for_server_status(self.servers_client, self.server['id'],
144 'SHUTOFF')
Dan Smithc18d8c62012-07-02 08:09:26 -0700145
Ken'ichi Ohmichib2631082015-08-27 01:31:00 +0000146 self.servers_client.start_server(self.server['id'])
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000147 waiters.wait_for_server_status(self.servers_client, self.server['id'],
148 'ACTIVE')
Dan Smithc18d8c62012-07-02 08:09:26 -0700149
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100150 if CONF.validation.run_validation:
151 linux_client = remote_client.RemoteClient(
152 self.get_server_ip(self.server),
153 self.image_ssh_user,
154 self.admin_pass,
155 self.validation_resources['keypair']['private_key'],
156 server=self.server,
157 servers_client=self.servers_client)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000158
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100159 partitions = linux_client.get_partitions()
160 self.assertNotIn(self.device, partitions)
Dan Smith1ced8422012-08-16 10:35:19 -0700161
Chris Hoge7579c1a2015-02-26 14:12:15 -0800162 @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
Ghanshyam5c2a5582014-04-14 17:16:57 +0900163 def test_list_get_volume_attachments(self):
164 # Create Server, Volume and attach that Volume to Server
165 self._create_and_attach()
166 # List Volume attachment of the server
David Kranz3ebc7212015-02-10 12:19:19 -0500167 body = self.servers_client.list_volume_attachments(
ghanshyam0f825252015-08-25 16:02:50 +0900168 self.server['id'])['volumeAttachments']
Ghanshyam5c2a5582014-04-14 17:16:57 +0900169 self.assertEqual(1, len(body))
170 self.assertIn(self.attachment, body)
171
172 # Get Volume attachment of the server
Ken'ichi Ohmichi277d1882015-11-20 00:44:06 +0000173 body = self.servers_client.show_volume_attachment(
Ghanshyam5c2a5582014-04-14 17:16:57 +0900174 self.server['id'],
ghanshyam0f825252015-08-25 16:02:50 +0900175 self.attachment['id'])['volumeAttachment']
Ghanshyam5c2a5582014-04-14 17:16:57 +0900176 self.assertEqual(self.server['id'], body['serverId'])
177 self.assertEqual(self.volume['id'], body['volumeId'])
178 self.assertEqual(self.attachment['id'], body['id'])
lanoux2746ba02016-03-16 17:41:01 +0900179
180
181class AttachVolumeShelveTestJSON(AttachVolumeTestJSON):
182 """Testing volume with shelved instance.
183
184 This test checks the attaching and detaching volumes from
185 a shelved or shelved ofload instance.
186 """
187
188 min_microversion = '2.20'
189 max_microversion = 'latest'
190
191 def _unshelve_server_and_check_volumes(self, number_of_partition):
192 # Unshelve the instance and check that there are expected volumes
193 self.servers_client.unshelve_server(self.server['id'])
194 waiters.wait_for_server_status(self.servers_client,
195 self.server['id'],
196 'ACTIVE')
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100197 if CONF.validation.run_validation:
198 linux_client = remote_client.RemoteClient(
199 self.get_server_ip(self.server['id']),
200 self.image_ssh_user,
201 self.admin_pass,
202 self.validation_resources['keypair']['private_key'],
203 server=self.server,
204 servers_client=self.servers_client)
lanoux2746ba02016-03-16 17:41:01 +0900205
Andrea Frittoli (andreaf)3f5aa982016-07-08 12:10:36 +0100206 command = 'grep [vs]d /proc/partitions | wc -l'
207 nb_partitions = linux_client.exec_command(command).strip()
208 self.assertEqual(number_of_partition, nb_partitions)
lanoux2746ba02016-03-16 17:41:01 +0900209
210 @test.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
211 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
212 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900213 def test_attach_volume_shelved_or_offload_server(self):
214 self._create_and_attach(shelve_server=True)
215
216 # Unshelve the instance and check that there are two volumes
217 self._unshelve_server_and_check_volumes('2')
218
219 # Get Volume attachment of the server
220 volume_attachment = self.servers_client.show_volume_attachment(
221 self.server['id'],
222 self.attachment['id'])['volumeAttachment']
223 self.assertEqual(self.server['id'], volume_attachment['serverId'])
224 self.assertEqual(self.attachment['id'], volume_attachment['id'])
225 # Check the mountpoint is not None after unshelve server even in
226 # case of shelved_offloaded.
227 self.assertIsNotNone(volume_attachment['device'])
228
229 @test.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
230 @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
231 'Shelve is not available.')
lanoux2746ba02016-03-16 17:41:01 +0900232 def test_detach_volume_shelved_or_offload_server(self):
233 self._create_and_attach(shelve_server=True)
234
235 # Detach the volume
236 self._detach(self.server['id'], self.volume['id'])
237 self.attachment = None
238
239 # Unshelve the instance and check that there is only one volume
240 self._unshelve_server_and_check_volumes('1')