From 766b6e1ecf534b60d3b002fe86dfa70964891291 Mon Sep 17 00:00:00 2001 From: "Swapnil Kulkarni (coolsvap)" Date: Thu, 21 Jul 2016 17:16:56 +0000 Subject: [PATCH 1/6] Remove discover from test-requirements It's only needed for python < 2.7 which is not supported Change-Id: I998be560850a2e51d2ba29552617f5722b67f203 --- test-requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test-requirements.txt b/test-requirements.txt index 93d7ad3..ca1a61a 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -3,7 +3,6 @@ # process, which may cause wedges in the gate later. # Hacking already pins down pep8, pyflakes and flake8 coverage>=3.6 # Apache-2.0 -discover # BSD fixtures<2.0,>=1.3.1 # Apache-2.0/BSD mock>=1.2 # BSD oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0 From f0faf477afe22f691e586900dcd8abaaccbb767c Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Wed, 27 Jul 2016 15:27:30 +0200 Subject: [PATCH 2/6] Add support for Python 3.5 This fixes a test that check too much of the output formatting. Just test that some of the values we expect are there. Change-Id: I43a2c2d017bc99ef045ff2e4c5943f1607343ec1 --- ceilometerclient/tests/unit/v2/test_shell.py | 71 ++------------------ setup.cfg | 1 + tox.ini | 2 +- 3 files changed, 7 insertions(+), 67 deletions(-) diff --git a/ceilometerclient/tests/unit/v2/test_shell.py b/ceilometerclient/tests/unit/v2/test_shell.py index d4d5dd9..ce26af1 100644 --- a/ceilometerclient/tests/unit/v2/test_shell.py +++ b/ceilometerclient/tests/unit/v2/test_shell.py @@ -538,72 +538,11 @@ class ShellAlarmGnocchiCommandTest(test_shell.ShellTestBase): ceilometer_shell.\ do_alarm_gnocchi_aggregation_by_metrics_threshold_create( self.cc, self.args) - self.assertEqual('''\ -+---------------------------+------------------------------------------\ ---------------------------+ -| Property | Value \ - | -+---------------------------+------------------------------------------\ ---------------------------+ -| aggregation_method | count \ - | -| alarm_actions | ["http://something/alarm"] \ - | -| alarm_id | b69ecdb9-f19b-4fb5-950f-5eb53938b718 \ - | -| comparison_operator | le \ - | -| description | description_gnocchi_alarm \ - | -| enabled | True \ - | -| evaluation_periods | 3 \ - | -| granularity | 60 \ - | -| insufficient_data_actions | ["http://something/insufficient"] \ - | -| metrics | ["b3d9d8ab-05e8-439f-89ad-5e978dd2a5eb", \ -"009d4faf-c275-46f0-8f2d- | -| | 670b15bac2b0"] \ - | -| name | name_gnocchi_alarm \ - | -| ok_actions | ["http://something/ok"] \ - | -| project_id | 97fcad0402ce4f65ac3bd42a0c6a7e74 \ - | -| repeat_actions | True \ - | -| severity | critical \ - | -| state | ok \ - | -| threshold | 70.0 \ - | -| time_constraints | [{name: cons1, \ - | -| | description: desc1, \ - | -| | start: 0 11 * * *, \ - | -| | duration: 300}, \ - | -| | {name: cons2, \ - | -| | description: desc2, \ - | -| | start: 0 23 * * *, \ - | -| | duration: 600}] \ - | -| type | gnocchi_aggregation_by_metrics_threshold \ - | -| user_id | f28735621ee84f329144eb467c91fce6 \ - | -+---------------------------+------------------------------------------\ ---------------------------+ -''', sys.stdout.getvalue()) + stdout = sys.stdout.getvalue() + self.assertIn("b69ecdb9-f19b-4fb5-950f-5eb53938b718", stdout) + self.assertIn("[\"http://something/alarm\"]", stdout) + self.assertIn("description_gnocchi_alarm", stdout) + self.assertIn("gnocchi_aggregation_by_metrics_threshold", stdout) @mock.patch('sys.stdout', new=six.StringIO()) def test_do_alarm_gnocchi_aggr_by_resources_threshold_create(self): diff --git a/setup.cfg b/setup.cfg index f4be586..7bc5f80 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,6 +17,7 @@ classifier = Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.4 + Programming Language :: Python :: 3.5 [files] packages = diff --git a/tox.ini b/tox.ini index 50e6353..023352d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py34,py27,pypy,pep8 +envlist = py34,py35,py27,pypy,pep8 minversion = 1.6 skipsdist = True From 6ca1f270fdc8f04309577c2a9966cf9826595c3e Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Thu, 28 Jul 2016 16:52:29 +0200 Subject: [PATCH 3/6] Remove keystoneclient dependency Change-Id: I3589eca8fd6a581e57524cffa8a8f1278358f38c --- ceilometerclient/tests/unit/fakes.py | 64 ---------------------- ceilometerclient/tests/unit/test_client.py | 3 - requirements.txt | 1 - 3 files changed, 68 deletions(-) delete mode 100644 ceilometerclient/tests/unit/fakes.py diff --git a/ceilometerclient/tests/unit/fakes.py b/ceilometerclient/tests/unit/fakes.py deleted file mode 100644 index 10d8d8c..0000000 --- a/ceilometerclient/tests/unit/fakes.py +++ /dev/null @@ -1,64 +0,0 @@ -# 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 -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystoneclient.v2_0 import client as ksclient - - -def script_keystone_client(): - ksclient.Client(auth_url='http://no.where', - insecure=False, - password='password', - tenant_id='', - tenant_name='tenant_name', - username='username').AndReturn(FakeKeystone('abcd1234')) - - -def fake_headers(): - return {'X-Auth-Token': 'abcd1234', - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'User-Agent': 'python-ceilometerclient'} - - -class FakeServiceCatalog(object): - @staticmethod - def url_for(endpoint_type, service_type): - return 'http://192.168.1.5:8004/v1/f14b41234' - - -class FakeKeystone(object): - service_catalog = FakeServiceCatalog() - - def __init__(self, auth_token): - self.auth_token = auth_token - - -class FakeHTTPResponse(object): - - version = 1.1 - - def __init__(self, status, reason, headers, body): - self.headers = headers - self.body = body - self.status = status - self.reason = reason - - def getheader(self, name, default=None): - return self.headers.get(name, default) - - def getheaders(self): - return self.headers.items() - - def read(self, amt=None): - b = self.body - self.body = None - return b diff --git a/ceilometerclient/tests/unit/test_client.py b/ceilometerclient/tests/unit/test_client.py index 174037b..e8a1eb5 100644 --- a/ceilometerclient/tests/unit/test_client.py +++ b/ceilometerclient/tests/unit/test_client.py @@ -22,7 +22,6 @@ import requests from ceilometerclient import client from ceilometerclient import exc from ceilometerclient.openstack.common.apiclient import exceptions -from ceilometerclient.tests.unit import fakes from ceilometerclient.tests.unit import utils from ceilometerclient.v2 import client as v2client @@ -77,7 +76,6 @@ class ClientTest(utils.BaseTestCase): c2 = self.create_client(env) self.assertIsInstance(c2, v2client.Client) - @mock.patch('keystoneclient.v2_0.client', fakes.FakeKeystone) def test_client_without_auth_plugin(self): env = FAKE_ENV.copy() del env['auth_plugin'] @@ -201,7 +199,6 @@ class ClientTestWithAodh(ClientTest): return_value=mock.MagicMock()): return client.get_client(api_version, **env) - @mock.patch('keystoneclient.v2_0.client', fakes.FakeKeystone) def test_client_without_auth_plugin(self): env = FAKE_ENV.copy() del env['auth_plugin'] diff --git a/requirements.txt b/requirements.txt index a026806..51fc204 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ oslo.i18n>=2.1.0 # Apache-2.0 oslo.serialization>=1.10.0 # Apache-2.0 oslo.utils>=3.5.0 # Apache-2.0 PrettyTable<0.8,>=0.7 # BSD -python-keystoneclient!=1.8.0,!=2.1.0,>=1.6.0 # Apache-2.0 requests!=2.9.0,>=2.8.1 # Apache-2.0 six>=1.9.0 # MIT stevedore>=1.10.0 # Apache-2.0 From 481cd7d33bf5f91c39888fa695238c562eda7945 Mon Sep 17 00:00:00 2001 From: xiaozhuangqing Date: Fri, 29 Jul 2016 10:47:04 +0800 Subject: [PATCH 4/6] Correct the parameters's position of assertEqual assertEqual using should be assertEqual(expected, actual) misplace have two impacts: 1.giving confusing messages when some tests failed. 2.mislead other developer,new test modules may follow these wrong pattern see Partial-Bug https://bugs.launchpad.net/oslo.config/+bug/1604213 Change-Id: I4467d5efb1eed9f4c473c947c93afcfaf9be6ea6 --- ceilometerclient/tests/unit/v2/test_alarms.py | 22 +++++++++---------- .../tests/unit/v2/test_event_types.py | 10 ++++----- .../tests/unit/v2/test_resources.py | 12 +++++----- .../tests/unit/v2/test_samples.py | 8 +++---- .../tests/unit/v2/test_statistics.py | 22 +++++++++---------- .../tests/unit/v2/test_trait_descriptions.py | 2 +- ceilometerclient/tests/unit/v2/test_traits.py | 2 +- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/ceilometerclient/tests/unit/v2/test_alarms.py b/ceilometerclient/tests/unit/v2/test_alarms.py index 7511557..44fa50c 100644 --- a/ceilometerclient/tests/unit/v2/test_alarms.py +++ b/ceilometerclient/tests/unit/v2/test_alarms.py @@ -279,8 +279,8 @@ class AlarmManagerTest(testtools.TestCase): 'GET', '/v2/alarms' ] self.http_client.assert_called(*expect) - self.assertEqual(len(alarms), 1) - self.assertEqual(alarms[0].alarm_id, 'alarm-id') + self.assertEqual(1, len(alarms)) + self.assertEqual('alarm-id', alarms[0].alarm_id) def test_list_with_query(self): alarms = list(self.mgr.list(q=[{"field": "project_id", @@ -293,8 +293,8 @@ class AlarmManagerTest(testtools.TestCase): '&q.type=&q.type=&q.value=project-id&q.value=SwiftObjectAlarm', ] self.http_client.assert_called(*expect) - self.assertEqual(len(alarms), 1) - self.assertEqual(alarms[0].alarm_id, 'alarm-id') + self.assertEqual(1, len(alarms)) + self.assertEqual('alarm-id', alarms[0].alarm_id) def test_get(self): alarm = self.mgr.get(alarm_id='alarm-id') @@ -303,7 +303,7 @@ class AlarmManagerTest(testtools.TestCase): ] self.http_client.assert_called(*expect) self.assertIsNotNone(alarm) - self.assertEqual(alarm.alarm_id, 'alarm-id') + self.assertEqual('alarm-id', alarm.alarm_id) self.assertEqual(alarm.rule, alarm.threshold_rule) def test_create(self): @@ -325,7 +325,7 @@ class AlarmManagerTest(testtools.TestCase): self.http_client.assert_called(*expect_get, pos=0) self.http_client.assert_called(*expect_put, pos=1) self.assertIsNotNone(alarm) - self.assertEqual(alarm.alarm_id, 'alarm-id') + self.assertEqual('alarm-id', alarm.alarm_id) for (key, value) in six.iteritems(UPDATED_ALARM): self.assertEqual(getattr(alarm, key), value) @@ -340,7 +340,7 @@ class AlarmManagerTest(testtools.TestCase): self.http_client.assert_called(*expect_get, pos=0) self.http_client.assert_called(*expect_put, pos=1) self.assertIsNotNone(alarm) - self.assertEqual(alarm.alarm_id, 'alarm-id') + self.assertEqual('alarm-id', alarm.alarm_id) for (key, value) in six.iteritems(UPDATED_ALARM): self.assertEqual(getattr(alarm, key), value) @@ -350,7 +350,7 @@ class AlarmManagerTest(testtools.TestCase): 'PUT', '/v2/alarms/alarm-id/state' ] self.http_client.assert_called(*expect, body='alarm') - self.assertEqual(state, {'alarm': 'alarm'}) + self.assertEqual({'alarm': 'alarm'}, state) def test_get_state(self): state = self.mgr.get_state(alarm_id='alarm-id') @@ -358,7 +358,7 @@ class AlarmManagerTest(testtools.TestCase): 'GET', '/v2/alarms/alarm-id/state' ] self.http_client.assert_called(*expect) - self.assertEqual(state, {'alarm': 'alarm'}) + self.assertEqual({'alarm': 'alarm'}, state) def test_delete(self): deleted = self.mgr.delete(alarm_id='victim-id') @@ -472,7 +472,7 @@ class AlarmLegacyManagerTest(testtools.TestCase): ] self.http_client.assert_called(*expect_put) self.assertIsNotNone(alarm) - self.assertEqual(alarm.alarm_id, 'alarm-id') + self.assertEqual('alarm-id', alarm.alarm_id) for (key, value) in six.iteritems(UPDATED_ALARM): self.assertEqual(getattr(alarm, key), value) @@ -487,7 +487,7 @@ class AlarmLegacyManagerTest(testtools.TestCase): ] self.http_client.assert_called(*expect_put) self.assertIsNotNone(alarm) - self.assertEqual(alarm.alarm_id, 'alarm-id') + self.assertEqual('alarm-id', alarm.alarm_id) for (key, value) in six.iteritems(UPDATED_ALARM): self.assertEqual(getattr(alarm, key), value) diff --git a/ceilometerclient/tests/unit/v2/test_event_types.py b/ceilometerclient/tests/unit/v2/test_event_types.py index 7dc1508..518e853 100644 --- a/ceilometerclient/tests/unit/v2/test_event_types.py +++ b/ceilometerclient/tests/unit/v2/test_event_types.py @@ -43,8 +43,8 @@ class EventTypesManagerTest(utils.BaseTestCase): 'GET', '/v2/event_types/' ] self.http_client.assert_called(*expect) - self.assertEqual(len(event_types), 4) - self.assertEqual(event_types[0].event_type, "Foo") - self.assertEqual(event_types[1].event_type, "Bar") - self.assertEqual(event_types[2].event_type, "Sna") - self.assertEqual(event_types[3].event_type, "Fu") + self.assertEqual(4, len(event_types)) + self.assertEqual("Foo", event_types[0].event_type) + self.assertEqual("Bar", event_types[1].event_type) + self.assertEqual("Sna", event_types[2].event_type) + self.assertEqual("Fu", event_types[3].event_type) diff --git a/ceilometerclient/tests/unit/v2/test_resources.py b/ceilometerclient/tests/unit/v2/test_resources.py index 3c19654..a03f88b 100644 --- a/ceilometerclient/tests/unit/v2/test_resources.py +++ b/ceilometerclient/tests/unit/v2/test_resources.py @@ -100,9 +100,9 @@ class ResourceManagerTest(utils.BaseTestCase): 'GET', '/v2/resources?meter_links=0' ] self.http_client.assert_called(*expect) - self.assertEqual(len(resources), 2) - self.assertEqual(resources[0].resource_id, 'a') - self.assertEqual(resources[1].resource_id, 'b') + self.assertEqual(2, len(resources)) + self.assertEqual('a', resources[0].resource_id) + self.assertEqual('b', resources[1].resource_id) def test_list_all_with_links_enabled(self): resources = list(self.mgr.list(links=True)) @@ -121,7 +121,7 @@ class ResourceManagerTest(utils.BaseTestCase): ] self.http_client.assert_called(*expect) self.assertIsNotNone(resource) - self.assertEqual(resource.resource_id, 'a') + self.assertEqual('a', resource.resource_id) def test_list_by_query(self): resources = list(self.mgr.list(q=[{"field": "resource_id", @@ -132,8 +132,8 @@ class ResourceManagerTest(utils.BaseTestCase): '&q.type=&q.value=a&meter_links=0' ] self.http_client.assert_called(*expect) - self.assertEqual(len(resources), 1) - self.assertEqual(resources[0].resource_id, 'a') + self.assertEqual(1, len(resources)) + self.assertEqual('a', resources[0].resource_id) def test_get_from_resource_class(self): resource = self.mgr.get(resource_id='a') diff --git a/ceilometerclient/tests/unit/v2/test_samples.py b/ceilometerclient/tests/unit/v2/test_samples.py index 3a4cbd0..63a70fc 100644 --- a/ceilometerclient/tests/unit/v2/test_samples.py +++ b/ceilometerclient/tests/unit/v2/test_samples.py @@ -147,8 +147,8 @@ class OldSampleManagerTest(utils.BaseTestCase): 'GET', '/v2/meters/instance' ] self.http_client.assert_called(*expect) - self.assertEqual(len(samples), 1) - self.assertEqual(samples[0].resource_id, 'resource-id') + self.assertEqual(1, len(samples)) + self.assertEqual('resource-id', samples[0].resource_id) def test_list_by_meter_name_extended(self): samples = list(self.mgr.list(meter_name='instance', @@ -160,7 +160,7 @@ class OldSampleManagerTest(utils.BaseTestCase): ])) expect = ['GET', '%s?%s' % (METER_URL, QUERIES)] self.http_client.assert_called(*expect) - self.assertEqual(len(samples), 0) + self.assertEqual(0, len(samples)) def test_create(self): sample = self.mgr.create(**CREATE_SAMPLE) @@ -200,7 +200,7 @@ class OldSampleManagerTest(utils.BaseTestCase): samples = list(self.mgr.list(meter_name='instance', limit=1)) expect = ['GET', '/v2/meters/instance?limit=1'] self.http_client.assert_called(*expect) - self.assertEqual(len(samples), 1) + self.assertEqual(1, len(samples)) class SampleManagerTest(utils.BaseTestCase): diff --git a/ceilometerclient/tests/unit/v2/test_statistics.py b/ceilometerclient/tests/unit/v2/test_statistics.py index d2f7aee..e41b38c 100644 --- a/ceilometerclient/tests/unit/v2/test_statistics.py +++ b/ceilometerclient/tests/unit/v2/test_statistics.py @@ -125,8 +125,8 @@ class StatisticsManagerTest(utils.BaseTestCase): 'GET', '/v2/meters/instance/statistics' ] self.http_client.assert_called(*expect) - self.assertEqual(len(stats), 1) - self.assertEqual(stats[0].count, 135) + self.assertEqual(1, len(stats)) + self.assertEqual(135, stats[0].count) def test_list_by_meter_name_extended(self): stats = list(self.mgr.list(meter_name='instance', @@ -140,8 +140,8 @@ class StatisticsManagerTest(utils.BaseTestCase): 'GET', '%s?%s' % (base_url, qry) ] self.http_client.assert_called(*expect) - self.assertEqual(len(stats), 1) - self.assertEqual(stats[0].count, 135) + self.assertEqual(1, len(stats)) + self.assertEqual(135, stats[0].count) def test_list_by_meter_name_with_period(self): stats = list(self.mgr.list(meter_name='instance', @@ -156,8 +156,8 @@ class StatisticsManagerTest(utils.BaseTestCase): 'GET', '%s?%s%s' % (base_url, qry, period) ] self.http_client.assert_called(*expect) - self.assertEqual(len(stats), 1) - self.assertEqual(stats[0].count, 135) + self.assertEqual(1, len(stats)) + self.assertEqual(135, stats[0].count) def test_list_by_meter_name_with_groupby(self): stats = list(self.mgr.list(meter_name='instance', @@ -173,11 +173,11 @@ class StatisticsManagerTest(utils.BaseTestCase): '%s?%s%s' % (base_url, qry, groupby) ] self.http_client.assert_called(*expect) - self.assertEqual(len(stats), 2) - self.assertEqual(stats[0].count, 135) - self.assertEqual(stats[1].count, 12) - self.assertEqual(stats[0].groupby.get('resource_id'), 'foo') - self.assertEqual(stats[1].groupby.get('resource_id'), 'bar') + self.assertEqual(2, len(stats)) + self.assertEqual(135, stats[0].count) + self.assertEqual(12, stats[1].count) + self.assertEqual('foo', stats[0].groupby.get('resource_id')) + self.assertEqual('bar', stats[1].groupby.get('resource_id')) def test_list_by_meter_name_with_groupby_as_str(self): stats = list(self.mgr.list(meter_name='instance', diff --git a/ceilometerclient/tests/unit/v2/test_trait_descriptions.py b/ceilometerclient/tests/unit/v2/test_trait_descriptions.py index abe8288..b249d3d 100644 --- a/ceilometerclient/tests/unit/v2/test_trait_descriptions.py +++ b/ceilometerclient/tests/unit/v2/test_trait_descriptions.py @@ -46,7 +46,7 @@ class TraitDescriptionManagerTest(utils.BaseTestCase): 'GET', '/v2/event_types/Foo/traits' ] self.http_client.assert_called(*expect) - self.assertEqual(len(trait_descriptions), 3) + self.assertEqual(3, len(trait_descriptions)) for i, vals in enumerate([('trait_1', 'string'), ('trait_2', 'integer'), ('trait_3', 'datetime')]): diff --git a/ceilometerclient/tests/unit/v2/test_traits.py b/ceilometerclient/tests/unit/v2/test_traits.py index 7b44a69..e277524 100644 --- a/ceilometerclient/tests/unit/v2/test_traits.py +++ b/ceilometerclient/tests/unit/v2/test_traits.py @@ -48,7 +48,7 @@ class TraitManagerTest(utils.BaseTestCase): 'GET', '/v2/event_types/Foo/traits/trait_1' ] self.http_client.assert_called(*expect) - self.assertEqual(len(traits), 2) + self.assertEqual(2, len(traits)) for i, vals in enumerate([('trait_1', 'datetime', '2014-01-07T17:22:10.925553'), From 45d475dfe2de8af2eedb22bfd18b955749933248 Mon Sep 17 00:00:00 2001 From: zhangguoqing Date: Thu, 4 Aug 2016 03:14:15 +0000 Subject: [PATCH 5/6] [trivial] add a blank character In ceilometer help event-list, the line "integer, floator datetime." should be "integer, float or datetime." Change-Id: Ib8976b5e580e2a95a4e04d7d95c815011127749c --- ceilometerclient/v2/shell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ceilometerclient/v2/shell.py b/ceilometerclient/v2/shell.py index 8977836..8b4c65d 100644 --- a/ceilometerclient/v2/shell.py +++ b/ceilometerclient/v2/shell.py @@ -1108,7 +1108,7 @@ def do_resource_show(cc, args={}): @utils.arg('-q', '--query', metavar='', help='key[op]data_type::value; list. data_type is optional, ' - 'but if supplied must be string, integer, float' + 'but if supplied must be string, integer, float ' 'or datetime.') @utils.arg('--no-traits', dest='no_traits', action='store_true', help='If specified, traits will not be printed.') From 090e5ffc691c5d40e45ab0c20dc88032a0987b20 Mon Sep 17 00:00:00 2001 From: Andrey Kurilin Date: Wed, 7 Sep 2016 12:39:12 +0300 Subject: [PATCH 6/6] Fix from_response method to process response from requests SessionClient uses requests library. It's response class doesn't have "status" property[1], so in case of any errors(with status code > 400), from_response method is called and raises AttributeError. Also, HTTPClient implementation uses requests lib by default[2](if 'http' argument was not transmitted), so from_response method will raise AttributeError too. [1] - http://docs.python-requests.org/en/master/api/#requests.Response.status_code [2] - https://github.com/openstack/python-ceilometerclient/blob/2.6.0/ceilometerclient/openstack/common/apiclient/client.py#L99-L100 Change-Id: Id8fb2f386e8101951716f30a6365c9aa15bd4b24 Closes-Bug: #1620974 (cherry picked from commit 1b1917ab9b56fe92235ce336d3df3e7a8c1c81d2) --- ceilometerclient/exc.py | 14 ++++++++++++-- ceilometerclient/tests/unit/test_exc.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ceilometerclient/exc.py b/ceilometerclient/exc.py index c7e550b..3db1c0c 100644 --- a/ceilometerclient/exc.py +++ b/ceilometerclient/exc.py @@ -118,6 +118,16 @@ for obj_name in dir(sys.modules[__name__]): def from_response(response, details=None): - """Return an instance of an HTTPException based on httplib response.""" - cls = _code_map.get(response.status, HTTPException) + """Return an instance of an HTTPException based on http response.""" + if hasattr(response, "status"): + # it is response from HTTPClient (httplib) + code = response.status + elif hasattr(response, "status_code"): + # it is response from SessionClient (requests) + code = response.status_code + else: + # it is something unexpected + raise TypeError("Function 'from_response' expects only response object" + " from httplib or requests libraries.") + cls = _code_map.get(code, HTTPException) return cls(details) diff --git a/ceilometerclient/tests/unit/test_exc.py b/ceilometerclient/tests/unit/test_exc.py index db8df32..b0fd1b1 100644 --- a/ceilometerclient/tests/unit/test_exc.py +++ b/ceilometerclient/tests/unit/test_exc.py @@ -69,3 +69,19 @@ class HTTPExceptionsTest(utils.BaseTestCase): {"error_message": {"faultstring": "oops"}})) ret_str = k + " (HTTP " + str(exception.code) + ") ERROR oops" self.assertEqual(ret_str, str(exception)) + + def test_from_response(self): + class HTTPLibLikeResponse(object): + status = 400 + + class RequestsLikeResponse(object): + status_code = 401 + + class UnexpectedResponse(object): + code = 200 + + self.assertEqual(HTTPLibLikeResponse.status, + exc.from_response(HTTPLibLikeResponse).code) + self.assertEqual(RequestsLikeResponse.status_code, + exc.from_response(RequestsLikeResponse).code) + self.assertRaises(TypeError, exc.from_response, UnexpectedResponse)