Fix ContainerBroker to use policy-0 in default

Fix ContainerBroker to initialize as policy-0 on policy_stat
table in default when storage_policy_index argument is NOT given.

Current ContainerBroker makes policy-1 stats in default because
the "None" value will be passed through to the last function of
db access query (i.e. a query like as "INSERT INTO policy_stat
(storage_policy_index) VALUES (None)" will appear) which results
in a row "(1, 0, 0)" (the first value is the policy index) by
the PRIMARY KEY constraint on sqlite.

In worst case, container db keeps two policies, and then, ContainerBroker.get_info
might return invalid (non-touched) policy_stat information as container information.
(See tests in detail)

When using ContainerBroker with no storage_policy_index argument,
it should always act policy-0 simply.

Note that this patch doesn't affect immediately Swift behavior because
current swift ensures to use policy-0 on "Container-Server" when invalid
policy (includes None) is given. However, we should recheck also in
ContainerBroker for safety to prevent the unfortunate behavior above.

Change-Id: If64f0c94c069a2cc3140c99f21b8d371c183e28a
This commit is contained in:
Kota Tsuyuzaki 2015-02-23 00:26:30 -08:00
parent a6091c0f39
commit 16b435a4a8
2 changed files with 40 additions and 0 deletions

View File

@ -158,6 +158,8 @@ class ContainerBroker(DatabaseBroker):
if not self.container:
raise ValueError(
'Attempting to create a new database with no container set')
if storage_policy_index is None:
storage_policy_index = 0
self.create_object_table(conn)
self.create_policy_stat_table(conn, storage_policy_index)
self.create_container_info_table(conn, put_timestamp,

View File

@ -555,6 +555,44 @@ class TestContainerBroker(unittest.TestCase):
self.assertEqual(stat['bytes_used'],
sum(stats[policy_index].values()))
def test_initialize_container_broker_in_default(self):
broker = ContainerBroker(':memory:', account='test1',
container='test2')
# initialize with no storage_policy_index argument
broker.initialize(Timestamp(1).internal)
info = broker.get_info()
self.assertEquals(info['account'], 'test1')
self.assertEquals(info['container'], 'test2')
self.assertEquals(info['hash'], '00000000000000000000000000000000')
self.assertEqual(info['put_timestamp'], Timestamp(1).internal)
self.assertEqual(info['delete_timestamp'], '0')
info = broker.get_info()
self.assertEquals(info['object_count'], 0)
self.assertEquals(info['bytes_used'], 0)
policy_stats = broker.get_policy_stats()
# Act as policy-0
self.assertTrue(0 in policy_stats)
self.assertEquals(policy_stats[0]['bytes_used'], 0)
self.assertEquals(policy_stats[0]['object_count'], 0)
broker.put_object('o1', Timestamp(time()).internal, 123, 'text/plain',
'5af83e3196bf99f440f31f2e1a6c9afe')
info = broker.get_info()
self.assertEquals(info['object_count'], 1)
self.assertEquals(info['bytes_used'], 123)
policy_stats = broker.get_policy_stats()
self.assertTrue(0 in policy_stats)
self.assertEquals(policy_stats[0]['object_count'], 1)
self.assertEquals(policy_stats[0]['bytes_used'], 123)
def test_get_info(self):
# Test ContainerBroker.get_info
broker = ContainerBroker(':memory:', account='test1',