Skip to content

Commit 254b633

Browse files
committed
storage: add comprehensive tests for lvmohba storage repositories
Implement test suite for lvmohba SR operations including VDI management, snapshot/clone operations, XVA export/import, and intra/cross-pool migrations. Tests are mostly copied from lvmoiscsi with lvmohba-specific adjustments. Signed-off-by: Gaëtan Lehmann <gaetan.lehmann@vates.tech>
1 parent 317f3ec commit 254b633

6 files changed

Lines changed: 197 additions & 0 deletions

File tree

data.py-dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ LVMOISCSI_DEVICE_CONFIG: dict[str, str] = {
233233
# 'SCSIid': 'id'
234234
}
235235

236+
LVMOHBA_DEVICE_CONFIG: dict[str, str] = {
237+
# 'SCSIid': 'wwid'
238+
}
239+
236240
BASE_ANSWERFILES = dict(
237241
INSTALL={
238242
"TAG": "installation",

tests/storage/lvmohba/__init__.py

Whitespace-only changes.

tests/storage/lvmohba/conftest.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
import logging
4+
5+
from lib import config
6+
from lib.sr import SR
7+
from lib.vdi import ImageFormat
8+
9+
@pytest.fixture(scope='package')
10+
def lvmohba_device_config():
11+
return config.sr_device_config("LVMOHBA_DEVICE_CONFIG")
12+
13+
@pytest.fixture(scope='package')
14+
def lvmohba_sr(host, lvmohba_device_config, image_format: ImageFormat):
15+
""" A lvmohba SR on first host. """
16+
sr = host.sr_create('lvmohba', "lvmohba-SR-test",
17+
lvmohba_device_config | {'preferred-image-formats': image_format}, shared=True)
18+
yield sr
19+
# teardown
20+
sr.destroy()
21+
22+
@pytest.fixture()
23+
def vdi_on_lvmohba_sr(lvmohba_sr: SR):
24+
vdi = lvmohba_sr.create_vdi('lvmohba-VDI-test', virtual_size=config.volume_size)
25+
yield vdi
26+
vdi.destroy()
27+
28+
@pytest.fixture(scope='module')
29+
def vm_on_lvmohba_sr(host, lvmohba_sr, vm_ref):
30+
vm = host.import_vm(vm_ref, sr_uuid=lvmohba_sr.uuid)
31+
yield vm
32+
# teardown
33+
logging.info("<< Destroy VM")
34+
vm.destroy(verify=True)
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import pytest
2+
3+
from lib.commands import SSHCommandFailed
4+
from lib.common import Defer, vm_image, wait_for
5+
from lib.sr import SR
6+
from lib.vdi import VDI, ImageFormat
7+
from lib.vm import VM
8+
from tests.storage import (
9+
MAX_VDI_SIZE,
10+
CoalesceOperation,
11+
ImageFormat,
12+
XVACompression,
13+
coalesce_integrity,
14+
full_vdi_write,
15+
vdi_export_import,
16+
vdi_is_open,
17+
xva_export_import,
18+
)
19+
20+
# Requirements:
21+
# - one XCP-ng host >= 8.2
22+
# - a valid lvmohba config
23+
24+
class TestLVMOHBASRCreateDestroy:
25+
"""
26+
Tests that do not use fixtures that setup the SR or import VMs,
27+
because they precisely need to test SR creation and destruction,
28+
and VM import.
29+
"""
30+
31+
def test_create_and_destroy_sr(self, host, lvmohba_device_config, image_format: ImageFormat):
32+
# Create and destroy tested in the same test to leave the host as unchanged as possible
33+
sr = host.sr_create('lvmohba', "lvmohba-SR-test",
34+
lvmohba_device_config | {'preferred-image-formats': image_format},
35+
shared=True, verify=True)
36+
# import a VM in order to detect vm import issues here rather than in the vm_on_xfs_fixture used in
37+
# the next tests, because errors in fixtures break teardown
38+
vm = host.import_vm(vm_image('mini-linux-x86_64-bios'), sr_uuid=sr.uuid)
39+
vm.destroy(verify=True)
40+
sr.destroy(verify=True)
41+
42+
@pytest.mark.usefixtures('image_format')
43+
@pytest.mark.usefixtures("lvmohba_sr")
44+
@pytest.mark.thick_provisioned
45+
class TestLVMOHBASR:
46+
@pytest.mark.quicktest
47+
def test_quicktest(self, lvmohba_sr):
48+
lvmohba_sr.run_quicktest()
49+
50+
def test_vdi_is_not_open(self, vdi_on_lvmohba_sr):
51+
assert not vdi_is_open(vdi_on_lvmohba_sr)
52+
53+
@pytest.mark.small_vm # run with a small VM to test the features
54+
@pytest.mark.big_vm # and ideally with a big VM to test it scales
55+
def test_start_and_shutdown_VM(self, vm_on_lvmohba_sr):
56+
vm = vm_on_lvmohba_sr
57+
vm.start()
58+
vm.wait_for_os_booted()
59+
vm.shutdown(verify=True)
60+
61+
@pytest.mark.small_vm
62+
@pytest.mark.big_vm
63+
def test_snapshot(self, vm_on_lvmohba_sr):
64+
vm = vm_on_lvmohba_sr
65+
vm.start()
66+
try:
67+
vm.wait_for_os_booted()
68+
vm.test_snapshot_on_running_vm()
69+
finally:
70+
vm.shutdown(verify=True)
71+
72+
@pytest.mark.small_vm
73+
@pytest.mark.parametrize("vdi_op", ["snapshot", "clone"])
74+
def test_coalesce(self, storage_test_vm: 'VM', vdi_on_lvmohba_sr: 'VDI', vdi_op: CoalesceOperation, defer: Defer):
75+
coalesce_integrity(storage_test_vm, vdi_on_lvmohba_sr, vdi_op, defer)
76+
77+
@pytest.mark.small_vm
78+
@pytest.mark.disk_throughput_intensive
79+
def test_full_vdi_write(self, storage_test_vm: VM, vdi_on_lvmohba_sr: VDI, defer: Defer):
80+
full_vdi_write(storage_test_vm, vdi_on_lvmohba_sr, defer)
81+
82+
@pytest.mark.small_vm
83+
def test_invalid_vdi_size(self, lvmohba_sr: SR, image_format: ImageFormat):
84+
with pytest.raises(SSHCommandFailed) as excinfo:
85+
lvmohba_sr.create_vdi(virtual_size=MAX_VDI_SIZE[image_format] + 1)
86+
assert 'VDI Invalid size' in excinfo.value.stdout
87+
88+
@pytest.mark.small_vm
89+
@pytest.mark.parametrize("compression", ["none", "gzip", "zstd"])
90+
def test_xva_export_import(self, vm_on_lvmohba_sr: VM, compression: XVACompression, temp_large_dir: str,
91+
defer: Defer):
92+
xva_export_import(vm_on_lvmohba_sr, compression, temp_large_dir, defer)
93+
94+
@pytest.mark.small_vm
95+
def test_vdi_export_import(self, storage_test_vm: VM, lvmohba_sr: SR, image_format: ImageFormat,
96+
temp_large_dir: str, defer: Defer):
97+
vdi_export_import(storage_test_vm, lvmohba_sr, image_format, temp_large_dir, defer)
98+
99+
# *** tests with reboots (longer tests).
100+
101+
@pytest.mark.reboot
102+
@pytest.mark.small_vm
103+
def test_reboot(self, host, lvmohba_sr, vm_on_lvmohba_sr):
104+
sr = lvmohba_sr
105+
vm = vm_on_lvmohba_sr
106+
host.reboot(verify=True)
107+
wait_for(sr.all_pbds_attached, "Wait for PBD attached")
108+
# start the VM as a way to check that the underlying SR is operational
109+
vm.start(on=host.uuid)
110+
vm.wait_for_os_booted()
111+
vm.shutdown(verify=True)
112+
113+
# *** End of tests with reboots
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
3+
from tests.storage import cold_migration_then_come_back, live_storage_migration_then_come_back
4+
5+
# Requirements:
6+
# From --hosts parameter:
7+
# - host(A1): first XCP-ng host >= 8.2 with a valid lvmohba config.
8+
# - hostB1: Master of a second pool. Any local SR.
9+
# From --vm parameter
10+
# - A VM to import to the LVM SR
11+
12+
@pytest.mark.small_vm # run with a small VM to test the features
13+
@pytest.mark.big_vm # and ideally with a big VM to test it scales
14+
@pytest.mark.usefixtures("hostB1", "local_sr_on_hostB1")
15+
@pytest.mark.thick_provisioned
16+
class Test:
17+
def test_cold_crosspool_migration(self, host, hostB1, vm_on_lvmohba_sr, local_sr_on_hostB1):
18+
cold_migration_then_come_back(vm_on_lvmohba_sr, host, hostB1, local_sr_on_hostB1)
19+
20+
def test_live_crosspool_migration(self, host, hostB1, vm_on_lvmohba_sr, local_sr_on_hostB1):
21+
live_storage_migration_then_come_back(vm_on_lvmohba_sr, host, hostB1, local_sr_on_hostB1)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import pytest
2+
3+
from tests.storage import cold_migration_then_come_back, live_storage_migration_then_come_back
4+
5+
# Requirements:
6+
# From --hosts parameter:
7+
# - host(A1): first XCP-ng host >= 8.2 with a valid lvmohba config.
8+
# - hostA2: Second member of the pool. Can have any local SR. No need to specify it on CLI.
9+
# From --vm parameter
10+
# - A VM to import to the LVM SR
11+
12+
@pytest.mark.small_vm # run with a small VM to test the features
13+
@pytest.mark.big_vm # and ideally with a big VM to test it scales
14+
@pytest.mark.usefixtures("hostA2", "local_sr_on_hostA2")
15+
@pytest.mark.thick_provisioned
16+
class Test:
17+
def test_live_intrapool_shared_migration(self, host, hostA2, vm_on_lvmohba_sr):
18+
sr = vm_on_lvmohba_sr.get_sr()
19+
live_storage_migration_then_come_back(vm_on_lvmohba_sr, host, hostA2, sr)
20+
21+
def test_cold_intrapool_migration(self, host, hostA2, vm_on_lvmohba_sr, local_sr_on_hostA2):
22+
cold_migration_then_come_back(vm_on_lvmohba_sr, host, hostA2, local_sr_on_hostA2)
23+
24+
def test_live_intrapool_migration(self, host, hostA2, vm_on_lvmohba_sr, local_sr_on_hostA2):
25+
live_storage_migration_then_come_back(vm_on_lvmohba_sr, host, hostA2, local_sr_on_hostA2)

0 commit comments

Comments
 (0)