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
This commit is contained in:
Kennan 2015-03-04 16:20:23 +08:00
parent b5cfcb620c
commit 45bb98531b
2 changed files with 49 additions and 3 deletions

View File

@ -147,6 +147,14 @@ class Connection(pymongo_base.Connection):
return sort_instructions 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): def upgrade(self, version=None):
# Establish indexes # Establish indexes
# #
@ -163,7 +171,8 @@ class Connection(pymongo_base.Connection):
# VARCHAR(n) for the resource id which has n(n>70) characters. # VARCHAR(n) for the resource id which has n(n>70) characters.
# Users can adjust 'db2nosql_resource_id_maxlen'(default is 512) # Users can adjust 'db2nosql_resource_id_maxlen'(default is 512)
# for their ENV. # 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, self.db.resource.insert({'_id': resource_id,
'no_key': resource_id}) 'no_key': resource_id})
meter_id = str(bson.objectid.ObjectId()) meter_id = str(bson.objectid.ObjectId())

View File

@ -101,12 +101,15 @@ class CapabilitiesTest(test_base.BaseTestCase):
class ConnectionTest(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(pymongo_utils.ConnectionPool, 'connect')
@mock.patch.object(timeutils, 'utcnow') @mock.patch.object(timeutils, 'utcnow')
@mock.patch.object(bson.objectid, 'ObjectId') @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 = mock.MagicMock()
conn_mock.server_info.return_value = {} conn_mock.server_info.return_value = {}
_generate_random_str.return_value = 'wew' * 247 + 'x' * 3
conn_mock.ceilodb2.resource.index_information.return_value = {} conn_mock.ceilodb2.resource.index_information.return_value = {}
mongo_connect.return_value = conn_mock mongo_connect.return_value = conn_mock
meter_id.return_value = '54b8860d75bfe43b54e84ce7' meter_id.return_value = '54b8860d75bfe43b54e84ce7'
@ -115,7 +118,7 @@ class ConnectionTest(test_base.BaseTestCase):
256, 256,
group='database') group='database')
impl_db2.Connection('db2://user:pwd@localhost:27017/ceilodb2') 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( conn_mock.ceilodb2.resource.insert.assert_called_with(
{'_id': resource_id, {'_id': resource_id,
'no_key': resource_id}) 'no_key': resource_id})
@ -123,3 +126,37 @@ class ConnectionTest(test_base.BaseTestCase):
{'_id': '54b8860d75bfe43b54e84ce7', {'_id': '54b8860d75bfe43b54e84ce7',
'no_key': '54b8860d75bfe43b54e84ce7', 'no_key': '54b8860d75bfe43b54e84ce7',
'timestamp': 'timestamp'}) '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)