Files
cinder-tempest-plugin/cinder_tempest_plugin/scenario/test_volume_multiattach.py
Eric Harney 7329a20da5 Multiattach: Fix implicit requirement for encryption support
This test requires encrypted volume support but doesn't check
the tempest option for whether that support is enabled.

(This currently would mostly affect the NFS driver.)

For this test, encryption is not strictly required, so use it
when available to get a more interesting test scenario, but just
use regular volumes when the option is disabled.

This change maintains the original behavior that three volume
types are being used (default, multiattach, and encrypted/other),
but it isn't clear if the additional volume types really add
much of value to the test scenario.

Closes-Bug: #2043830
Change-Id: If41efc6ebd07c75d14b7d0cc5be183e9da7c8cfa
2024-08-20 11:38:46 -04:00

160 lines
6.3 KiB
Python

# Copyright 2022 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from cinder_tempest_plugin.scenario import manager
from tempest.scenario import manager as tempest_manager
CONF = config.CONF
class VolumeMultiattachTests(manager.ScenarioTest,
tempest_manager.EncryptionScenarioTest):
compute_min_microversion = '2.60'
compute_max_microversion = 'latest'
def setUp(self):
super(VolumeMultiattachTests, self).setUp()
self.validation_resources = self.get_test_validation_resources(
self.os_primary)
# NOTE(danms): If validation is enabled, we will have a keypair to use,
# otherwise we need to create our own.
if 'keypair' in self.validation_resources:
self.keypair = self.validation_resources['keypair']
else:
self.keypair = self.create_keypair()
self.security_group = self.create_security_group()
@classmethod
def skip_checks(cls):
super(VolumeMultiattachTests, cls).skip_checks()
if not CONF.compute_feature_enabled.volume_multiattach:
raise cls.skipException('Volume multi-attach is not available.')
def _verify_attachment(self, volume_id, server_id):
volume = self.volumes_client.show_volume(volume_id)['volume']
server_ids = (
[attachment['server_id'] for attachment in volume['attachments']])
self.assertIn(server_id, server_ids)
@decorators.idempotent_id('e6604b85-5280-4f7e-90b5-186248fd3423')
def test_multiattach_data_integrity(self):
# Create an instance
server_1 = self.create_server(
key_name=self.keypair['name'],
wait_until='SSHABLE',
validatable=True,
validation_resources=self.validation_resources,
security_groups=[{'name': self.security_group['name']}])
# Create multiattach type
multiattach_vol_type = self.create_volume_type(
extra_specs={'multiattach': "<is> True"})
# Create a multiattach volume
volume = self.create_volume(volume_type=multiattach_vol_type['id'])
# Create a volume with the default volume type
default_volume = self.create_volume()
# Create other volume
if CONF.compute_feature_enabled.attach_encrypted_volume:
other_volume = self.create_encrypted_volume(
'luks', volume_type='luks')
else:
# Create secondary volume type
second_vol_type = self.create_volume_type()
other_volume = self.create_volume(
volume_type=second_vol_type['id'])
# Attach default and secondary volumes (These volumes are not used in
# the current test but is used to emulate a real world scenario
# where different types of volumes will be attached to the server)
self.attach_volume(server_1, default_volume)
self.attach_volume(server_1, other_volume)
instance_ip = self.get_server_ip(server_1)
# Attach volume to instance and find it's device name (eg: /dev/vdb)
volume_device_name_inst_1, __ = (
self._attach_and_get_volume_device_name(
server_1, volume, instance_ip, self.keypair['private_key']))
out_device = '/dev/' + volume_device_name_inst_1
# This data is written from the first server and will be used to
# verify when reading data from second server
device_data_inst_1 = self.write_data_to_device(
instance_ip, out_device, private_key=self.keypair['private_key'],
server=server_1, sha_sum=True)
# Create another instance
server_2 = self.create_server(
key_name=self.keypair['name'],
validatable=True,
validation_resources=self.validation_resources,
wait_until='SSHABLE',
security_groups=[{'name': self.security_group['name']}])
instance_2_ip = self.get_server_ip(server_2)
# Attach volume to instance and find it's device name (eg: /dev/vdc)
volume_device_name_inst_2, __ = (
self._attach_and_get_volume_device_name(
server_2, volume, instance_2_ip, self.keypair['private_key']))
in_device = '/dev/' + volume_device_name_inst_2
# Read data from volume device
device_data_inst_2 = self.read_data_from_device(
instance_2_ip, in_device, private_key=self.keypair['private_key'],
server=server_2, sha_sum=True)
self._verify_attachment(volume['id'], server_1['id'])
self._verify_attachment(volume['id'], server_2['id'])
self.assertEqual(device_data_inst_1, device_data_inst_2)
@decorators.idempotent_id('53514da8-f49c-4cda-8792-ff4a2fa69977')
def test_volume_multiattach_same_host_negative(self):
# Create an instance
server = self.create_server(
key_name=self.keypair['name'],
validatable=True,
validation_resources=self.validation_resources,
wait_until='SSHABLE',
security_groups=[{'name': self.security_group['name']}])
# Create multiattach type
multiattach_vol_type = self.create_volume_type(
extra_specs={'multiattach': "<is> True"})
# Create an empty volume
volume = self.create_volume(volume_type=multiattach_vol_type['id'])
# Attach volume to instance
attachment = self.attach_volume(server, volume)
self.assertEqual(server['id'], attachment['serverId'])
# Try attaching the volume to the same instance
self.assertRaises(lib_exc.BadRequest, self.attach_volume, server,
volume)