Skip to content

Commit f1f390f

Browse files
committed
volume: add v3-specific volume type module
This makes testing easier. Change-Id: If1ed8d5003160e45d503971ae722fd9983d3dd6d Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
1 parent 65cce39 commit f1f390f

6 files changed

Lines changed: 2222 additions & 177 deletions

File tree

openstackclient/tests/unit/volume/v2/test_volume_type.py

Lines changed: 5 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from unittest import mock
1616
from unittest.mock import call
1717

18-
from cinderclient import api_versions
1918
from osc_lib.cli import format_columns
2019
from osc_lib import exceptions
2120
from osc_lib import utils
@@ -333,7 +332,7 @@ class TestTypeList(TestType):
333332
"Name",
334333
"Is Public",
335334
]
336-
columns_long = columns + ["Description", "Properties"]
335+
columns_long = columns + ["Description"]
337336
data_with_default_type = [(volume_types[0].id, volume_types[0].name, True)]
338337
data = []
339338
for t in volume_types:
@@ -352,7 +351,6 @@ class TestTypeList(TestType):
352351
t.name,
353352
t.is_public,
354353
t.description,
355-
format_columns.DictColumn(t.extra_specs),
356354
)
357355
)
358356

@@ -374,9 +372,7 @@ def test_type_list_without_options(self):
374372
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
375373

376374
columns, data = self.cmd.take_action(parsed_args)
377-
self.volume_types_mock.list.assert_called_once_with(
378-
search_opts={}, is_public=None
379-
)
375+
self.volume_types_mock.list.assert_called_once_with(is_public=None)
380376
self.assertEqual(self.columns, columns)
381377
self.assertCountEqual(self.data, list(data))
382378

@@ -393,9 +389,7 @@ def test_type_list_with_options(self):
393389
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
394390

395391
columns, data = self.cmd.take_action(parsed_args)
396-
self.volume_types_mock.list.assert_called_once_with(
397-
search_opts={}, is_public=True
398-
)
392+
self.volume_types_mock.list.assert_called_once_with(is_public=True)
399393
self.assertEqual(self.columns_long, columns)
400394
self.assertCountEqual(self.data_long, list(data))
401395

@@ -411,9 +405,7 @@ def test_type_list_with_private_option(self):
411405
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
412406

413407
columns, data = self.cmd.take_action(parsed_args)
414-
self.volume_types_mock.list.assert_called_once_with(
415-
search_opts={}, is_public=False
416-
)
408+
self.volume_types_mock.list.assert_called_once_with(is_public=False)
417409
self.assertEqual(self.columns, columns)
418410
self.assertCountEqual(self.data, list(data))
419411

@@ -434,77 +426,6 @@ def test_type_list_with_default_option(self):
434426
self.assertEqual(self.columns, columns)
435427
self.assertCountEqual(self.data_with_default_type, list(data))
436428

437-
def test_type_list_with_properties(self):
438-
self.app.client_manager.volume.api_version = api_versions.APIVersion(
439-
'3.52'
440-
)
441-
442-
arglist = [
443-
"--property",
444-
"foo=bar",
445-
"--multiattach",
446-
"--cacheable",
447-
"--replicated",
448-
"--availability-zone",
449-
"az1",
450-
]
451-
verifylist = [
452-
("encryption_type", False),
453-
("long", False),
454-
("is_public", None),
455-
("default", False),
456-
("properties", {"foo": "bar"}),
457-
("multiattach", True),
458-
("cacheable", True),
459-
("replicated", True),
460-
("availability_zones", ["az1"]),
461-
]
462-
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
463-
464-
columns, data = self.cmd.take_action(parsed_args)
465-
self.volume_types_mock.list.assert_called_once_with(
466-
search_opts={
467-
"extra_specs": {
468-
"foo": "bar",
469-
"multiattach": "<is> True",
470-
"cacheable": "<is> True",
471-
"replication_enabled": "<is> True",
472-
"RESKEY:availability_zones": "az1",
473-
}
474-
},
475-
is_public=None,
476-
)
477-
self.assertEqual(self.columns, columns)
478-
self.assertCountEqual(self.data, list(data))
479-
480-
def test_type_list_with_properties_pre_v352(self):
481-
self.app.client_manager.volume.api_version = api_versions.APIVersion(
482-
'3.51'
483-
)
484-
485-
arglist = [
486-
"--property",
487-
"foo=bar",
488-
]
489-
verifylist = [
490-
("encryption_type", False),
491-
("long", False),
492-
("is_public", None),
493-
("default", False),
494-
("properties", {"foo": "bar"}),
495-
]
496-
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
497-
498-
exc = self.assertRaises(
499-
exceptions.CommandError,
500-
self.cmd.take_action,
501-
parsed_args,
502-
)
503-
self.assertIn(
504-
'--os-volume-api-version 3.52 or greater is required',
505-
str(exc),
506-
)
507-
508429
def test_type_list_with_encryption(self):
509430
encryption_type = volume_fakes.create_one_encryption_volume_type(
510431
attrs={'volume_type_id': self.volume_types[0].id},
@@ -550,9 +471,7 @@ def test_type_list_with_encryption(self):
550471

551472
columns, data = self.cmd.take_action(parsed_args)
552473
self.volume_encryption_types_mock.list.assert_called_once_with()
553-
self.volume_types_mock.list.assert_called_once_with(
554-
search_opts={}, is_public=None
555-
)
474+
self.volume_types_mock.list.assert_called_once_with(is_public=None)
556475
self.assertEqual(encryption_columns, columns)
557476
self.assertCountEqual(encryption_data, list(data))
558477

openstackclient/tests/unit/volume/v3/fakes.py

Lines changed: 130 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,18 @@ def __init__(self, **kwargs):
6262
self.resource_filters.resource_class = fakes.FakeResource(None, {})
6363
self.restores = mock.Mock()
6464
self.restores.resource_class = fakes.FakeResource(None, {})
65-
self.volumes = mock.Mock()
66-
self.volumes.resource_class = fakes.FakeResource(None, {})
65+
self.volume_encryption_types = mock.Mock()
66+
self.volume_encryption_types.resource_class = fakes.FakeResource(
67+
None, {}
68+
)
6769
self.volume_snapshots = mock.Mock()
6870
self.volume_snapshots.resource_class = fakes.FakeResource(None, {})
71+
self.volume_type_access = mock.Mock()
72+
self.volume_type_access.resource_class = fakes.FakeResource(None, {})
6973
self.volume_types = mock.Mock()
7074
self.volume_types.resource_class = fakes.FakeResource(None, {})
75+
self.volumes = mock.Mock()
76+
self.volumes.resource_class = fakes.FakeResource(None, {})
7177
self.services = mock.Mock()
7278
self.services.resource_class = fakes.FakeResource(None, {})
7379
self.workers = mock.Mock()
@@ -118,7 +124,6 @@ def setUp(self):
118124

119125
# TODO(stephenfin): Check if the responses are actually the same
120126
create_one_snapshot = volume_v2_fakes.create_one_snapshot
121-
create_one_volume_type = volume_v2_fakes.create_one_volume_type
122127

123128

124129
def create_one_availability_zone(attrs=None):
@@ -364,6 +369,34 @@ def create_clusters(attrs=None, count=2):
364369
return clusters
365370

366371

372+
def create_one_encryption_volume_type(attrs=None):
373+
"""Create a fake encryption volume type.
374+
375+
:param dict attrs:
376+
A dictionary with all attributes
377+
:return:
378+
A FakeResource object with volume_type_id etc.
379+
"""
380+
attrs = attrs or {}
381+
382+
# Set default attributes.
383+
encryption_info = {
384+
"volume_type_id": 'type-id-' + uuid.uuid4().hex,
385+
'provider': 'LuksEncryptor',
386+
'cipher': None,
387+
'key_size': None,
388+
'control_location': 'front-end',
389+
}
390+
391+
# Overwrite default attributes.
392+
encryption_info.update(attrs)
393+
394+
encryption_type = fakes.FakeResource(
395+
info=copy.deepcopy(encryption_info), loaded=True
396+
)
397+
return encryption_type
398+
399+
367400
def create_one_resource_filter(attrs=None):
368401
"""Create a fake resource filter.
369402
@@ -405,6 +438,31 @@ def create_resource_filters(attrs=None, count=2):
405438
return resource_filters
406439

407440

441+
def create_one_type_access(attrs=None):
442+
"""Create a fake volume type access for project.
443+
444+
:param dict attrs:
445+
A dictionary with all attributes
446+
:return:
447+
A FakeResource object, with Volume_type_ID and Project_ID.
448+
"""
449+
if attrs is None:
450+
attrs = {}
451+
452+
# Set default attributes.
453+
type_access_attrs = {
454+
'volume_type_id': 'volume-type-id-' + uuid.uuid4().hex,
455+
'project_id': 'project-id-' + uuid.uuid4().hex,
456+
}
457+
458+
# Overwrite default attributes.
459+
type_access_attrs.update(attrs)
460+
461+
type_access = fakes.FakeResource(None, type_access_attrs, loaded=True)
462+
463+
return type_access
464+
465+
408466
def create_one_volume(attrs=None):
409467
"""Create a fake volume.
410468
@@ -821,6 +879,75 @@ def get_volume_attachments(attachments=None, count=2):
821879
return mock.Mock(side_effect=attachments)
822880

823881

882+
def create_one_volume_type(attrs=None, methods=None):
883+
"""Create a fake volume type.
884+
885+
:param dict attrs:
886+
A dictionary with all attributes
887+
:param dict methods:
888+
A dictionary with all methods
889+
:return:
890+
A FakeResource object with id, name, description, etc.
891+
"""
892+
attrs = attrs or {}
893+
methods = methods or {}
894+
895+
# Set default attributes.
896+
volume_type_info = {
897+
"id": 'type-id-' + uuid.uuid4().hex,
898+
"name": 'type-name-' + uuid.uuid4().hex,
899+
"description": 'type-description-' + uuid.uuid4().hex,
900+
"extra_specs": {"foo": "bar"},
901+
"is_public": True,
902+
}
903+
904+
# Overwrite default attributes.
905+
volume_type_info.update(attrs)
906+
907+
volume_type = fakes.FakeResource(
908+
info=copy.deepcopy(volume_type_info), methods=methods, loaded=True
909+
)
910+
return volume_type
911+
912+
913+
def create_volume_types(attrs=None, count=2):
914+
"""Create multiple fake volume_types.
915+
916+
:param dict attrs:
917+
A dictionary with all attributes
918+
:param int count:
919+
The number of types to fake
920+
:return:
921+
A list of FakeResource objects faking the types
922+
"""
923+
volume_types = []
924+
for i in range(0, count):
925+
volume_type = create_one_volume_type(attrs)
926+
volume_types.append(volume_type)
927+
928+
return volume_types
929+
930+
931+
def get_volume_types(volume_types=None, count=2):
932+
"""Get an iterable MagicMock object with a list of faked volume types.
933+
934+
If volume_types list is provided, then initialize the Mock object with
935+
the list. Otherwise create one.
936+
937+
:param List volume_types:
938+
A list of FakeResource objects faking volume types
939+
:param Integer count:
940+
The number of volume types to be faked
941+
:return
942+
An iterable Mock object with side_effect set to a list of faked
943+
volume types
944+
"""
945+
if volume_types is None:
946+
volume_types = create_volume_types(count)
947+
948+
return mock.Mock(side_effect=volume_types)
949+
950+
824951
def create_service_log_level_entry(attrs=None):
825952
service_log_level_info = {
826953
'host': 'host_test',

0 commit comments

Comments
 (0)