From 8968bc09797b674b83eee2b3da0f09b3ea4e2d70 Mon Sep 17 00:00:00 2001 From: lin-hua-cheng Date: Thu, 5 Feb 2015 23:40:11 -0800 Subject: [PATCH] Check volume status before extending size Added test for Volume Set as well. Change-Id: I8e6794f67b160ca328fcafa8f1d67138b4f3becd Closes-Bug: #1415182 --- openstackclient/tests/fakes.py | 23 +- openstackclient/tests/utils.py | 3 +- openstackclient/tests/volume/v1/fakes.py | 3 +- .../tests/volume/v1/test_volume.py | 196 +++++++++++++++++- openstackclient/volume/v1/volume.py | 5 + 5 files changed, 220 insertions(+), 10 deletions(-) diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py index d37555e347..323f954306 100644 --- a/openstackclient/tests/fakes.py +++ b/openstackclient/tests/fakes.py @@ -52,13 +52,34 @@ class FakeStdout(object): return result +class FakeLog(object): + def __init__(self): + self.messages = {} + + def debug(self, msg): + self.messages['debug'] = msg + + def info(self, msg): + self.messages['info'] = msg + + def warning(self, msg): + self.messages['warning'] = msg + + def error(self, msg): + self.messages['error'] = msg + + def critical(self, msg): + self.messages['critical'] = msg + + class FakeApp(object): - def __init__(self, _stdout): + def __init__(self, _stdout, _log): self.stdout = _stdout self.client_manager = None self.stdin = sys.stdin self.stdout = _stdout or sys.stdout self.stderr = sys.stderr + self.log = _log class FakeClient(object): diff --git a/openstackclient/tests/utils.py b/openstackclient/tests/utils.py index 7fc7ddfed1..d9abd572bf 100644 --- a/openstackclient/tests/utils.py +++ b/openstackclient/tests/utils.py @@ -80,7 +80,8 @@ class TestCommand(TestCase): super(TestCommand, self).setUp() # Build up a fake app self.fake_stdout = fakes.FakeStdout() - self.app = fakes.FakeApp(self.fake_stdout) + self.fake_log = fakes.FakeLog() + self.app = fakes.FakeApp(self.fake_stdout, self.fake_log) self.app.client_manager = fakes.FakeClientManager() def check_parser(self, cmd, args, verify_args): diff --git a/openstackclient/tests/volume/v1/fakes.py b/openstackclient/tests/volume/v1/fakes.py index 3477819072..339fb2d482 100644 --- a/openstackclient/tests/volume/v1/fakes.py +++ b/openstackclient/tests/volume/v1/fakes.py @@ -23,6 +23,7 @@ from openstackclient.tests import utils volume_id = 'vvvvvvvv-vvvv-vvvv-vvvvvvvv' volume_name = 'nigel' volume_description = 'Nigel Tufnel' +volume_status = 'available' volume_size = 120 volume_type = 'to-eleven' volume_zone = 'stonehenge' @@ -38,7 +39,7 @@ VOLUME = { 'display_name': volume_name, 'display_description': volume_description, 'size': volume_size, - 'status': '', + 'status': volume_status, 'attach_status': 'detached', 'availability_zone': volume_zone, 'volume_type': volume_type, diff --git a/openstackclient/tests/volume/v1/test_volume.py b/openstackclient/tests/volume/v1/test_volume.py index cc5aeff80b..f73260e91d 100644 --- a/openstackclient/tests/volume/v1/test_volume.py +++ b/openstackclient/tests/volume/v1/test_volume.py @@ -114,7 +114,7 @@ class TestVolumeCreate(TestVolume): volume_fakes.volume_id, volume_fakes.volume_metadata_str, volume_fakes.volume_size, - '', + volume_fakes.volume_status, volume_fakes.volume_type, ) self.assertEqual(datalist, data) @@ -178,7 +178,7 @@ class TestVolumeCreate(TestVolume): volume_fakes.volume_id, volume_fakes.volume_metadata_str, volume_fakes.volume_size, - '', + volume_fakes.volume_status, volume_fakes.volume_type, ) self.assertEqual(datalist, data) @@ -253,7 +253,7 @@ class TestVolumeCreate(TestVolume): volume_fakes.volume_id, volume_fakes.volume_metadata_str, volume_fakes.volume_size, - '', + volume_fakes.volume_status, volume_fakes.volume_type, ) self.assertEqual(datalist, data) @@ -328,7 +328,7 @@ class TestVolumeCreate(TestVolume): volume_fakes.volume_id, volume_fakes.volume_metadata_str, volume_fakes.volume_size, - '', + volume_fakes.volume_status, volume_fakes.volume_type, ) self.assertEqual(datalist, data) @@ -389,7 +389,7 @@ class TestVolumeCreate(TestVolume): volume_fakes.volume_id, volume_fakes.volume_metadata_str, volume_fakes.volume_size, - '', + volume_fakes.volume_status, volume_fakes.volume_type, ) self.assertEqual(datalist, data) @@ -455,7 +455,7 @@ class TestVolumeCreate(TestVolume): volume_fakes.volume_id, volume_fakes.volume_metadata_str, volume_fakes.volume_size, - '', + volume_fakes.volume_status, volume_fakes.volume_type, ) self.assertEqual(datalist, data) @@ -521,7 +521,189 @@ class TestVolumeCreate(TestVolume): volume_fakes.volume_id, volume_fakes.volume_metadata_str, volume_fakes.volume_size, - '', + volume_fakes.volume_status, volume_fakes.volume_type, ) self.assertEqual(datalist, data) + + +class TestVolumeSet(TestVolume): + + def setUp(self): + super(TestVolumeSet, self).setUp() + + self.volumes_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.VOLUME), + loaded=True, + ) + + self.volumes_mock.update.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.VOLUME), + loaded=True, + ) + # Get the command object to test + self.cmd = volume.SetVolume(self.app, None) + + def test_volume_set_no_options(self): + arglist = [ + volume_fakes.volume_name, + ] + verifylist = [ + ('name', None), + ('description', None), + ('size', None), + ('property', None), + ('volume', volume_fakes.volume_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.run(parsed_args) + self.assertEqual(0, result) + self.assertEqual("No changes requested\n", + self.app.log.messages.get('error')) + + def test_volume_set_name(self): + arglist = [ + '--name', 'qwerty', + volume_fakes.volume_name, + ] + verifylist = [ + ('name', 'qwerty'), + ('description', None), + ('size', None), + ('property', None), + ('volume', volume_fakes.volume_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'display_name': 'qwerty', + } + self.volumes_mock.update.assert_called_with( + volume_fakes.volume_id, + **kwargs + ) + + def test_volume_set_description(self): + arglist = [ + '--description', 'new desc', + volume_fakes.volume_name, + ] + verifylist = [ + ('name', None), + ('description', 'new desc'), + ('size', None), + ('property', None), + ('volume', volume_fakes.volume_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'display_description': 'new desc', + } + self.volumes_mock.update.assert_called_with( + volume_fakes.volume_id, + **kwargs + ) + + def test_volume_set_size(self): + arglist = [ + '--size', '130', + volume_fakes.volume_name, + ] + verifylist = [ + ('name', None), + ('description', None), + ('size', 130), + ('property', None), + ('volume', volume_fakes.volume_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + # Set expected values + size = 130 + + self.volumes_mock.extend.assert_called_with( + volume_fakes.volume_id, + size + ) + + def test_volume_set_size_smaller(self): + arglist = [ + '--size', '100', + volume_fakes.volume_name, + ] + verifylist = [ + ('name', None), + ('description', None), + ('size', 100), + ('property', None), + ('volume', volume_fakes.volume_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.run(parsed_args) + self.assertEqual(0, result) + self.assertEqual("New size must be greater than %s GB" % + volume_fakes.volume_size, + self.app.log.messages.get('error')) + + def test_volume_set_size_not_available(self): + self.volumes_mock.get.return_value.status = 'error' + arglist = [ + '--size', '130', + volume_fakes.volume_name, + ] + verifylist = [ + ('name', None), + ('description', None), + ('size', 130), + ('property', None), + ('volume', volume_fakes.volume_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.run(parsed_args) + self.assertEqual(0, result) + self.assertEqual("Volume is in %s state, it must be available before " + "size can be extended" % 'error', + self.app.log.messages.get('error')) + + def test_volume_set_property(self): + arglist = [ + '--property', 'myprop=myvalue', + volume_fakes.volume_name, + ] + verifylist = [ + ('name', None), + ('description', None), + ('size', None), + ('property', {'myprop': 'myvalue'}), + ('volume', volume_fakes.volume_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + # Set expected values + metadata = { + 'myprop': 'myvalue' + } + self.volumes_mock.set_metadata.assert_called_with( + volume_fakes.volume_id, + metadata + ) diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py index 9e548977e0..3d26a5e9e5 100644 --- a/openstackclient/volume/v1/volume.py +++ b/openstackclient/volume/v1/volume.py @@ -348,6 +348,11 @@ class SetVolume(command.Command): volume = utils.find_resource(volume_client.volumes, parsed_args.volume) if parsed_args.size: + if volume.status != 'available': + self.app.log.error("Volume is in %s state, it must be " + "available before size can be extended" % + volume.status) + return if parsed_args.size <= volume.size: self.app.log.error("New size must be greater than %s GB" % volume.size)