From 0c25628deda34694917b0e2928ccc4e9d9ed566c Mon Sep 17 00:00:00 2001 From: robk-tahoe <robk-tahoe@allmydata.com> Date: Fri, 3 Oct 2008 15:48:33 -0700 Subject: [PATCH] fuse/runtests: add overlapping write tests using both small and large blocksizes for writes, write a 1Mb file to fuse where every write overlaps another. This serves a useful purpose - in manual testing of blackmatch some time ago most operations e.g. bulk copies, worked fine, but using rsync caused data corruption on most files. it turned out to be that rsync writes in 64K blocks, but rather than making the last block short, the last block instead overlaps the preceding (already written) block. This revealed a problem where cache files were being opened 'append' rather than 'write' and hence the overlapping write to the fuse layer caused the overlapping portion of the file to be duplicated in cache, leading to oversized and corrupt files being uploaded. --- contrib/fuse/runtests.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/contrib/fuse/runtests.py b/contrib/fuse/runtests.py index 54c12a2e..cf009705 100644 --- a/contrib/fuse/runtests.py +++ b/contrib/fuse/runtests.py @@ -464,6 +464,34 @@ class SystemTest (object): tmpl = 'Expected file contents %r but found %r' raise TestFailure(tmpl, expected_body, uploaded_body) + def test_write_overlapping_small_writes(self, testcap, testdir): + self._write_test_overlap(testcap, testdir, name='large_overlap', bs=2**9, sz=2**20) + + def test_write_overlapping_large_writes(self, testcap, testdir): + self._write_test_overlap(testcap, testdir, name='small_overlap', bs=2**18, sz=2**20) + + def _write_test_overlap(self, testcap, testdir, name, bs, sz): + body = os.urandom(sz) + try: + path = os.path.join(testdir, name) + f = file(path, 'w') + except Exception, err: + tmpl = 'Could not open file for write at %r: %r' + raise TestFailure(tmpl, path, err) + try: + for posn in range(0,sz,bs): + start = max(0, posn-bs) + end = min(sz, posn+bs) + f.seek(start) + f.write(body[start:end]) + f.close() + except Exception, err: + tmpl = 'Could not write to file %r: %r' + raise TestFailure(tmpl, path, err) + + self._check_write(testcap, name, body) + + # Utilities: def run_tahoe(self, *args): realargs = ('tahoe',) + args -- 2.45.2