From 797d932d0f564221a9d126d1ca49de36870c62b6 Mon Sep 17 00:00:00 2001 From: Mykhailo Dovgal <mdovgal@mirantis.com> Date: Wed, 9 Nov 2016 16:18:09 +0200 Subject: [PATCH] Add convertation of query parameters to string There are some problems with non-ascii chars and special symbols during using cinderclient. This patch closes bug connected with parse.urlencode py27 unicode encode bug by adding convertation of query parameters before creating query string in manager._build_list_url method. Also it fix the problems with encoding in quota commands. Change-Id: I96269cca7ad203eaad02d87b30c16d970b26b25f Closes-Bug: #1636621 Closes-Bug: #1518141 --- cinderclient/base.py | 2 +- cinderclient/shell_utils.py | 6 ++++-- cinderclient/tests/unit/test_base.py | 19 ++++++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/cinderclient/base.py b/cinderclient/base.py index fd783f0d0..0705a5e5e 100644 --- a/cinderclient/base.py +++ b/cinderclient/base.py @@ -162,7 +162,7 @@ class Manager(common_base.HookableMixin): if offset: query_params['offset'] = offset - + query_params = utils.unicode_key_value_to_string(query_params) # Transform the dict to a sequence of two-element tuples in fixed # order, then the encoded string will be consistent in Python 2&3. query_string = "" diff --git a/cinderclient/shell_utils.py b/cinderclient/shell_utils.py index fa73777ca..76a814f6a 100644 --- a/cinderclient/shell_utils.py +++ b/cinderclient/shell_utils.py @@ -168,8 +168,9 @@ def print_group_type_list(gtypes): def quota_show(quotas): + quotas_info_dict = utils.unicode_key_value_to_string(quotas._info) quota_dict = {} - for resource in quotas._info: + for resource in quotas_info_dict.keys(): good_name = False for name in _quota_resources: if resource.startswith(name): @@ -182,7 +183,8 @@ def quota_show(quotas): def quota_usage_show(quotas): quota_list = [] - for resource in quotas._info.keys(): + quotas_info_dict = utils.unicode_key_value_to_string(quotas._info) + for resource in quotas_info_dict.keys(): good_name = False for name in _quota_resources: if resource.startswith(name): diff --git a/cinderclient/tests/unit/test_base.py b/cinderclient/tests/unit/test_base.py index e42c34c96..91f96baf3 100644 --- a/cinderclient/tests/unit/test_base.py +++ b/cinderclient/tests/unit/test_base.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -11,14 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +import mock from requests import Response +import six from cinderclient import api_versions from cinderclient.apiclient import base as common_base from cinderclient import base from cinderclient.v3 import client from cinderclient import exceptions -from cinderclient.v1 import volumes +from cinderclient.v3 import volumes from cinderclient.tests.unit import utils from cinderclient.tests.unit import test_utils from cinderclient.tests.unit.v1 import fakes @@ -99,6 +102,20 @@ class BaseTest(utils.TestCase): r1 = base.Resource(manager, {'id': 1}) self.assertEqual(version, r1.api_version) + @mock.patch('cinderclient.utils.unicode_key_value_to_string', + side_effect=lambda x: x) + def test_build_list_url_failed(self, fake_encode): + # NOTE(mdovgal): This test is reasonable only for py27 version, + # due to issue with parse.urlencode method only in py27 + if six.PY2: + arguments = dict(resource_type = 'volumes', + search_opts = {'all_tenants': 1, + 'name': u'ффф'}) + manager = base.Manager(None) + self.assertRaises(UnicodeEncodeError, + manager._build_list_url, + **arguments) + class ListWithMetaTest(utils.TestCase): def test_list_with_meta(self):