From 45bb98531ba4ef757c50a080652c81bc21e3d9dd Mon Sep 17 00:00:00 2001 From: Kennan Date: Wed, 4 Mar 2015 16:20:23 +0800 Subject: [PATCH] Fix db2 upgrade in multi-thread run issue In multi-thread run cases(like chef recipes run), it would hit insert same record issue, this fix make sure insert different data in db, thus not hit duplicated insert issue, it is mainly improve in multi-thread cases run. Change-Id: I1690dc5863cbd2b213d241477e23e82d295856fe Closes-Bug: #1427997 --- ceilometer/storage/impl_db2.py | 11 +++++- ceilometer/tests/storage/test_impl_db2.py | 41 +++++++++++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/ceilometer/storage/impl_db2.py b/ceilometer/storage/impl_db2.py index c2e8446d1..bf8843a06 100644 --- a/ceilometer/storage/impl_db2.py +++ b/ceilometer/storage/impl_db2.py @@ -147,6 +147,14 @@ class Connection(pymongo_base.Connection): return sort_instructions + def _generate_random_str(self, str_len): + init_str = str(bson.objectid.ObjectId()) + objectid_len = len(init_str) + if str_len >= objectid_len: + init_str = (init_str * int(str_len/objectid_len) + + 'x' * int(str_len % objectid_len)) + return init_str + def upgrade(self, version=None): # Establish indexes # @@ -163,7 +171,8 @@ class Connection(pymongo_base.Connection): # VARCHAR(n) for the resource id which has n(n>70) characters. # Users can adjust 'db2nosql_resource_id_maxlen'(default is 512) # for their ENV. - resource_id = 'x' * cfg.CONF.database.db2nosql_resource_id_maxlen + resource_id = self._generate_random_str( + cfg.CONF.database.db2nosql_resource_id_maxlen) self.db.resource.insert({'_id': resource_id, 'no_key': resource_id}) meter_id = str(bson.objectid.ObjectId()) diff --git a/ceilometer/tests/storage/test_impl_db2.py b/ceilometer/tests/storage/test_impl_db2.py index 9e7911c28..a35f04ac5 100644 --- a/ceilometer/tests/storage/test_impl_db2.py +++ b/ceilometer/tests/storage/test_impl_db2.py @@ -101,12 +101,15 @@ class CapabilitiesTest(test_base.BaseTestCase): class ConnectionTest(test_base.BaseTestCase): + @mock.patch.object(impl_db2.Connection, '_generate_random_str') @mock.patch.object(pymongo_utils.ConnectionPool, 'connect') @mock.patch.object(timeutils, 'utcnow') @mock.patch.object(bson.objectid, 'ObjectId') - def test_upgrade(self, meter_id, timestamp, mongo_connect): + def test_upgrade(self, meter_id, timestamp, mongo_connect, + _generate_random_str): conn_mock = mock.MagicMock() conn_mock.server_info.return_value = {} + _generate_random_str.return_value = 'wew' * 247 + 'x' * 3 conn_mock.ceilodb2.resource.index_information.return_value = {} mongo_connect.return_value = conn_mock meter_id.return_value = '54b8860d75bfe43b54e84ce7' @@ -115,7 +118,7 @@ class ConnectionTest(test_base.BaseTestCase): 256, group='database') impl_db2.Connection('db2://user:pwd@localhost:27017/ceilodb2') - resource_id = 'x' * 256 + resource_id = 'wew' * 247 + 'x' * 3 conn_mock.ceilodb2.resource.insert.assert_called_with( {'_id': resource_id, 'no_key': resource_id}) @@ -123,3 +126,37 @@ class ConnectionTest(test_base.BaseTestCase): {'_id': '54b8860d75bfe43b54e84ce7', 'no_key': '54b8860d75bfe43b54e84ce7', 'timestamp': 'timestamp'}) + + @mock.patch.object(pymongo_utils.ConnectionPool, 'connect') + @mock.patch.object(bson.objectid, 'ObjectId') + def test_generate_random_str_with_less_config_len(self, objectid, + mongo_connect): + fake_str = '54b8860d75bfe43b54e84ce7' + conn_mock = mock.MagicMock() + conn_mock.server_info.return_value = {} + mongo_connect.return_value = conn_mock + objectid.return_value = fake_str + cfg.CONF.set_override('db2nosql_resource_id_maxlen', + 20, + group='database') + conn = impl_db2.Connection('db2://user:pwd@localhost:27017/ceilodb2') + rand_str = conn._generate_random_str(20) + self.assertEqual(fake_str, rand_str) + + @mock.patch.object(pymongo_utils.ConnectionPool, 'connect') + @mock.patch.object(bson.objectid, 'ObjectId') + def test_generate_random_str_with_default_config_len(self, objectid, + mongo_connect): + fake_str = '54b8860d75bfe43b54e84ce7' + conn_mock = mock.MagicMock() + conn_mock.server_info.return_value = {} + mongo_connect.return_value = conn_mock + objectid.return_value = fake_str + cfg.CONF.set_override('db2nosql_resource_id_maxlen', + 512, + group='database') + conn = impl_db2.Connection('db2://user:pwd@localhost:27017/ceilodb2') + rand_str = conn._generate_random_str(512) + str_len = len(str(fake_str)) + expect_str = fake_str * int(512 / str_len) + 'x' * (512 % str_len) + self.assertEqual(expect_str, rand_str)