|
0 |
# Copyright 2022 Red Hat, Inc.
|
|
1 |
# All Rights Reserved.
|
|
2 |
#
|
|
3 |
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
4 |
# not use this file except in compliance with the License. You may obtain
|
|
5 |
# a copy of the License at
|
|
6 |
#
|
|
7 |
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8 |
#
|
|
9 |
# Unless required by applicable law or agreed to in writing, software
|
|
10 |
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
11 |
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
12 |
# License for the specific language governing permissions and limitations
|
|
13 |
# under the License.
|
|
14 |
|
|
15 |
from tempest import config
|
|
16 |
from tempest.lib import decorators
|
|
17 |
from tempest.lib import exceptions as lib_exc
|
|
18 |
|
|
19 |
from cinder_tempest_plugin.scenario import manager
|
|
20 |
from tempest.scenario import manager as tempest_manager
|
|
21 |
|
|
22 |
CONF = config.CONF
|
|
23 |
|
|
24 |
|
|
25 |
class VolumeMultiattachTests(manager.ScenarioTest,
|
|
26 |
tempest_manager.EncryptionScenarioTest):
|
|
27 |
|
|
28 |
compute_min_microversion = '2.60'
|
|
29 |
compute_max_microversion = 'latest'
|
|
30 |
|
|
31 |
def setUp(self):
|
|
32 |
super(VolumeMultiattachTests, self).setUp()
|
|
33 |
self.keypair = self.create_keypair()
|
|
34 |
self.security_group = self.create_security_group()
|
|
35 |
|
|
36 |
@classmethod
|
|
37 |
def skip_checks(cls):
|
|
38 |
super(VolumeMultiattachTests, cls).skip_checks()
|
|
39 |
if not CONF.compute_feature_enabled.volume_multiattach:
|
|
40 |
raise cls.skipException('Volume multi-attach is not available.')
|
|
41 |
|
|
42 |
def _verify_attachment(self, volume_id, server_id):
|
|
43 |
volume = self.volumes_client.show_volume(volume_id)['volume']
|
|
44 |
server_ids = (
|
|
45 |
[attachment['server_id'] for attachment in volume['attachments']])
|
|
46 |
self.assertIn(server_id, server_ids)
|
|
47 |
|
|
48 |
@decorators.idempotent_id('e6604b85-5280-4f7e-90b5-186248fd3423')
|
|
49 |
def test_multiattach_data_integrity(self):
|
|
50 |
|
|
51 |
# Create an instance
|
|
52 |
server_1 = self.create_server(
|
|
53 |
key_name=self.keypair['name'],
|
|
54 |
security_groups=[{'name': self.security_group['name']}])
|
|
55 |
|
|
56 |
# Create multiattach type
|
|
57 |
multiattach_vol_type = self.create_volume_type(
|
|
58 |
extra_specs={'multiattach': "<is> True"})
|
|
59 |
|
|
60 |
# Create a multiattach volume
|
|
61 |
volume = self.create_volume(volume_type=multiattach_vol_type['id'])
|
|
62 |
|
|
63 |
# Create encrypted volume
|
|
64 |
encrypted_volume = self.create_encrypted_volume(
|
|
65 |
'luks', volume_type='luks')
|
|
66 |
|
|
67 |
# Create a normal volume
|
|
68 |
simple_volume = self.create_volume()
|
|
69 |
|
|
70 |
# Attach normal and encrypted volumes (These volumes are not used in
|
|
71 |
# the current test but is used to emulate a real world scenario
|
|
72 |
# where different types of volumes will be attached to the server)
|
|
73 |
self.attach_volume(server_1, simple_volume)
|
|
74 |
self.attach_volume(server_1, encrypted_volume)
|
|
75 |
|
|
76 |
instance_ip = self.get_server_ip(server_1)
|
|
77 |
|
|
78 |
# Attach volume to instance and find it's device name (eg: /dev/vdb)
|
|
79 |
volume_device_name_inst_1, __ = (
|
|
80 |
self._attach_and_get_volume_device_name(
|
|
81 |
server_1, volume, instance_ip, self.keypair['private_key']))
|
|
82 |
|
|
83 |
out_device = '/dev/' + volume_device_name_inst_1
|
|
84 |
|
|
85 |
# This data is written from the first server and will be used to
|
|
86 |
# verify when reading data from second server
|
|
87 |
device_data_inst_1 = self.write_data_to_device(
|
|
88 |
instance_ip, out_device, private_key=self.keypair['private_key'],
|
|
89 |
server=server_1, sha_sum=True)
|
|
90 |
|
|
91 |
# Create another instance
|
|
92 |
server_2 = self.create_server(
|
|
93 |
key_name=self.keypair['name'],
|
|
94 |
security_groups=[{'name': self.security_group['name']}])
|
|
95 |
|
|
96 |
instance_2_ip = self.get_server_ip(server_2)
|
|
97 |
|
|
98 |
# Attach volume to instance and find it's device name (eg: /dev/vdc)
|
|
99 |
volume_device_name_inst_2, __ = (
|
|
100 |
self._attach_and_get_volume_device_name(
|
|
101 |
server_2, volume, instance_2_ip, self.keypair['private_key']))
|
|
102 |
|
|
103 |
in_device = '/dev/' + volume_device_name_inst_2
|
|
104 |
|
|
105 |
# Read data from volume device
|
|
106 |
device_data_inst_2 = self.read_data_from_device(
|
|
107 |
instance_2_ip, in_device, private_key=self.keypair['private_key'],
|
|
108 |
server=server_2, sha_sum=True)
|
|
109 |
|
|
110 |
self._verify_attachment(volume['id'], server_1['id'])
|
|
111 |
self._verify_attachment(volume['id'], server_2['id'])
|
|
112 |
self.assertEqual(device_data_inst_1, device_data_inst_2)
|
|
113 |
|
|
114 |
@decorators.idempotent_id('53514da8-f49c-4cda-8792-ff4a2fa69977')
|
|
115 |
def test_volume_multiattach_same_host_negative(self):
|
|
116 |
# Create an instance
|
|
117 |
server = self.create_server(
|
|
118 |
key_name=self.keypair['name'],
|
|
119 |
security_groups=[{'name': self.security_group['name']}])
|
|
120 |
|
|
121 |
# Create multiattach type
|
|
122 |
multiattach_vol_type = self.create_volume_type(
|
|
123 |
extra_specs={'multiattach': "<is> True"})
|
|
124 |
|
|
125 |
# Create an empty volume
|
|
126 |
volume = self.create_volume(volume_type=multiattach_vol_type['id'])
|
|
127 |
|
|
128 |
# Attach volume to instance
|
|
129 |
attachment = self.attach_volume(server, volume)
|
|
130 |
|
|
131 |
self.assertEqual(server['id'], attachment['serverId'])
|
|
132 |
|
|
133 |
# Try attaching the volume to the same instance
|
|
134 |
self.assertRaises(lib_exc.BadRequest, self.attach_volume, server,
|
|
135 |
volume)
|