Merge "tests: clarify timestamp formats"
This commit is contained in:
@@ -995,8 +995,14 @@ class TestObjectController(BaseTestCase):
|
||||
resp, head_resp = self._do_test_diskfile_metadata_unavailable(req)
|
||||
self.assertEqual(resp.status_int, 201)
|
||||
self.assertEqual(head_resp.status_int, 200)
|
||||
self.assertEqual(req.headers['X-Timestamp'],
|
||||
# response x-timestamp uses the *normal* format
|
||||
self.assertEqual(Timestamp(req.headers['X-Timestamp']).normal,
|
||||
head_resp.headers['X-Timestamp'])
|
||||
# response x-<*>-timestamp uses the *internal* format
|
||||
self.assertEqual(Timestamp(req.headers['X-Timestamp']).internal,
|
||||
head_resp.headers['X-Backend-Timestamp'])
|
||||
self.assertEqual(Timestamp(req.headers['X-Timestamp']).internal,
|
||||
head_resp.headers['X-Backend-Data-Timestamp'])
|
||||
self.assertNotIn('X-Object-Meta-Test', head_resp.headers)
|
||||
|
||||
def test_POST_metafile_unavailable(self):
|
||||
@@ -2015,7 +2021,7 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'X-Timestamp': old_timestamp.normal,
|
||||
headers={'X-Timestamp': old_timestamp.internal,
|
||||
'Content-Length': '0',
|
||||
'Content-Type': 'application/octet-stream'})
|
||||
resp = req.get_response(self.object_controller)
|
||||
@@ -2023,7 +2029,7 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': new_timestamp.normal,
|
||||
headers={'X-Timestamp': new_timestamp.internal,
|
||||
'Content-Type': 'text/plain',
|
||||
'Content-Encoding': 'gzip'})
|
||||
req.body = 'VERIFY TWO'
|
||||
@@ -2052,14 +2058,14 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'X-Timestamp': new_timestamp.normal,
|
||||
headers={'X-Timestamp': new_timestamp.internal,
|
||||
'Content-Length': '0',
|
||||
'Content-Type': 'application/octet-stream'})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': old_timestamp.normal,
|
||||
headers={'X-Timestamp': old_timestamp.internal,
|
||||
'Content-Type': 'text/plain',
|
||||
'Content-Encoding': 'gzip'})
|
||||
req.body = 'VERIFY TWO'
|
||||
@@ -2125,11 +2131,11 @@ class TestObjectController(BaseTestCase):
|
||||
'Content-Encoding': 'gzip'})
|
||||
|
||||
def test_PUT_old_timestamp(self):
|
||||
ts = time()
|
||||
orig_timestamp = utils.Timestamp(ts).internal
|
||||
older_timestamp = next(self.ts)
|
||||
orig_timestamp = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': orig_timestamp,
|
||||
headers={'X-Timestamp': orig_timestamp.internal,
|
||||
'Content-Length': '6',
|
||||
'Content-Type': 'application/octet-stream'})
|
||||
req.body = 'VERIFY'
|
||||
@@ -2137,23 +2143,25 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertEqual(resp.status_int, 201)
|
||||
|
||||
req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': normalize_timestamp(ts),
|
||||
headers={'X-Timestamp': orig_timestamp.internal,
|
||||
'Content-Type': 'text/plain',
|
||||
'Content-Encoding': 'gzip'})
|
||||
req.body = 'VERIFY TWO'
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 409)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'], orig_timestamp)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
orig_timestamp.internal)
|
||||
|
||||
req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={
|
||||
'X-Timestamp': normalize_timestamp(ts - 1),
|
||||
'X-Timestamp': older_timestamp.internal,
|
||||
'Content-Type': 'text/plain',
|
||||
'Content-Encoding': 'gzip'})
|
||||
req.body = 'VERIFY THREE'
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 409)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'], orig_timestamp)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
orig_timestamp.internal)
|
||||
|
||||
def test_PUT_new_object_really_old_timestamp(self):
|
||||
req = Request.blank(
|
||||
@@ -3603,10 +3611,10 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
|
||||
sleep(.00001)
|
||||
timestamp = normalize_timestamp(time())
|
||||
timestamp = Timestamp.now()
|
||||
req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={
|
||||
'X-Timestamp': timestamp,
|
||||
'X-Timestamp': timestamp.internal,
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'Content-length': '6'})
|
||||
req.body = b'VERIFY'
|
||||
@@ -3614,10 +3622,10 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertEqual(resp.status_int, 201)
|
||||
|
||||
sleep(.00001)
|
||||
timestamp = normalize_timestamp(time())
|
||||
timestamp = Timestamp.now()
|
||||
req = Request.blank('/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'X-Timestamp': timestamp})
|
||||
headers={'X-Timestamp': timestamp.internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 204)
|
||||
|
||||
@@ -3626,7 +3634,7 @@ class TestObjectController(BaseTestCase):
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
utils.Timestamp(timestamp).internal)
|
||||
timestamp.internal)
|
||||
|
||||
def test_HEAD_quarantine_zbyte(self):
|
||||
# Test swift.obj.server.ObjectController.GET
|
||||
@@ -5644,9 +5652,9 @@ class TestObjectController(BaseTestCase):
|
||||
def capture_updates(ip, port, method, path, headers, *args, **kwargs):
|
||||
container_updates.append((ip, port, method, path, headers))
|
||||
# create a new object
|
||||
create_timestamp = next(self.ts).internal
|
||||
create_timestamp = next(self.ts)
|
||||
req = Request.blank('/sda1/p/a/c/o', method='PUT', body=b'test1',
|
||||
headers={'X-Timestamp': create_timestamp,
|
||||
headers={'X-Timestamp': create_timestamp.internal,
|
||||
'X-Container-Host': '10.0.0.1:8080',
|
||||
'X-Container-Device': 'sda1',
|
||||
'X-Container-Partition': 'p',
|
||||
@@ -5668,7 +5676,7 @@ class TestObjectController(BaseTestCase):
|
||||
'X-Size': len(b'test1'),
|
||||
'X-Etag': md5(b'test1', usedforsecurity=False).hexdigest(),
|
||||
'X-Content-Type': 'text/plain',
|
||||
'X-Timestamp': create_timestamp,
|
||||
'X-Timestamp': create_timestamp.internal,
|
||||
}
|
||||
for key, value in expected.items():
|
||||
self.assertEqual(headers[key], str(value))
|
||||
@@ -5677,16 +5685,16 @@ class TestObjectController(BaseTestCase):
|
||||
req = Request.blank('/sda1/p/a/c/o', method='GET')
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(resp.headers['X-Timestamp'],
|
||||
utils.Timestamp(create_timestamp).normal)
|
||||
self.assertEqual(resp.headers['X-Timestamp'], create_timestamp.normal)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
create_timestamp)
|
||||
create_timestamp.internal)
|
||||
self.assertEqual(resp.headers['X-Backend-Data-Timestamp'],
|
||||
create_timestamp.internal)
|
||||
self.assertEqual(resp.body, b'test1')
|
||||
# send an update with an offset
|
||||
offset_timestamp = utils.Timestamp(
|
||||
create_timestamp, offset=1).internal
|
||||
offset_timestamp = utils.Timestamp(create_timestamp, offset=1)
|
||||
req = Request.blank('/sda1/p/a/c/o', method='PUT', body=b'test2',
|
||||
headers={'X-Timestamp': offset_timestamp,
|
||||
headers={'X-Timestamp': offset_timestamp.internal,
|
||||
'X-Container-Host': '10.0.0.1:8080',
|
||||
'X-Container-Device': 'sda1',
|
||||
'X-Container-Partition': 'p',
|
||||
@@ -5708,7 +5716,7 @@ class TestObjectController(BaseTestCase):
|
||||
'X-Size': len(b'test2'),
|
||||
'X-Etag': md5(b'test2', usedforsecurity=False).hexdigest(),
|
||||
'X-Content-Type': 'text/html',
|
||||
'X-Timestamp': offset_timestamp,
|
||||
'X-Timestamp': offset_timestamp.internal,
|
||||
}
|
||||
for key, value in expected.items():
|
||||
self.assertEqual(headers[key], str(value))
|
||||
@@ -5717,19 +5725,19 @@ class TestObjectController(BaseTestCase):
|
||||
req = Request.blank('/sda1/p/a/c/o', method='GET')
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(resp.headers['X-Timestamp'],
|
||||
utils.Timestamp(offset_timestamp).normal)
|
||||
self.assertEqual(resp.headers['X-Timestamp'], offset_timestamp.normal)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
offset_timestamp)
|
||||
offset_timestamp.internal)
|
||||
self.assertEqual(resp.body, b'test2')
|
||||
# now overwrite with a newer time
|
||||
overwrite_timestamp = next(self.ts).internal
|
||||
req = Request.blank('/sda1/p/a/c/o', method='PUT', body=b'test3',
|
||||
headers={'X-Timestamp': overwrite_timestamp,
|
||||
'X-Container-Host': '10.0.0.1:8080',
|
||||
'X-Container-Device': 'sda1',
|
||||
'X-Container-Partition': 'p',
|
||||
'Content-Type': 'text/enriched'})
|
||||
overwrite_timestamp = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', method='PUT', body=b'test3',
|
||||
headers={'X-Timestamp': overwrite_timestamp.internal,
|
||||
'X-Container-Host': '10.0.0.1:8080',
|
||||
'X-Container-Device': 'sda1',
|
||||
'X-Container-Partition': 'p',
|
||||
'Content-Type': 'text/enriched'})
|
||||
with mocked_http_conn(200, give_connect=capture_updates) as fake_conn:
|
||||
with fake_spawn():
|
||||
resp = req.get_response(self.object_controller)
|
||||
@@ -5747,7 +5755,7 @@ class TestObjectController(BaseTestCase):
|
||||
'X-Size': len(b'test3'),
|
||||
'X-Etag': md5(b'test3', usedforsecurity=False).hexdigest(),
|
||||
'X-Content-Type': 'text/enriched',
|
||||
'X-Timestamp': overwrite_timestamp,
|
||||
'X-Timestamp': overwrite_timestamp.internal,
|
||||
}
|
||||
for key, value in expected.items():
|
||||
self.assertEqual(headers[key], str(value))
|
||||
@@ -5757,18 +5765,20 @@ class TestObjectController(BaseTestCase):
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(resp.headers['X-Timestamp'],
|
||||
utils.Timestamp(overwrite_timestamp).normal)
|
||||
overwrite_timestamp.normal)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
overwrite_timestamp)
|
||||
overwrite_timestamp.internal)
|
||||
self.assertEqual(resp.headers['X-Backend-Data-Timestamp'],
|
||||
overwrite_timestamp.internal)
|
||||
self.assertEqual(resp.body, b'test3')
|
||||
# delete with an offset
|
||||
offset_delete = utils.Timestamp(overwrite_timestamp,
|
||||
offset=1).internal
|
||||
req = Request.blank('/sda1/p/a/c/o', method='DELETE',
|
||||
headers={'X-Timestamp': offset_delete,
|
||||
'X-Container-Host': '10.0.0.1:8080',
|
||||
'X-Container-Device': 'sda1',
|
||||
'X-Container-Partition': 'p'})
|
||||
offset_delete = utils.Timestamp(overwrite_timestamp, offset=1)
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', method='DELETE',
|
||||
headers={'X-Timestamp': offset_delete.internal,
|
||||
'X-Container-Host': '10.0.0.1:8080',
|
||||
'X-Container-Device': 'sda1',
|
||||
'X-Container-Partition': 'p'})
|
||||
with mocked_http_conn(200, give_connect=capture_updates) as fake_conn:
|
||||
with fake_spawn():
|
||||
resp = req.get_response(self.object_controller)
|
||||
@@ -5783,7 +5793,7 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertEqual(method, 'DELETE')
|
||||
self.assertEqual(path, '/sda1/p/a/c/o')
|
||||
expected = {
|
||||
'X-Timestamp': offset_delete,
|
||||
'X-Timestamp': offset_delete.internal,
|
||||
}
|
||||
for key, value in expected.items():
|
||||
self.assertEqual(headers[key], str(value))
|
||||
@@ -5793,11 +5803,12 @@ class TestObjectController(BaseTestCase):
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
self.assertIsNone(resp.headers['X-Timestamp'])
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'], offset_delete)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
offset_delete.internal)
|
||||
# and one more delete with a newer timestamp
|
||||
delete_timestamp = next(self.ts).internal
|
||||
delete_timestamp = next(self.ts)
|
||||
req = Request.blank('/sda1/p/a/c/o', method='DELETE',
|
||||
headers={'X-Timestamp': delete_timestamp,
|
||||
headers={'X-Timestamp': delete_timestamp.internal,
|
||||
'X-Container-Host': '10.0.0.1:8080',
|
||||
'X-Container-Device': 'sda1',
|
||||
'X-Container-Partition': 'p'})
|
||||
@@ -5815,7 +5826,7 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertEqual(method, 'DELETE')
|
||||
self.assertEqual(path, '/sda1/p/a/c/o')
|
||||
expected = {
|
||||
'X-Timestamp': delete_timestamp,
|
||||
'X-Timestamp': delete_timestamp.internal,
|
||||
}
|
||||
for key, value in expected.items():
|
||||
self.assertEqual(headers[key], str(value))
|
||||
@@ -5825,7 +5836,8 @@ class TestObjectController(BaseTestCase):
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
self.assertIsNone(resp.headers['X-Timestamp'])
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'], delete_timestamp)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
delete_timestamp.internal)
|
||||
|
||||
def test_call_bad_request(self):
|
||||
# Test swift.obj.server.ObjectController.__call__
|
||||
@@ -6533,14 +6545,15 @@ class TestObjectController(BaseTestCase):
|
||||
def fake_http_connect(*args):
|
||||
raise Exception('test')
|
||||
|
||||
timestamp = next(self.ts)
|
||||
orig_http_connect = object_server.http_connect
|
||||
try:
|
||||
object_server.http_connect = fake_http_connect
|
||||
self.object_controller.async_update(
|
||||
'PUT', 'a', 'c', 'o', '127.0.0.1:1234', 1, 'sdc1',
|
||||
{'x-timestamp': '1', 'x-out': 'set',
|
||||
'X-Backend-Storage-Policy-Index': int(policy)}, 'sda1',
|
||||
policy, db_state='unsharded')
|
||||
{'x-timestamp': timestamp.internal, 'x-out': 'set',
|
||||
'X-Backend-Storage-Policy-Index': int(policy)},
|
||||
'sda1', policy, db_state='unsharded')
|
||||
finally:
|
||||
object_server.http_connect = orig_http_connect
|
||||
utils.HASH_PATH_PREFIX = _prefix
|
||||
@@ -6548,9 +6561,9 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertEqual(
|
||||
pickle.load(open(os.path.join(
|
||||
self.testdir, 'sda1', async_dir, 'a83',
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83-%s' %
|
||||
utils.Timestamp(1).internal), 'rb')),
|
||||
{'headers': {'x-timestamp': '1', 'x-out': 'set',
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83-%s' % timestamp.internal),
|
||||
'rb')),
|
||||
{'headers': {'x-timestamp': timestamp.internal, 'x-out': 'set',
|
||||
'user-agent': 'object-server %s' % os.getpid(),
|
||||
'X-Backend-Storage-Policy-Index': int(policy)},
|
||||
'account': 'a', 'container': 'c', 'obj': 'o', 'op': 'PUT',
|
||||
@@ -6580,19 +6593,21 @@ class TestObjectController(BaseTestCase):
|
||||
orig_http_connect = object_server.http_connect
|
||||
try:
|
||||
for status in (199, 300, 503):
|
||||
timestamp = next(self.ts)
|
||||
object_server.http_connect = fake_http_connect(status)
|
||||
self.object_controller.async_update(
|
||||
'PUT', 'a', 'c', 'o', '127.0.0.1:1234', 1, 'sdc1',
|
||||
{'x-timestamp': '1', 'x-out': str(status),
|
||||
'X-Backend-Storage-Policy-Index': int(policy)}, 'sda1',
|
||||
policy, db_state='unsharded')
|
||||
{'x-timestamp': timestamp.internal, 'x-out': str(status),
|
||||
'X-Backend-Storage-Policy-Index': int(policy)},
|
||||
'sda1', policy, db_state='unsharded')
|
||||
async_dir = diskfile.get_async_dir(policy)
|
||||
self.assertEqual(
|
||||
pickle.load(open(os.path.join(
|
||||
self.testdir, 'sda1', async_dir, 'a83',
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83-%s' %
|
||||
utils.Timestamp(1).internal), 'rb')),
|
||||
{'headers': {'x-timestamp': '1', 'x-out': str(status),
|
||||
timestamp.internal), 'rb')),
|
||||
{'headers': {'x-timestamp': timestamp.internal,
|
||||
'x-out': str(status),
|
||||
'user-agent':
|
||||
'object-server %s' % os.getpid(),
|
||||
'X-Backend-Storage-Policy-Index':
|
||||
@@ -6625,14 +6640,18 @@ class TestObjectController(BaseTestCase):
|
||||
orig_http_connect = object_server.http_connect
|
||||
try:
|
||||
for status in (200, 299):
|
||||
timestamp = next(self.ts)
|
||||
object_server.http_connect = fake_http_connect(status)
|
||||
self.object_controller.async_update(
|
||||
'PUT', 'a', 'c', 'o', '127.0.0.1:1234', 1, 'sdc1',
|
||||
{'x-timestamp': '1', 'x-out': str(status)}, 'sda1', 0)
|
||||
{'x-timestamp': timestamp.internal,
|
||||
'x-out': str(status)},
|
||||
'sda1', 0)
|
||||
self.assertFalse(
|
||||
os.path.exists(os.path.join(
|
||||
self.testdir, 'sda1', 'async_pending', 'a83',
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83-0000000001.00000')))
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83-%s'
|
||||
% timestamp.internal)))
|
||||
finally:
|
||||
object_server.http_connect = orig_http_connect
|
||||
utils.HASH_PATH_PREFIX = _prefix
|
||||
@@ -6655,18 +6674,20 @@ class TestObjectController(BaseTestCase):
|
||||
orig_http_connect = object_server.http_connect
|
||||
try:
|
||||
for status in (200, 299):
|
||||
timestamp = next(self.ts)
|
||||
object_server.http_connect = fake_http_connect()
|
||||
self.object_controller.node_timeout = 0.001
|
||||
self.object_controller.async_update(
|
||||
'PUT', 'a', 'c', 'o', '127.0.0.1:1234', 1, 'sdc1',
|
||||
{'x-timestamp': '1', 'x-out': str(status)}, 'sda1',
|
||||
policy)
|
||||
{'x-timestamp': timestamp.internal,
|
||||
'x-out': str(status)},
|
||||
'sda1', policy)
|
||||
async_dir = diskfile.get_async_dir(policy)
|
||||
self.assertTrue(
|
||||
os.path.exists(os.path.join(
|
||||
self.testdir, 'sda1', async_dir, 'a83',
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83-%s' %
|
||||
utils.Timestamp(1).internal)))
|
||||
timestamp.internal)))
|
||||
finally:
|
||||
object_server.http_connect = orig_http_connect
|
||||
utils.HASH_PATH_PREFIX = _prefix
|
||||
@@ -6698,10 +6719,11 @@ class TestObjectController(BaseTestCase):
|
||||
def capture_updates(ip, port, method, path, headers, *args, **kwargs):
|
||||
container_updates.append((ip, port, method, path, headers))
|
||||
|
||||
timestamp = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/0/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': 1,
|
||||
headers={'X-Timestamp': timestamp.internal,
|
||||
'X-Trans-Id': '123',
|
||||
'X-Container-Host': 'chost:cport',
|
||||
'X-Container-Partition': 'cpartition',
|
||||
@@ -6724,7 +6746,7 @@ class TestObjectController(BaseTestCase):
|
||||
'x-size': '0',
|
||||
'x-etag': 'd41d8cd98f00b204e9800998ecf8427e',
|
||||
'x-content-type': 'text/plain',
|
||||
'x-timestamp': utils.Timestamp(1).internal,
|
||||
'x-timestamp': timestamp.internal,
|
||||
'X-Backend-Storage-Policy-Index': '0', # default when not given
|
||||
'x-trans-id': '123',
|
||||
'referer': 'PUT http://localhost/sda1/0/a/c/o'}))
|
||||
@@ -6991,10 +7013,11 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
def test_container_update_async(self):
|
||||
policy = random.choice(list(POLICIES))
|
||||
ts = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/0/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': 1,
|
||||
headers={'X-Timestamp': ts.internal,
|
||||
'X-Trans-Id': '123',
|
||||
'X-Container-Host': 'chost:cport',
|
||||
'X-Container-Partition': 'cpartition',
|
||||
@@ -7023,14 +7046,14 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertEqual(account, 'a')
|
||||
self.assertEqual(container, 'c')
|
||||
self.assertEqual(obj, 'o')
|
||||
self.assertEqual(timestamp, utils.Timestamp(1).internal)
|
||||
self.assertEqual(timestamp, ts.internal)
|
||||
self.assertEqual(policy, policy)
|
||||
self.assertEqual(data, {
|
||||
'headers': HeaderKeyDict({
|
||||
'X-Size': '0',
|
||||
'User-Agent': 'object-server %s' % os.getpid(),
|
||||
'X-Content-Type': 'text/plain',
|
||||
'X-Timestamp': utils.Timestamp(1).internal,
|
||||
'X-Timestamp': ts.internal,
|
||||
'X-Trans-Id': '123',
|
||||
'Referer': 'PUT http://localhost/sda1/0/a/c/o',
|
||||
'X-Backend-Storage-Policy-Index': int(policy),
|
||||
@@ -7054,10 +7077,11 @@ class TestObjectController(BaseTestCase):
|
||||
# just capture the args to see that we would have called
|
||||
called_async_update_args.append([a, kw])
|
||||
|
||||
ts = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': '12345',
|
||||
headers={'X-Timestamp': ts.internal,
|
||||
'Content-Type': 'application/burrito',
|
||||
'Content-Length': '0',
|
||||
'X-Backend-Storage-Policy-Index': 0,
|
||||
@@ -7083,7 +7107,7 @@ class TestObjectController(BaseTestCase):
|
||||
# check that the calls to async_update have happened
|
||||
headers_out = {'X-Size': '0',
|
||||
'X-Content-Type': 'application/burrito',
|
||||
'X-Timestamp': '0000012345.00000',
|
||||
'X-Timestamp': ts.internal,
|
||||
'X-Trans-Id': '-',
|
||||
'Referer': 'PUT http://localhost/sda1/p/a/c/o',
|
||||
'X-Backend-Storage-Policy-Index': '0',
|
||||
@@ -7113,10 +7137,11 @@ class TestObjectController(BaseTestCase):
|
||||
# just capture the args to see that we would have called
|
||||
called_async_update_args.append([a, kw])
|
||||
|
||||
ts = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': '12345',
|
||||
headers={'X-Timestamp': ts.internal,
|
||||
'Content-Type': 'application/burrito',
|
||||
'Content-Length': '0',
|
||||
'X-Backend-Storage-Policy-Index': 0,
|
||||
@@ -7145,10 +7170,11 @@ class TestObjectController(BaseTestCase):
|
||||
def fake_async_update(*args):
|
||||
given_args.extend(args)
|
||||
|
||||
ts = next(self.ts)
|
||||
req = Request.blank(
|
||||
'/v1/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': 1,
|
||||
headers={'X-Timestamp': ts.internal,
|
||||
'X-Trans-Id': '123',
|
||||
'X-Container-Host': 'chost,badhost',
|
||||
'X-Container-Partition': 'cpartition',
|
||||
@@ -7175,6 +7201,7 @@ class TestObjectController(BaseTestCase):
|
||||
# Test how delete_at_update works with a request to overwrite an object
|
||||
# with delete-at metadata
|
||||
policy = random.choice(list(POLICIES))
|
||||
ts = next(self.ts)
|
||||
|
||||
def do_test(method, headers, expected_args):
|
||||
given_args = []
|
||||
@@ -7182,7 +7209,7 @@ class TestObjectController(BaseTestCase):
|
||||
def fake_async_update(*args):
|
||||
given_args.extend(args)
|
||||
|
||||
headers.update({'X-Timestamp': 1,
|
||||
headers.update({'X-Timestamp': ts.internal,
|
||||
'X-Trans-Id': '123',
|
||||
'X-Backend-Storage-Policy-Index': int(policy)})
|
||||
req = Request.blank(
|
||||
@@ -7201,7 +7228,7 @@ class TestObjectController(BaseTestCase):
|
||||
'0000000002-a/c/o', None, None,
|
||||
None, HeaderKeyDict({
|
||||
'X-Backend-Storage-Policy-Index': 0,
|
||||
'x-timestamp': utils.Timestamp('1').internal,
|
||||
'x-timestamp': ts.internal,
|
||||
'x-trans-id': '123',
|
||||
'referer': '%s http://localhost/v1/a/c/o' % method}),
|
||||
'sda1', policy]
|
||||
@@ -7226,11 +7253,12 @@ class TestObjectController(BaseTestCase):
|
||||
def fake_async_update(*args):
|
||||
given_args.extend(args)
|
||||
|
||||
ts = next(self.ts)
|
||||
self.object_controller.async_update = fake_async_update
|
||||
req = Request.blank(
|
||||
'/v1/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': 1,
|
||||
headers={'X-Timestamp': ts.internal,
|
||||
'X-Trans-Id': '1234', 'X-Backend-Storage-Policy-Index':
|
||||
int(policy)})
|
||||
self.object_controller.delete_at_update(
|
||||
@@ -7241,7 +7269,7 @@ class TestObjectController(BaseTestCase):
|
||||
HeaderKeyDict({
|
||||
# the expiring objects account is always 0
|
||||
'X-Backend-Storage-Policy-Index': 0,
|
||||
'x-timestamp': utils.Timestamp('1').internal,
|
||||
'x-timestamp': ts.internal,
|
||||
'x-trans-id': '1234',
|
||||
'referer': 'PUT http://localhost/v1/a/c/o'}),
|
||||
'sda1', policy])
|
||||
@@ -7695,13 +7723,13 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
def test_GET_but_expired(self):
|
||||
# Start off with an existing object that will expire
|
||||
now = time()
|
||||
delete_at_timestamp = int(now + 100)
|
||||
ts_now = Timestamp.now()
|
||||
delete_at_seconds = int(ts_now) + 100
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers=self._update_delete_at_headers({
|
||||
'X-Timestamp': normalize_timestamp(now),
|
||||
'X-Delete-At': str(delete_at_timestamp),
|
||||
'X-Timestamp': ts_now.internal,
|
||||
'X-Delete-At': delete_at_seconds,
|
||||
'Content-Length': '4',
|
||||
'Content-Type': 'application/octet-stream'}))
|
||||
req.body = 'TEST'
|
||||
@@ -7711,7 +7739,7 @@ class TestObjectController(BaseTestCase):
|
||||
# It expires in the future, so it's accessible via GET
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'X-Timestamp': normalize_timestamp(now)})
|
||||
headers={'X-Timestamp': ts_now.internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
|
||||
@@ -7719,18 +7747,15 @@ class TestObjectController(BaseTestCase):
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'X-Timestamp': normalize_timestamp(
|
||||
delete_at_timestamp + 1)})
|
||||
headers={'X-Timestamp': Timestamp(delete_at_seconds + 1).internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
utils.Timestamp(now))
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'], ts_now.internal)
|
||||
|
||||
# ...unless X-Backend-Replication is sent
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', method='GET',
|
||||
headers={'X-Timestamp':
|
||||
normalize_timestamp(delete_at_timestamp + 1),
|
||||
headers={'X-Timestamp': Timestamp(delete_at_seconds + 1).internal,
|
||||
'X-Backend-Replication': 'True'})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
@@ -7739,8 +7764,7 @@ class TestObjectController(BaseTestCase):
|
||||
# ...or x-backend-open-expired is sent
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', method='GET',
|
||||
headers={'X-Timestamp':
|
||||
normalize_timestamp(delete_at_timestamp + 1),
|
||||
headers={'X-Timestamp': Timestamp(delete_at_seconds + 1).internal,
|
||||
'x-backend-open-expired': 'True'})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
@@ -7748,13 +7772,13 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
def test_HEAD_but_expired(self):
|
||||
# We have an object that expires in the future
|
||||
now = time()
|
||||
delete_at_timestamp = int(now + 100)
|
||||
ts_now = Timestamp.now()
|
||||
delete_at_seconds = int(ts_now) + 100
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers=self._update_delete_at_headers({
|
||||
'X-Timestamp': normalize_timestamp(now),
|
||||
'X-Delete-At': str(delete_at_timestamp),
|
||||
'X-Timestamp': ts_now.internal,
|
||||
'X-Delete-At': delete_at_seconds,
|
||||
'Content-Length': '4',
|
||||
'Content-Type': 'application/octet-stream'}))
|
||||
req.body = b'TEST'
|
||||
@@ -7765,7 +7789,7 @@ class TestObjectController(BaseTestCase):
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'HEAD'},
|
||||
headers={'X-Timestamp': normalize_timestamp(now)})
|
||||
headers={'X-Timestamp': ts_now.internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
|
||||
@@ -7773,19 +7797,18 @@ class TestObjectController(BaseTestCase):
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'HEAD'},
|
||||
headers={'X-Timestamp': normalize_timestamp(
|
||||
delete_at_timestamp + 1)})
|
||||
headers={'X-Timestamp': Timestamp(delete_at_seconds + 1).internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'],
|
||||
utils.Timestamp(now))
|
||||
utils.Timestamp(ts_now))
|
||||
|
||||
# It should be accessible with x-backend-open-expired
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'HEAD'},
|
||||
headers={'X-Timestamp': normalize_timestamp(
|
||||
delete_at_timestamp + 2), 'x-backend-open-expired': 'true'})
|
||||
headers={'X-Timestamp': Timestamp(delete_at_seconds + 2).internal,
|
||||
'x-backend-open-expired': 'true'})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
|
||||
@@ -7793,8 +7816,8 @@ class TestObjectController(BaseTestCase):
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'HEAD'},
|
||||
headers={'X-Timestamp': normalize_timestamp(
|
||||
delete_at_timestamp + 2), 'x-backend-replication': 'true'})
|
||||
headers={'X-Timestamp': Timestamp(delete_at_seconds + 2).internal,
|
||||
'x-backend-replication': 'true'})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(b'', resp.body)
|
||||
@@ -9623,15 +9646,15 @@ class TestObjectController(BaseTestCase):
|
||||
self.assertFalse(os.path.isdir(object_dir))
|
||||
|
||||
def test_race_doesnt_quarantine(self):
|
||||
existing_timestamp = normalize_timestamp(time())
|
||||
delete_timestamp = normalize_timestamp(time() + 1)
|
||||
put_timestamp = normalize_timestamp(time() + 2)
|
||||
head_timestamp = normalize_timestamp(time() + 3)
|
||||
existing_timestamp = next(self.ts)
|
||||
delete_timestamp = next(self.ts)
|
||||
put_timestamp = next(self.ts)
|
||||
head_timestamp = next(self.ts)
|
||||
|
||||
# make a .ts
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'X-Timestamp': existing_timestamp})
|
||||
headers={'X-Timestamp': existing_timestamp.internal})
|
||||
req.get_response(self.object_controller)
|
||||
|
||||
# force a PUT between the listdir and read_metadata of a DELETE
|
||||
@@ -9644,7 +9667,7 @@ class TestObjectController(BaseTestCase):
|
||||
put_once[0] = True
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': put_timestamp,
|
||||
headers={'X-Timestamp': put_timestamp.internal,
|
||||
'Content-Length': '9',
|
||||
'Content-Type': 'application/octet-stream'})
|
||||
req.body = 'some data'
|
||||
@@ -9655,7 +9678,7 @@ class TestObjectController(BaseTestCase):
|
||||
with mock.patch('os.listdir', mock_listdir):
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'X-Timestamp': delete_timestamp})
|
||||
headers={'X-Timestamp': delete_timestamp.internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
|
||||
@@ -9664,21 +9687,21 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
req = Request.blank('/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'HEAD'},
|
||||
headers={'X-Timestamp': head_timestamp})
|
||||
headers={'X-Timestamp': head_timestamp.internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(resp.headers['X-Timestamp'], put_timestamp)
|
||||
self.assertEqual(resp.headers['X-Timestamp'], put_timestamp.normal)
|
||||
|
||||
def test_race_with_PUT_POST_PUT(self):
|
||||
existing_timestamp = normalize_timestamp(time())
|
||||
post_timestamp = normalize_timestamp(time() + 1)
|
||||
put_timestamp = normalize_timestamp(time() + 2)
|
||||
head_timestamp = normalize_timestamp(time() + 3)
|
||||
existing_timestamp = next(self.ts)
|
||||
post_timestamp = next(self.ts)
|
||||
put_timestamp = next(self.ts)
|
||||
head_timestamp = next(self.ts)
|
||||
|
||||
# make a .data
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': existing_timestamp,
|
||||
headers={'X-Timestamp': existing_timestamp.internal,
|
||||
'Content-Type': 'application/octet-stream'},
|
||||
body=b'orig data')
|
||||
resp = req.get_response(self.object_controller)
|
||||
@@ -9694,7 +9717,7 @@ class TestObjectController(BaseTestCase):
|
||||
put_once[0] = True
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'X-Timestamp': put_timestamp,
|
||||
headers={'X-Timestamp': put_timestamp.internal,
|
||||
'Content-Type': 'application/octet-stream'},
|
||||
body=b'some data')
|
||||
resp = req.get_response(self.object_controller)
|
||||
@@ -9704,7 +9727,7 @@ class TestObjectController(BaseTestCase):
|
||||
with mock.patch('os.listdir', mock_listdir):
|
||||
req = Request.blank(
|
||||
'/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'POST'},
|
||||
headers={'X-Timestamp': post_timestamp})
|
||||
headers={'X-Timestamp': post_timestamp.internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertNotIn('X-Backend-Timestamp', resp.headers)
|
||||
self.assertEqual(resp.status_int, 503)
|
||||
@@ -9714,10 +9737,10 @@ class TestObjectController(BaseTestCase):
|
||||
|
||||
req = Request.blank('/sda1/p/a/c/o',
|
||||
environ={'REQUEST_METHOD': 'HEAD'},
|
||||
headers={'X-Timestamp': head_timestamp})
|
||||
headers={'X-Timestamp': head_timestamp.internal})
|
||||
resp = req.get_response(self.object_controller)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(resp.headers['X-Timestamp'], put_timestamp)
|
||||
self.assertEqual(resp.headers['X-Timestamp'], put_timestamp.normal)
|
||||
|
||||
def test_multiphase_put_draining(self):
|
||||
# We want to ensure that we read the whole response body even if
|
||||
@@ -10224,7 +10247,7 @@ class TestObjectServer(unittest.TestCase):
|
||||
expected_meta = {'Content-Length': '82',
|
||||
'name': '/a/c/o',
|
||||
'X-Object-Sysmeta-Ec-Frag-Index': '2',
|
||||
'X-Timestamp': put_timestamp.normal,
|
||||
'X-Timestamp': put_timestamp.internal,
|
||||
'Content-Type': 'text/plain'}
|
||||
for k, v in actual_meta.items():
|
||||
# See diskfile.py:_decode_metadata
|
||||
|
||||
@@ -198,8 +198,7 @@ class BaseObjectControllerMixin(object):
|
||||
# default policy and ring references
|
||||
self.policy = POLICIES.default
|
||||
self.obj_ring = self.policy.object_ring
|
||||
self._ts_iter = (utils.Timestamp(t) for t in
|
||||
itertools.count(int(time.time())))
|
||||
self._ts_iter = make_timestamp_iter()
|
||||
|
||||
def _make_app(self):
|
||||
self.app = PatchedObjControllerApp(
|
||||
@@ -1081,9 +1080,8 @@ class CommonObjectControllerMixin(BaseObjectControllerMixin):
|
||||
def test_HEAD_x_newest_different_timestamps(self):
|
||||
req = swob.Request.blank('/v1/a/c/o', method='HEAD',
|
||||
headers={'X-Newest': 'true'})
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
num_expected_requests = 2 * self.replicas()
|
||||
timestamps = [next(ts) for i in range(num_expected_requests)]
|
||||
timestamps = [self.ts() for i in range(num_expected_requests)]
|
||||
newest_timestamp = timestamps[-1]
|
||||
random.shuffle(timestamps)
|
||||
backend_response_headers = [{
|
||||
@@ -1099,11 +1097,13 @@ class CommonObjectControllerMixin(BaseObjectControllerMixin):
|
||||
def test_HEAD_x_newest_with_two_vector_timestamps(self):
|
||||
req = swob.Request.blank('/v1/a/c/o', method='HEAD',
|
||||
headers={'X-Newest': 'true'})
|
||||
ts = (utils.Timestamp.now(offset=offset)
|
||||
for offset in itertools.count())
|
||||
# constant float part, varying offset...
|
||||
now = Timestamp.now()
|
||||
ts = (Timestamp(now, offset) for offset in itertools.count())
|
||||
num_expected_requests = 2 * self.replicas()
|
||||
timestamps = [next(ts) for i in range(num_expected_requests)]
|
||||
newest_timestamp = timestamps[-1]
|
||||
self.assertGreater(newest_timestamp, timestamps[0])
|
||||
random.shuffle(timestamps)
|
||||
backend_response_headers = [{
|
||||
'X-Backend-Timestamp': t.internal,
|
||||
@@ -1114,15 +1114,14 @@ class CommonObjectControllerMixin(BaseObjectControllerMixin):
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertEqual(resp.headers['x-backend-timestamp'],
|
||||
newest_timestamp.internal)
|
||||
newest_timestamp.internal, timestamps)
|
||||
|
||||
def test_HEAD_x_newest_with_some_missing(self):
|
||||
req = swob.Request.blank('/v1/a/c/o', method='HEAD',
|
||||
headers={'X-Newest': 'true'})
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
request_count = self.app.request_node_count(self.obj_ring.replicas)
|
||||
backend_response_headers = [{
|
||||
'x-timestamp': next(ts).normal,
|
||||
'x-timestamp': self.ts().normal,
|
||||
} for i in range(request_count)]
|
||||
responses = [404] * (request_count - 1)
|
||||
responses.append(200)
|
||||
@@ -1167,14 +1166,13 @@ class CommonObjectControllerMixin(BaseObjectControllerMixin):
|
||||
self.assertEqual(resp.headers['X-Backend-Timestamp'], '2')
|
||||
|
||||
def test_container_sync_delete(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
test_indexes = [None] + [int(p) for p in POLICIES]
|
||||
for policy_index in test_indexes:
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='DELETE', headers={
|
||||
'X-Timestamp': next(ts).internal})
|
||||
'X-Timestamp': self.ts().internal})
|
||||
codes = [409] * self.obj_ring.replicas
|
||||
ts_iter = itertools.repeat(next(ts).internal)
|
||||
ts_iter = itertools.repeat(self.ts().internal)
|
||||
with set_http_connect(*codes, timestamps=ts_iter):
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 409)
|
||||
@@ -2778,29 +2776,27 @@ class TestReplicatedObjController(CommonObjectControllerMixin,
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_container_sync_put_x_timestamp_older(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
test_indexes = [None] + [int(p) for p in POLICIES]
|
||||
for policy_index in test_indexes:
|
||||
self.app.container_info['storage_policy'] = policy_index
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
'X-Timestamp': next(ts).internal})
|
||||
ts_iter = itertools.repeat(next(ts).internal)
|
||||
'X-Timestamp': self.ts().internal})
|
||||
ts_iter = itertools.repeat(self.ts().internal)
|
||||
codes = [409] * self.obj_ring.replicas
|
||||
with set_http_connect(*codes, timestamps=ts_iter):
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_container_sync_put_x_timestamp_newer(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
test_indexes = [None] + [int(p) for p in POLICIES]
|
||||
for policy_index in test_indexes:
|
||||
orig_timestamp = next(ts).internal
|
||||
orig_timestamp = self.ts().internal
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
'X-Timestamp': next(ts).internal})
|
||||
'X-Timestamp': self.ts().internal})
|
||||
ts_iter = itertools.repeat(orig_timestamp)
|
||||
codes = [201] * self.obj_ring.replicas
|
||||
with set_http_connect(*codes, timestamps=ts_iter):
|
||||
@@ -2808,23 +2804,21 @@ class TestReplicatedObjController(CommonObjectControllerMixin,
|
||||
self.assertEqual(resp.status_int, 201)
|
||||
|
||||
def test_put_x_timestamp_conflict(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
'X-Timestamp': next(ts).internal})
|
||||
ts_iter = iter([next(ts).internal, None, None])
|
||||
'X-Timestamp': self.ts().internal})
|
||||
ts_iter = iter([self.ts().internal, None, None])
|
||||
codes = [409] + [201] * (self.obj_ring.replicas - 1)
|
||||
with set_http_connect(*codes, timestamps=ts_iter):
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_put_x_timestamp_conflict_with_missing_backend_timestamp(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
'X-Timestamp': next(ts).internal})
|
||||
'X-Timestamp': self.ts().internal})
|
||||
ts_iter = iter([None, None, None])
|
||||
codes = [409] * self.obj_ring.replicas
|
||||
with set_http_connect(*codes, timestamps=ts_iter):
|
||||
@@ -2832,35 +2826,32 @@ class TestReplicatedObjController(CommonObjectControllerMixin,
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_put_x_timestamp_conflict_with_other_weird_success_response(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
'X-Timestamp': next(ts).internal})
|
||||
ts_iter = iter([next(ts).internal, None, None])
|
||||
'X-Timestamp': self.ts().internal})
|
||||
ts_iter = iter([self.ts().internal, None, None])
|
||||
codes = [409] + [(201, 'notused')] * (self.obj_ring.replicas - 1)
|
||||
with set_http_connect(*codes, timestamps=ts_iter):
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_put_x_timestamp_conflict_with_if_none_match(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
'If-None-Match': '*',
|
||||
'X-Timestamp': next(ts).internal})
|
||||
ts_iter = iter([next(ts).internal, None, None])
|
||||
'X-Timestamp': self.ts().internal})
|
||||
ts_iter = iter([self.ts().internal, None, None])
|
||||
codes = [409] + [(412, 'notused')] * (self.obj_ring.replicas - 1)
|
||||
with set_http_connect(*codes, timestamps=ts_iter):
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 412)
|
||||
|
||||
def test_container_sync_put_x_timestamp_race(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
test_indexes = [None] + [int(p) for p in POLICIES]
|
||||
for policy_index in test_indexes:
|
||||
put_timestamp = next(ts).internal
|
||||
put_timestamp = self.ts().internal
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
@@ -2877,10 +2868,9 @@ class TestReplicatedObjController(CommonObjectControllerMixin,
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_container_sync_put_x_timestamp_unsynced_race(self):
|
||||
ts = (utils.Timestamp(t) for t in itertools.count(int(time.time())))
|
||||
test_indexes = [None] + [int(p) for p in POLICIES]
|
||||
for policy_index in test_indexes:
|
||||
put_timestamp = next(ts).internal
|
||||
put_timestamp = self.ts().internal
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='PUT', headers={
|
||||
'Content-Length': 0,
|
||||
|
||||
Reference in New Issue
Block a user