From 1fcdca09d351c9b86aa9371242be50d853ba256b Mon Sep 17 00:00:00 2001 From: JordanP Date: Mon, 23 Jun 2014 14:48:45 +0200 Subject: [PATCH] Handle non-ascii character in meter name In Ceilometer, meter's name is user supplied, thus can contain non ascii characters. This patch encode Unicode objects to UTF-8 before returning the the meter to the client. Change-Id: I15696b1b09286270de237084869d4a2d4418be8d Closes-Bug: 1333177 --- ceilometer/api/controllers/v2.py | 6 +++-- .../api/v2/test_list_meters_scenarios.py | 24 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/ceilometer/api/controllers/v2.py b/ceilometer/api/controllers/v2.py index 4b566a7f07..34c965bc0f 100644 --- a/ceilometer/api/controllers/v2.py +++ b/ceilometer/api/controllers/v2.py @@ -970,8 +970,10 @@ class Meter(_Base): "The unique identifier for the meter" def __init__(self, **kwargs): - meter_id = base64.encodestring('%s+%s' % (kwargs['resource_id'], - kwargs['name'])) + meter_id = '%s+%s' % (kwargs['resource_id'], kwargs['name']) + # meter_id is of type Unicode but base64.encodestring() only accepts + # strings. See bug #1333177 + meter_id = base64.encodestring(meter_id.encode('utf-8')) kwargs['meter_id'] = meter_id super(Meter, self).__init__(**kwargs) diff --git a/ceilometer/tests/api/v2/test_list_meters_scenarios.py b/ceilometer/tests/api/v2/test_list_meters_scenarios.py index a30e438a41..95e08b234e 100644 --- a/ceilometer/tests/api/v2/test_list_meters_scenarios.py +++ b/ceilometer/tests/api/v2/test_list_meters_scenarios.py @@ -166,6 +166,17 @@ class TestListMeters(FunctionalTest, 'size': 0, 'util': 0.58, 'is_public': True}, + source='test_source1'), + sample.Sample( + u'meter.accent\xe9\u0437', + 'gauge', + '', + 1, + 'user-id4', + 'project-id2', + 'resource-id4', + timestamp=datetime.datetime(2014, 7, 2, 10, 43), + resource_metadata={}, source='test_source1')]: msg = utils.meter_message_from_counter( cnt, @@ -175,13 +186,14 @@ class TestListMeters(FunctionalTest, def test_list_meters(self): data = self.get_json('/meters') - self.assertEqual(5, len(data)) + self.assertEqual(6, len(data)) self.assertEqual(set(['resource-id', 'resource-id2', 'resource-id3', 'resource-id4']), set(r['resource_id'] for r in data)) - self.assertEqual(set(['meter.test', 'meter.mine', 'meter.test.new']), + self.assertEqual(set(['meter.test', 'meter.mine', 'meter.test.new', + u'meter.accent\xe9\u0437']), set(r['name'] for r in data)) self.assertEqual(set(['test_source', 'test_source1']), set(r['source'] for r in data)) @@ -202,7 +214,7 @@ class TestListMeters(FunctionalTest, def test_list_samples(self): data = self.get_json('/samples') - self.assertEqual(6, len(data)) + self.assertEqual(7, len(data)) def test_query_samples_with_invalid_field_name_and_non_eq_operator(self): resp = self.get_json('/samples', @@ -487,7 +499,7 @@ class TestListMeters(FunctionalTest, 'value': 'test_source1', }]) nids = set(r['name'] for r in data) - self.assertEqual(set(['meter.mine']), nids) + self.assertEqual(set(['meter.mine', u'meter.accent\xe9\u0437']), nids) sids = set(r['source'] for r in data) self.assertEqual(set(['test_source1']), sids) @@ -657,6 +669,6 @@ class TestListMeters(FunctionalTest, def test_list_meters_meter_id(self): data = self.get_json('/meters') for i in data: - expected = base64.encodestring('%s+%s' % (i['resource_id'], - i['name'])) + meter_id = '%s+%s' % (i['resource_id'], i['name']) + expected = base64.encodestring(meter_id.encode('utf-8')) self.assertEqual(expected, i['meter_id'])