Optional size parameter for volume creation
This patch makes optional the parameter size for creating a volume from a snapshot or other volume. The parameter is still required for other kind of volume creation. Change-Id: I75dcf0e647f6e82a2407bcf23ef359f5f87323e8 Closes-Bug: #1304463
This commit is contained in:
		@@ -34,7 +34,22 @@ def assert_has_keys(dict, required=[], optional=[]):
 | 
			
		||||
 | 
			
		||||
class FakeClient(object):
 | 
			
		||||
 | 
			
		||||
    def assert_called(self, method, url, body=None, pos=-1, **kwargs):
 | 
			
		||||
    def _dict_match(self, partial, real):
 | 
			
		||||
 | 
			
		||||
        result = True
 | 
			
		||||
        try:
 | 
			
		||||
            for key, value in partial.items():
 | 
			
		||||
                if type(value) is dict:
 | 
			
		||||
                    result = self._dict_match(value, real[key])
 | 
			
		||||
                else:
 | 
			
		||||
                    assert real[key] == value
 | 
			
		||||
                    result = True
 | 
			
		||||
        except (AssertionError, KeyError):
 | 
			
		||||
            result = False
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def assert_called(self, method, url, body=None,
 | 
			
		||||
                      partial_body=None, pos=-1, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Assert than an API method was just called.
 | 
			
		||||
        """
 | 
			
		||||
@@ -50,7 +65,17 @@ class FakeClient(object):
 | 
			
		||||
        if body is not None:
 | 
			
		||||
            assert self.client.callstack[pos][2] == body
 | 
			
		||||
 | 
			
		||||
    def assert_called_anytime(self, method, url, body=None):
 | 
			
		||||
        if partial_body is not None:
 | 
			
		||||
            try:
 | 
			
		||||
                assert self._dict_match(partial_body,
 | 
			
		||||
                                        self.client.callstack[pos][2])
 | 
			
		||||
            except AssertionError:
 | 
			
		||||
                print(self.client.callstack[pos][2])
 | 
			
		||||
                print("does not contain")
 | 
			
		||||
                print(partial_body)
 | 
			
		||||
                raise
 | 
			
		||||
 | 
			
		||||
    def assert_called_anytime(self, method, url, body=None, partial_body=None):
 | 
			
		||||
        """
 | 
			
		||||
        Assert than an API method was called anytime in the test.
 | 
			
		||||
        """
 | 
			
		||||
@@ -77,6 +102,15 @@ class FakeClient(object):
 | 
			
		||||
                print(body)
 | 
			
		||||
                raise
 | 
			
		||||
 | 
			
		||||
        if partial_body is not None:
 | 
			
		||||
            try:
 | 
			
		||||
                assert self._dict_match(partial_body, entry[2])
 | 
			
		||||
            except AssertionError:
 | 
			
		||||
                print(entry[2])
 | 
			
		||||
                print("does not contain")
 | 
			
		||||
                print(partial_body)
 | 
			
		||||
                raise
 | 
			
		||||
 | 
			
		||||
    def clear_callstack(self):
 | 
			
		||||
        self.client.callstack = []
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -376,7 +376,9 @@ class FakeHTTPClient(base_client.HTTPClient):
 | 
			
		||||
        return self.post_volumes_1234_action(body, **kw)
 | 
			
		||||
 | 
			
		||||
    def post_volumes(self, **kw):
 | 
			
		||||
        return (202, {}, {'volume': {}})
 | 
			
		||||
        size = kw['body']['volume'].get('size', 1)
 | 
			
		||||
        volume = _stub_volume(id='1234', size=size)
 | 
			
		||||
        return (202, {}, {'volume': volume})
 | 
			
		||||
 | 
			
		||||
    def delete_volumes_1234(self, **kw):
 | 
			
		||||
        return (202, {}, None)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,13 +14,13 @@
 | 
			
		||||
#    under the License.
 | 
			
		||||
 | 
			
		||||
import fixtures
 | 
			
		||||
import httpretty
 | 
			
		||||
 | 
			
		||||
from cinderclient import client
 | 
			
		||||
from cinderclient import shell
 | 
			
		||||
from cinderclient.tests import utils
 | 
			
		||||
from cinderclient.tests.v2 import fakes
 | 
			
		||||
from cinderclient.tests.fixture_data import keystone_client
 | 
			
		||||
import httpretty
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShellTest(utils.TestCase):
 | 
			
		||||
@@ -66,11 +66,15 @@ class ShellTest(utils.TestCase):
 | 
			
		||||
    def run_command(self, cmd):
 | 
			
		||||
        self.shell.main(cmd.split())
 | 
			
		||||
 | 
			
		||||
    def assert_called(self, method, url, body=None, **kwargs):
 | 
			
		||||
        return self.shell.cs.assert_called(method, url, body, **kwargs)
 | 
			
		||||
    def assert_called(self, method, url, body=None,
 | 
			
		||||
                      partial_body=None, **kwargs):
 | 
			
		||||
        return self.shell.cs.assert_called(method, url, body,
 | 
			
		||||
                                           partial_body, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def assert_called_anytime(self, method, url, body=None):
 | 
			
		||||
        return self.shell.cs.assert_called_anytime(method, url, body)
 | 
			
		||||
    def assert_called_anytime(self, method, url, body=None,
 | 
			
		||||
                              partial_body=None):
 | 
			
		||||
        return self.shell.cs.assert_called_anytime(method, url, body,
 | 
			
		||||
                                                   partial_body)
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_list(self):
 | 
			
		||||
@@ -103,6 +107,41 @@ class ShellTest(utils.TestCase):
 | 
			
		||||
        self.run_command('availability-zone-list')
 | 
			
		||||
        self.assert_called('GET', '/os-availability-zone')
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_create_volume_from_snapshot(self):
 | 
			
		||||
        self.register_keystone_auth_fixture()
 | 
			
		||||
        expected = {'volume': {'size': None}}
 | 
			
		||||
 | 
			
		||||
        expected['volume']['snapshot_id'] = '1234'
 | 
			
		||||
        self.run_command('create --snapshot-id=1234')
 | 
			
		||||
        self.assert_called_anytime('POST', '/volumes', partial_body=expected)
 | 
			
		||||
        self.assert_called('GET', '/volumes/1234')
 | 
			
		||||
 | 
			
		||||
        expected['volume']['size'] = 2
 | 
			
		||||
        self.run_command('create --snapshot-id=1234 2')
 | 
			
		||||
        self.assert_called_anytime('POST', '/volumes', partial_body=expected)
 | 
			
		||||
        self.assert_called('GET', '/volumes/1234')
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_create_volume_from_volume(self):
 | 
			
		||||
        self.register_keystone_auth_fixture()
 | 
			
		||||
        expected = {'volume': {'size': None}}
 | 
			
		||||
 | 
			
		||||
        expected['volume']['source_volid'] = '1234'
 | 
			
		||||
        self.run_command('create --source-volid=1234')
 | 
			
		||||
        self.assert_called_anytime('POST', '/volumes', partial_body=expected)
 | 
			
		||||
        self.assert_called('GET', '/volumes/1234')
 | 
			
		||||
 | 
			
		||||
        expected['volume']['size'] = 2
 | 
			
		||||
        self.run_command('create --source-volid=1234 2')
 | 
			
		||||
        self.assert_called_anytime('POST', '/volumes', partial_body=expected)
 | 
			
		||||
        self.assert_called('GET', '/volumes/1234')
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_create_size_required_if_not_snapshot_or_clone(self):
 | 
			
		||||
        self.register_keystone_auth_fixture()
 | 
			
		||||
        self.assertRaises(SystemExit, self.run_command, 'create')
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_show(self):
 | 
			
		||||
        self.register_keystone_auth_fixture()
 | 
			
		||||
 
 | 
			
		||||
@@ -195,10 +195,21 @@ def do_show(cs, args):
 | 
			
		||||
    utils.print_dict(info)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CheckSizeArgForCreate(argparse.Action):
 | 
			
		||||
    def __call__(self, parser, args, values, option_string=None):
 | 
			
		||||
        if (values or args.snapshot_id or args.source_volid) is None:
 | 
			
		||||
            parser.error('Size is a required parameter if snapshot '
 | 
			
		||||
                         'or source volume is not specified.')
 | 
			
		||||
        setattr(args, self.dest, values)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@utils.arg('size',
 | 
			
		||||
           metavar='<size>',
 | 
			
		||||
           nargs='?',
 | 
			
		||||
           type=int,
 | 
			
		||||
           help='Size of volume, in GBs.')
 | 
			
		||||
           action=CheckSizeArgForCreate,
 | 
			
		||||
           help='Size of volume, in GBs. (Required unless '
 | 
			
		||||
                'snapshot-id/source-volid is specified).')
 | 
			
		||||
@utils.arg('--snapshot-id',
 | 
			
		||||
           metavar='<snapshot-id>',
 | 
			
		||||
           default=None,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user