blob: f9ab605a3bec6e44b072e24412f2bdf798a6e85a [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Rohit Karajgia42fe442012-09-21 03:08:33 -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.
Jordan Pittier9e227c52016-02-09 14:35:18 +010015import testtools
Rohit Karajgia42fe442012-09-21 03:08:33 -070016
Zhi Kun Liubb363a22013-11-28 18:47:39 +080017from tempest.api.volume import base
Fei Long Wangd39431f2015-05-14 11:30:48 +120018from tempest.common.utils import data_utils
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000019from tempest.common import waiters
Matthew Treinish4d352bc2014-01-29 18:29:18 +000020from tempest import config
Matt Riedemann2aa19d42016-06-06 17:45:41 -040021from tempest import exceptions
Jordan Pittier9e227c52016-02-09 14:35:18 +010022from tempest.lib.common.utils import test_utils
Masayuki Igawaba7bcf62014-02-17 14:56:41 +090023from tempest import test
Rohit Karajgia42fe442012-09-21 03:08:33 -070024
Matthew Treinish4d352bc2014-01-29 18:29:18 +000025CONF = config.CONF
26
Rohit Karajgia42fe442012-09-21 03:08:33 -070027
Zhi Kun Liu3d6d9862014-06-16 16:43:59 +080028class VolumesV2ActionsTest(base.BaseVolumeTest):
Rohit Karajgia42fe442012-09-21 03:08:33 -070029
30 @classmethod
Rohan Kanade05749152015-01-30 17:15:18 +053031 def setup_clients(cls):
32 super(VolumesV2ActionsTest, cls).setup_clients()
Rohit Karajgia42fe442012-09-21 03:08:33 -070033 cls.client = cls.volumes_client
Matt Riedemann2aa19d42016-06-06 17:45:41 -040034 if CONF.service_available.glance:
35 # Check if glance v1 is available to determine which client to use.
36 if CONF.image_feature_enabled.api_v1:
37 cls.image_client = cls.os.image_client
38 elif CONF.image_feature_enabled.api_v2:
39 cls.image_client = cls.os.image_client_v2
40 else:
41 raise exceptions.InvalidConfiguration(
42 'Either api_v1 or api_v2 must be True in '
43 '[image-feature-enabled].')
Rohit Karajgia42fe442012-09-21 03:08:33 -070044
Rohan Kanade05749152015-01-30 17:15:18 +053045 @classmethod
46 def resource_setup(cls):
47 super(VolumesV2ActionsTest, cls).resource_setup()
Rohit Karajgia42fe442012-09-21 03:08:33 -070048
Ken'ichi Ohmichi5687d552013-12-26 19:00:12 +090049 # Create a test shared volume for attach/detach tests
50 cls.volume = cls.create_volume()
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050051 waiters.wait_for_volume_status(cls.client,
52 cls.volume['id'], 'available')
Rohit Karajgia42fe442012-09-21 03:08:33 -070053
Chris Hoge7579c1a2015-02-26 14:12:15 -080054 @test.idempotent_id('fff42874-7db5-4487-a8e1-ddda5fb5288d')
Masayuki Igawaba7bcf62014-02-17 14:56:41 +090055 @test.stresstest(class_setup_per='process')
56 @test.attr(type='smoke')
57 @test.services('compute')
Rohit Karajgia42fe442012-09-21 03:08:33 -070058 def test_attach_detach_volume_to_instance(self):
lkuchlan5fc69362016-09-05 08:42:34 +030059 # Create a server
60 srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
61 server = self.create_server(
62 name=srv_name,
63 wait_until='ACTIVE')
Sean Dague72a00382013-01-03 17:53:38 -050064 # Volume is attached and detached successfully from an instance
Joseph Lanoux6809bab2014-12-18 14:57:18 +000065 self.client.attach_volume(self.volume['id'],
lkuchlan5fc69362016-09-05 08:42:34 +030066 instance_uuid=server['id'],
bkopilovbc830d02016-03-27 14:09:47 +030067 mountpoint='/dev/%s' %
68 CONF.compute.volume_device_name)
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050069 waiters.wait_for_volume_status(self.client,
70 self.volume['id'], 'in-use')
Joseph Lanoux6809bab2014-12-18 14:57:18 +000071 self.client.detach_volume(self.volume['id'])
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050072 waiters.wait_for_volume_status(self.client,
73 self.volume['id'], 'available')
Rohit Karajgia42fe442012-09-21 03:08:33 -070074
bkopilov8a657ae2015-05-11 11:45:23 +030075 @test.idempotent_id('63e21b4c-0a0c-41f6-bfc3-7c2816815599')
76 @testtools.skipUnless(CONF.volume_feature_enabled.bootable,
77 'Update bootable status of a volume is not enabled.')
78 def test_volume_bootable(self):
79 # Verify that a volume bootable flag is retrieved
80 for bool_bootable in [True, False]:
Ghanshyam58a9e872015-12-18 10:46:07 +090081 self.client.set_bootable_volume(self.volume['id'],
82 bootable=bool_bootable)
John Warren6177c9e2015-08-19 20:00:17 +000083 fetched_volume = self.client.show_volume(
84 self.volume['id'])['volume']
bkopilov8a657ae2015-05-11 11:45:23 +030085 # Get Volume information
86 bool_flag = self._is_true(fetched_volume['bootable'])
87 self.assertEqual(bool_bootable, bool_flag)
88
Chris Hoge7579c1a2015-02-26 14:12:15 -080089 @test.idempotent_id('9516a2c8-9135-488c-8dd6-5677a7e5f371')
Masayuki Igawaba7bcf62014-02-17 14:56:41 +090090 @test.stresstest(class_setup_per='process')
Masayuki Igawaba7bcf62014-02-17 14:56:41 +090091 @test.services('compute')
Rohit Karajgia42fe442012-09-21 03:08:33 -070092 def test_get_volume_attachment(self):
lkuchlan5fc69362016-09-05 08:42:34 +030093 # Create a server
94 srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
95 server = self.create_server(
96 name=srv_name,
97 wait_until='ACTIVE')
Sean Dague72a00382013-01-03 17:53:38 -050098 # Verify that a volume's attachment information is retrieved
Joseph Lanoux6809bab2014-12-18 14:57:18 +000099 self.client.attach_volume(self.volume['id'],
lkuchlan5fc69362016-09-05 08:42:34 +0300100 instance_uuid=server['id'],
bkopilovbc830d02016-03-27 14:09:47 +0300101 mountpoint='/dev/%s' %
102 CONF.compute.volume_device_name)
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -0500103 waiters.wait_for_volume_status(self.client,
104 self.volume['id'], 'in-use')
Giulio Fidente92f77192013-08-26 17:13:28 +0200105 # NOTE(gfidente): added in reverse order because functions will be
106 # called in reverse order to the order they are added (LIFO)
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -0500107 self.addCleanup(waiters.wait_for_volume_status, self.client,
Giulio Fidente92f77192013-08-26 17:13:28 +0200108 self.volume['id'],
109 'available')
110 self.addCleanup(self.client.detach_volume, self.volume['id'])
John Warren6177c9e2015-08-19 20:00:17 +0000111 volume = self.client.show_volume(self.volume['id'])['volume']
Giulio Fidente92f77192013-08-26 17:13:28 +0200112 self.assertIn('attachments', volume)
anju tiwari789449a2013-08-29 16:56:17 +0530113 attachment = self.client.get_attachment_from_volume(volume)
bkopilovbc830d02016-03-27 14:09:47 +0300114 self.assertEqual('/dev/%s' %
115 CONF.compute.volume_device_name,
116 attachment['device'])
lkuchlan5fc69362016-09-05 08:42:34 +0300117 self.assertEqual(server['id'], attachment['server_id'])
Giulio Fidente92f77192013-08-26 17:13:28 +0200118 self.assertEqual(self.volume['id'], attachment['id'])
119 self.assertEqual(self.volume['id'], attachment['volume_id'])
Giulio Fidente884e9da2013-06-21 17:25:42 +0200120
Chris Hoge7579c1a2015-02-26 14:12:15 -0800121 @test.idempotent_id('d8f1ca95-3d5b-44a3-b8ca-909691c9532d')
Masayuki Igawaba7bcf62014-02-17 14:56:41 +0900122 @test.services('image')
Giulio Fidente884e9da2013-06-21 17:25:42 +0200123 def test_volume_upload(self):
124 # NOTE(gfidente): the volume uploaded in Glance comes from setUpClass,
125 # it is shared with the other tests. After it is uploaded in Glance,
126 # there is no way to delete it from Cinder, so we delete it from Glance
127 # using the Glance image_client and from Cinder via tearDownClass.
zhuflc6ce5392016-08-17 14:34:37 +0800128 image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
John Warren6177c9e2015-08-19 20:00:17 +0000129 body = self.client.upload_volume(
Ghanshyam8fc0ed22015-12-18 10:25:14 +0900130 self.volume['id'], image_name=image_name,
131 disk_format=CONF.volume.disk_format)['os-volume_upload_image']
Giulio Fidente884e9da2013-06-21 17:25:42 +0200132 image_id = body["image_id"]
Jordan Pittier9e227c52016-02-09 14:35:18 +0100133 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
134 self.image_client.delete_image,
135 image_id)
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300136 waiters.wait_for_image_status(self.image_client, image_id, 'active')
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -0500137 waiters.wait_for_volume_status(self.client,
138 self.volume['id'], 'available')
anju tiwari789449a2013-08-29 16:56:17 +0530139
Chris Hoge7579c1a2015-02-26 14:12:15 -0800140 @test.idempotent_id('92c4ef64-51b2-40c0-9f7e-4749fbaaba33')
zhangyanzi6b632432013-10-24 19:08:50 +0800141 def test_reserve_unreserve_volume(self):
142 # Mark volume as reserved.
Joseph Lanoux6809bab2014-12-18 14:57:18 +0000143 body = self.client.reserve_volume(self.volume['id'])
zhangyanzi6b632432013-10-24 19:08:50 +0800144 # To get the volume info
John Warren6177c9e2015-08-19 20:00:17 +0000145 body = self.client.show_volume(self.volume['id'])['volume']
zhangyanzi6b632432013-10-24 19:08:50 +0800146 self.assertIn('attaching', body['status'])
147 # Unmark volume as reserved.
Joseph Lanoux6809bab2014-12-18 14:57:18 +0000148 body = self.client.unreserve_volume(self.volume['id'])
zhangyanzi6b632432013-10-24 19:08:50 +0800149 # To get the volume info
John Warren6177c9e2015-08-19 20:00:17 +0000150 body = self.client.show_volume(self.volume['id'])['volume']
zhangyanzi6b632432013-10-24 19:08:50 +0800151 self.assertIn('available', body['status'])
152
zhangyanziaa180072013-11-21 12:31:26 +0800153 def _is_true(self, val):
154 return val in ['true', 'True', True]
155
Chris Hoge7579c1a2015-02-26 14:12:15 -0800156 @test.idempotent_id('fff74e1e-5bd3-4b33-9ea9-24c103bc3f59')
zhangyanziaa180072013-11-21 12:31:26 +0800157 def test_volume_readonly_update(self):
158 # Update volume readonly true
159 readonly = True
Joseph Lanoux6809bab2014-12-18 14:57:18 +0000160 self.client.update_volume_readonly(self.volume['id'],
Ghanshyam58a9e872015-12-18 10:46:07 +0900161 readonly=readonly)
zhangyanziaa180072013-11-21 12:31:26 +0800162 # Get Volume information
John Warren6177c9e2015-08-19 20:00:17 +0000163 fetched_volume = self.client.show_volume(self.volume['id'])['volume']
zhangyanziaa180072013-11-21 12:31:26 +0800164 bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
zhangyanziaa180072013-11-21 12:31:26 +0800165 self.assertEqual(True, bool_flag)
166
167 # Update volume readonly false
168 readonly = False
Ghanshyam58a9e872015-12-18 10:46:07 +0900169 self.client.update_volume_readonly(self.volume['id'],
170 readonly=readonly)
zhangyanziaa180072013-11-21 12:31:26 +0800171
172 # Get Volume information
John Warren6177c9e2015-08-19 20:00:17 +0000173 fetched_volume = self.client.show_volume(self.volume['id'])['volume']
zhangyanziaa180072013-11-21 12:31:26 +0800174 bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
zhangyanziaa180072013-11-21 12:31:26 +0800175 self.assertEqual(False, bool_flag)
176
anju tiwari789449a2013-08-29 16:56:17 +0530177
Zhi Kun Liu3d6d9862014-06-16 16:43:59 +0800178class VolumesV1ActionsTest(VolumesV2ActionsTest):
179 _api_version = 1