container-server unit tests: use self.ts everywhere
The setUp method creates a timestamp iterator, so let's use it consistently in all the tests. Change-Id: Ibd06b243c6db93380b99227ac79157269a64b28a
This commit is contained in:
@@ -1618,36 +1618,33 @@ class TestContainerController(unittest.TestCase):
|
||||
[mock.call(os.path.join(self.testdir, 'sda1'))])
|
||||
|
||||
def test_UPDATE(self):
|
||||
ts_iter = make_timestamp_iter()
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': next(ts_iter).internal})
|
||||
headers={'X-Timestamp': next(self.ts).internal})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.status_int, 201)
|
||||
|
||||
ts_iter = make_timestamp_iter()
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c',
|
||||
environ={'REQUEST_METHOD': 'UPDATE'},
|
||||
headers={'X-Timestamp': next(ts_iter).internal},
|
||||
headers={'X-Timestamp': next(self.ts).internal},
|
||||
body='[invalid json')
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.status_int, 400)
|
||||
|
||||
ts_iter = make_timestamp_iter()
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c',
|
||||
environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'X-Timestamp': next(ts_iter).internal})
|
||||
headers={'X-Timestamp': next(self.ts).internal})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.status_int, 204)
|
||||
|
||||
obj_ts = next(ts_iter)
|
||||
obj_ts = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c',
|
||||
environ={'REQUEST_METHOD': 'UPDATE'},
|
||||
headers={'X-Timestamp': next(ts_iter).internal},
|
||||
headers={'X-Timestamp': next(self.ts).internal},
|
||||
body=json.dumps([
|
||||
{'name': 'some obj', 'deleted': 0,
|
||||
'created_at': obj_ts.internal,
|
||||
@@ -1655,12 +1652,12 @@ class TestContainerController(unittest.TestCase):
|
||||
'storage_policy_index': POLICIES.default.idx,
|
||||
'content_type': 'foo/bar'},
|
||||
{'name': 'some tombstone', 'deleted': 1,
|
||||
'created_at': next(ts_iter).internal,
|
||||
'created_at': next(self.ts).internal,
|
||||
'etag': 'noetag', 'size': 0,
|
||||
'storage_policy_index': POLICIES.default.idx,
|
||||
'content_type': 'application/deleted'},
|
||||
{'name': 'wrong policy', 'deleted': 0,
|
||||
'created_at': next(ts_iter).internal,
|
||||
'created_at': next(self.ts).internal,
|
||||
'etag': 'whatever', 'size': 6789,
|
||||
'storage_policy_index': 1,
|
||||
'content_type': 'foo/bar'},
|
||||
@@ -1671,7 +1668,7 @@ class TestContainerController(unittest.TestCase):
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c?format=json',
|
||||
environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'X-Timestamp': next(ts_iter).internal})
|
||||
headers={'X-Timestamp': next(self.ts).internal})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(json.loads(resp.body), [
|
||||
@@ -1680,20 +1677,19 @@ class TestContainerController(unittest.TestCase):
|
||||
])
|
||||
|
||||
def test_UPDATE_autocreate(self):
|
||||
ts_iter = make_timestamp_iter()
|
||||
req = Request.blank(
|
||||
'/sda1/p/.a/c',
|
||||
environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'X-Timestamp': next(ts_iter).internal})
|
||||
headers={'X-Timestamp': next(self.ts).internal})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
|
||||
obj_ts = next(ts_iter)
|
||||
obj_ts = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/p/.a/c',
|
||||
environ={'REQUEST_METHOD': 'UPDATE'},
|
||||
headers={
|
||||
'X-Timestamp': next(ts_iter).internal,
|
||||
'X-Timestamp': next(self.ts).internal,
|
||||
'X-Backend-Storage-Policy-Index': str(POLICIES.default.idx)},
|
||||
body=json.dumps([
|
||||
{'name': 'some obj', 'deleted': 0,
|
||||
@@ -1702,12 +1698,12 @@ class TestContainerController(unittest.TestCase):
|
||||
'storage_policy_index': POLICIES.default.idx,
|
||||
'content_type': 'foo/bar'},
|
||||
{'name': 'some tombstone', 'deleted': 1,
|
||||
'created_at': next(ts_iter).internal,
|
||||
'created_at': next(self.ts).internal,
|
||||
'etag': 'noetag', 'size': 0,
|
||||
'storage_policy_index': POLICIES.default.idx,
|
||||
'content_type': 'application/deleted'},
|
||||
{'name': 'wrong policy', 'deleted': 0,
|
||||
'created_at': next(ts_iter).internal,
|
||||
'created_at': next(self.ts).internal,
|
||||
'etag': 'whatever', 'size': 6789,
|
||||
'storage_policy_index': 1,
|
||||
'content_type': 'foo/bar'},
|
||||
@@ -1718,7 +1714,7 @@ class TestContainerController(unittest.TestCase):
|
||||
req = Request.blank(
|
||||
'/sda1/p/.a/c?format=json',
|
||||
environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'X-Timestamp': next(ts_iter).internal})
|
||||
headers={'X-Timestamp': next(self.ts).internal})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(json.loads(resp.body), [
|
||||
@@ -2481,9 +2477,8 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(resp.status_int, 412)
|
||||
|
||||
def test_PUT_shard_range_autocreates_shard_container(self):
|
||||
ts_iter = make_timestamp_iter()
|
||||
shard_range = ShardRange('.shards_a/shard_c', next(ts_iter))
|
||||
put_timestamp = next(ts_iter).internal
|
||||
shard_range = ShardRange('.shards_a/shard_c', next(self.ts))
|
||||
put_timestamp = next(self.ts).internal
|
||||
headers = {'X-Backend-Record-Type': 'shard',
|
||||
'X-Timestamp': put_timestamp,
|
||||
'X-Container-Sysmeta-Test': 'set',
|
||||
@@ -2498,7 +2493,7 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
# PUT shard range to non-existent container with autocreate flag,
|
||||
# missing storage policy
|
||||
headers['X-Timestamp'] = next(ts_iter).internal
|
||||
headers['X-Timestamp'] = next(self.ts).internal
|
||||
headers['X-Backend-Auto-Create'] = 't'
|
||||
req = Request.blank(
|
||||
'/sda1/p/.shards_a/shard_c', method='PUT', headers=headers,
|
||||
@@ -2509,7 +2504,7 @@ class TestContainerController(unittest.TestCase):
|
||||
resp.body)
|
||||
|
||||
# PUT shard range to non-existent container with autocreate flag
|
||||
headers['X-Timestamp'] = next(ts_iter).internal
|
||||
headers['X-Timestamp'] = next(self.ts).internal
|
||||
policy_index = random.choice(POLICIES).idx
|
||||
headers['X-Backend-Storage-Policy-Index'] = str(policy_index)
|
||||
req = Request.blank(
|
||||
@@ -2519,7 +2514,7 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(201, resp.status_int)
|
||||
|
||||
# repeat PUT of shard range to autocreated container - 202 response
|
||||
headers['X-Timestamp'] = next(ts_iter).internal
|
||||
headers['X-Timestamp'] = next(self.ts).internal
|
||||
headers.pop('X-Backend-Storage-Policy-Index') # no longer required
|
||||
req = Request.blank(
|
||||
'/sda1/p/.shards_a/shard_c', method='PUT', headers=headers,
|
||||
@@ -2528,17 +2523,16 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(202, resp.status_int)
|
||||
|
||||
# regular PUT to autocreated container - 202 response
|
||||
headers['X-Timestamp'] = next(ts_iter).internal
|
||||
headers['X-Timestamp'] = next(self.ts).internal
|
||||
req = Request.blank(
|
||||
'/sda1/p/.shards_a/shard_c', method='PUT',
|
||||
headers={'X-Timestamp': next(ts_iter).internal},
|
||||
headers={'X-Timestamp': next(self.ts).internal},
|
||||
body=json.dumps([dict(shard_range)]))
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(202, resp.status_int)
|
||||
|
||||
def test_PUT_shard_range_to_deleted_container(self):
|
||||
ts_iter = make_timestamp_iter()
|
||||
put_time = next(ts_iter).internal
|
||||
put_time = next(self.ts).internal
|
||||
# create a container, get it to sharded state and then delete it
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT',
|
||||
headers={'X-Timestamp': put_time})
|
||||
@@ -2546,11 +2540,11 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(201, resp.status_int)
|
||||
|
||||
broker = self.controller._get_container_broker('sda1', 'p', 'a', 'c')
|
||||
broker.enable_sharding(next(ts_iter))
|
||||
broker.enable_sharding(next(self.ts))
|
||||
self.assertTrue(broker.set_sharding_state())
|
||||
self.assertTrue(broker.set_sharded_state())
|
||||
|
||||
delete_time = next(ts_iter).internal
|
||||
delete_time = next(self.ts).internal
|
||||
req = Request.blank('/sda1/p/a/c', method='DELETE',
|
||||
headers={'X-Timestamp': delete_time})
|
||||
resp = req.get_response(self.controller)
|
||||
@@ -2563,10 +2557,10 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(404, resp.status_int)
|
||||
|
||||
# shard range PUT is accepted but container remains deleted
|
||||
shard_range = ShardRange('.shards_a/shard_c', next(ts_iter),
|
||||
shard_range = ShardRange('.shards_a/shard_c', next(self.ts),
|
||||
state=ShardRange.ACTIVE)
|
||||
headers = {'X-Backend-Record-Type': 'shard',
|
||||
'X-Timestamp': next(ts_iter).internal,
|
||||
'X-Timestamp': next(self.ts).internal,
|
||||
'X-Container-Sysmeta-Test': 'set',
|
||||
'X-Container-Meta-Test': 'persisted'}
|
||||
|
||||
@@ -2582,7 +2576,7 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(404, resp.status_int)
|
||||
|
||||
# unless shard range has non-zero stats, then container is revived
|
||||
shard_range.update_meta(99, 1234, meta_timestamp=next(ts_iter))
|
||||
shard_range.update_meta(99, 1234, meta_timestamp=next(self.ts))
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers=headers,
|
||||
body=json.dumps([dict(shard_range)]))
|
||||
resp = req.get_response(self.controller)
|
||||
@@ -2596,19 +2590,18 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual('99', resp.headers['X-Container-Object-Count'])
|
||||
|
||||
def test_PUT_shard_range_json_in_body(self):
|
||||
ts_iter = make_timestamp_iter()
|
||||
oldest_ts = next(ts_iter) # used for stale shard range PUT later
|
||||
oldest_ts = next(self.ts) # used for stale shard range PUT later
|
||||
shard_bounds = [('', 'ham', ShardRange.ACTIVE),
|
||||
('ham', 'salami', ShardRange.ACTIVE),
|
||||
('salami', '', ShardRange.CREATED)]
|
||||
shard_ranges = [
|
||||
ShardRange('.shards_a/_%s' % upper, next(ts_iter),
|
||||
ShardRange('.shards_a/_%s' % upper, next(self.ts),
|
||||
lower, upper,
|
||||
i * 100, i * 1000, meta_timestamp=next(ts_iter),
|
||||
state=state, state_timestamp=next(ts_iter))
|
||||
i * 100, i * 1000, meta_timestamp=next(self.ts),
|
||||
state=state, state_timestamp=next(self.ts))
|
||||
for i, (lower, upper, state) in enumerate(shard_bounds)]
|
||||
|
||||
put_timestamp = next(ts_iter).internal
|
||||
put_timestamp = next(self.ts).internal
|
||||
headers = {'X-Backend-Record-Type': 'shard',
|
||||
'X-Timestamp': put_timestamp,
|
||||
'X-Container-Sysmeta-Test': 'set',
|
||||
@@ -2647,7 +2640,7 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
# empty json dict
|
||||
body = json.dumps({})
|
||||
headers['X-Timestamp'] = next(ts_iter).internal
|
||||
headers['X-Timestamp'] = next(self.ts).internal
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
resp = req.get_response(self.controller)
|
||||
@@ -2658,12 +2651,12 @@ class TestContainerController(unittest.TestCase):
|
||||
broker.get_shard_ranges())
|
||||
self.assertEqual(put_timestamp, broker.get_info()['put_timestamp'])
|
||||
|
||||
older_ts = next(ts_iter) # used for stale shard range PUT later
|
||||
older_ts = next(self.ts) # used for stale shard range PUT later
|
||||
# updated and new shard ranges
|
||||
shard_ranges[1].bytes_used += 100
|
||||
shard_ranges[1].meta_timestamp = next(ts_iter)
|
||||
shard_ranges[1].meta_timestamp = next(self.ts)
|
||||
body = json.dumps([dict(sr) for sr in shard_ranges[1:]])
|
||||
headers['X-Timestamp'] = next(ts_iter).internal
|
||||
headers['X-Timestamp'] = next(self.ts).internal
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
resp = req.get_response(self.controller)
|
||||
@@ -2682,7 +2675,7 @@ class TestContainerController(unittest.TestCase):
|
||||
stale_shard_range.state = ShardRange.CREATED
|
||||
stale_shard_range.state_timestamp = oldest_ts
|
||||
body = json.dumps([dict(stale_shard_range)])
|
||||
headers['X-Timestamp'] = next(ts_iter).internal
|
||||
headers['X-Timestamp'] = next(self.ts).internal
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
resp = req.get_response(self.controller)
|
||||
@@ -2695,7 +2688,7 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
# deleted shard range
|
||||
shard_ranges[0].deleted = 1
|
||||
shard_ranges[0].timestamp = next(ts_iter)
|
||||
shard_ranges[0].timestamp = next(self.ts)
|
||||
body = json.dumps([dict(shard_ranges[0])])
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
@@ -2708,7 +2701,7 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(put_timestamp, broker.get_info()['put_timestamp'])
|
||||
|
||||
def check_bad_body(body):
|
||||
bad_put_timestamp = next(ts_iter).internal
|
||||
bad_put_timestamp = next(self.ts).internal
|
||||
headers['X-Timestamp'] = bad_put_timestamp
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
@@ -2725,7 +2718,7 @@ class TestContainerController(unittest.TestCase):
|
||||
check_bad_body('')
|
||||
check_bad_body('["not a shard range"]')
|
||||
check_bad_body('[[]]')
|
||||
bad_shard_range = dict(ShardRange('a/c', next(ts_iter)))
|
||||
bad_shard_range = dict(ShardRange('a/c', next(self.ts)))
|
||||
bad_shard_range.pop('timestamp')
|
||||
check_bad_body(json.dumps([bad_shard_range]))
|
||||
|
||||
@@ -2733,7 +2726,7 @@ class TestContainerController(unittest.TestCase):
|
||||
# body ignored
|
||||
body = json.dumps([dict(sr) for sr in shard_ranges])
|
||||
# note, regular PUT so put timestamp is updated
|
||||
put_timestamp = next(ts_iter).internal
|
||||
put_timestamp = next(self.ts).internal
|
||||
headers['X-Timestamp'] = put_timestamp
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
@@ -2744,21 +2737,20 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(put_timestamp, broker.get_info()['put_timestamp'])
|
||||
|
||||
check_not_shard_record_type({'X-Backend-Record-Type': 'object',
|
||||
'X-Timestamp': next(ts_iter).internal})
|
||||
'X-Timestamp': next(self.ts).internal})
|
||||
|
||||
check_not_shard_record_type({'X-Timestamp': next(ts_iter).internal})
|
||||
check_not_shard_record_type({'X-Timestamp': next(self.ts).internal})
|
||||
|
||||
def test_PUT_GET_shard_ranges(self):
|
||||
# make a container
|
||||
ts_iter = make_timestamp_iter()
|
||||
ts_now = Timestamp.now() # used when mocking Timestamp.now()
|
||||
ts_put = next(ts_iter)
|
||||
ts_put = next(self.ts)
|
||||
headers = {'X-Timestamp': ts_put.normal}
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers=headers)
|
||||
self.assertEqual(201, req.get_response(self.controller).status_int)
|
||||
# PUT some objects
|
||||
objects = [{'name': 'obj_%d' % i,
|
||||
'x-timestamp': next(ts_iter).normal,
|
||||
'x-timestamp': next(self.ts).normal,
|
||||
'x-content-type': 'text/plain',
|
||||
'x-etag': 'etag_%d' % i,
|
||||
'x-size': 1024 * i
|
||||
@@ -2777,10 +2769,10 @@ class TestContainerController(unittest.TestCase):
|
||||
('yoghurt', '', ShardRange.FOUND),
|
||||
]
|
||||
shard_ranges = [
|
||||
ShardRange('.sharded_a/_%s' % upper, next(ts_iter),
|
||||
ShardRange('.sharded_a/_%s' % upper, next(self.ts),
|
||||
lower, upper,
|
||||
i * 100, i * 1000, meta_timestamp=next(ts_iter),
|
||||
state=state, state_timestamp=next(ts_iter))
|
||||
i * 100, i * 1000, meta_timestamp=next(self.ts),
|
||||
state=state, state_timestamp=next(self.ts))
|
||||
for i, (lower, upper, state) in enumerate(shard_bounds)]
|
||||
for shard_range in shard_ranges:
|
||||
self._put_shard_range(shard_range)
|
||||
@@ -3013,7 +3005,7 @@ class TestContainerController(unittest.TestCase):
|
||||
params='&states=listing&reverse=true&marker=egg')
|
||||
self.assertIsNone(
|
||||
resp.headers.get('X-Backend-Override-Shard-Name-Filter'))
|
||||
ts_epoch = next(ts_iter)
|
||||
ts_epoch = next(self.ts)
|
||||
broker.enable_sharding(ts_epoch)
|
||||
self.assertTrue(broker.set_sharding_state())
|
||||
check_shard_GET(
|
||||
@@ -3032,7 +3024,7 @@ class TestContainerController(unittest.TestCase):
|
||||
# params and return listing shard ranges for entire namespace if
|
||||
# X-Backend-Override-Shard-Name-Filter == 'sharded'
|
||||
self.assertTrue(broker.set_sharded_state())
|
||||
ts_now = next(ts_iter)
|
||||
ts_now = next(self.ts)
|
||||
with mock_timestamp_now(ts_now):
|
||||
extra_shard_range = broker.get_own_shard_range()
|
||||
extra_shard_range.lower = shard_ranges[2].upper
|
||||
@@ -3065,7 +3057,7 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
# delete a shard range
|
||||
shard_range = shard_ranges[1]
|
||||
shard_range.set_deleted(timestamp=next(ts_iter))
|
||||
shard_range.set_deleted(timestamp=next(self.ts))
|
||||
self._put_shard_range(shard_range)
|
||||
|
||||
self._assert_shard_ranges_equal(shard_ranges[:1] + shard_ranges[2:],
|
||||
@@ -3091,32 +3083,31 @@ class TestContainerController(unittest.TestCase):
|
||||
# make a shrunk shard container with two acceptors that overlap with
|
||||
# the shard's namespace
|
||||
shard_path = '.shards_a/c_f'
|
||||
ts_iter = make_timestamp_iter()
|
||||
ts_now = Timestamp.now() # used when mocking Timestamp.now()
|
||||
own_shard_range = ShardRange(shard_path, next(ts_iter),
|
||||
own_shard_range = ShardRange(shard_path, next(self.ts),
|
||||
'b', 'f', 100, 1000,
|
||||
meta_timestamp=next(ts_iter),
|
||||
meta_timestamp=next(self.ts),
|
||||
state=ShardRange.SHRUNK,
|
||||
state_timestamp=next(ts_iter),
|
||||
epoch=next(ts_iter))
|
||||
state_timestamp=next(self.ts),
|
||||
epoch=next(self.ts))
|
||||
shard_ranges = []
|
||||
for lower, upper in (('a', 'd'), ('d', 'g')):
|
||||
shard_ranges.append(
|
||||
ShardRange('.shards_a/c_%s' % upper, next(ts_iter),
|
||||
ShardRange('.shards_a/c_%s' % upper, next(self.ts),
|
||||
lower, upper, 100, 1000,
|
||||
meta_timestamp=next(ts_iter),
|
||||
meta_timestamp=next(self.ts),
|
||||
state=ShardRange.ACTIVE,
|
||||
state_timestamp=next(ts_iter)))
|
||||
state_timestamp=next(self.ts)))
|
||||
|
||||
# create container
|
||||
headers = {'X-Timestamp': next(ts_iter).normal}
|
||||
headers = {'X-Timestamp': next(self.ts).normal}
|
||||
req = Request.blank(
|
||||
'/sda1/p/%s' % shard_path, method='PUT', headers=headers)
|
||||
self.assertIn(
|
||||
req.get_response(self.controller).status_int, (201, 202))
|
||||
|
||||
# PUT the acceptor shard ranges and own shard range
|
||||
headers = {'X-Timestamp': next(ts_iter).normal,
|
||||
headers = {'X-Timestamp': next(self.ts).normal,
|
||||
'X-Container-Sysmeta-Shard-Root': 'a/c',
|
||||
'X-Backend-Record-Type': 'shard'}
|
||||
body = json.dumps(
|
||||
@@ -3185,27 +3176,26 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
def test_GET_shard_ranges_using_state_aliases(self):
|
||||
# make a shard container
|
||||
ts_iter = make_timestamp_iter()
|
||||
shard_ranges = []
|
||||
lower = ''
|
||||
for state in sorted(ShardRange.STATES.keys()):
|
||||
upper = str(state)
|
||||
shard_ranges.append(
|
||||
ShardRange('.shards_a/c_%s' % upper, next(ts_iter),
|
||||
ShardRange('.shards_a/c_%s' % upper, next(self.ts),
|
||||
lower, upper, state * 100, state * 1000,
|
||||
meta_timestamp=next(ts_iter),
|
||||
state=state, state_timestamp=next(ts_iter)))
|
||||
meta_timestamp=next(self.ts),
|
||||
state=state, state_timestamp=next(self.ts)))
|
||||
lower = upper
|
||||
|
||||
def do_test(root_path, path, params, expected_states):
|
||||
expected = [
|
||||
sr for sr in shard_ranges if sr.state in expected_states]
|
||||
own_shard_range = ShardRange(path, next(ts_iter), '', '',
|
||||
own_shard_range = ShardRange(path, next(self.ts), '', '',
|
||||
state=ShardRange.ACTIVE)
|
||||
expected.append(own_shard_range.copy(lower=expected[-1].upper))
|
||||
expected = [dict(sr, last_modified=sr.timestamp.isoformat)
|
||||
for sr in expected]
|
||||
headers = {'X-Timestamp': next(ts_iter).normal}
|
||||
headers = {'X-Timestamp': next(self.ts).normal}
|
||||
|
||||
# create container
|
||||
req = Request.blank(
|
||||
@@ -3213,7 +3203,7 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertIn(
|
||||
req.get_response(self.controller).status_int, (201, 202))
|
||||
# PUT some shard ranges
|
||||
headers = {'X-Timestamp': next(ts_iter).normal,
|
||||
headers = {'X-Timestamp': next(self.ts).normal,
|
||||
'X-Container-Sysmeta-Shard-Root': root_path,
|
||||
'X-Backend-Record-Type': 'shard'}
|
||||
body = json.dumps(
|
||||
@@ -3259,26 +3249,25 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
def test_GET_shard_ranges_include_deleted(self):
|
||||
# make a shard container
|
||||
ts_iter = make_timestamp_iter()
|
||||
ts_now = Timestamp.now() # used when mocking Timestamp.now()
|
||||
shard_ranges = []
|
||||
lower = ''
|
||||
for state in sorted(ShardRange.STATES.keys()):
|
||||
upper = str(state)
|
||||
shard_ranges.append(
|
||||
ShardRange('.shards_a/c_%s' % upper, next(ts_iter),
|
||||
ShardRange('.shards_a/c_%s' % upper, next(self.ts),
|
||||
lower, upper, state * 100, state * 1000,
|
||||
meta_timestamp=next(ts_iter),
|
||||
state=state, state_timestamp=next(ts_iter)))
|
||||
meta_timestamp=next(self.ts),
|
||||
state=state, state_timestamp=next(self.ts)))
|
||||
lower = upper
|
||||
# create container
|
||||
headers = {'X-Timestamp': next(ts_iter).normal}
|
||||
headers = {'X-Timestamp': next(self.ts).normal}
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers)
|
||||
self.assertIn(
|
||||
req.get_response(self.controller).status_int, (201, 202))
|
||||
# PUT some shard ranges
|
||||
headers = {'X-Timestamp': next(ts_iter).normal,
|
||||
headers = {'X-Timestamp': next(self.ts).normal,
|
||||
'X-Backend-Record-Type': 'shard'}
|
||||
body = json.dumps([dict(sr) for sr in shard_ranges])
|
||||
req = Request.blank(
|
||||
@@ -3303,10 +3292,10 @@ class TestContainerController(unittest.TestCase):
|
||||
do_test(False, shard_ranges)
|
||||
do_test(True, shard_ranges)
|
||||
|
||||
headers = {'X-Timestamp': next(ts_iter).normal,
|
||||
headers = {'X-Timestamp': next(self.ts).normal,
|
||||
'X-Backend-Record-Type': 'shard'}
|
||||
for sr in shard_ranges[::2]:
|
||||
sr.set_deleted(timestamp=next(ts_iter))
|
||||
sr.set_deleted(timestamp=next(self.ts))
|
||||
body = json.dumps([dict(sr) for sr in shard_ranges])
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
@@ -3317,10 +3306,10 @@ class TestContainerController(unittest.TestCase):
|
||||
do_test(False, shard_ranges[1::2])
|
||||
do_test(True, shard_ranges)
|
||||
|
||||
headers = {'X-Timestamp': next(ts_iter).normal,
|
||||
headers = {'X-Timestamp': next(self.ts).normal,
|
||||
'X-Backend-Record-Type': 'shard'}
|
||||
for sr in shard_ranges[1::2]:
|
||||
sr.set_deleted(timestamp=next(ts_iter))
|
||||
sr.set_deleted(timestamp=next(self.ts))
|
||||
body = json.dumps([dict(sr) for sr in shard_ranges])
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers, body=body)
|
||||
@@ -3331,26 +3320,25 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
def test_GET_shard_ranges_errors(self):
|
||||
# verify that x-backend-record-type is not included in error responses
|
||||
ts_iter = make_timestamp_iter()
|
||||
ts_now = Timestamp.now() # used when mocking Timestamp.now()
|
||||
shard_ranges = []
|
||||
lower = ''
|
||||
for state in sorted(ShardRange.STATES.keys()):
|
||||
upper = str(state)
|
||||
shard_ranges.append(
|
||||
ShardRange('.shards_a/c_%s' % upper, next(ts_iter),
|
||||
ShardRange('.shards_a/c_%s' % upper, next(self.ts),
|
||||
lower, upper, state * 100, state * 1000,
|
||||
meta_timestamp=next(ts_iter),
|
||||
state=state, state_timestamp=next(ts_iter)))
|
||||
meta_timestamp=next(self.ts),
|
||||
state=state, state_timestamp=next(self.ts)))
|
||||
lower = upper
|
||||
# create container
|
||||
headers = {'X-Timestamp': next(ts_iter).normal}
|
||||
headers = {'X-Timestamp': next(self.ts).normal}
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c', method='PUT', headers=headers)
|
||||
self.assertIn(
|
||||
req.get_response(self.controller).status_int, (201, 202))
|
||||
# PUT some shard ranges
|
||||
headers = {'X-Timestamp': next(ts_iter).normal,
|
||||
headers = {'X-Timestamp': next(self.ts).normal,
|
||||
'X-Backend-Record-Type': 'shard'}
|
||||
body = json.dumps([dict(sr) for sr in shard_ranges])
|
||||
req = Request.blank(
|
||||
@@ -3381,7 +3369,7 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
# delete the container
|
||||
req = Request.blank('/sda1/p/a/c', method='DELETE',
|
||||
headers={'X-Timestamp': next(ts_iter).normal})
|
||||
headers={'X-Timestamp': next(self.ts).normal})
|
||||
self.assertEqual(204, req.get_response(self.controller).status_int)
|
||||
|
||||
do_test({'states': 'bad'}, 404)
|
||||
@@ -3486,14 +3474,13 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
def test_GET_auto_record_type(self):
|
||||
# make a container
|
||||
ts_iter = make_timestamp_iter()
|
||||
ts_now = Timestamp.now() # used when mocking Timestamp.now()
|
||||
headers = {'X-Timestamp': next(ts_iter).normal}
|
||||
headers = {'X-Timestamp': next(self.ts).normal}
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers=headers)
|
||||
self.assertEqual(201, req.get_response(self.controller).status_int)
|
||||
# PUT some objects
|
||||
objects = [{'name': 'obj_%d' % i,
|
||||
'x-timestamp': next(ts_iter).normal,
|
||||
'x-timestamp': next(self.ts).normal,
|
||||
'x-content-type': 'text/plain',
|
||||
'x-etag': 'etag_%d' % i,
|
||||
'x-size': 1024 * i
|
||||
@@ -3508,10 +3495,10 @@ class TestContainerController(unittest.TestCase):
|
||||
shard_bounds = [('', 'm', ShardRange.CLEAVED),
|
||||
('m', '', ShardRange.CREATED)]
|
||||
shard_ranges = [
|
||||
ShardRange('.sharded_a/_%s' % upper, next(ts_iter),
|
||||
ShardRange('.sharded_a/_%s' % upper, next(self.ts),
|
||||
lower, upper,
|
||||
i * 100, i * 1000, meta_timestamp=next(ts_iter),
|
||||
state=state, state_timestamp=next(ts_iter))
|
||||
i * 100, i * 1000, meta_timestamp=next(self.ts),
|
||||
state=state, state_timestamp=next(self.ts))
|
||||
for i, (lower, upper, state) in enumerate(shard_bounds)]
|
||||
for shard_range in shard_ranges:
|
||||
self._put_shard_range(shard_range)
|
||||
@@ -3578,7 +3565,7 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(headers, resp.headers)
|
||||
|
||||
# move to sharding state
|
||||
broker.enable_sharding(next(ts_iter))
|
||||
broker.enable_sharding(next(self.ts))
|
||||
self.assertTrue(broker.set_sharding_state())
|
||||
req = Request.blank('/sda1/p/a/c?format=json', method='GET',
|
||||
headers={'X-Backend-Record-Type': 'auto'})
|
||||
@@ -3633,14 +3620,13 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
def test_PUT_GET_to_sharding_container(self):
|
||||
broker = self.controller._get_container_broker('sda1', 'p', 'a', 'c')
|
||||
ts_iter = make_timestamp_iter()
|
||||
headers = {'X-Timestamp': next(ts_iter).normal}
|
||||
headers = {'X-Timestamp': next(self.ts).normal}
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers=headers)
|
||||
self.assertEqual(201, req.get_response(self.controller).status_int)
|
||||
|
||||
def do_update(name, timestamp=None, headers=None):
|
||||
# Make a PUT request to container controller to update an object
|
||||
timestamp = timestamp or next(ts_iter)
|
||||
timestamp = timestamp or next(self.ts)
|
||||
headers = headers or {}
|
||||
headers.update({'X-Timestamp': timestamp.internal,
|
||||
'X-Size': 17,
|
||||
@@ -3674,7 +3660,7 @@ class TestContainerController(unittest.TestCase):
|
||||
assert_broker_rows(broker, ['unsharded'], 1)
|
||||
|
||||
# move container to sharding state
|
||||
broker.enable_sharding(next(ts_iter))
|
||||
broker.enable_sharding(next(self.ts))
|
||||
self.assertTrue(broker.set_sharding_state())
|
||||
assert_broker_rows(broker.get_brokers()[0], ['unsharded'], 1)
|
||||
assert_broker_rows(broker.get_brokers()[1], [], 1)
|
||||
@@ -3714,14 +3700,13 @@ class TestContainerController(unittest.TestCase):
|
||||
def _check_object_update_redirected_to_shard(self, method):
|
||||
expected_status = 204 if method == 'DELETE' else 201
|
||||
broker = self.controller._get_container_broker('sda1', 'p', 'a', 'c')
|
||||
ts_iter = make_timestamp_iter()
|
||||
headers = {'X-Timestamp': next(ts_iter).normal}
|
||||
headers = {'X-Timestamp': next(self.ts).normal}
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers=headers)
|
||||
self.assertEqual(201, req.get_response(self.controller).status_int)
|
||||
|
||||
def do_update(name, timestamp=None, headers=None):
|
||||
# Make a PUT request to container controller to update an object
|
||||
timestamp = timestamp or next(ts_iter)
|
||||
timestamp = timestamp or next(self.ts)
|
||||
headers = headers or {}
|
||||
headers.update({'X-Timestamp': timestamp.internal,
|
||||
'X-Size': 17,
|
||||
@@ -3752,7 +3737,7 @@ class TestContainerController(unittest.TestCase):
|
||||
resp.headers['X-Backend-Redirect-Timestamp'])
|
||||
|
||||
# sanity check
|
||||
ts_bashful_orig = next(ts_iter)
|
||||
ts_bashful_orig = next(self.ts)
|
||||
mocked_fn = 'swift.container.backend.ContainerBroker.get_shard_ranges'
|
||||
with mock.patch(mocked_fn) as mock_get_shard_ranges:
|
||||
assert_not_redirected('bashful', ts_bashful_orig)
|
||||
@@ -3760,10 +3745,10 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
shard_ranges = {
|
||||
'dopey': ShardRange(
|
||||
'.sharded_a/sr_dopey', next(ts_iter), '', 'dopey'),
|
||||
'.sharded_a/sr_dopey', next(self.ts), '', 'dopey'),
|
||||
'happy': ShardRange(
|
||||
'.sharded_a/sr_happy', next(ts_iter), 'dopey', 'happy'),
|
||||
'': ShardRange('.sharded_a/sr_', next(ts_iter), 'happy', '')
|
||||
'.sharded_a/sr_happy', next(self.ts), 'dopey', 'happy'),
|
||||
'': ShardRange('.sharded_a/sr_', next(self.ts), 'happy', '')
|
||||
}
|
||||
# start with only the middle shard range
|
||||
self._put_shard_range(shard_ranges['happy'])
|
||||
@@ -3777,7 +3762,7 @@ class TestContainerController(unittest.TestCase):
|
||||
for state in ShardRange.STATES:
|
||||
self.assertTrue(
|
||||
sr_happy.update_state(state,
|
||||
state_timestamp=next(ts_iter)))
|
||||
state_timestamp=next(self.ts)))
|
||||
self._put_shard_range(sr_happy)
|
||||
with annotate_failure(state):
|
||||
obj_name = 'grumpy%s' % state
|
||||
@@ -3797,12 +3782,12 @@ class TestContainerController(unittest.TestCase):
|
||||
[obj['name'] for obj in get_listing(-1)])
|
||||
|
||||
# set broker to sharding state
|
||||
broker.enable_sharding(next(ts_iter))
|
||||
broker.enable_sharding(next(self.ts))
|
||||
self.assertTrue(broker.set_sharding_state())
|
||||
for state in ShardRange.STATES:
|
||||
self.assertTrue(
|
||||
sr_happy.update_state(state,
|
||||
state_timestamp=next(ts_iter)))
|
||||
state_timestamp=next(self.ts)))
|
||||
self._put_shard_range(sr_happy)
|
||||
with annotate_failure(state):
|
||||
obj_name = 'grumpier%s' % state
|
||||
@@ -3829,19 +3814,19 @@ class TestContainerController(unittest.TestCase):
|
||||
|
||||
# no shard for this object yet so it is accepted by root container
|
||||
# and stored in misplaced objects...
|
||||
assert_not_redirected('dopey', timestamp=next(ts_iter))
|
||||
assert_not_redirected('dopey', timestamp=next(self.ts))
|
||||
self.assertIn('dopey', [obj['name'] for obj in get_listing(-1)])
|
||||
self.assertNotIn('dopey', [obj['name'] for obj in get_listing(0)])
|
||||
|
||||
# now PUT the first shard range
|
||||
sr_dopey = shard_ranges['dopey']
|
||||
sr_dopey.update_state(ShardRange.CLEAVED,
|
||||
state_timestamp=next(ts_iter))
|
||||
state_timestamp=next(self.ts))
|
||||
self._put_shard_range(sr_dopey)
|
||||
for state in ShardRange.STATES:
|
||||
self.assertTrue(
|
||||
sr_happy.update_state(state,
|
||||
state_timestamp=next(ts_iter)))
|
||||
state_timestamp=next(self.ts)))
|
||||
self._put_shard_range(sr_happy)
|
||||
with annotate_failure(state):
|
||||
obj_name = 'dopey%s' % state
|
||||
@@ -3879,7 +3864,7 @@ class TestContainerController(unittest.TestCase):
|
||||
for state in ShardRange.STATES:
|
||||
self.assertTrue(
|
||||
sr_happy.update_state(state,
|
||||
state_timestamp=next(ts_iter)))
|
||||
state_timestamp=next(self.ts)))
|
||||
self._put_shard_range(sr_happy)
|
||||
with annotate_failure(state):
|
||||
obj_name = 'grumpiest%s' % state
|
||||
|
||||
Reference in New Issue
Block a user