'name',
'description')
+ def test_create_volume_with_float_fails(self):
+ """Test volume creation with invalid float size."""
+ volume_api = cinder.volume.api.API()
+ self.assertRaises(exception.InvalidInput,
+ volume_api.create,
+ self.context,
+ '1.5',
+ 'name',
+ 'description')
+
+ def test_create_volume_with_zero_size_fails(self):
+ """Test volume creation with string size."""
+ volume_api = cinder.volume.api.API()
+ self.assertRaises(exception.InvalidInput,
+ volume_api.create,
+ self.context,
+ '0',
+ 'name',
+ 'description')
+
def test_begin_detaching_fails_available(self):
volume_api = cinder.volume.api.API()
volume = tests_utils.create_volume(self.context, **self.volume_params)
return obj
+def is_int_like(val):
+ """Check if a value looks like an int."""
+ try:
+ return str(int(val)) == str(val)
+ except Exception:
+ return False
+
+
def check_exclusive_options(**kwargs):
"""Checks that only one of the provided options is actually not-none.
scheduler_hints=None, backup_source_volume=None,
source_replica=None, consistencygroup=None):
+ # NOTE(jdg): we can have a create without size if we're
+ # doing a create from snap or volume. Currently
+ # the taskflow api will handle this and pull in the
+ # size from the source.
+
+ # NOTE(jdg): cinderclient sends in a string representation
+ # of the size value. BUT there is a possbility that somebody
+ # could call the API directly so the is_int_like check
+ # handles both cases (string representation or true float or int).
+ if size and (not utils.is_int_like(size) or int(size) <= 0):
+ msg = _('Invalid volume size provided for create request '
+ '(size argument must be an integer (or string '
+ 'represenation or an integer) and greater '
+ 'than zero).')
+ raise exception.InvalidInput(reason=msg)
+
if consistencygroup:
if not volume_type:
msg = _("volume_type must be provided when creating "