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:
Alistair Coles
2024-01-04 16:43:26 +00:00
parent 3cbf01b12d
commit f2c6c19411

View File

@@ -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