Merge "Allow to deprecate policy" into feature/ec

This commit is contained in:
Jenkins 2014-05-29 23:32:06 +00:00 committed by Gerrit Code Review
commit 6ede2692c7
4 changed files with 96 additions and 8 deletions

View File

@ -64,7 +64,7 @@ class StoragePolicy(object):
is known via the Collection's get_object_ring method, but it may be
over-ridden via object_ring kwarg at create time for testing.
"""
def __init__(self, idx, name='', is_default=False,
def __init__(self, idx, name='', is_default=False, is_deprecated=False,
policy_type=DEFAULT_TYPE, object_ring=None):
try:
self.idx = int(idx)
@ -75,7 +75,10 @@ class StoragePolicy(object):
if not name:
raise PolicyError('Invalid name', idx)
self.name = name
self.is_default = config_true_value(is_default)
self.is_deprecated = config_true_value(is_deprecated)
# deprecation takes precedence over default
self.is_default = config_true_value(is_default) and \
not self.is_deprecated
if policy_type not in VALID_TYPES:
raise PolicyError('Invalid type', idx)
self.policy_type = policy_type
@ -91,8 +94,10 @@ class StoragePolicy(object):
return cmp(self.idx, int(other))
def __repr__(self):
return "StoragePolicy(%d, %r, is_default=%s, policy_type=%r)" % (
self.idx, self.name, self.is_default, self.policy_type)
return ("StoragePolicy(%d, %r, is_default=%s, "
"is_deprecated=%s, policy_type=%r)") % (
self.idx, self.name, self.is_default, self.is_deprecated,
self.policy_type)
def load_ring(self, swift_dir):
if self.object_ring:
@ -165,9 +170,14 @@ class StoragePolicyCollection(object):
if 0 not in self.by_index:
self.add_policy(StoragePolicy(0, 'Policy_0', False))
# if needed, specify default of policy 0
# at least one policy must be enabled
enabled_policies = [p for p in self if not p.is_deprecated]
if not enabled_policies:
raise PolicyError("Unable to find policy that's not deprecated!")
# if needed, specify default
if not self.default:
self.default = self[0]
self.default = sorted(enabled_policies)[0]
self.default.is_default = True
def get_by_name(self, name):
@ -220,6 +230,9 @@ class StoragePolicyCollection(object):
"""
policy_info = []
for pol in self:
# delete from /info if deprecated
if pol.is_deprecated:
continue
policy_entry = {}
policy_entry['name'] = pol.name
policy_entry['type'] = pol.policy_type
@ -263,6 +276,7 @@ def parse_storage_policies(conf):
config_to_policy_option_map = {
'name': 'name',
'default': 'is_default',
'deprecated': 'is_deprecated',
'type': 'policy_type',
}
policy_options = {}

View File

@ -124,6 +124,12 @@ class ContainerController(Controller):
if policy_index is None:
# make sure all backend servers get the same default policy
policy_index = POLICIES.default.idx
policy = POLICIES[policy_index]
if policy.is_deprecated:
resp = HTTPBadRequest(request=req)
resp.body = 'Storage Policy %r is deprecated' % \
(policy.name)
return resp
if not req.environ.get('swift_owner'):
for key in self.app.swift_owner_headers:
req.headers.pop(key, None)

View File

@ -35,8 +35,10 @@ class TestStoragePolicies(unittest.TestCase):
@patch_policies([StoragePolicy(0, 'zero', True),
StoragePolicy(1, 'one', False),
StoragePolicy(2, 'two', False)])
StoragePolicy(2, 'two', False),
StoragePolicy(3, 'three', False, is_deprecated=True)])
def test_swift_info(self):
# the deprecated 'three' should not exist in expect
expect = [{'default': True, 'type': 'replication', 'name': 'zero'},
{'type': 'replication', 'name': 'two'},
{'type': 'replication', 'name': 'one'}]
@ -101,6 +103,25 @@ class TestStoragePolicies(unittest.TestCase):
self.assertEquals(policies.default, policies[0])
self.assertEquals(policies.default.name, 'Policy_0')
def test_deprecate_policies(self):
# deprecation specified
test_policies = [StoragePolicy(0, 'zero', True),
StoragePolicy(1, 'one', False),
StoragePolicy(2, 'two', False, is_deprecated=True)]
policies = StoragePolicyCollection(test_policies)
self.assertEquals(policies.default, test_policies[0])
self.assertEquals(policies.default.name, 'zero')
self.assertEquals(len(policies), 3)
# deprecating old default makes policy 0 the default
test_policies = [StoragePolicy(0, 'zero', False),
StoragePolicy(1, 'one', True, is_deprecated=True),
StoragePolicy(2, 'two', False)]
policies = StoragePolicyCollection(test_policies)
self.assertEquals(policies.default, test_policies[0])
self.assertEquals(policies.default.name, 'zero')
self.assertEquals(len(policies), 3)
def test_validate_policies_indexes(self):
# duplicate indexes
test_policies = [StoragePolicy(0, 'zero', True),
@ -149,7 +170,39 @@ class TestStoragePolicies(unittest.TestCase):
else:
self.fail('%r did not raise %s' % (message, exc_class.__name__))
def test_deprecated_default(self):
bad_conf = self._conf("""
[storage-policy:1]
name = one
deprecated = yes
default = yes
""")
policies = parse_storage_policies(bad_conf)
self.assertEqual(len(policies), 2)
self.assertTrue(policies[1].is_deprecated)
self.assertFalse(policies[1].is_default)
self.assertEqual(policies.default.idx, 0)
self.assertTrue(policies[0].is_default)
self.assertFalse(policies[0].is_deprecated)
def test_parse_storage_policies(self):
# ValueError when deprecating policy 0
bad_conf = self._conf("""
[storage-policy:0]
name = zero
deprecated = yes
default = yes
[storage-policy:1]
name = one
deprecated = yes
""")
self.assertRaisesWithMessage(
ValueError, "Unable to find policy that's not deprecated",
parse_storage_policies, bad_conf)
bad_conf = self._conf("""
[storage-policy:x]
name = zero

View File

@ -4541,7 +4541,8 @@ class TestObjectController(unittest.TestCase):
@patch_policies([
StoragePolicy(0, 'zero', True, object_ring=FakeRing()),
StoragePolicy(1, 'one', False, object_ring=FakeRing())
StoragePolicy(1, 'one', False, object_ring=FakeRing()),
StoragePolicy(2, 'two', False, True, object_ring=FakeRing())
])
class TestContainerController(unittest.TestCase):
"Test swift.proxy_server.ContainerController"
@ -4561,6 +4562,9 @@ class TestContainerController(unittest.TestCase):
req = Request.blank('/a/c', headers={'Content-Length': '0',
'Content-Type': 'text/plain', POLICY: 'one'})
self.assertEqual(controller._convert_policy_to_index(req), 1)
req = Request.blank('/a/c', headers={'Content-Length': '0',
'Content-Type': 'text/plain', POLICY: 'two'})
self.assertEqual(controller._convert_policy_to_index(req), 2)
req = Request.blank('/a/c', headers={'Content-Length': '0',
'Content-Type': 'text/plain', POLICY: 'nada'})
self.assertRaises(HTTPException, controller._convert_policy_to_index,
@ -4695,6 +4699,14 @@ class TestContainerController(unittest.TestCase):
else:
policy = POLICIES.default
res = req.get_response(self.app)
if policy.is_deprecated:
self.assertEquals(res.status_int, 400)
self.assertEqual(0, len(backend_requests))
expected = 'is deprecated'
self.assertTrue(expected in res.body,
'%r did not include %r' % (
res.body, expected))
return
self.assertEquals(res.status_int, 201)
self.assertEqual(
policy.object_ring.replicas,
@ -6350,6 +6362,7 @@ class TestProxyObjectPerformance(unittest.TestCase):
@patch_policies([StoragePolicy(0, 'migrated'),
StoragePolicy(1, 'ernie', True),
StoragePolicy(2, 'deprecated', is_deprecated=True),
StoragePolicy(3, 'bert')])
class TestSwiftInfo(unittest.TestCase):
def setUp(self):
@ -6391,6 +6404,8 @@ class TestSwiftInfo(unittest.TestCase):
self.assertTrue('policies' in si)
sorted_pols = sorted(si['policies'], key=operator.itemgetter('name'))
self.assertEqual(len(sorted_pols), 3)
for policy in sorted_pols:
self.assertNotEquals(policy['name'], 'deprecated')
self.assertEqual(sorted_pols[0]['name'], 'bert')
self.assertEqual(sorted_pols[1]['name'], 'ernie')
self.assertEqual(sorted_pols[2]['name'], 'migrated')