summaryrefslogtreecommitdiff
path: root/openstackclient/tests/unit/volume
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/tests/unit/volume')
-rw-r--r--openstackclient/tests/unit/volume/v1/test_volume_backup.py52
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume_backup.py74
-rw-r--r--openstackclient/tests/unit/volume/v3/fakes.py109
-rw-r--r--openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py434
-rw-r--r--openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py144
-rw-r--r--openstackclient/tests/unit/volume/v3/test_volume_attachment.py3
6 files changed, 798 insertions, 18 deletions
diff --git a/openstackclient/tests/unit/volume/v1/test_volume_backup.py b/openstackclient/tests/unit/volume/v1/test_volume_backup.py
index f25a5ffa..2f568929 100644
--- a/openstackclient/tests/unit/volume/v1/test_volume_backup.py
+++ b/openstackclient/tests/unit/volume/v1/test_volume_backup.py
@@ -319,29 +319,69 @@ class TestBackupRestore(TestBackup):
attrs={'volume_id': volume.id})
def setUp(self):
- super(TestBackupRestore, self).setUp()
+ super().setUp()
self.backups_mock.get.return_value = self.backup
self.volumes_mock.get.return_value = self.volume
- self.restores_mock.restore.return_value = None
+ self.restores_mock.restore.return_value = (
+ volume_fakes.FakeVolume.create_one_volume(
+ {'id': self.volume['id']},
+ )
+ )
# Get the command object to mock
self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
def test_backup_restore(self):
arglist = [
self.backup.id,
- self.backup.volume_id
]
verifylist = [
("backup", self.backup.id),
- ("volume", self.backup.volume_id)
+ ("volume", None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.restores_mock.restore.assert_called_with(self.backup.id,
- self.backup.volume_id)
- self.assertIsNone(result)
+ None)
+ self.assertIsNotNone(result)
+
+ def test_backup_restore_with_existing_volume(self):
+ arglist = [
+ self.backup.id,
+ self.backup.volume_id,
+ ]
+ verifylist = [
+ ("backup", self.backup.id),
+ ("volume", self.backup.volume_id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.restores_mock.restore.assert_called_with(
+ self.backup.id, self.backup.volume_id,
+ )
+ self.assertIsNotNone(result)
+
+ def test_backup_restore_with_invalid_volume(self):
+ arglist = [
+ self.backup.id,
+ "unexist_volume",
+ ]
+ verifylist = [
+ ("backup", self.backup.id),
+ ("volume", "unexist_volume"),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ with mock.patch.object(
+ utils, 'find_resource',
+ side_effect=exceptions.CommandError(),
+ ):
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args,
+ )
class TestBackupShow(TestBackup):
diff --git a/openstackclient/tests/unit/volume/v2/test_volume_backup.py b/openstackclient/tests/unit/volume/v2/test_volume_backup.py
index 4b9212d0..ffd84901 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume_backup.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume_backup.py
@@ -458,35 +458,95 @@ class TestBackupRestore(TestBackup):
volume = volume_fakes.FakeVolume.create_one_volume()
backup = volume_fakes.FakeBackup.create_one_backup(
- attrs={'volume_id': volume.id})
+ attrs={'volume_id': volume.id},
+ )
def setUp(self):
- super(TestBackupRestore, self).setUp()
+ super().setUp()
self.backups_mock.get.return_value = self.backup
self.volumes_mock.get.return_value = self.volume
self.restores_mock.restore.return_value = (
volume_fakes.FakeVolume.create_one_volume(
- {'id': self.volume['id']}))
+ {'id': self.volume['id']},
+ )
+ )
# Get the command object to mock
self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
def test_backup_restore(self):
+ self.volumes_mock.get.side_effect = exceptions.CommandError()
+ self.volumes_mock.find.side_effect = exceptions.CommandError()
+ arglist = [
+ self.backup.id
+ ]
+ verifylist = [
+ ("backup", self.backup.id),
+ ("volume", None),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.restores_mock.restore.assert_called_with(
+ self.backup.id, None, None,
+ )
+ self.assertIsNotNone(result)
+
+ def test_backup_restore_with_volume(self):
+ self.volumes_mock.get.side_effect = exceptions.CommandError()
+ self.volumes_mock.find.side_effect = exceptions.CommandError()
+ arglist = [
+ self.backup.id,
+ self.backup.volume_id,
+ ]
+ verifylist = [
+ ("backup", self.backup.id),
+ ("volume", self.backup.volume_id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.restores_mock.restore.assert_called_with(
+ self.backup.id, None, self.backup.volume_id,
+ )
+ self.assertIsNotNone(result)
+
+ def test_backup_restore_with_volume_force(self):
arglist = [
+ "--force",
self.backup.id,
- self.backup.volume_id
+ self.volume.name,
]
verifylist = [
+ ("force", True),
("backup", self.backup.id),
- ("volume", self.backup.volume_id)
+ ("volume", self.volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.restores_mock.restore.assert_called_with(self.backup.id,
- self.backup.volume_id)
+ self.restores_mock.restore.assert_called_with(
+ self.backup.id, self.volume.id, None,
+ )
self.assertIsNotNone(result)
+ def test_backup_restore_with_volume_existing(self):
+ arglist = [
+ self.backup.id,
+ self.volume.name,
+ ]
+ verifylist = [
+ ("backup", self.backup.id),
+ ("volume", self.volume.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args,
+ )
+
class TestBackupSet(TestBackup):
diff --git a/openstackclient/tests/unit/volume/v3/fakes.py b/openstackclient/tests/unit/volume/v3/fakes.py
index 9040b2be..e27d7fca 100644
--- a/openstackclient/tests/unit/volume/v3/fakes.py
+++ b/openstackclient/tests/unit/volume/v3/fakes.py
@@ -32,6 +32,8 @@ class FakeVolumeClient(object):
self.attachments = mock.Mock()
self.attachments.resource_class = fakes.FakeResource(None, {})
+ self.clusters = mock.Mock()
+ self.clusters.resource_class = fakes.FakeResource(None, {})
self.groups = mock.Mock()
self.groups.resource_class = fakes.FakeResource(None, {})
self.group_snapshots = mock.Mock()
@@ -40,6 +42,8 @@ class FakeVolumeClient(object):
self.group_types.resource_class = fakes.FakeResource(None, {})
self.messages = mock.Mock()
self.messages.resource_class = fakes.FakeResource(None, {})
+ self.resource_filters = mock.Mock()
+ self.resource_filters.resource_class = fakes.FakeResource(None, {})
self.volumes = mock.Mock()
self.volumes.resource_class = fakes.FakeResource(None, {})
self.volume_types = mock.Mock()
@@ -70,6 +74,105 @@ FakeVolume = volume_v2_fakes.FakeVolume
FakeVolumeType = volume_v2_fakes.FakeVolumeType
+class FakeCluster:
+ """Fake one or more clusters."""
+
+ @staticmethod
+ def create_one_cluster(attrs=None):
+ """Create a fake service cluster.
+
+ :param attrs: A dictionary with all attributes of service cluster
+ :return: A FakeResource object with id, name, status, etc.
+ """
+ attrs = attrs or {}
+
+ # Set default attribute
+ cluster_info = {
+ 'name': f'cluster-{uuid.uuid4().hex}',
+ 'binary': f'binary-{uuid.uuid4().hex}',
+ 'state': random.choice(['up', 'down']),
+ 'status': random.choice(['enabled', 'disabled']),
+ 'disabled_reason': None,
+ 'num_hosts': random.randint(1, 64),
+ 'num_down_hosts': random.randint(1, 64),
+ 'last_heartbeat': '2015-09-16T09:28:52.000000',
+ 'created_at': '2015-09-16T09:28:52.000000',
+ 'updated_at': '2015-09-16T09:28:52.000000',
+ 'replication_status': None,
+ 'frozen': False,
+ 'active_backend_id': None,
+ }
+
+ # Overwrite default attributes if there are some attributes set
+ cluster_info.update(attrs)
+
+ return fakes.FakeResource(
+ None,
+ cluster_info,
+ loaded=True)
+
+ @staticmethod
+ def create_clusters(attrs=None, count=2):
+ """Create multiple fake service clusters.
+
+ :param attrs: A dictionary with all attributes of service cluster
+ :param count: The number of service clusters to be faked
+ :return: A list of FakeResource objects
+ """
+ clusters = []
+ for n in range(0, count):
+ clusters.append(FakeCluster.create_one_cluster(attrs))
+
+ return clusters
+
+
+class FakeResourceFilter:
+ """Fake one or more resource filters."""
+
+ @staticmethod
+ def create_one_resource_filter(attrs=None):
+ """Create a fake resource filter.
+
+ :param attrs: A dictionary with all attributes of resource filter
+ :return: A FakeResource object with id, name, status, etc.
+ """
+ attrs = attrs or {}
+
+ # Set default attribute
+
+ resource_filter_info = {
+ 'filters': [
+ 'name',
+ 'status',
+ 'image_metadata',
+ 'bootable',
+ 'migration_status',
+ ],
+ 'resource': 'volume',
+ }
+
+ # Overwrite default attributes if there are some attributes set
+ resource_filter_info.update(attrs)
+
+ return fakes.FakeResource(None, resource_filter_info, loaded=True)
+
+ @staticmethod
+ def create_resource_filters(attrs=None, count=2):
+ """Create multiple fake resource filters.
+
+ :param attrs: A dictionary with all attributes of resource filter
+ :param count: The number of resource filters to be faked
+ :return: A list of FakeResource objects
+ """
+ resource_filters = []
+ for n in range(0, count):
+ resource_filters.append(
+ FakeResourceFilter.create_one_resource_filter(attrs)
+ )
+
+ return resource_filters
+
+
class FakeVolumeGroup:
"""Fake one or more volume groups."""
@@ -255,11 +358,10 @@ class FakeVolumeMessage:
# Overwrite default attributes if there are some attributes set
message_info.update(attrs)
- message = fakes.FakeResource(
+ return fakes.FakeResource(
None,
message_info,
loaded=True)
- return message
@staticmethod
def create_volume_messages(attrs=None, count=2):
@@ -348,11 +450,10 @@ class FakeVolumeAttachment:
# Overwrite default attributes if there are some attributes set
attachment_info.update(attrs)
- attachment = fakes.FakeResource(
+ return fakes.FakeResource(
None,
attachment_info,
loaded=True)
- return attachment
@staticmethod
def create_volume_attachments(attrs=None, count=2):
diff --git a/openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py b/openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py
new file mode 100644
index 00000000..d87a946b
--- /dev/null
+++ b/openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py
@@ -0,0 +1,434 @@
+# 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 cinderclient import api_versions
+from osc_lib import exceptions
+
+from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
+from openstackclient.volume.v3 import block_storage_cluster
+
+
+class TestBlockStorageCluster(volume_fakes.TestVolume):
+
+ def setUp(self):
+ super().setUp()
+
+ # Get a shortcut to the BlockStorageClusterManager Mock
+ self.cluster_mock = self.app.client_manager.volume.clusters
+ self.cluster_mock.reset_mock()
+
+
+class TestBlockStorageClusterList(TestBlockStorageCluster):
+
+ # The cluster to be listed
+ fake_clusters = volume_fakes.FakeCluster.create_clusters()
+
+ def setUp(self):
+ super().setUp()
+
+ self.cluster_mock.list.return_value = self.fake_clusters
+
+ # Get the command object to test
+ self.cmd = \
+ block_storage_cluster.ListBlockStorageCluster(self.app, None)
+
+ def test_cluster_list(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.7')
+
+ arglist = [
+ ]
+ verifylist = [
+ ('cluster', None),
+ ('binary', None),
+ ('is_up', None),
+ ('is_disabled', None),
+ ('num_hosts', None),
+ ('num_down_hosts', None),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ expected_columns = ('Name', 'Binary', 'State', 'Status')
+ expected_data = tuple(
+ (
+ cluster.name,
+ cluster.binary,
+ cluster.state,
+ cluster.status,
+ ) for cluster in self.fake_clusters
+ )
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, tuple(data))
+
+ # checking if proper call was made to list clusters
+ self.cluster_mock.list.assert_called_with(
+ name=None,
+ binary=None,
+ is_up=None,
+ disabled=None,
+ num_hosts=None,
+ num_down_hosts=None,
+ detailed=False,
+ )
+
+ def test_cluster_list_with_full_options(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.7')
+
+ arglist = [
+ '--cluster', 'foo',
+ '--binary', 'bar',
+ '--up',
+ '--disabled',
+ '--num-hosts', '5',
+ '--num-down-hosts', '0',
+ '--long',
+ ]
+ verifylist = [
+ ('cluster', 'foo'),
+ ('binary', 'bar'),
+ ('is_up', True),
+ ('is_disabled', True),
+ ('num_hosts', 5),
+ ('num_down_hosts', 0),
+ ('long', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ expected_columns = (
+ 'Name',
+ 'Binary',
+ 'State',
+ 'Status',
+ 'Num Hosts',
+ 'Num Down Hosts',
+ 'Last Heartbeat',
+ 'Disabled Reason',
+ 'Created At',
+ 'Updated At',
+ )
+ expected_data = tuple(
+ (
+ cluster.name,
+ cluster.binary,
+ cluster.state,
+ cluster.status,
+ cluster.num_hosts,
+ cluster.num_down_hosts,
+ cluster.last_heartbeat,
+ cluster.disabled_reason,
+ cluster.created_at,
+ cluster.updated_at,
+ ) for cluster in self.fake_clusters
+ )
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, tuple(data))
+
+ # checking if proper call was made to list clusters
+ self.cluster_mock.list.assert_called_with(
+ name='foo',
+ binary='bar',
+ is_up=True,
+ disabled=True,
+ num_hosts=5,
+ num_down_hosts=0,
+ detailed=True,
+ )
+
+ def test_cluster_list_pre_v37(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.6')
+
+ arglist = [
+ ]
+ verifylist = [
+ ('cluster', None),
+ ('binary', None),
+ ('is_up', None),
+ ('is_disabled', None),
+ ('num_hosts', None),
+ ('num_down_hosts', None),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-volume-api-version 3.7 or greater is required', str(exc))
+
+
+class TestBlockStorageClusterSet(TestBlockStorageCluster):
+
+ cluster = volume_fakes.FakeCluster.create_one_cluster()
+ columns = (
+ 'Name',
+ 'Binary',
+ 'State',
+ 'Status',
+ 'Disabled Reason',
+ 'Hosts',
+ 'Down Hosts',
+ 'Last Heartbeat',
+ 'Created At',
+ 'Updated At',
+ 'Replication Status',
+ 'Frozen',
+ 'Active Backend ID',
+ )
+ data = (
+ cluster.name,
+ cluster.binary,
+ cluster.state,
+ cluster.status,
+ cluster.disabled_reason,
+ cluster.num_hosts,
+ cluster.num_down_hosts,
+ cluster.last_heartbeat,
+ cluster.created_at,
+ cluster.updated_at,
+ cluster.replication_status,
+ cluster.frozen,
+ cluster.active_backend_id,
+ )
+
+ def setUp(self):
+ super().setUp()
+
+ self.cluster_mock.update.return_value = self.cluster
+
+ self.cmd = \
+ block_storage_cluster.SetBlockStorageCluster(self.app, None)
+
+ def test_cluster_set(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.7')
+
+ arglist = [
+ '--enable',
+ self.cluster.name,
+ ]
+ verifylist = [
+ ('cluster', self.cluster.name),
+ ('binary', 'cinder-volume'),
+ ('disabled', False),
+ ('disabled_reason', None),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, tuple(data))
+
+ self.cluster_mock.update.assert_called_once_with(
+ self.cluster.name,
+ 'cinder-volume',
+ disabled=False,
+ disabled_reason=None,
+ )
+
+ def test_cluster_set_disable_with_reason(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.7')
+
+ arglist = [
+ '--binary', self.cluster.binary,
+ '--disable',
+ '--disable-reason', 'foo',
+ self.cluster.name,
+ ]
+ verifylist = [
+ ('cluster', self.cluster.name),
+ ('binary', self.cluster.binary),
+ ('disabled', True),
+ ('disabled_reason', 'foo'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, tuple(data))
+
+ self.cluster_mock.update.assert_called_once_with(
+ self.cluster.name,
+ self.cluster.binary,
+ disabled=True,
+ disabled_reason='foo',
+ )
+
+ def test_cluster_set_only_with_disable_reason(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.7')
+
+ arglist = [
+ '--disable-reason', 'foo',
+ self.cluster.name,
+ ]
+ verifylist = [
+ ('cluster', self.cluster.name),
+ ('binary', 'cinder-volume'),
+ ('disabled', None),
+ ('disabled_reason', 'foo'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ "Cannot specify --disable-reason without --disable", str(exc))
+
+ def test_cluster_set_enable_with_disable_reason(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.7')
+
+ arglist = [
+ '--enable',
+ '--disable-reason', 'foo',
+ self.cluster.name,
+ ]
+ verifylist = [
+ ('cluster', self.cluster.name),
+ ('binary', 'cinder-volume'),
+ ('disabled', False),
+ ('disabled_reason', 'foo'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ "Cannot specify --disable-reason without --disable", str(exc))
+
+ def test_cluster_set_pre_v37(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.6')
+
+ arglist = [
+ '--enable',
+ self.cluster.name,
+ ]
+ verifylist = [
+ ('cluster', self.cluster.name),
+ ('binary', 'cinder-volume'),
+ ('disabled', False),
+ ('disabled_reason', None),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-volume-api-version 3.7 or greater is required', str(exc))
+
+
+class TestBlockStorageClusterShow(TestBlockStorageCluster):
+
+ cluster = volume_fakes.FakeCluster.create_one_cluster()
+ columns = (
+ 'Name',
+ 'Binary',
+ 'State',
+ 'Status',
+ 'Disabled Reason',
+ 'Hosts',
+ 'Down Hosts',
+ 'Last Heartbeat',
+ 'Created At',
+ 'Updated At',
+ 'Replication Status',
+ 'Frozen',
+ 'Active Backend ID',
+ )
+ data = (
+ cluster.name,
+ cluster.binary,
+ cluster.state,
+ cluster.status,
+ cluster.disabled_reason,
+ cluster.num_hosts,
+ cluster.num_down_hosts,
+ cluster.last_heartbeat,
+ cluster.created_at,
+ cluster.updated_at,
+ cluster.replication_status,
+ cluster.frozen,
+ cluster.active_backend_id,
+ )
+
+ def setUp(self):
+ super().setUp()
+
+ self.cluster_mock.show.return_value = self.cluster
+
+ self.cmd = \
+ block_storage_cluster.ShowBlockStorageCluster(self.app, None)
+
+ def test_cluster_show(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.7')
+
+ arglist = [
+ '--binary', self.cluster.binary,
+ self.cluster.name,
+ ]
+ verifylist = [
+ ('cluster', self.cluster.name),
+ ('binary', self.cluster.binary),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, tuple(data))
+
+ self.cluster_mock.show.assert_called_once_with(
+ self.cluster.name,
+ binary=self.cluster.binary,
+ )
+
+ def test_cluster_show_pre_v37(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.6')
+
+ arglist = [
+ '--binary', self.cluster.binary,
+ self.cluster.name,
+ ]
+ verifylist = [
+ ('cluster', self.cluster.name),
+ ('binary', self.cluster.binary),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-volume-api-version 3.7 or greater is required', str(exc))
diff --git a/openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py b/openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py
new file mode 100644
index 00000000..b886726d
--- /dev/null
+++ b/openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py
@@ -0,0 +1,144 @@
+# 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 cinderclient import api_versions
+from osc_lib import exceptions
+
+from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
+from openstackclient.volume.v3 import block_storage_resource_filter
+
+
+class TestBlockStorageResourceFilter(volume_fakes.TestVolume):
+
+ def setUp(self):
+ super().setUp()
+
+ # Get a shortcut to the ResourceFilterManager Mock
+ self.resource_filter_mock = \
+ self.app.client_manager.volume.resource_filters
+ self.resource_filter_mock.reset_mock()
+
+
+class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
+
+ # The resource filters to be listed
+ fake_resource_filters = \
+ volume_fakes.FakeResourceFilter.create_resource_filters()
+
+ def setUp(self):
+ super().setUp()
+
+ self.resource_filter_mock.list.return_value = \
+ self.fake_resource_filters
+
+ # Get the command object to test
+ self.cmd = block_storage_resource_filter\
+ .ListBlockStorageResourceFilter(self.app, None)
+
+ def test_resource_filter_list(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.33')
+
+ arglist = []
+ verifylist = []
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ expected_columns = ('Resource', 'Filters')
+ expected_data = tuple(
+ (
+ resource_filter.resource,
+ resource_filter.filters,
+ ) for resource_filter in self.fake_resource_filters
+ )
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, tuple(data))
+
+ # checking if proper call was made to list clusters
+ self.resource_filter_mock.list.assert_called_with()
+
+ def test_resource_filter_list_pre_v333(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.32')
+
+ arglist = []
+ verifylist = []
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-volume-api-version 3.33 or greater is required', str(exc))
+
+
+class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
+
+ # The resource filters to be listed
+ fake_resource_filter = \
+ volume_fakes.FakeResourceFilter.create_one_resource_filter()
+
+ def setUp(self):
+ super().setUp()
+
+ self.resource_filter_mock.list.return_value = \
+ iter([self.fake_resource_filter])
+
+ # Get the command object to test
+ self.cmd = block_storage_resource_filter\
+ .ShowBlockStorageResourceFilter(self.app, None)
+
+ def test_resource_filter_show(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.33')
+
+ arglist = [
+ self.fake_resource_filter.resource,
+ ]
+ verifylist = [
+ ('resource', self.fake_resource_filter.resource),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ expected_columns = ('filters', 'resource')
+ expected_data = (
+ self.fake_resource_filter.filters,
+ self.fake_resource_filter.resource,
+ )
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, data)
+
+ # checking if proper call was made to list clusters
+ self.resource_filter_mock.list.assert_called_with(resource='volume')
+
+ def test_resource_filter_show_pre_v333(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.32')
+
+ arglist = [
+ self.fake_resource_filter.resource,
+ ]
+ verifylist = [
+ ('resource', self.fake_resource_filter.resource),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-volume-api-version 3.33 or greater is required', str(exc))
diff --git a/openstackclient/tests/unit/volume/v3/test_volume_attachment.py b/openstackclient/tests/unit/volume/v3/test_volume_attachment.py
index 09f698e7..44fac6c5 100644
--- a/openstackclient/tests/unit/volume/v3/test_volume_attachment.py
+++ b/openstackclient/tests/unit/volume/v3/test_volume_attachment.py
@@ -73,8 +73,9 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
self.volumes_mock.get.return_value = self.volume
self.servers_mock.get.return_value = self.server
+ # VolumeAttachmentManager.create returns a dict
self.volume_attachments_mock.create.return_value = \
- self.volume_attachment
+ self.volume_attachment.to_dict()
self.cmd = volume_attachment.CreateVolumeAttachment(self.app, None)