Merge "Refactor test_server_shares: Mock in Base Class and trait verification"

This commit is contained in:
Zuul 2024-12-13 10:40:32 +00:00 committed by Gerrit Code Review
commit 3c038645db

View File

@ -28,8 +28,6 @@ from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from unittest import mock
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
@ -59,6 +57,22 @@ class ServerSharesTestBase(base.ServersTestBase):
self.host = self.computes[self.compute].driver._host
self.mock_connect = self.useFixture(fixtures.MockPatch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'connect_volume')).mock
self.mock_disconnect = self.useFixture(fixtures.MockPatch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'disconnect_volume')).mock
self.mock_connect_ceph = self.useFixture(fixtures.MockPatch(
'nova.virt.libvirt.volume.cephfs.LibvirtCEPHFSVolumeDriver'
'.connect_volume')).mock
self.mock_disconnect_ceph = self.useFixture(fixtures.MockPatch(
'nova.virt.libvirt.volume.cephfs.LibvirtCEPHFSVolumeDriver'
'.disconnect_volume')).mock
def _get_xml(self, server):
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
@ -107,146 +121,111 @@ class ServerSharesTestBase(base.ServersTestBase):
device_share_and_tag.append((device['share_id'], device['tag']))
self.assertIn((share_id, tag), device_share_and_tag)
def _check_traits(self):
expected_traits = {
"COMPUTE_STORAGE_VIRTIO_FS", "COMPUTE_MEM_BACKING_FILE"
}
traits = self._get_provider_traits(self.compute_rp_uuids[self.compute])
self.assertEqual(expected_traits, expected_traits.intersection(traits))
class ServerSharesTest(ServerSharesTestBase):
def test_server_share_metadata(self):
"""Verify that share metadata are available"""
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'disconnect_volume'
), mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'connect_volume'
):
traits = self._get_provider_traits(
self.compute_rp_uuids[self.compute])
for trait in (
'COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
self.assertIn(trait, traits)
server = self._create_server(networks='auto')
self._stop_server(server)
self._check_traits()
server = self._create_server(networks='auto')
self._stop_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
# tag is the filesystem target directory.
# if post /server/{server_id}/share was called without a specific
# tag then the tag is the share id.
self._assert_filesystem_tag(self._get_xml(server), share_id)
# tag is the filesystem target directory.
# if post /server/{server_id}/share was called without a specific
# tag then the tag is the share id.
self._assert_filesystem_tag(self._get_xml(server), share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
return (server, share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
return (server, share_id)
def test_server_share_metadata_with_tag(self):
"""Verify that share metadata are available with the provided tag"""
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'disconnect_volume'
), mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'connect_volume'
):
traits = self._get_provider_traits(
self.compute_rp_uuids[self.compute])
for trait in (
'COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
self.assertIn(trait, traits)
server = self._create_server(networks='auto')
self._stop_server(server)
self._check_traits()
server = self._create_server(networks='auto')
self._stop_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
tag = 'mytag'
self._attach_share(server, share_id, tag=tag)
self._start_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
tag = 'mytag'
self._attach_share(server, share_id, tag=tag)
self._start_server(server)
# tag is the filesystem target directory.
# if post /server/{server_id}/share was called without a specific
# tag then the tag is the share id.
self._assert_filesystem_tag(self._get_xml(server), tag)
# tag is the filesystem target directory.
# if post /server/{server_id}/share was called without a specific
# tag then the tag is the share id.
self._assert_filesystem_tag(self._get_xml(server), tag)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, tag)
return (server, share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, tag)
return (server, share_id)
def test_server_share_fails_with_tag_already_used(self):
"""Verify that share create fails if we use an already assigned tag"""
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'disconnect_volume'
), mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'connect_volume'
):
traits = self._get_provider_traits(
self.compute_rp_uuids[self.compute])
for trait in (
'COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
self.assertIn(trait, traits)
server = self._create_server(networks='auto')
self._stop_server(server)
self._check_traits()
server = self._create_server(networks='auto')
self._stop_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
tag = 'mytag'
self._attach_share(server, share_id, tag=tag)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
tag = 'mytag'
self._attach_share(server, share_id, tag=tag)
share_id = '1457bd85-7e7f-4835-92de-47834e1516b5'
tag = 'mytag'
share_id = '1457bd85-7e7f-4835-92de-47834e1516b5'
tag = 'mytag'
exc = self.assertRaises(
client.OpenStackApiException,
self._attach_share,
server,
share_id,
tag=tag
)
exc = self.assertRaises(
client.OpenStackApiException,
self._attach_share,
server,
share_id,
tag=tag
)
self.assertEqual(409, exc.response.status_code)
self.assertIn(
"Share '1457bd85-7e7f-4835-92de-47834e1516b5' or "
"tag 'mytag' already associated to this server.",
str(exc.response.text),
)
self.assertEqual(409, exc.response.status_code)
self.assertIn(
"Share '1457bd85-7e7f-4835-92de-47834e1516b5' or "
"tag 'mytag' already associated to this server.",
str(exc.response.text),
)
def test_server_cephfs_share_metadata(self):
"""Verify that cephfs share metadata are available"""
with mock.patch(
'nova.virt.libvirt.volume.cephfs.LibvirtCEPHFSVolumeDriver.'
'disconnect_volume'
), mock.patch(
'nova.virt.libvirt.volume.cephfs.LibvirtCEPHFSVolumeDriver.'
'connect_volume'
):
# update the mock to call the cephfs fake values
self.manila_fixture.mock_get.side_effect = (
self.manila_fixture.fake_get_cephfs
)
self.manila_fixture.mock_get_access.side_effect = (
self.manila_fixture.fake_get_access_cephfs
)
# update the mock to call the cephfs fake values
self.manila_fixture.mock_get.side_effect = (
self.manila_fixture.fake_get_cephfs
)
self.manila_fixture.mock_get_access.side_effect = (
self.manila_fixture.fake_get_access_cephfs
)
traits = self._get_provider_traits(
self.compute_rp_uuids[self.compute])
for trait in (
'COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
self.assertIn(trait, traits)
server = self._create_server(networks='auto')
self._stop_server(server)
self._check_traits()
server = self._create_server(networks='auto')
self._stop_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
# tag is the filesystem target directory.
# if post /server/{server_id}/share was called without a specific
# tag then the tag is the share id.
self._assert_filesystem_tag(self._get_xml(server), share_id)
# tag is the filesystem target directory.
# if post /server/{server_id}/share was called without a specific
# tag then the tag is the share id.
self._assert_filesystem_tag(self._get_xml(server), share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
return (server, share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
return (server, share_id)
def test_server_share_after_hard_reboot(self):
"""Verify that share is still available after a reboot"""
@ -260,52 +239,47 @@ class ServerSharesTest(ServerSharesTestBase):
def test_server_share_mount_failure(self):
os.environ['OS_DEBUG'] = "true"
traits = self._get_provider_traits(self.compute_rp_uuids[self.compute])
for trait in ('COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
self.assertIn(trait, traits)
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver'
'.connect_volume',
side_effect=processutils.ProcessExecutionError
):
server = self._create_server(networks='auto')
self._stop_server(server)
self._check_traits()
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self.mock_connect.side_effect = processutils.ProcessExecutionError
server = self._create_server(networks='auto')
self._stop_server(server)
self._attach_share(server, share_id)
response = self._get_share(server, share_id)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self.assertEqual(
response["share_id"], "4b021746-d0eb-4031-92aa-23c3bec182cd"
)
self.assertEqual(response["status"], "inactive")
self._attach_share(server, share_id)
response = self._get_share(server, share_id)
# Here we are using CastAsCallFixture so we got an exception from
# nova compute. This should not happen without the fixture and
# the api should answer with a 201 status code.
exc = self.assertRaises(
client.OpenStackApiException,
self._start_server,
server
)
self.assertEqual(
response["share_id"], "4b021746-d0eb-4031-92aa-23c3bec182cd"
)
self.assertEqual(response["status"], "inactive")
self.assertIn("nova.exception.ShareMountError", str(exc))
# Here we are using CastAsCallFixture so we got an exception from
# nova compute. This should not happen without the fixture and
# the api should answer with a 201 status code.
exc = self.assertRaises(
client.OpenStackApiException,
self._start_server,
server
)
log_out = self.stdlog.logger.output
self.assertIn("nova.exception.ShareMountError", str(exc))
self.assertIn(
"Share id 4b021746-d0eb-4031-92aa-23c3bec182cd mount error "
"from server",
log_out)
log_out = self.stdlog.logger.output
sm = share_mapping.ShareMapping.get_by_instance_uuid_and_share_id(
self.context, server['id'], share_id)
self.assertEqual(sm.status, 'error')
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'error')
return (server, share_id)
self.assertIn(
"Share id 4b021746-d0eb-4031-92aa-23c3bec182cd mount error "
"from server",
log_out)
sm = share_mapping.ShareMapping.get_by_instance_uuid_and_share_id(
self.context, server['id'], share_id)
self.assertEqual(sm.status, 'error')
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'error')
return (server, share_id)
def test_server_start_fails_share_in_error(self):
"""Ensure a server can not start if its attached share is in error
@ -332,49 +306,41 @@ class ServerSharesTest(ServerSharesTestBase):
# Reboot to do another mount attempt and fix the error.
# But the error is not fixed.
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver'
'.connect_volume',
side_effect=processutils.ProcessExecutionError
):
self.mock_connect.side_effect = processutils.ProcessExecutionError
# Here we are using CastAsCallFixture so we got an exception from
# nova api. This should not happen without the fixture.
exc = self.assertRaises(
client.OpenStackApiException,
self._reboot_server,
server,
hard=True
)
# Here we are using CastAsCallFixture so we got an exception from
# nova api. This should not happen without the fixture.
exc = self.assertRaises(
client.OpenStackApiException,
self._reboot_server,
server,
hard=True
)
log_out = self.stdlog.logger.output
log_out = self.stdlog.logger.output
self.assertIn(
"Share id 4b021746-d0eb-4031-92aa-23c3bec182cd mount error "
"from server",
log_out)
self.assertIn(
"Share id 4b021746-d0eb-4031-92aa-23c3bec182cd mount error "
"from server",
log_out)
sm = share_mapping.ShareMapping.get_by_instance_uuid_and_share_id(
self.context, server['id'], share_id)
self.assertEqual(sm.status, 'error')
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'error')
sm = share_mapping.ShareMapping.get_by_instance_uuid_and_share_id(
self.context, server['id'], share_id)
self.assertEqual(sm.status, 'error')
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'error')
# Reboot to do another mount attempt and fix the error.
# But the error is fixed now.
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver'
'.connect_volume',
):
self._reboot_server(server, hard=True)
self.mock_connect.side_effect = None
self._reboot_server(server, hard=True)
sm = share_mapping.ShareMapping.get_by_instance_uuid_and_share_id(
self.context, server['id'], share_id)
self.assertEqual(sm.status, 'active')
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'active')
sm = share_mapping.ShareMapping.get_by_instance_uuid_and_share_id(
self.context, server['id'], share_id)
self.assertEqual(sm.status, 'active')
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'active')
def test_detach_server_share_in_error(self):
"""Ensure share can still be detached even if
@ -385,52 +351,41 @@ class ServerSharesTest(ServerSharesTestBase):
# Simulate an attempt to detach that fail due to umount error.
# In that case we should have an umount error.
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver'
'.disconnect_volume',
side_effect=processutils.ProcessExecutionError
):
self.mock_disconnect.side_effect = processutils.ProcessExecutionError
# Ensure we failed to umount he share
log_out = self.stdlog.logger.output
# Ensure we failed to umount he share
log_out = self.stdlog.logger.output
self.assertIn(
"Share id 4b021746-d0eb-4031-92aa-23c3bec182cd umount error",
log_out)
self.assertIn(
"Share id 4b021746-d0eb-4031-92aa-23c3bec182cd umount error",
log_out)
# We detach the share. As a consequence, we are leaking the share
# mounted on the compute.
self._detach_share(server, share_id)
# We detach the share. As a consequence, we are leaking the share
# mounted on the compute.
self._detach_share(server, share_id)
# Share is removed so not anymore in the DB.
self.assertRaises(
exception.ShareNotFound,
share_mapping.ShareMapping.get_by_instance_uuid_and_share_id,
self.context,
server['id'],
share_id
)
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'error')
# Share is removed so not anymore in the DB.
self.assertRaises(
exception.ShareNotFound,
share_mapping.ShareMapping.get_by_instance_uuid_and_share_id,
self.context,
server['id'],
share_id
)
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'error')
# Reboot the server to restart it without the share.
self._reboot_server(server, hard=True)
# Reboot the server to restart it without the share.
self._reboot_server(server, hard=True)
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'active')
self.instance = instance.Instance.get_by_uuid(
self.context, server['id'])
self.assertEqual(self.instance.vm_state, 'active')
@mock.patch('nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver'
'.disconnect_volume',
side_effect=processutils.ProcessExecutionError)
@mock.patch('nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver'
'.connect_volume')
def test_server_share_umount_failure(self, mock_mount, mock_umount):
def test_server_share_umount_failure(self):
self.mock_disconnect.side_effect = processutils.ProcessExecutionError
os.environ['OS_DEBUG'] = "true"
traits = self._get_provider_traits(self.compute_rp_uuids[self.compute])
for trait in ('COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
self.assertIn(trait, traits)
self._check_traits()
server = self._create_server(networks='auto')
self._stop_server(server)
@ -465,50 +420,36 @@ class ServerSharesTest(ServerSharesTestBase):
return (server, share_id)
def test_server_resume_with_shares(self):
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'disconnect_volume'
), mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'connect_volume'
):
server = self._create_server(networks='auto')
self._stop_server(server)
server = self._create_server(networks='auto')
self._stop_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
self.assertRaises(
client.OpenStackApiException,
self._suspend_server,
server,
)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
self.assertRaises(
client.OpenStackApiException,
self._suspend_server,
server,
)
def test_server_rescue_with_shares(self):
with mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'disconnect_volume'
), mock.patch(
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
'connect_volume'
):
server = self._create_server(networks='auto')
self._stop_server(server)
server = self._create_server(networks='auto')
self._stop_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
self._rescue_server(server)
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
self._attach_share(server, share_id)
self._start_server(server)
self._rescue_server(server)
self._assert_filesystem_tag(self._get_xml(server), share_id)
self._assert_filesystem_tag(self._get_xml(server), share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
self._unrescue_server(server)
self._unrescue_server(server)
self._assert_filesystem_tag(self._get_xml(server), share_id)
self._assert_filesystem_tag(self._get_xml(server), share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
return (server, share_id)
self._assert_share_in_metadata(
self._get_metadata_url(server), share_id, share_id)
return (server, share_id)