volume: Migrate 'volume show' to SDK

Change-Id: Ibd9d7a62c2500a1f31aa2d3d13ac7e8bad4e6964
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane
2025-03-07 14:16:02 +00:00
parent 5e5f12ba40
commit c7d465a221
6 changed files with 211 additions and 108 deletions

View File

@@ -171,7 +171,7 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["volume_image_metadata"], cmd_output["volume_image_metadata"],
) )
self.assertEqual( self.assertEqual(
'true', True,
cmd_output["bootable"], cmd_output["bootable"],
) )

View File

@@ -172,7 +172,7 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["volume_image_metadata"], cmd_output["volume_image_metadata"],
) )
self.assertEqual( self.assertEqual(
'true', True,
cmd_output["bootable"], cmd_output["bootable"],
) )

View File

@@ -12,6 +12,7 @@
# under the License. # under the License.
from unittest import mock from unittest import mock
import uuid
from openstack.block_storage.v2 import snapshot as _snapshot from openstack.block_storage.v2 import snapshot as _snapshot
from openstack.block_storage.v2 import volume as _volume from openstack.block_storage.v2 import volume as _volume
@@ -1622,42 +1623,83 @@ class TestVolumeSet(TestVolume):
self.assertIsNone(result) self.assertIsNone(result)
class TestVolumeShow(TestVolume): class TestVolumeShow(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self._volume = volume_fakes.create_one_volume() self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
self.volumes_mock.get.return_value = self._volume self.volume_sdk_client.find_volume.return_value = self.volume
# Get the command object to test
self.columns = (
'attachments',
'availability_zone',
'bootable',
'consistencygroup_id',
'created_at',
'description',
'encrypted',
'id',
'multiattach',
'name',
'os-vol-host-attr:host',
'os-vol-mig-status-attr:migstat',
'os-vol-mig-status-attr:name_id',
'os-vol-tenant-attr:tenant_id',
'os-volume-replication:driver_data',
'os-volume-replication:extended_status',
'properties',
'replication_status',
'size',
'snapshot_id',
'source_volid',
'status',
'type',
'updated_at',
'user_id',
'volume_image_metadata',
)
self.data = (
self.volume.attachments,
self.volume.availability_zone,
self.volume.is_bootable,
self.volume.consistency_group_id,
self.volume.created_at,
self.volume.description,
self.volume.is_encrypted,
self.volume.id,
self.volume.is_multiattach,
self.volume.name,
self.volume.host,
self.volume.migration_status,
self.volume.migration_id,
self.volume.project_id,
self.volume.replication_driver_data,
self.volume.extended_replication_status,
format_columns.DictColumn(self.volume.metadata),
self.volume.replication_status,
self.volume.size,
self.volume.snapshot_id,
self.volume.source_volume_id,
self.volume.status,
self.volume.volume_type,
self.volume.updated_at,
self.volume.user_id,
self.volume.volume_image_metadata,
)
self.cmd = volume.ShowVolume(self.app, None) self.cmd = volume.ShowVolume(self.app, None)
def test_volume_show(self): def test_volume_show(self):
arglist = [self._volume.id] arglist = [self.volume.id]
verifylist = [("volume", self._volume.id)] verifylist = [("volume", self.volume.id)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.get.assert_called_with(self._volume.id)
self.assertEqual( self.assertEqual(self.columns, columns)
tuple(sorted(self._volume.keys())), self.assertEqual(self.data, data)
columns, self.volume_sdk_client.find_volume.assert_called_with(
) self.volume.id, ignore_missing=False
self.assertTupleEqual(
(
self._volume.attachments,
self._volume.availability_zone,
self._volume.bootable,
self._volume.description,
self._volume.id,
self._volume.name,
format_columns.DictColumn(self._volume.metadata),
self._volume.size,
self._volume.snapshot_id,
self._volume.status,
self._volume.volume_type,
),
data,
) )
@@ -1748,31 +1790,47 @@ class TestVolumeUnset(TestVolume):
) )
class TestColumns(TestVolume): class TestColumns(volume_fakes.TestVolume):
def test_attachments_column_without_server_cache(self): def test_attachments_column_without_server_cache(self):
_volume = volume_fakes.create_one_volume() vol = sdk_fakes.generate_fake_resource(
server_id = _volume.attachments[0]['server_id'] _volume.Volume,
device = _volume.attachments[0]['device'] attachments=[
{
'device': '/dev/' + uuid.uuid4().hex,
'server_id': uuid.uuid4().hex,
},
],
)
server_id = vol.attachments[0]['server_id']
device = vol.attachments[0]['device']
col = volume.AttachmentsColumn(_volume.attachments, {}) col = volume.AttachmentsColumn(vol.attachments, {})
self.assertEqual( self.assertEqual(
f'Attached to {server_id} on {device} ', f'Attached to {server_id} on {device} ',
col.human_readable(), col.human_readable(),
) )
self.assertEqual(_volume.attachments, col.machine_readable()) self.assertEqual(vol.attachments, col.machine_readable())
def test_attachments_column_with_server_cache(self): def test_attachments_column_with_server_cache(self):
_volume = volume_fakes.create_one_volume() vol = sdk_fakes.generate_fake_resource(
_volume.Volume,
attachments=[
{
'device': '/dev/' + uuid.uuid4().hex,
'server_id': uuid.uuid4().hex,
},
],
)
server_id = _volume.attachments[0]['server_id'] server_id = vol.attachments[0]['server_id']
device = _volume.attachments[0]['device'] device = vol.attachments[0]['device']
fake_server = mock.Mock() fake_server = mock.Mock()
fake_server.name = 'fake-server-name' fake_server.name = 'fake-server-name'
server_cache = {server_id: fake_server} server_cache = {server_id: fake_server}
col = volume.AttachmentsColumn(_volume.attachments, server_cache) col = volume.AttachmentsColumn(vol.attachments, server_cache)
self.assertEqual( self.assertEqual(
'Attached to {} on {} '.format('fake-server-name', device), 'Attached to {} on {} '.format('fake-server-name', device),
col.human_readable(), col.human_readable(),
) )
self.assertEqual(_volume.attachments, col.machine_readable()) self.assertEqual(vol.attachments, col.machine_readable())

View File

@@ -13,6 +13,7 @@
import copy import copy
from unittest import mock from unittest import mock
import uuid
from openstack.block_storage.v3 import backup as _backup from openstack.block_storage.v3 import backup as _backup
from openstack.block_storage.v3 import block_storage_summary as _summary from openstack.block_storage.v3 import block_storage_summary as _summary
@@ -2004,41 +2005,91 @@ class TestVolumeShow(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volumes_mock = self.volume_client.volumes self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
self.volumes_mock.reset_mock() self.volume_sdk_client.find_volume.return_value = self.volume
self.columns = (
'attachments',
'availability_zone',
'bootable',
'cluster_name',
'consistencygroup_id',
'consumes_quota',
'created_at',
'description',
'encrypted',
'encryption_key_id',
'group_id',
'id',
'multiattach',
'name',
'os-vol-host-attr:host',
'os-vol-mig-status-attr:migstat',
'os-vol-mig-status-attr:name_id',
'os-vol-tenant-attr:tenant_id',
'properties',
'provider_id',
'replication_status',
'service_uuid',
'shared_targets',
'size',
'snapshot_id',
'source_volid',
'status',
'type',
'updated_at',
'user_id',
'volume_image_metadata',
'volume_type_id',
)
self.data = (
self.volume.attachments,
self.volume.availability_zone,
self.volume.is_bootable,
self.volume.cluster_name,
self.volume.consistency_group_id,
self.volume.consumes_quota,
self.volume.created_at,
self.volume.description,
self.volume.is_encrypted,
self.volume.encryption_key_id,
self.volume.group_id,
self.volume.id,
self.volume.is_multiattach,
self.volume.name,
self.volume.host,
self.volume.migration_status,
self.volume.migration_id,
self.volume.project_id,
format_columns.DictColumn(self.volume.metadata),
self.volume.provider_id,
self.volume.replication_status,
self.volume.service_uuid,
self.volume.shared_targets,
self.volume.size,
self.volume.snapshot_id,
self.volume.source_volume_id,
self.volume.status,
self.volume.volume_type,
self.volume.updated_at,
self.volume.user_id,
self.volume.volume_image_metadata,
self.volume.volume_type_id,
)
self._volume = volume_fakes.create_one_volume()
self.volumes_mock.get.return_value = self._volume
# Get the command object to test
self.cmd = volume.ShowVolume(self.app, None) self.cmd = volume.ShowVolume(self.app, None)
def test_volume_show(self): def test_volume_show(self):
arglist = [self._volume.id] arglist = [self.volume.id]
verifylist = [("volume", self._volume.id)] verifylist = [("volume", self.volume.id)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.get.assert_called_with(self._volume.id)
self.assertEqual( self.assertEqual(self.columns, columns)
tuple(sorted(self._volume.keys())), self.assertEqual(self.data, data)
columns, self.volume_sdk_client.find_volume.assert_called_with(
) self.volume.id, ignore_missing=False
self.assertTupleEqual(
(
self._volume.attachments,
self._volume.availability_zone,
self._volume.bootable,
self._volume.description,
self._volume.id,
self._volume.name,
format_columns.DictColumn(self._volume.metadata),
self._volume.size,
self._volume.snapshot_id,
self._volume.status,
self._volume.volume_type,
),
data,
) )
@@ -2284,29 +2335,45 @@ class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
class TestColumns(volume_fakes.TestVolume): class TestColumns(volume_fakes.TestVolume):
def test_attachments_column_without_server_cache(self): def test_attachments_column_without_server_cache(self):
_volume = volume_fakes.create_one_volume() vol = sdk_fakes.generate_fake_resource(
server_id = _volume.attachments[0]['server_id'] _volume.Volume,
device = _volume.attachments[0]['device'] attachments=[
{
'device': '/dev/' + uuid.uuid4().hex,
'server_id': uuid.uuid4().hex,
},
],
)
server_id = vol.attachments[0]['server_id']
device = vol.attachments[0]['device']
col = volume.AttachmentsColumn(_volume.attachments, {}) col = volume.AttachmentsColumn(vol.attachments, {})
self.assertEqual( self.assertEqual(
f'Attached to {server_id} on {device} ', f'Attached to {server_id} on {device} ',
col.human_readable(), col.human_readable(),
) )
self.assertEqual(_volume.attachments, col.machine_readable()) self.assertEqual(vol.attachments, col.machine_readable())
def test_attachments_column_with_server_cache(self): def test_attachments_column_with_server_cache(self):
_volume = volume_fakes.create_one_volume() vol = sdk_fakes.generate_fake_resource(
_volume.Volume,
attachments=[
{
'device': '/dev/' + uuid.uuid4().hex,
'server_id': uuid.uuid4().hex,
},
],
)
server_id = _volume.attachments[0]['server_id'] server_id = vol.attachments[0]['server_id']
device = _volume.attachments[0]['device'] device = vol.attachments[0]['device']
fake_server = mock.Mock() fake_server = mock.Mock()
fake_server.name = 'fake-server-name' fake_server.name = 'fake-server-name'
server_cache = {server_id: fake_server} server_cache = {server_id: fake_server}
col = volume.AttachmentsColumn(_volume.attachments, server_cache) col = volume.AttachmentsColumn(vol.attachments, server_cache)
self.assertEqual( self.assertEqual(
'Attached to {} on {} '.format('fake-server-name', device), 'Attached to {} on {} '.format('fake-server-name', device),
col.human_readable(), col.human_readable(),
) )
self.assertEqual(_volume.attachments, col.machine_readable()) self.assertEqual(vol.attachments, col.machine_readable())

View File

@@ -955,24 +955,13 @@ class ShowVolume(command.ShowOne):
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.sdk_connection.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume) volume = volume_client.find_volume(
parsed_args.volume, ignore_missing=False
# Special mapping for columns to make the output easier to read:
# 'metadata' --> 'properties'
# 'volume_type' --> 'type'
volume._info.update(
{
'properties': format_columns.DictColumn(
volume._info.pop('metadata')
),
'type': volume._info.pop('volume_type'),
},
) )
# Remove key links from being displayed data = _format_volume(volume)
volume._info.pop("links", None) return zip(*sorted(data.items()))
return zip(*sorted(volume._info.items()))
class UnsetVolume(command.Command): class UnsetVolume(command.Command):

View File

@@ -1116,24 +1116,13 @@ class ShowVolume(command.ShowOne):
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.sdk_connection.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume) volume = volume_client.find_volume(
parsed_args.volume, ignore_missing=False
# Special mapping for columns to make the output easier to read:
# 'metadata' --> 'properties'
# 'volume_type' --> 'type'
volume._info.update(
{
'properties': format_columns.DictColumn(
volume._info.pop('metadata')
),
'type': volume._info.pop('volume_type'),
},
) )
# Remove key links from being displayed data = _format_volume(volume)
volume._info.pop("links", None) return zip(*sorted(data.items()))
return zip(*sorted(volume._info.items()))
class UnsetVolume(command.Command): class UnsetVolume(command.Command):