Fix python integer interpretation in Py2 and Py3

If user passes large number "11111111111111111111111111111" as size to
the create volume api, then the api behaves inconsistently depending
on whether the cinder-api service is running on Py2 and Py3.
In case of Py2, it returns following error message:

ERROR: Invalid input received: Volume size '11111111111111111111111111111'
must be an integer and greater than 0 (HTTP 400) (Request-ID: req-abe6cd5
e-a0c6-4e0d-ba05-c9eceef547bf)

But in case of Py3, it passes this validation.

This patch fixes this inconsistency issue by checking isinstance(size, int)
to isinstance(size, six.integer_types).

NOTE:
The unit test written in the patch will fail on master on Py2 environment
and it's written to just ensure that the issue is resolved for Py2.

Closes-Bug: #1651103
Change-Id: Ib43b96d458f0d4e9477886bd19c35a7e05664929
This commit is contained in:
dineshbhor 2016-12-19 21:13:45 +05:30 committed by Dinesh Bhor
parent 7d51ced776
commit c03c2fa70d
2 changed files with 59 additions and 1 deletions

View File

@ -14,6 +14,8 @@
# under the License.
""" Tests for create_volume TaskFlow """
import sys
import ddt
import mock
@ -343,6 +345,61 @@ class CreateVolumeFlowTestCase(test.TestCase):
'replication_status': 'disabled'}
self.assertEqual(expected_result, result)
@mock.patch('cinder.volume.volume_types.is_encrypted')
@mock.patch('cinder.volume.volume_types.get_volume_type_qos_specs')
@mock.patch('cinder.volume.flows.api.create_volume.'
'ExtractVolumeRequestTask.'
'_get_volume_type_id')
def test_extract_volume_request_task_with_large_volume_size(
self,
fake_get_type_id,
fake_get_qos,
fake_is_encrypted):
fake_image_service = fake_image.FakeImageService()
image_id = 11
image_meta = {}
image_meta['id'] = image_id
image_meta['status'] = 'active'
image_meta['size'] = 1
fake_image_service.create(self.ctxt, image_meta)
fake_key_manager = mock_key_manager.MockKeyManager()
volume_type = 'type1'
task = create_volume.ExtractVolumeRequestTask(
fake_image_service,
{'nova'})
fake_is_encrypted.return_value = False
fake_get_type_id.return_value = 1
fake_get_qos.return_value = {'qos_specs': None}
result = task.execute(self.ctxt,
size=(sys.maxsize + 1),
snapshot=None,
image_id=image_id,
source_volume=None,
availability_zone=None,
volume_type=volume_type,
metadata=None,
key_manager=fake_key_manager,
source_replica=None,
consistencygroup=None,
cgsnapshot=None,
group=None)
expected_result = {'size': (sys.maxsize + 1),
'snapshot_id': None,
'source_volid': None,
'availability_zone': 'nova',
'volume_type': volume_type,
'volume_type_id': 1,
'encryption_key_id': None,
'qos_specs': None,
'replication_status': 'disabled',
'source_replicaid': None,
'consistencygroup_id': None,
'cgsnapshot_id': None,
'group_id': None, }
self.assertEqual(expected_result, result)
@mock.patch('cinder.volume.volume_types.is_encrypted')
@mock.patch('cinder.volume.volume_types.get_volume_type_qos_specs')
@mock.patch('cinder.volume.flows.api.create_volume.'

View File

@ -15,6 +15,7 @@ from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import timeutils
from oslo_utils import units
import six
import taskflow.engines
from taskflow.patterns import linear_flow
from taskflow.types import failure as ft
@ -169,7 +170,7 @@ class ExtractVolumeRequestTask(flow_utils.CinderTask):
raise exception.InvalidInput(reason=msg)
def validate_int(size):
if not isinstance(size, int) or size <= 0:
if not isinstance(size, six.integer_types) or size <= 0:
msg = _("Volume size '%(size)s' must be an integer and"
" greater than 0") % {'size': size}
raise exception.InvalidInput(reason=msg)