Add more crosscheck tests
This commit is contained in:
@@ -100,6 +100,12 @@ tox -e integration
|
|||||||
.venv/bin/pytest tests/integration
|
.venv/bin/pytest tests/integration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Some tests are marked as ``slow`` and skipped unless you pass ``--runslow``:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tox -e integration -- --runslow
|
||||||
|
```
|
||||||
|
|
||||||
Compare write/read throughput of openvixdisklib and native VDDK
|
Compare write/read throughput of openvixdisklib and native VDDK
|
||||||
(`64KiB`, 129-sector, and `32MiB` transfers; `nbdssl` and `nbd`;
|
(`64KiB`, 129-sector, and `32MiB` transfers; `nbdssl` and `nbd`;
|
||||||
plain and FastLZ):
|
plain and FastLZ):
|
||||||
|
|||||||
@@ -35,3 +35,32 @@ def lab() -> Iterator[LabEnv]:
|
|||||||
def vddk() -> None:
|
def vddk() -> None:
|
||||||
"""Skip VDDK-backed tests when ``libvixDiskLib`` cannot be loaded."""
|
"""Skip VDDK-backed tests when ``libvixDiskLib`` cannot be loaded."""
|
||||||
require_vddk()
|
require_vddk()
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_addoption(parser: pytest.Parser) -> None:
|
||||||
|
"""Add ``--runslow`` to opt in to long-running tests."""
|
||||||
|
parser.addoption(
|
||||||
|
"--runslow",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="run tests marked as slow",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_configure(config: pytest.Config) -> None:
|
||||||
|
"""Register the ``slow`` marker."""
|
||||||
|
config.addinivalue_line(
|
||||||
|
"markers", "slow: long-running tests; enable with --runslow"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_collection_modifyitems(
|
||||||
|
config: pytest.Config, items: list[pytest.Item]
|
||||||
|
) -> None:
|
||||||
|
"""Skip ``slow`` tests unless ``--runslow`` was given."""
|
||||||
|
if config.getoption("--runslow"):
|
||||||
|
return
|
||||||
|
skip_slow = pytest.mark.skip(reason="need --runslow to run")
|
||||||
|
for item in items:
|
||||||
|
if "slow" in item.keywords:
|
||||||
|
item.add_marker(skip_slow)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ _LAB_VM_PREFIX = "ovdl-test-"
|
|||||||
VDDK_DIR = _VDDK_DIR
|
VDDK_DIR = _VDDK_DIR
|
||||||
SECTOR_SIZE = 512
|
SECTOR_SIZE = 512
|
||||||
SECTOR_AT_1GB = (1024 * 1024 * 1024) // SECTOR_SIZE
|
SECTOR_AT_1GB = (1024 * 1024 * 1024) // SECTOR_SIZE
|
||||||
|
SECTOR_AT_5GB = (5 * 1024 * 1024 * 1024) // SECTOR_SIZE
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -3,13 +3,25 @@
|
|||||||
|
|
||||||
"""Compare writes and reads from VDDK with openvixdisklib."""
|
"""Compare writes and reads from VDDK with openvixdisklib."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from openvixdisklib import openvixdisklib as open_vix
|
from openvixdisklib import openvixdisklib as open_vix
|
||||||
from tests.integration import vixdisklib
|
from tests.integration import vixdisklib
|
||||||
from tests.integration.base import SECTOR_AT_1GB, SECTOR_SIZE, LabEnv, pattern_bytes
|
from tests.integration.base import (
|
||||||
|
SECTOR_AT_1GB,
|
||||||
|
SECTOR_AT_5GB,
|
||||||
|
SECTOR_SIZE,
|
||||||
|
LabEnv,
|
||||||
|
pattern_bytes,
|
||||||
|
)
|
||||||
|
|
||||||
|
_64MIB = 64 * 1024 * 1024
|
||||||
|
_5GIB = SECTOR_AT_5GB * SECTOR_SIZE
|
||||||
|
|
||||||
|
|
||||||
def _connect_extra(lab: LabEnv, module: Any) -> dict[str, Any] | None:
|
def _connect_extra(lab: LabEnv, module: Any) -> dict[str, Any] | None:
|
||||||
@@ -70,6 +82,52 @@ def _assert_both_read(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _write_bytes(
|
||||||
|
lab: LabEnv, module: Any, start_byte: int, data: bytes, flags: int = 0
|
||||||
|
) -> None:
|
||||||
|
"""Write ``data`` starting at ``start_byte`` using ``module``."""
|
||||||
|
handle = module.VixDiskLibHandle(
|
||||||
|
vixdisklib_compatibility_version="8.0", config_path=None
|
||||||
|
)
|
||||||
|
buf = module.get_buffer(len(data))
|
||||||
|
buf[: len(data)] = data
|
||||||
|
kwargs = lab.vixdisklib_connect_kwargs(_connect_extra(lab, module))
|
||||||
|
with (
|
||||||
|
handle.connect(**kwargs) as conn,
|
||||||
|
handle.open(conn, lab.disk_path, flags=flags) as disk,
|
||||||
|
):
|
||||||
|
handle.write(disk, start_byte // SECTOR_SIZE, len(data) // SECTOR_SIZE, buf)
|
||||||
|
|
||||||
|
|
||||||
|
def _read_bytes(
|
||||||
|
lab: LabEnv, module: Any, start_byte: int, nbytes: int, flags: int = 0
|
||||||
|
) -> bytes:
|
||||||
|
"""Read ``nbytes`` starting at ``start_byte`` using ``module``."""
|
||||||
|
handle = module.VixDiskLibHandle(
|
||||||
|
vixdisklib_compatibility_version="8.0", config_path=None
|
||||||
|
)
|
||||||
|
buf = module.get_buffer(nbytes)
|
||||||
|
buf[:nbytes] = b"\xa5" * nbytes
|
||||||
|
kwargs = lab.vixdisklib_connect_kwargs(_connect_extra(lab, module))
|
||||||
|
with (
|
||||||
|
handle.connect(**kwargs) as conn,
|
||||||
|
handle.open(conn, lab.disk_path, flags=flags) as disk,
|
||||||
|
):
|
||||||
|
handle.read(disk, start_byte // SECTOR_SIZE, nbytes // SECTOR_SIZE, buf)
|
||||||
|
return buf.raw[:nbytes]
|
||||||
|
|
||||||
|
|
||||||
|
def _assert_both_read_bytes(
|
||||||
|
lab: LabEnv, start_byte: int, expected: bytes, flags: int = 0
|
||||||
|
) -> None:
|
||||||
|
vddk_data = _read_bytes(lab, vixdisklib, start_byte, len(expected), flags=flags)
|
||||||
|
replacement = _read_bytes(lab, open_vix, start_byte, len(expected), flags=flags)
|
||||||
|
assert vddk_data == expected, f"VDDK mismatch at byte offset {start_byte}"
|
||||||
|
assert replacement == expected, (
|
||||||
|
f"openvixdisklib mismatch at byte offset {start_byte}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestCrosscheck:
|
class TestCrosscheck:
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"open_flags",
|
"open_flags",
|
||||||
@@ -80,11 +138,12 @@ class TestCrosscheck:
|
|||||||
self, lab: LabEnv, vddk: None, open_flags: int
|
self, lab: LabEnv, vddk: None, open_flags: int
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Writes from either library must be visible to both readers."""
|
"""Writes from either library must be visible to both readers."""
|
||||||
sectors = (0, 1, SECTOR_AT_1GB)
|
sectors = (0, 1, SECTOR_AT_1GB, SECTOR_AT_5GB)
|
||||||
vddk_payloads = {
|
vddk_payloads = {
|
||||||
0: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-S0"),
|
0: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-S0"),
|
||||||
1: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-S1"),
|
1: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-S1"),
|
||||||
SECTOR_AT_1GB: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-1G"),
|
SECTOR_AT_1GB: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-1G"),
|
||||||
|
SECTOR_AT_5GB: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-5G"),
|
||||||
}
|
}
|
||||||
_write_sectors(lab, vixdisklib, vddk_payloads, flags=open_flags)
|
_write_sectors(lab, vixdisklib, vddk_payloads, flags=open_flags)
|
||||||
_assert_both_read(lab, sectors, vddk_payloads, flags=open_flags)
|
_assert_both_read(lab, sectors, vddk_payloads, flags=open_flags)
|
||||||
@@ -93,6 +152,29 @@ class TestCrosscheck:
|
|||||||
0: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-S0"),
|
0: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-S0"),
|
||||||
1: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-S1"),
|
1: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-S1"),
|
||||||
SECTOR_AT_1GB: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-1G"),
|
SECTOR_AT_1GB: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-1G"),
|
||||||
|
SECTOR_AT_5GB: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-5G"),
|
||||||
}
|
}
|
||||||
_write_sectors(lab, open_vix, ovdl_payloads, flags=open_flags)
|
_write_sectors(lab, open_vix, ovdl_payloads, flags=open_flags)
|
||||||
_assert_both_read(lab, sectors, ovdl_payloads, flags=open_flags)
|
_assert_both_read(lab, sectors, ovdl_payloads, flags=open_flags)
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"open_flags",
|
||||||
|
[0, vixdisklib.VIXDISKLIB_FLAG_OPEN_COMPRESSION_FASTLZ],
|
||||||
|
ids=["plain", "fastlz"],
|
||||||
|
)
|
||||||
|
def test_openvixdisklib_matches_vddk_64mib_at_5gib(
|
||||||
|
self, lab: LabEnv, vddk: None, open_flags: int
|
||||||
|
) -> None:
|
||||||
|
"""Write 64 MiB of random data at a 5 GiB offset and compare both libraries.
|
||||||
|
|
||||||
|
The 5 GiB start is past the 4 GiB (2**32) byte boundary, so a
|
||||||
|
32-bit disk offset would wrap and fail the comparison.
|
||||||
|
"""
|
||||||
|
vddk_payload = os.urandom(_64MIB)
|
||||||
|
_write_bytes(lab, vixdisklib, _5GIB, vddk_payload, flags=open_flags)
|
||||||
|
_assert_both_read_bytes(lab, _5GIB, vddk_payload, flags=open_flags)
|
||||||
|
|
||||||
|
ovdl_payload = os.urandom(_64MIB)
|
||||||
|
_write_bytes(lab, open_vix, _5GIB, ovdl_payload, flags=open_flags)
|
||||||
|
_assert_both_read_bytes(lab, _5GIB, ovdl_payload, flags=open_flags)
|
||||||
|
|||||||
Reference in New Issue
Block a user