Esempio n. 1
0
def test_copy_nbd_to_nbd(tmpdir, src_fmt, dst_fmt, zero, hole):
    # Default cluser size with qcow2 format.
    cluster_size = 64 * 1024
    extents = [
        ("data", cluster_size),
        ("zero", cluster_size),
        ("data", cluster_size),
        ("hole", cluster_size + io.MAX_ZERO_SIZE),
        ("data", cluster_size + io.BUFFER_SIZE),
        ("hole", cluster_size),
        ("data", cluster_size),
    ]
    size = sum(length for _, length in extents)

    src = str(tmpdir.join("src." + src_fmt))
    qemu_img.create(src, src_fmt, size=size)
    populate_image(src, src_fmt, extents)

    src_sock = UnixAddress(tmpdir.join("src.sock"))
    src_url = urlparse(src_sock.url())

    dst = str(tmpdir.join("dst." + dst_fmt))
    qemu_img.create(dst, dst_fmt, size=size)
    dst_sock = UnixAddress(tmpdir.join("dst.sock"))
    dst_url = urlparse(dst_sock.url())

    # Note: We need extra worker for reading extents for source.
    max_workers = 2
    with qemu_nbd.run(
                src, src_fmt, src_sock,
                read_only=True,
                shared=max_workers + 1), \
            qemu_nbd.run(
                dst, dst_fmt, dst_sock,
                shared=max_workers), \
            nbd.open(src_url, "r") as src_backend, \
            nbd.open(dst_url, "r+", sparse=True) as dst_backend:

        # Because we copy to new image, we can always use zero=False, but we
        # test both to verify that the result is the same.
        io.copy(src_backend,
                dst_backend,
                max_workers=max_workers,
                zero=zero,
                hole=hole)

    # Compare image content - must match.
    qemu_img.compare(src, dst)

    # Allocation can be compared only with qcow2 images when we write zeroes to
    # zero extents and skip holes.
    if src_fmt == "qcow2" and dst_fmt == "qcow2" and zero and not hole:
        qemu_img.compare(src, dst, strict=True)
Esempio n. 2
0
def test_copy_dirty(progress):
    src = memory.Backend(
        mode="r",
        data=create_backing("ABCD"),
        extents={"dirty": create_dirty_extents("AbCd")},
    )
    dst_backing = create_backing("0000")
    dst = memory.Backend("r+", data=dst_backing)

    io.copy(src, dst, dirty=True, max_workers=1, progress=progress)

    # Copy dirty extents, skip clean extents.
    assert dst_backing == create_backing("A0C0")
Esempio n. 3
0
def test_copy_dirty_progress():
    src = memory.Backend(
        mode="r",
        data=create_backing("A0C-"),
        extents={"dirty": create_zero_extents("A0C-")},
    )
    dst_backing = create_backing("0000")
    dst = memory.Backend("r+", data=dst_backing)

    p = FakeProgress()
    io.copy(src, dst, dirty=True, max_workers=1, progress=p)

    # Report at least every extent.
    assert len(p.updates) >= 4

    # Report entire image size.
    assert sum(p.updates) == len(dst_backing)
Esempio n. 4
0
def test_copy_write_to(buffer_size, zero, hole, progress):
    src_extents = create_zero_extents("B0-")
    src_backing = create_backing("B0-")

    dst_backing = create_backing(
        "AAA" if zero and hole else "AA0" if zero else "A00")

    src = memory.WriterTo(mode="r",
                          data=src_backing,
                          extents={"zero": src_extents})

    dst = memory.Backend("r+", data=dst_backing)

    io.copy(src,
            dst,
            max_workers=1,
            buffer_size=buffer_size,
            zero=zero,
            hole=hole,
            progress=progress)

    assert dst_backing == src_backing
Esempio n. 5
0
def test_reraise_src_error():
    src = FailingBackend(fail_read=True)
    dst = FailingBackend()
    with pytest.raises(BackendError) as e:
        io.copy(src, dst)
    assert str(e.value) == "read error"
Esempio n. 6
0
def test_reraise_dst_error():
    src = FailingBackend()
    dst = FailingBackend(fail_write=True)
    with pytest.raises(BackendError) as e:
        io.copy(src, dst)
    assert str(e.value) == "write error"