Skip to content

Commit ef4ead1

Browse files
committed
storage: keep the vdi available when entering the debugger
Signed-off-by: Gaëtan Lehmann <gaetan.lehmann@vates.tech>
1 parent 4488beb commit ef4ead1

8 files changed

Lines changed: 116 additions & 101 deletions

File tree

tests/storage/ext/test_ext_sr.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,17 @@ def test_snapshot(self, vm_on_ext_sr):
8787

8888
@pytest.mark.small_vm
8989
@pytest.mark.parametrize("vdi_op", ["snapshot", "clone"])
90-
def test_coalesce(self, storage_test_vm: VM, vdi_on_ext_sr: VDI, vdi_op: CoalesceOperation):
91-
coalesce_integrity(storage_test_vm, vdi_on_ext_sr, vdi_op)
90+
def test_coalesce(self, storage_test_vm: VM, vdi_on_ext_sr: VDI, vdi_op: CoalesceOperation, defer: Defer):
91+
coalesce_integrity(storage_test_vm, vdi_on_ext_sr, vdi_op, defer)
9292

9393
@pytest.mark.small_vm
9494
@pytest.mark.parametrize("compression", ["none", "gzip", "zstd"])
9595
def test_xva_export_import(self, vm_on_ext_sr: VM, compression: XVACompression, defer: Defer):
9696
xva_export_import(vm_on_ext_sr, compression, defer)
9797

9898
@pytest.mark.small_vm
99-
def test_vdi_export_import(self, storage_test_vm: VM, ext_sr: SR, image_format: ImageFormat):
100-
vdi_export_import(storage_test_vm, ext_sr, image_format)
99+
def test_vdi_export_import(self, storage_test_vm: VM, ext_sr: SR, image_format: ImageFormat, defer: Defer):
100+
vdi_export_import(storage_test_vm, ext_sr, image_format, defer)
101101

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

tests/storage/lvm/test_lvm_sr.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,17 @@ def test_failing_resize_on_inflate_after_setSizePhys(self, host, lvm_sr, vm_on_l
140140

141141
@pytest.mark.small_vm
142142
@pytest.mark.parametrize("vdi_op", ["snapshot", "clone"])
143-
def test_coalesce(self, storage_test_vm: VM, vdi_on_lvm_sr: VDI, vdi_op: CoalesceOperation):
144-
coalesce_integrity(storage_test_vm, vdi_on_lvm_sr, vdi_op)
143+
def test_coalesce(self, storage_test_vm: VM, vdi_on_lvm_sr: VDI, vdi_op: CoalesceOperation, defer: Defer):
144+
coalesce_integrity(storage_test_vm, vdi_on_lvm_sr, vdi_op, defer)
145145

146146
@pytest.mark.small_vm
147147
@pytest.mark.parametrize("compression", ["none", "gzip", "zstd"])
148148
def test_xva_export_import(self, vm_on_lvm_sr: VM, compression: XVACompression, defer: Defer):
149149
xva_export_import(vm_on_lvm_sr, compression, defer)
150150

151151
@pytest.mark.small_vm
152-
def test_vdi_export_import(self, storage_test_vm: VM, lvm_sr: SR, image_format: ImageFormat):
153-
vdi_export_import(storage_test_vm, lvm_sr, image_format)
152+
def test_vdi_export_import(self, storage_test_vm: VM, lvm_sr: SR, image_format: ImageFormat, defer: Defer):
153+
vdi_export_import(storage_test_vm, lvm_sr, image_format, defer)
154154

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

tests/storage/lvmoiscsi/test_lvmoiscsi_sr.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ def test_snapshot(self, vm_on_lvmoiscsi_sr):
6767

6868
@pytest.mark.small_vm
6969
@pytest.mark.parametrize("vdi_op", ["snapshot", "clone"])
70-
def test_coalesce(self, storage_test_vm: 'VM', vdi_on_lvmoiscsi_sr: 'VDI', vdi_op: CoalesceOperation):
71-
coalesce_integrity(storage_test_vm, vdi_on_lvmoiscsi_sr, vdi_op)
70+
def test_coalesce(self, storage_test_vm: 'VM', vdi_on_lvmoiscsi_sr: 'VDI', vdi_op: CoalesceOperation, defer: Defer):
71+
coalesce_integrity(storage_test_vm, vdi_on_lvmoiscsi_sr, vdi_op, defer)
7272

7373
@pytest.mark.small_vm
7474
@pytest.mark.parametrize("compression", ["none", "gzip", "zstd"])
7575
def test_xva_export_import(self, vm_on_lvmoiscsi_sr: VM, compression: XVACompression, defer: Defer):
7676
xva_export_import(vm_on_lvmoiscsi_sr, compression, defer)
7777

7878
@pytest.mark.small_vm
79-
def test_vdi_export_import(self, storage_test_vm: VM, lvmoiscsi_sr: SR, image_format: ImageFormat):
80-
vdi_export_import(storage_test_vm, lvmoiscsi_sr, image_format)
79+
def test_vdi_export_import(self, storage_test_vm: VM, lvmoiscsi_sr: SR, image_format: ImageFormat, defer: Defer):
80+
vdi_export_import(storage_test_vm, lvmoiscsi_sr, image_format, defer)
8181

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

tests/storage/nfs/test_nfs_sr.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ def test_snapshot(self, dispatch_nfs):
115115
@pytest.mark.small_vm
116116
@pytest.mark.parametrize('dispatch_nfs', ['vdi_on_nfs_sr', 'vdi_on_nfs4_sr'], indirect=True)
117117
@pytest.mark.parametrize('vdi_op', ['snapshot', 'clone'])
118-
def test_coalesce(self, storage_test_vm: VM, dispatch_nfs: VDI, vdi_op: CoalesceOperation):
119-
coalesce_integrity(storage_test_vm, dispatch_nfs, vdi_op)
118+
def test_coalesce(self, storage_test_vm: VM, dispatch_nfs: VDI, vdi_op: CoalesceOperation, defer: Defer):
119+
coalesce_integrity(storage_test_vm, dispatch_nfs, vdi_op, defer)
120120

121121
@pytest.mark.small_vm
122122
# Make sure this fixture is called before the parametrized one
@@ -128,8 +128,8 @@ def test_xva_export_import(self, dispatch_nfs: VM, compression: XVACompression,
128128

129129
@pytest.mark.small_vm
130130
@pytest.mark.parametrize('dispatch_nfs', ['nfs_sr', 'nfs4_sr'], indirect=True)
131-
def test_vdi_export_import(self, storage_test_vm: VM, dispatch_nfs: SR, image_format: ImageFormat):
132-
vdi_export_import(storage_test_vm, dispatch_nfs, image_format)
131+
def test_vdi_export_import(self, storage_test_vm: VM, dispatch_nfs: SR, image_format: ImageFormat, defer: Defer):
132+
vdi_export_import(storage_test_vm, dispatch_nfs, image_format, defer)
133133

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

tests/storage/storage.py

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -181,25 +181,23 @@ def install_randstream(vm: 'VM'):
181181

182182
CoalesceOperation = Literal['snapshot', 'clone']
183183

184-
def coalesce_integrity(vm: VM, vdi: VDI, vdi_op: CoalesceOperation):
184+
def coalesce_integrity(vm: VM, vdi: VDI, vdi_op: CoalesceOperation, defer: Defer):
185185
vbd = vm.connect_vdi(vdi)
186+
defer(lambda: vm.disconnect_vdi(vdi))
187+
186188
dev = f'/dev/{vbd.param_get("device")}'
187-
new_vdi = None
188-
try:
189-
vm.ssh(f"randstream generate -v {dev}")
190-
# default seed is 0
191-
vm.ssh(f"randstream validate -v --expected-checksum 65280014 {dev}")
192-
match vdi_op:
193-
case 'clone': new_vdi = vdi.clone()
194-
case 'snapshot': new_vdi = vdi.snapshot()
195-
vm.ssh(f"randstream generate -v --seed 1 --size 128Mi {dev}")
196-
vm.ssh(f"randstream validate -v --expected-checksum ad2ca9af {dev}")
197-
new_vdi = vdi.wait_for_coalesce(new_vdi.destroy)
198-
vm.ssh(f"randstream validate -v --expected-checksum ad2ca9af {dev}")
199-
finally:
200-
vm.disconnect_vdi(vdi)
201-
if new_vdi is not None:
202-
new_vdi.destroy()
189+
vm.ssh(f"randstream generate -v {dev}")
190+
# default seed is 0
191+
vm.ssh(f"randstream validate -v --expected-checksum 65280014 {dev}")
192+
match vdi_op:
193+
case 'clone': new_vdi = vdi.clone()
194+
case 'snapshot': new_vdi = vdi.snapshot()
195+
defer(lambda: new_vdi.destroy() if new_vdi is not None else None)
196+
197+
vm.ssh(f"randstream generate -v --seed 1 --size 128Mi {dev}")
198+
vm.ssh(f"randstream validate -v --expected-checksum ad2ca9af {dev}")
199+
new_vdi = vdi.wait_for_coalesce(new_vdi.destroy)
200+
vm.ssh(f"randstream validate -v --expected-checksum ad2ca9af {dev}")
203201

204202
XVACompression = Literal['none', 'gzip', 'zstd']
205203

@@ -229,31 +227,37 @@ def xva_export_import(vm: VM, compression: XVACompression, defer: Defer):
229227
imported_vm.wait_for_vm_running_and_ssh_up()
230228
imported_vm.ssh("randstream validate -v --expected-checksum 24e905d6 /root/data")
231229

232-
def vdi_export_import(vm: VM, sr: SR, image_format: ImageFormat):
233-
vdi = sr.create_vdi(image_format=image_format)
234-
image_path = f'/tmp/{vdi.uuid}.{image_format}'
235-
try:
236-
vbd = vm.connect_vdi(vdi)
237-
dev = f'/dev/{vbd.param_get("device")}'
238-
# generate 2 blocks of data of 200MiB, at position 0 and at position 500MiB
239-
vm.ssh(f"randstream generate -v --size 200MiB {dev}")
240-
# use a different seed to not write the same data (default seed is 0)
241-
vm.ssh(f"randstream generate -v --seed 1 --position 500MiB --size 200MiB {dev}")
242-
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
243-
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")
244-
vm.disconnect_vdi(vdi)
245-
vm.host.xe('vdi-export', {'uuid': vdi.uuid, 'filename': image_path, 'format': image_format})
246-
vdi = vdi.destroy()
247-
# check that the zero blocks are not part of the result
248-
size_mb = int(vm.host.ssh(f'du -sm --apparent-size {image_path}').split()[0])
249-
assert 400 < size_mb < 410, f"unexpected image size: {size_mb}"
250-
vdi = sr.create_vdi(image_format=image_format)
251-
vm.host.xe('vdi-import', {'uuid': vdi.uuid, 'filename': image_path, 'format': image_format})
252-
vm.connect_vdi(vdi, 'xvdb')
253-
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
254-
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")
255-
finally:
256-
if vdi is not None:
257-
vm.disconnect_vdi(vdi)
258-
vdi.destroy()
259-
vm.host.ssh(f'rm -f {image_path}')
230+
def vdi_export_import(vm: VM, sr: SR, image_format: ImageFormat, defer: Defer):
231+
vdi_src = sr.create_vdi(image_format=image_format)
232+
defer(lambda: vdi_src.destroy() if vdi_src is not None else None)
233+
234+
vbd = vm.connect_vdi(vdi_src)
235+
defer(lambda: vm.disconnect_vdi(vdi_src) if vdi_src is not None and vdi_src.uuid in vm.vdis else None)
236+
dev = f'/dev/{vbd.param_get("device")}'
237+
238+
# generate 2 blocks of data of 200MiB, at position 0 and at position 500MiB
239+
vm.ssh(f"randstream generate -v --size 200MiB {dev}")
240+
# use a different seed to not write the same data (default seed is 0)
241+
vm.ssh(f"randstream generate -v --seed 1 --position 500MiB --size 200MiB {dev}")
242+
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
243+
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")
244+
vm.disconnect_vdi(vdi_src)
245+
246+
image_path = f'/tmp/{vdi_src.uuid}.{image_format}'
247+
defer(lambda: vm.host.ssh(f'rm -f {image_path}'))
248+
249+
vm.host.xe('vdi-export', {'uuid': vdi_src.uuid, 'filename': image_path, 'format': image_format})
250+
vdi_src = vdi_src.destroy()
251+
252+
# check that the zero blocks are not part of the result
253+
size_mb = int(vm.host.ssh(f'du -sm --apparent-size {image_path}').split()[0])
254+
assert 400 < size_mb < 410, f"unexpected image size: {size_mb}"
255+
vdi_dest = sr.create_vdi(image_format=image_format)
256+
defer(lambda: vdi_dest.destroy())
257+
258+
vm.host.xe('vdi-import', {'uuid': vdi_dest.uuid, 'filename': image_path, 'format': image_format})
259+
vm.connect_vdi(vdi_dest, 'xvdb')
260+
defer(lambda: vm.disconnect_vdi(vdi_dest))
261+
262+
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
263+
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")

tests/storage/xfs/test_xfs_sr.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,21 @@ def test_snapshot(self, vm_on_xfs_sr):
104104

105105
@pytest.mark.small_vm
106106
@pytest.mark.parametrize("vdi_op", ["snapshot", "clone"])
107-
def test_coalesce(self, storage_test_vm: VM, vdi_on_xfs_sr: VDI, vdi_op: CoalesceOperation):
108-
coalesce_integrity(storage_test_vm, vdi_on_xfs_sr, vdi_op)
107+
def test_coalesce(
108+
self, storage_test_vm: VM, vdi_on_xfs_sr: VDI, vdi_op: CoalesceOperation, defer: Defer
109+
):
110+
coalesce_integrity(storage_test_vm, vdi_on_xfs_sr, vdi_op, defer)
109111

110112
@pytest.mark.small_vm
111113
@pytest.mark.parametrize("compression", ["none", "gzip", "zstd"])
112114
def test_xva_export_import(self, vm_on_xfs_sr: VM, compression: XVACompression, defer: Defer):
113115
xva_export_import(vm_on_xfs_sr, compression, defer)
114116

115117
@pytest.mark.small_vm
116-
def test_vdi_export_import(self, storage_test_vm: VM, xfs_sr: SR, image_format: ImageFormat):
117-
vdi_export_import(storage_test_vm, xfs_sr, image_format)
118+
def test_vdi_export_import(
119+
self, storage_test_vm: VM, xfs_sr: SR, image_format: ImageFormat, defer: Defer
120+
):
121+
vdi_export_import(storage_test_vm, xfs_sr, image_format, defer)
118122

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

tests/storage/zfs/test_zfs_sr.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,17 @@ def test_snapshot(self, vm_on_zfs_sr):
106106

107107
@pytest.mark.small_vm
108108
@pytest.mark.parametrize("vdi_op", ["snapshot", "clone"])
109-
def test_coalesce(self, storage_test_vm: VM, vdi_on_zfs_sr: VDI, vdi_op: CoalesceOperation):
110-
coalesce_integrity(storage_test_vm, vdi_on_zfs_sr, vdi_op)
109+
def test_coalesce(self, storage_test_vm: VM, vdi_on_zfs_sr: VDI, vdi_op: CoalesceOperation, defer: Defer):
110+
coalesce_integrity(storage_test_vm, vdi_on_zfs_sr, vdi_op, defer)
111111

112112
@pytest.mark.small_vm
113113
@pytest.mark.parametrize("compression", ["none", "gzip", "zstd"])
114114
def test_xva_export_import(self, vm_on_zfs_sr: VM, compression: XVACompression, defer: Defer):
115115
xva_export_import(vm_on_zfs_sr, compression, defer)
116116

117117
@pytest.mark.small_vm
118-
def test_vdi_export_import(self, storage_test_vm: VM, zfs_sr: SR, image_format: ImageFormat):
119-
vdi_export_import(storage_test_vm, zfs_sr, image_format)
118+
def test_vdi_export_import(self, storage_test_vm: VM, zfs_sr: SR, image_format: ImageFormat, defer: Defer):
119+
vdi_export_import(storage_test_vm, zfs_sr, image_format, defer)
120120

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

tests/storage/zfsvol/test_zfsvol_sr.py

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -64,47 +64,54 @@ def test_snapshot(self, vm_on_zfsvol_sr):
6464
@pytest.mark.small_vm
6565
@pytest.mark.parametrize("vdi_op", ["snapshot"]) # "clone" requires a snapshot
6666
@pytest.mark.skip("zfsvol doesn't provide vhd-parent")
67-
def test_coalesce(self, storage_test_vm: VM, vdi_on_zfsvol_sr: VDI, vdi_op: CoalesceOperation):
68-
coalesce_integrity(storage_test_vm, vdi_on_zfsvol_sr, vdi_op)
67+
def test_coalesce(self, storage_test_vm: VM, vdi_on_zfsvol_sr: VDI, vdi_op: CoalesceOperation, defer: Defer):
68+
coalesce_integrity(storage_test_vm, vdi_on_zfsvol_sr, vdi_op, defer)
6969

7070
@pytest.mark.small_vm
7171
@pytest.mark.parametrize("compression", ["none", "gzip", "zstd"])
7272
def test_xva_export_import(self, vm_on_zfsvol_sr: VM, compression: XVACompression, defer: Defer):
7373
xva_export_import(vm_on_zfsvol_sr, compression, defer)
7474

7575
@pytest.mark.small_vm
76-
def test_vdi_export_import(self, storage_test_vm: VM, zfsvol_sr: SR, image_format: ImageFormat):
76+
def test_vdi_export_import(self, storage_test_vm: VM, zfsvol_sr: SR, image_format: ImageFormat, defer: Defer):
7777
vm = storage_test_vm
7878
sr = zfsvol_sr
79-
vdi = sr.create_vdi(image_format=image_format)
80-
image_path = f'/tmp/{vdi.uuid}.{image_format}'
81-
try:
82-
vbd = vm.connect_vdi(vdi)
83-
dev = f'/dev/{vbd.param_get("device")}'
84-
# generate 2 blocks of data of 200MiB, at position 0 and at position 500MiB
85-
vm.ssh(f"randstream generate -v --size 200MiB {dev}")
86-
vm.ssh(f"randstream generate -v --seed 1 --position 500MiB --size 200MiB {dev}")
87-
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
88-
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")
89-
vm.disconnect_vdi(vdi)
90-
vm.host.xe('vdi-export', {'uuid': vdi.uuid, 'filename': image_path, 'format': image_format})
91-
vdi = vdi.destroy()
92-
# check that the zero blocks are not part of the result
93-
size_mb = int(vm.host.ssh(f'du -sm --apparent-size {image_path}').split()[0])
94-
if image_format == 'vhd':
95-
logging.warning(f"FIXME: this is broken with vhd, skip for now (XCPNG-2631). File size is {size_mb}MB")
96-
else:
97-
assert 400 < size_mb < 410, f"unexpected image size: {size_mb}"
98-
vdi = sr.create_vdi(image_format=image_format)
99-
vm.host.xe('vdi-import', {'uuid': vdi.uuid, 'filename': image_path, 'format': image_format})
100-
vm.connect_vdi(vdi, 'xvdb')
101-
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
102-
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")
103-
finally:
104-
if vdi is not None:
105-
vm.disconnect_vdi(vdi)
106-
vdi.destroy()
107-
vm.host.ssh(f'rm -f {image_path}')
79+
vdi_src = sr.create_vdi(image_format=image_format)
80+
defer(lambda: vdi_src.destroy() if vdi_src is not None else None)
81+
82+
vbd = vm.connect_vdi(vdi_src)
83+
defer(lambda: vm.disconnect_vdi(vdi_src) if vdi_src is not None else None)
84+
dev = f'/dev/{vbd.param_get("device")}'
85+
86+
# generate 2 blocks of data of 200MiB, at position 0 and at position 500MiB
87+
vm.ssh(f"randstream generate -v --size 200MiB {dev}")
88+
# use a different seed to not write the same data (default seed is 0)
89+
vm.ssh(f"randstream generate -v --seed 1 --position 500MiB --size 200MiB {dev}")
90+
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
91+
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")
92+
vm.disconnect_vdi(vdi_src)
93+
94+
image_path = f'/tmp/{vdi_src.uuid}.{image_format}'
95+
defer(lambda: vm.host.ssh(f'rm -f {image_path}'))
96+
97+
vm.host.xe('vdi-export', {'uuid': vdi_src.uuid, 'filename': image_path, 'format': image_format})
98+
vdi_src = vdi_src.destroy()
99+
100+
# check that the zero blocks are not part of the result
101+
size_mb = int(vm.host.ssh(f'du -sm --apparent-size {image_path}').split()[0])
102+
if image_format == 'vhd':
103+
logging.warning(f"FIXME: this is broken with vhd, skip for now (XCPNG-2631). File size is {size_mb}MB")
104+
else:
105+
assert 400 < size_mb < 410, f"unexpected image size: {size_mb}"
106+
vdi_dest = sr.create_vdi(image_format=image_format)
107+
defer(lambda: vdi_dest.destroy())
108+
109+
vm.host.xe('vdi-import', {'uuid': vdi_dest.uuid, 'filename': image_path, 'format': image_format})
110+
vm.connect_vdi(vdi_dest, 'xvdb')
111+
defer(lambda: vm.disconnect_vdi(vdi_dest))
112+
113+
vm.ssh(f"randstream validate -v --size 200MiB --expected-checksum c6310c52 {dev}")
114+
vm.ssh(f"randstream validate -v --position 500MiB --size 200MiB --expected-checksum 1cb4218e {dev}")
108115

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

0 commit comments

Comments
 (0)