Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
if TYPE_CHECKING:
import lib.host

KiB = 2**10
MiB = KiB**2
GiB = KiB**3
TiB = KiB**4

T = TypeVar("T")

HostAddress: TypeAlias = str
Expand Down
3 changes: 2 additions & 1 deletion lib/sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import lib.commands as commands
from lib.common import (
GiB,
prefix_object_name,
safe_split,
strtobool,
Expand Down Expand Up @@ -166,7 +167,7 @@ def get_type(self) -> str:
self._type = self.pool.master.xe("sr-param-get", {"uuid": self.uuid, "param-name": "type"})
return self._type

def create_vdi(self, name_label: str, virtual_size: int = 64, image_format: Optional[str] = None) -> VDI:
def create_vdi(self, name_label: str, virtual_size: int = 1 * GiB, image_format: Optional[str] = None) -> VDI:
logging.info("Create VDI %r on SR %s", name_label, self.uuid)
args = {
'name-label': prefix_object_name(name_label),
Expand Down
28 changes: 15 additions & 13 deletions lib/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,30 +309,32 @@ def connect_vdi(self, vdi: VDI, device: str = "autodetect") -> str:
"vm-uuid": self.uuid,
"device": device,
})
try:
self.host.xe("vbd-plug", {"uuid": vbd_uuid})
except commands.SSHCommandFailed:
self.host.xe("vbd-destroy", {"uuid": vbd_uuid})
raise
if self.is_running():
try:
self.host.xe("vbd-plug", {"uuid": vbd_uuid})
except commands.SSHCommandFailed:
self.host.xe("vbd-destroy", {"uuid": vbd_uuid})
raise

self.vdis.append(vdi)

return vbd_uuid

def disconnect_vdi(self, vdi: VDI):
logging.info(f"<< Unplugging VDI {vdi.uuid} from VM {self.uuid}")
assert vdi in self.vdis, "VDI {vdi.uuid} not in VM {self.uuid} VDI list"
assert vdi in self.vdis, f"VDI {vdi.uuid} not in VM {self.uuid} VDI list"
vbd_uuid = self.host.xe("vbd-list", {
"vdi-uuid": vdi.uuid,
"vm-uuid": self.uuid
}, minimal=True)
try:
self.host.xe("vbd-unplug", {"uuid": vbd_uuid})
except commands.SSHCommandFailed as e:
if e.stdout == f"The device is not currently attached\ndevice: {vbd_uuid}":
logging.info(f"VBD {vbd_uuid} already unplugged")
else:
raise
if self.is_running():
try:
self.host.xe("vbd-unplug", {"uuid": vbd_uuid})
except commands.SSHCommandFailed as e:
if e.stdout == f"The device is not currently attached\ndevice: {vbd_uuid}":
logging.info(f"VBD {vbd_uuid} already unplugged")
else:
raise
self.host.xe("vbd-destroy", {"uuid": vbd_uuid})
self.vdis.remove(vdi)

Expand Down
3 changes: 3 additions & 0 deletions tests/storage/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from .storage import (
cold_migration_then_come_back,
install_randstream,
live_storage_migration_then_come_back,
operation_on_vdi,
try_to_create_sr_with_missing_device,
vdi_is_open,
wait_for_vdi_coalesce,
)
Empty file removed tests/storage/coalesce/__init__.py
Empty file.
58 changes: 0 additions & 58 deletions tests/storage/coalesce/conftest.py

This file was deleted.

49 changes: 0 additions & 49 deletions tests/storage/coalesce/test_coalesce.py

This file was deleted.

50 changes: 0 additions & 50 deletions tests/storage/coalesce/utils.py

This file was deleted.

18 changes: 18 additions & 0 deletions tests/storage/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
import pytest

from tests.storage import install_randstream

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from lib.vdi import VDI
from lib.vm import VM


def pytest_collection_modifyitems(config, items):
# modify ordering so that ext is always tested first,
# before more complex storage drivers
for item in reversed(list(items)):
if "_ext_" in item.path.name:
items.remove(item)
items.insert(0, item)

@pytest.fixture(scope='module')
def storage_test_vm(unix_vm: 'VM'):
unix_vm.start()
unix_vm.wait_for_vm_running_and_ssh_up()
install_randstream(unix_vm)
yield unix_vm
9 changes: 4 additions & 5 deletions tests/storage/ext/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

import logging

from typing import TYPE_CHECKING, Generator
from lib.host import Host
from lib.sr import SR

if TYPE_CHECKING:
from lib.host import Host
from lib.sr import SR
from typing import Generator

@pytest.fixture(scope='package')
def ext_sr(host: Host, unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]]) -> Generator[SR]:
Expand All @@ -20,7 +19,7 @@ def ext_sr(host: Host, unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]]
sr.destroy()

@pytest.fixture(scope='module')
def vdi_on_ext_sr(ext_sr):
def vdi_on_ext_sr(ext_sr: SR):
vdi = ext_sr.create_vdi('EXT-local-VDI-test')
yield vdi
vdi.destroy()
Expand Down
36 changes: 30 additions & 6 deletions tests/storage/ext/test_ext_sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
from lib.commands import SSHCommandFailed
from lib.common import vm_image, wait_for
from lib.fistpoint import FistPoint
from lib.host import Host
from lib.vdi import VDI
from tests.storage import try_to_create_sr_with_missing_device, vdi_is_open

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from lib.host import Host
from lib.vm import VM
from tests.storage import (
operation_on_vdi,
try_to_create_sr_with_missing_device,
vdi_is_open,
wait_for_vdi_coalesce,
)

# Requirements:
# - one XCP-ng host with an additional unused disk for the SR
Expand Down Expand Up @@ -66,6 +68,28 @@ def test_snapshot(self, vm_on_ext_sr):
finally:
vm.shutdown(verify=True)

@pytest.mark.small_vm
@pytest.mark.parametrize("vdi_op", ["snapshot", "clone"])
def test_coalesce(self, storage_test_vm: VM, vdi_on_ext_sr: VDI, vdi_op):
vm = storage_test_vm
vdi = vdi_on_ext_sr
vm.connect_vdi(vdi, 'xvdb')
new_vdi = None
try:
vm.ssh("randstream generate -v /dev/xvdb")
vm.ssh("randstream validate -v --expected-checksum 65280014 /dev/xvdb")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are you getting the expected checksum that is hardcoded?
There is a seed on the second generate call a few lines later but not here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generate a first stream with the same size and copy/paste it.
This run uses the default seed (0). The second one uses a different seed to write something different on the disk.

new_vdi = operation_on_vdi(vm.host, vdi.uuid, vdi_op)
vm.ssh("randstream generate -v --seed 1 --size 128Mi /dev/xvdb")
vm.ssh("randstream validate -v --expected-checksum ad2ca9af /dev/xvdb")
new_vdi.destroy()
new_vdi = None
wait_for_vdi_coalesce(vdi)
vm.ssh("randstream validate -v --expected-checksum ad2ca9af /dev/xvdb")
finally:
vm.disconnect_vdi(vdi)
if new_vdi is not None:
new_vdi.destroy()

# *** tests with reboots (longer tests).

@pytest.mark.small_vm
Expand Down
9 changes: 4 additions & 5 deletions tests/storage/lvm/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

import logging

from typing import TYPE_CHECKING, Generator
from lib.host import Host
from lib.sr import SR

if TYPE_CHECKING:
from lib.host import Host
from lib.sr import SR
from typing import Generator

@pytest.fixture(scope='package')
def lvm_sr(host: Host, unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]]) -> Generator[SR]:
Expand All @@ -20,7 +19,7 @@ def lvm_sr(host: Host, unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]]
sr.destroy()

@pytest.fixture(scope='module')
def vdi_on_lvm_sr(lvm_sr):
def vdi_on_lvm_sr(lvm_sr: SR):
vdi = lvm_sr.create_vdi('LVM-local-VDI-test')
yield vdi
vdi.destroy()
Expand Down
Loading