示例#1
0
def test_clone(user_file):
    size = user_file.sector_size * 2

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    with file.open(user_file.url, "r+", sparse=True) as a, \
            a.clone() as b, \
            util.aligned_buffer(user_file.sector_size) as buf:

        # Backends are identical when created.
        assert a.size() == b.size()
        assert a.tell() == b.tell()
        assert a.block_size == b.block_size

        # Operations on one backend do not affect the other.
        buf[:] = b"y" * len(buf)
        a.write(buf)
        assert a.tell() == len(buf)
        assert b.tell() == 0

        # But both expose the same file contents.
        buf[:] = b"\0" * len(buf)
        b.readinto(buf)
        assert buf[:] == b"y" * len(buf)
示例#2
0
def test_zero_sparse_deallocate_space(user_file):
    size = 1024**2
    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)
    with file.open(user_file.url, "r+", sparse=True) as f:
        f.zero(size)
    assert os.stat(user_file.path).st_blocks * 512 < size
示例#3
0
def test_open_read_only(user_file):
    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * user_file.sector_size)
    with file.open(user_file.url) as f, \
            closing(util.aligned_buffer(user_file.sector_size)) as buf:
        assert f.readable()
        assert not f.writable()
        f.readinto(buf)
        assert buf[:] == b"x" * user_file.sector_size
示例#4
0
def test_readinto(user_file):
    with io.open(user_file.path, "wb") as f:
        f.write(b"a" * 4096)
    with file.open(user_file.url) as f, \
            closing(util.aligned_buffer(4096)) as buf:
        n = f.readinto(buf)
        assert n == len(buf)
        assert f.tell() == len(buf)
        assert buf[:] == b"a" * 4096
示例#5
0
def test_block_size_allocated(user_file, size):
    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    with file.open(user_file.url) as f:
        assert f.block_size == user_file.sector_size

    with io.open(user_file.path, "rb") as f:
        assert f.read() == b"x" * size
示例#6
0
def test_extents(user_file):
    size = user_file.sector_size * 2

    with io.open(user_file.path, "wb") as f:
        f.truncate(size)

    with file.open(user_file.url, "r+", sparse=True) as f:
        # We support detecting extents now; empty file reports one data
        # extents.
        assert list(f.extents()) == [extent.ZeroExtent(0, size, False, False)]
示例#7
0
def test_write_unbuffered_stream_partial_content(user_file):
    chunks = [b"a" * 8192, b"b" * 42, b"c" * (8192 - 42)]
    src = util.UnbufferedStream(chunks)
    size = sum(len(c) for c in chunks)

    with file.open(user_file.url, "r+") as dst, \
            util.aligned_buffer(1024**2) as buf:
        op = ops.Write(dst, src, buf, size + 1)
        with pytest.raises(errors.PartialContent):
            op.run()
示例#8
0
def test_zero_aligned_after_end(user_file, sparse):
    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * 4096)
    with file.open(user_file.url, "r+", sparse=sparse) as f:
        f.seek(8192)
        n = f.zero(4096)
        assert n == 4096
        assert f.tell() == 12288
    with io.open(user_file.path, "rb") as f:
        assert f.read(4096) == b"x" * 4096
        assert f.read() == b"\0" * 8192
示例#9
0
def test_zero_aligned_middle(user_file, sparse):
    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * 3 * 4096)
    with file.open(user_file.url, "r+", sparse=sparse) as f:
        f.seek(4096)
        n = f.zero(4096)
        assert n == 4096
        assert f.tell() == 8192
    with io.open(user_file.path, "rb") as f:
        assert f.read(4096) == b"x" * 4096
        assert f.read(4096) == b"\0" * 4096
        assert f.read() == b"x" * 4096
示例#10
0
def test_block_size_sparse(user_file, size):
    with io.open(user_file.path, "wb") as f:
        f.truncate(size)

    with file.open(user_file.url) as f:
        if user_file.can_detect_sector_size:
            assert f.block_size == user_file.sector_size
        else:
            assert f.block_size in (user_file.sector_size, 4096)

    with io.open(user_file.path, "rb") as f:
        assert f.read(size) == b"\0" * size
示例#11
0
def test_flush(user_file, monkeypatch):
    count = [0]

    def fsync(fd):
        count[0] += 1

    # This is ugly but probably the only way to test that we call fsync.
    monkeypatch.setattr(os, "fsync", fsync)
    with file.open(user_file.url, "r+") as f:
        f.write(b"x")
        f.flush()
    assert count[0] == 1
示例#12
0
def test_write_partial_content(user_file, offset, size):
    with io.open(user_file.path, "wb") as f:
        f.truncate(size + offset)

    src = io.BytesIO(b"x" * (size - 1))
    with file.open(user_file.url, "r+") as dst, \
            util.aligned_buffer(1024**2) as buf:
        op = ops.Write(dst, src, buf, size, offset=offset)
        with pytest.raises(errors.PartialContent) as e:
            op.run()

    assert e.value.requested == size
    assert e.value.available == size - 1
示例#13
0
def test_open_read_write(user_file):
    with io.open(user_file.path, "wb") as f:
        f.write(b"a" * user_file.sector_size)
    with file.open(user_file.url, "r+") as f, \
            closing(util.aligned_buffer(user_file.sector_size)) as buf:
        assert f.readable()
        assert f.writable()
        f.readinto(buf)
        buf[:] = b"b" * user_file.sector_size
        f.seek(0)
        f.write(buf)
    with io.open(user_file.path, "rb") as f:
        assert f.read() == b"b" * user_file.sector_size
示例#14
0
def test_read_partial_content(user_file, offset, size):
    with io.open(user_file.path, "wb") as f:
        f.truncate(offset + size - 1)

    dst = io.BytesIO()
    with file.open(user_file.url, "r") as src, \
            util.aligned_buffer(1024**2) as buf:
        op = ops.Read(src, dst, buf, size, offset=offset)
        with pytest.raises(errors.PartialContent) as e:
            op.run()

    assert e.value.requested == size
    assert e.value.available == size - 1
示例#15
0
def test_write_aligned_at_end(user_file):
    with io.open(user_file.path, "wb") as f:
        f.write(b"a" * 8192)
    with file.open(user_file.url, "r+") as f, \
            closing(util.aligned_buffer(8192)) as buf:
        buf.write(b"b" * 8192)
        f.seek(4096)
        n = f.write(buf)
        assert n == len(buf)
        assert f.tell() == 4096 + len(buf)
    with io.open(user_file.path, "rb") as f:
        assert f.read(4096) == b"a" * 4096
        assert f.read() == b"b" * 8192
示例#16
0
def test_write_unbuffered_stream(user_file):
    chunks = [b"a" * 8192, b"b" * 42, b"c" * (8192 - 42)]
    src = util.UnbufferedStream(chunks)
    size = sum(len(c) for c in chunks)

    with file.open(user_file.url, "r+") as dst, \
            util.aligned_buffer(1024**2) as buf:
        op = ops.Write(dst, src, buf, size)
        op.run()

    with io.open(user_file.path, "rb") as f:
        for c in chunks:
            assert f.read(len(c)) == c
        assert f.read() == b""
示例#17
0
def test_readinto_short_unaligned(user_file):
    size = 42
    buf_size = user_file.sector_size

    with io.open(user_file.path, "wb") as f:
        f.write(b"a" * size)

    with file.open(user_file.url) as f, \
            closing(util.aligned_buffer(buf_size)) as buf:
        n = f.readinto(buf)
        assert n == size
        assert f.tell() == size
        assert buf[:size] == b"a" * size
        assert buf[size:] == b"\0" * (buf_size - size)
示例#18
0
def test_block_size_preallocated(user_file, size):
    # This is how vdsm preallocates volumes. This uses fallocate() or fallback
    # to writing one byte per block.
    subprocess.check_output(
        ["fallocate", "--posix", "--length",
         str(size), user_file.path])

    with file.open(user_file.url) as f:
        if user_file.can_detect_sector_size:
            assert f.block_size == user_file.sector_size
        else:
            assert f.block_size in (user_file.sector_size, 4096)

    with io.open(user_file.path, "rb") as f:
        assert f.read(size) == b"\0" * size
示例#19
0
def test_read_full(user_file, offset, size, trailer):
    data = b"b" * size

    with io.open(user_file.path, "wb") as f:
        f.write(b"a" * offset)
        f.write(data)
        f.write(b"c" * trailer)

    dst = io.BytesIO()
    with file.open(user_file.url, "r") as src, \
            util.aligned_buffer(1024**2) as buf:
        op = ops.Read(src, dst, buf, size, offset=offset)
        op.run()

    assert dst.getvalue() == data
示例#20
0
def test_size(user_file):
    size = 4096

    with io.open(user_file.path, "wb") as f:
        f.truncate(size)

    with file.open(user_file.url, "r+", sparse=True) as f:
        # Check initial size.
        f.seek(100)
        assert f.size() == size
        assert f.tell() == 100

        # Check that size() updates when file size is modified.
        f.seek(size)
        f.zero(4096)
        assert f.size() == 8192
示例#21
0
def test_zero_unaligned_offset_after_end(user_file):
    size = user_file.sector_size
    start = size + 10

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    with file.open(user_file.url, "r+") as f:
        f.seek(start)
        n = f.zero(10)
        assert n == 10
        assert f.tell() == start + 10

    with io.open(user_file.path, "rb") as f:
        assert f.read(size) == b"x" * size
        assert f.read() == b"\0" * user_file.sector_size
示例#22
0
def test_write_unaligned_offset_after_end(user_file):
    size = user_file.sector_size

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    with file.open(user_file.url, "r+") as f:
        f.seek(size + 10)
        n = f.write(b"y" * 10)
        assert n == 10
        assert f.tell() == size + 20

    with io.open(user_file.path, "rb") as f:
        assert f.read(size) == b"x" * size
        assert f.read(10) == b"\0" * 10
        assert f.read(10) == b"y" * 10
        assert f.read() == b"\0" * (user_file.sector_size - 20)
示例#23
0
def test_zero_unaligned_offset_at_end(user_file):
    size = user_file.sector_size * 2
    start = size - 10

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    # Zero 10 bytes into the last block.
    with file.open(user_file.url, "r+") as f:
        f.seek(start)
        n = f.zero(100)
        assert n == 10
        assert f.tell() == size

    with io.open(user_file.path, "rb") as f:
        assert f.read(start) == b"x" * start
        assert f.read() == b"\0" * 10
示例#24
0
def test_write_unaligned_offset_at_end(user_file):
    size = user_file.sector_size * 2
    start = size - 24

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    # Write 24 bytes into the last block.
    with file.open(user_file.url, "r+") as f:
        f.seek(size - 24)
        n = f.write(b"y" * 100)
        assert n == 24
        assert f.tell() == size

    with io.open(user_file.path, "rb") as f:
        assert f.read(start) == b"x" * start
        assert f.read() == b"y" * 24
示例#25
0
def test_write_unaligned_buffer_slow_path(user_file):
    size = user_file.sector_size * 2

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    # Perform slow read-modify-write in the second block.
    with file.open(user_file.url, "r+") as f:
        f.seek(user_file.sector_size)
        n = f.write(b"y" * 10)
        assert n == 10
        assert f.tell() == user_file.sector_size + 10

    with io.open(user_file.path, "rb") as f:
        assert f.read(user_file.sector_size) == b"x" * user_file.sector_size
        assert f.read(10) == b"y" * 10
        assert f.read() == b"x" * (user_file.sector_size - 10)
示例#26
0
def test_write_no_size(user_file, offset, size):
    with io.open(user_file.path, "wb") as f:
        f.truncate(offset + size)

    src = io.BytesIO(b"x" * size)
    with file.open(user_file.url, "r+") as dst, \
            util.aligned_buffer(1024**2) as buf:
        op = ops.Write(dst, src, buf, offset=offset)
        op.run()

    with io.open(user_file.path, "rb") as f:
        assert f.read(offset) == b"\0" * offset
        assert f.read(size) == src.getvalue()

        file_size = os.path.getsize(user_file.path)
        trailer = file_size - offset - size
        assert file_size % user_file.sector_size == 0
        assert f.read() == b"\0" * trailer
示例#27
0
def test_block_size_first_block_unallocated(user_file):
    # Assumes file system block size <= 4096.
    hole_size = 4096
    data_size = 4096

    with io.open(user_file.path, "wb") as f:
        f.seek(hole_size)
        f.write(b"x" * data_size)

    with file.open(user_file.url) as f:
        if user_file.can_detect_sector_size:
            assert f.block_size == user_file.sector_size
        else:
            assert f.block_size in (user_file.sector_size, 4096)

    with io.open(user_file.path, "rb") as f:
        assert f.read(hole_size) == b"\0" * hole_size
        assert f.read(data_size) == b"x" * data_size
示例#28
0
def test_write_unaligned_offset_inside(user_file):
    size = user_file.sector_size * 2
    start = user_file.sector_size - 12

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    # Write 12 bytes into the first block.
    with file.open(user_file.url, "r+") as f:
        f.seek(start)
        n = f.write(b"y" * 100)
        assert n == 12
        assert f.tell() == user_file.sector_size

    with io.open(user_file.path, "rb") as f:
        assert f.read(start) == b"x" * start
        assert f.read(12) == b"y" * 12
        assert f.read() == b"x" * user_file.sector_size
示例#29
0
def test_zero_unaligned_buffer_slow_path(user_file):
    size = user_file.sector_size * 2
    start = user_file.sector_size

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    # Perform slow read-modify-write in the second block.
    with file.open(user_file.url, "r+") as f:
        f.seek(start)
        n = f.zero(10)
        assert n == 10
        assert f.tell() == start + 10

    with io.open(user_file.path, "rb") as f:
        assert f.read(start) == b"x" * start
        assert f.read(10) == b"\0" * 10
        assert f.read() == b"x" * (size - start - 10)
示例#30
0
def test_zero_unaligned_offset_complete(user_file):
    size = user_file.sector_size * 2
    start = user_file.sector_size + 10

    with io.open(user_file.path, "wb") as f:
        f.write(b"x" * size)

    # Zero 10 bytes into the second block.
    with file.open(user_file.url, "r+") as f:
        f.seek(start)
        n = f.zero(10)
        assert n == 10
        assert f.tell() == start + 10

    with io.open(user_file.path, "rb") as f:
        assert f.read(start) == b"x" * start
        assert f.read(10) == b"\0" * 10
        assert f.read() == b"x" * (size - start - 10)