Add more crosscheck tests
This commit is contained in:
@@ -100,6 +100,12 @@ tox -e 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
|
||||
(`64KiB`, 129-sector, and `32MiB` transfers; `nbdssl` and `nbd`;
|
||||
plain and FastLZ):
|
||||
|
||||
@@ -35,3 +35,32 @@ def lab() -> Iterator[LabEnv]:
|
||||
def vddk() -> None:
|
||||
"""Skip VDDK-backed tests when ``libvixDiskLib`` cannot be loaded."""
|
||||
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
|
||||
SECTOR_SIZE = 512
|
||||
SECTOR_AT_1GB = (1024 * 1024 * 1024) // SECTOR_SIZE
|
||||
SECTOR_AT_5GB = (5 * 1024 * 1024 * 1024) // SECTOR_SIZE
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -3,13 +3,25 @@
|
||||
|
||||
"""Compare writes and reads from VDDK with openvixdisklib."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from openvixdisklib import openvixdisklib as open_vix
|
||||
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:
|
||||
@@ -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:
|
||||
@pytest.mark.parametrize(
|
||||
"open_flags",
|
||||
@@ -80,11 +138,12 @@ class TestCrosscheck:
|
||||
self, lab: LabEnv, vddk: None, open_flags: int
|
||||
) -> None:
|
||||
"""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 = {
|
||||
0: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-S0"),
|
||||
1: pattern_bytes(SECTOR_SIZE, b"XCHK-VDDK-S1"),
|
||||
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)
|
||||
_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"),
|
||||
1: pattern_bytes(SECTOR_SIZE, b"XCHK-OVDL-S1"),
|
||||
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)
|
||||
_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