Fix 500 error while listing manageable volumes and snapshots

List api for manageable volumes and snapshots returns 500 error if you pass
non-existent marker to it. Both the calls gives rpc.call to volume service
for returning the list. Volume service returns InvalidInput but it's not
catched at c-api side.

At c-api side it comes in the form of oslo_messaging.messaging.RemoteError.
Caught 'InvalidInput' exception by checking RemoteError.exc_type and raised
InvalidInput if manageable volumes and snapshots called with non-existent
marker.

Closes-Bug: #1659772
Change-Id: Icb319a7bffe01c763e5867bc4f7f8eea4f3b893f
This commit is contained in:
Dinesh Bhor 2017-01-24 19:12:32 +05:30
parent a59bce7cfd
commit bb3bfb1434
3 changed files with 50 additions and 4 deletions

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import oslo_messaging as messaging
from cinder.api import common
from cinder import exception
from cinder.i18n import _
@ -39,10 +41,16 @@ def get_manageable_resources(req, is_detail, function_get_manageable,
msg = _("Invalid sort dirs passed: %s") % ', '.join(invalid_dirs)
raise exception.InvalidParameterValue(err=msg)
resources = function_get_manageable(context, host, cluster_name,
marker=marker, limit=limit,
offset=offset, sort_keys=sort_keys,
sort_dirs=sort_dirs)
try:
resources = function_get_manageable(context, host, cluster_name,
marker=marker, limit=limit,
offset=offset, sort_keys=sort_keys,
sort_dirs=sort_dirs)
except messaging.RemoteError as err:
if err.exc_type == "InvalidInput":
raise exception.InvalidInput(err.value)
raise
resource_count = len(resources)
if is_detail:

View File

@ -15,6 +15,7 @@
import mock
from oslo_config import cfg
import oslo_messaging as messaging
from oslo_serialization import jsonutils
try:
from urllib import urlencode
@ -258,6 +259,15 @@ class SnapshotManageTest(test.TestCase):
marker=None, offset=0, sort_dirs=['desc'],
sort_keys=['reference'])
@mock.patch('cinder.volume.api.API.get_manageable_snapshots',
side_effect=messaging.RemoteError(
exc_type='InvalidInput', value='marker not found: 1234'))
def test_get_manageable_snapshots_non_existent_marker(
self, mock_api_manageable):
res = self._get_resp_get('fakehost', detailed=False, paging=True)
self.assertEqual(400, res.status_int)
self.assertTrue(mock_api_manageable.called)
@mock.patch('cinder.volume.api.API.get_manageable_snapshots',
wraps=api_get_manageable_snapshots)
def test_get_manageable_snapshots_detailed_ok(self, mock_api_manageable):
@ -280,6 +290,15 @@ class SnapshotManageTest(test.TestCase):
self._admin_ctxt, 'fakehost', None, limit=10, marker='1234',
offset=4, sort_dirs=['asc'], sort_keys=['reference'])
@mock.patch('cinder.volume.api.API.get_manageable_snapshots',
side_effect=messaging.RemoteError(
exc_type='InvalidInput', value='marker not found: 1234'))
def test_get_manageable_snapshots_non_existent_marker_detailed(
self, mock_api_manageable):
res = self._get_resp_get('fakehost', detailed=True, paging=True)
self.assertEqual(400, res.status_int)
self.assertTrue(mock_api_manageable.called)
@mock.patch('cinder.objects.service.Service.is_up', return_value=True)
@mock.patch('cinder.db.sqlalchemy.api.service_get')
def test_get_manageable_snapshots_disabled(self, mock_db, mock_is_up):

View File

@ -16,6 +16,7 @@
import ddt
import mock
from oslo_config import cfg
import oslo_messaging as messaging
from oslo_serialization import jsonutils
try:
from urllib import urlencode
@ -414,6 +415,15 @@ class VolumeManageTest(test.TestCase):
self._admin_ctxt, 'fakehost', None, limit=10, marker='1234',
offset=4, sort_dirs=['asc'], sort_keys=['reference'])
@mock.patch('cinder.volume.api.API.get_manageable_volumes',
side_effect=messaging.RemoteError(
exc_type='InvalidInput', value='marker not found: 1234'))
def test_get_manageable_volumes_non_existent_marker(self,
mock_api_manageable):
res = self._get_resp_get('fakehost', detailed=False, paging=True)
self.assertEqual(400, res.status_int)
self.assertTrue(mock_api_manageable.called)
@mock.patch('cinder.volume.api.API.get_manageable_volumes',
wraps=api_get_manageable_volumes)
def test_get_manageable_volumes_detailed_ok(self, mock_api_manageable):
@ -433,6 +443,15 @@ class VolumeManageTest(test.TestCase):
marker=None, offset=0, sort_dirs=['desc'],
sort_keys=['reference'])
@mock.patch('cinder.volume.api.API.get_manageable_volumes',
side_effect=messaging.RemoteError(
exc_type='InvalidInput', value='marker not found: 1234'))
def test_get_manageable_volumes_non_existent_marker_detailed(
self, mock_api_manageable):
res = self._get_resp_get('fakehost', detailed=True, paging=True)
self.assertEqual(400, res.status_int)
self.assertTrue(mock_api_manageable.called)
@ddt.data({'a' * 256: 'a'},
{'a': 'a' * 256},
{'': 'a'},