Skip to content

Commit 5cf3929

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Check volume status before extending size"
2 parents 1cb56a6 + 8968bc0 commit 5cf3929

5 files changed

Lines changed: 220 additions & 10 deletions

File tree

openstackclient/tests/fakes.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,34 @@ def make_string(self):
5252
return result
5353

5454

55+
class FakeLog(object):
56+
def __init__(self):
57+
self.messages = {}
58+
59+
def debug(self, msg):
60+
self.messages['debug'] = msg
61+
62+
def info(self, msg):
63+
self.messages['info'] = msg
64+
65+
def warning(self, msg):
66+
self.messages['warning'] = msg
67+
68+
def error(self, msg):
69+
self.messages['error'] = msg
70+
71+
def critical(self, msg):
72+
self.messages['critical'] = msg
73+
74+
5575
class FakeApp(object):
56-
def __init__(self, _stdout):
76+
def __init__(self, _stdout, _log):
5777
self.stdout = _stdout
5878
self.client_manager = None
5979
self.stdin = sys.stdin
6080
self.stdout = _stdout or sys.stdout
6181
self.stderr = sys.stderr
82+
self.log = _log
6283

6384

6485
class FakeClient(object):

openstackclient/tests/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ def setUp(self):
8080
super(TestCommand, self).setUp()
8181
# Build up a fake app
8282
self.fake_stdout = fakes.FakeStdout()
83-
self.app = fakes.FakeApp(self.fake_stdout)
83+
self.fake_log = fakes.FakeLog()
84+
self.app = fakes.FakeApp(self.fake_stdout, self.fake_log)
8485
self.app.client_manager = fakes.FakeClientManager()
8586

8687
def check_parser(self, cmd, args, verify_args):

openstackclient/tests/volume/v1/fakes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
volume_id = 'vvvvvvvv-vvvv-vvvv-vvvvvvvv'
2424
volume_name = 'nigel'
2525
volume_description = 'Nigel Tufnel'
26+
volume_status = 'available'
2627
volume_size = 120
2728
volume_type = 'to-eleven'
2829
volume_zone = 'stonehenge'
@@ -38,7 +39,7 @@
3839
'display_name': volume_name,
3940
'display_description': volume_description,
4041
'size': volume_size,
41-
'status': '',
42+
'status': volume_status,
4243
'attach_status': 'detached',
4344
'availability_zone': volume_zone,
4445
'volume_type': volume_type,

openstackclient/tests/volume/v1/test_volume.py

Lines changed: 189 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def test_volume_create_min_options(self):
114114
volume_fakes.volume_id,
115115
volume_fakes.volume_metadata_str,
116116
volume_fakes.volume_size,
117-
'',
117+
volume_fakes.volume_status,
118118
volume_fakes.volume_type,
119119
)
120120
self.assertEqual(datalist, data)
@@ -178,7 +178,7 @@ def test_volume_create_options(self):
178178
volume_fakes.volume_id,
179179
volume_fakes.volume_metadata_str,
180180
volume_fakes.volume_size,
181-
'',
181+
volume_fakes.volume_status,
182182
volume_fakes.volume_type,
183183
)
184184
self.assertEqual(datalist, data)
@@ -253,7 +253,7 @@ def test_volume_create_user_project_id(self):
253253
volume_fakes.volume_id,
254254
volume_fakes.volume_metadata_str,
255255
volume_fakes.volume_size,
256-
'',
256+
volume_fakes.volume_status,
257257
volume_fakes.volume_type,
258258
)
259259
self.assertEqual(datalist, data)
@@ -328,7 +328,7 @@ def test_volume_create_user_project_name(self):
328328
volume_fakes.volume_id,
329329
volume_fakes.volume_metadata_str,
330330
volume_fakes.volume_size,
331-
'',
331+
volume_fakes.volume_status,
332332
volume_fakes.volume_type,
333333
)
334334
self.assertEqual(datalist, data)
@@ -389,7 +389,7 @@ def test_volume_create_properties(self):
389389
volume_fakes.volume_id,
390390
volume_fakes.volume_metadata_str,
391391
volume_fakes.volume_size,
392-
'',
392+
volume_fakes.volume_status,
393393
volume_fakes.volume_type,
394394
)
395395
self.assertEqual(datalist, data)
@@ -455,7 +455,7 @@ def test_volume_create_image_id(self):
455455
volume_fakes.volume_id,
456456
volume_fakes.volume_metadata_str,
457457
volume_fakes.volume_size,
458-
'',
458+
volume_fakes.volume_status,
459459
volume_fakes.volume_type,
460460
)
461461
self.assertEqual(datalist, data)
@@ -521,7 +521,189 @@ def test_volume_create_image_name(self):
521521
volume_fakes.volume_id,
522522
volume_fakes.volume_metadata_str,
523523
volume_fakes.volume_size,
524-
'',
524+
volume_fakes.volume_status,
525525
volume_fakes.volume_type,
526526
)
527527
self.assertEqual(datalist, data)
528+
529+
530+
class TestVolumeSet(TestVolume):
531+
532+
def setUp(self):
533+
super(TestVolumeSet, self).setUp()
534+
535+
self.volumes_mock.get.return_value = fakes.FakeResource(
536+
None,
537+
copy.deepcopy(volume_fakes.VOLUME),
538+
loaded=True,
539+
)
540+
541+
self.volumes_mock.update.return_value = fakes.FakeResource(
542+
None,
543+
copy.deepcopy(volume_fakes.VOLUME),
544+
loaded=True,
545+
)
546+
# Get the command object to test
547+
self.cmd = volume.SetVolume(self.app, None)
548+
549+
def test_volume_set_no_options(self):
550+
arglist = [
551+
volume_fakes.volume_name,
552+
]
553+
verifylist = [
554+
('name', None),
555+
('description', None),
556+
('size', None),
557+
('property', None),
558+
('volume', volume_fakes.volume_name),
559+
]
560+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
561+
562+
result = self.cmd.run(parsed_args)
563+
self.assertEqual(0, result)
564+
self.assertEqual("No changes requested\n",
565+
self.app.log.messages.get('error'))
566+
567+
def test_volume_set_name(self):
568+
arglist = [
569+
'--name', 'qwerty',
570+
volume_fakes.volume_name,
571+
]
572+
verifylist = [
573+
('name', 'qwerty'),
574+
('description', None),
575+
('size', None),
576+
('property', None),
577+
('volume', volume_fakes.volume_name),
578+
]
579+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
580+
581+
# DisplayCommandBase.take_action() returns two tuples
582+
self.cmd.take_action(parsed_args)
583+
584+
# Set expected values
585+
kwargs = {
586+
'display_name': 'qwerty',
587+
}
588+
self.volumes_mock.update.assert_called_with(
589+
volume_fakes.volume_id,
590+
**kwargs
591+
)
592+
593+
def test_volume_set_description(self):
594+
arglist = [
595+
'--description', 'new desc',
596+
volume_fakes.volume_name,
597+
]
598+
verifylist = [
599+
('name', None),
600+
('description', 'new desc'),
601+
('size', None),
602+
('property', None),
603+
('volume', volume_fakes.volume_name),
604+
]
605+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
606+
607+
# DisplayCommandBase.take_action() returns two tuples
608+
self.cmd.take_action(parsed_args)
609+
610+
# Set expected values
611+
kwargs = {
612+
'display_description': 'new desc',
613+
}
614+
self.volumes_mock.update.assert_called_with(
615+
volume_fakes.volume_id,
616+
**kwargs
617+
)
618+
619+
def test_volume_set_size(self):
620+
arglist = [
621+
'--size', '130',
622+
volume_fakes.volume_name,
623+
]
624+
verifylist = [
625+
('name', None),
626+
('description', None),
627+
('size', 130),
628+
('property', None),
629+
('volume', volume_fakes.volume_name),
630+
]
631+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
632+
633+
# DisplayCommandBase.take_action() returns two tuples
634+
self.cmd.take_action(parsed_args)
635+
636+
# Set expected values
637+
size = 130
638+
639+
self.volumes_mock.extend.assert_called_with(
640+
volume_fakes.volume_id,
641+
size
642+
)
643+
644+
def test_volume_set_size_smaller(self):
645+
arglist = [
646+
'--size', '100',
647+
volume_fakes.volume_name,
648+
]
649+
verifylist = [
650+
('name', None),
651+
('description', None),
652+
('size', 100),
653+
('property', None),
654+
('volume', volume_fakes.volume_name),
655+
]
656+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
657+
658+
result = self.cmd.run(parsed_args)
659+
self.assertEqual(0, result)
660+
self.assertEqual("New size must be greater than %s GB" %
661+
volume_fakes.volume_size,
662+
self.app.log.messages.get('error'))
663+
664+
def test_volume_set_size_not_available(self):
665+
self.volumes_mock.get.return_value.status = 'error'
666+
arglist = [
667+
'--size', '130',
668+
volume_fakes.volume_name,
669+
]
670+
verifylist = [
671+
('name', None),
672+
('description', None),
673+
('size', 130),
674+
('property', None),
675+
('volume', volume_fakes.volume_name),
676+
]
677+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
678+
679+
result = self.cmd.run(parsed_args)
680+
self.assertEqual(0, result)
681+
self.assertEqual("Volume is in %s state, it must be available before "
682+
"size can be extended" % 'error',
683+
self.app.log.messages.get('error'))
684+
685+
def test_volume_set_property(self):
686+
arglist = [
687+
'--property', 'myprop=myvalue',
688+
volume_fakes.volume_name,
689+
]
690+
verifylist = [
691+
('name', None),
692+
('description', None),
693+
('size', None),
694+
('property', {'myprop': 'myvalue'}),
695+
('volume', volume_fakes.volume_name),
696+
]
697+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
698+
699+
# DisplayCommandBase.take_action() returns two tuples
700+
self.cmd.take_action(parsed_args)
701+
702+
# Set expected values
703+
metadata = {
704+
'myprop': 'myvalue'
705+
}
706+
self.volumes_mock.set_metadata.assert_called_with(
707+
volume_fakes.volume_id,
708+
metadata
709+
)

openstackclient/volume/v1/volume.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ def take_action(self, parsed_args):
348348
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
349349

350350
if parsed_args.size:
351+
if volume.status != 'available':
352+
self.app.log.error("Volume is in %s state, it must be "
353+
"available before size can be extended" %
354+
volume.status)
355+
return
351356
if parsed_args.size <= volume.size:
352357
self.app.log.error("New size must be greater than %s GB" %
353358
volume.size)

0 commit comments

Comments
 (0)