diff --git a/test_s3.py b/test_s3.py index e143ef4..18156ec 100644 --- a/test_s3.py +++ b/test_s3.py @@ -1000,3 +1000,76 @@ def test_100_continue(): status = _simple_http_req_100_cont(s3.main.host, s3.main.port, 'PUT', resource) eq(status, '100') + +def _test_atomic_write(file_size): + bucket = get_new_bucket() + objname = 'testobj' + key = bucket.new_key(objname) + + class FakeFile(object): + def __init__(self, size, char='A', interrupt=None): + self.offset = 0 + self.size = size + self.char = char + self.interrupt = interrupt + + def seek(self, offset): + self.offset = offset + + def tell(self): + return self.offset + + def read(self, size=-1): + if size < 0: + size = self.size - self.offset + count = min(size, self.size - self.offset) + self.offset += count + + # Sneaky! do stuff before we return (the last time) + if self.interrupt != None and self.offset == self.size: + self.interrupt() + + return self.char*count + + class FakeFileVerifier(object): + def __init__(self, char=None): + self.char = char + self.size = 0 + + def write(self, data): + size = len(data) + if self.char == None: + self.char = data[0] + self.size += size + eq(data, self.char*size) + + # create file of A's + fp_a = FakeFile(file_size, 'A') + key.set_contents_from_file(fp_a) + + # verify A's + fp_a_verify = FakeFileVerifier('A') + key.get_contents_to_file(fp_a_verify) + eq(fp_a_verify.size, file_size) + + # create file of B's + # but try to verify the file before we finish writing all the B's + fp_b = FakeFile(file_size, 'B', + lambda: key.get_contents_to_file(FakeFileVerifier()) + ) + key.set_contents_from_file(fp_b) + + # verify B's + fp_b_verify = FakeFileVerifier('B') + key.get_contents_to_file(fp_b_verify) + eq(fp_b_verify.size, file_size) + +def test_atomic_write_1mb(): + _test_atomic_write(1024*1024) + +def test_atomic_write_4mb(): + _test_atomic_write(1024*1024*4) + +def test_atomic_write_8mb(): + _test_atomic_write(1024*1024*8) +