Skip to content

Commit b7719bc

Browse files
nirsebblake
authored andcommitted
iotests: Make qemu_nbd_popen() a contextmanager
Instead of duplicating the code to wait until the server is ready and remember to terminate the server and wait for it, make it possible to use like this: with qemu_nbd_popen('-k', sock, image): # Access image via qemu-nbd socket... Only test 264 used this helper, but I had to modify the output since it did not consistently when starting and stopping qemu-nbd. Signed-off-by: Nir Soffer <[email protected]> Message-Id: <[email protected]> Reviewed-by: Vladimir Sementsov-Ogievskiy <[email protected]> Signed-off-by: Eric Blake <[email protected]>
1 parent a2b333c commit b7719bc

File tree

3 files changed

+56
-50
lines changed

3 files changed

+56
-50
lines changed

tests/qemu-iotests/264

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -36,48 +36,32 @@ wait_step = 0.2
3636

3737
qemu_img_create('-f', iotests.imgfmt, disk_a, str(size))
3838
qemu_img_create('-f', iotests.imgfmt, disk_b, str(size))
39-
srv = qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b)
4039

41-
# Wait for NBD server availability
42-
t = 0
43-
ok = False
44-
while t < wait_limit:
45-
ok = qemu_io_silent_check('-f', 'raw', '-c', 'read 0 512', nbd_uri)
46-
if ok:
47-
break
48-
time.sleep(wait_step)
49-
t += wait_step
40+
with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b):
41+
vm = iotests.VM().add_drive(disk_a)
42+
vm.launch()
43+
vm.hmp_qemu_io('drive0', 'write 0 {}'.format(size))
44+
45+
vm.qmp_log('blockdev-add', filters=[iotests.filter_qmp_testfiles],
46+
**{'node_name': 'backup0',
47+
'driver': 'raw',
48+
'file': {'driver': 'nbd',
49+
'server': {'type': 'unix', 'path': nbd_sock},
50+
'reconnect-delay': 10}})
51+
vm.qmp_log('blockdev-backup', device='drive0', sync='full', target='backup0',
52+
speed=(1 * 1024 * 1024))
53+
54+
# Wait for some progress
55+
t = 0
56+
while t < wait_limit:
57+
jobs = vm.qmp('query-block-jobs')['return']
58+
if jobs and jobs[0]['offset'] > 0:
59+
break
60+
time.sleep(wait_step)
61+
t += wait_step
5062

51-
assert ok
52-
53-
vm = iotests.VM().add_drive(disk_a)
54-
vm.launch()
55-
vm.hmp_qemu_io('drive0', 'write 0 {}'.format(size))
56-
57-
vm.qmp_log('blockdev-add', filters=[iotests.filter_qmp_testfiles],
58-
**{'node_name': 'backup0',
59-
'driver': 'raw',
60-
'file': {'driver': 'nbd',
61-
'server': {'type': 'unix', 'path': nbd_sock},
62-
'reconnect-delay': 10}})
63-
vm.qmp_log('blockdev-backup', device='drive0', sync='full', target='backup0',
64-
speed=(1 * 1024 * 1024))
65-
66-
# Wait for some progress
67-
t = 0
68-
while t < wait_limit:
69-
jobs = vm.qmp('query-block-jobs')['return']
7063
if jobs and jobs[0]['offset'] > 0:
71-
break
72-
time.sleep(wait_step)
73-
t += wait_step
74-
75-
if jobs and jobs[0]['offset'] > 0:
76-
log('Backup job is started')
77-
78-
log('Kill NBD server')
79-
srv.kill()
80-
srv.wait()
64+
log('Backup job is started')
8165

8266
jobs = vm.qmp('query-block-jobs')['return']
8367
if jobs and jobs[0]['offset'] < jobs[0]['len']:
@@ -88,12 +72,8 @@ vm.qmp_log('block-job-set-speed', device='drive0', speed=0)
8872
# Emulate server down time for 1 second
8973
time.sleep(1)
9074

91-
log('Start NBD server')
92-
srv = qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b)
93-
94-
e = vm.event_wait('BLOCK_JOB_COMPLETED')
95-
log('Backup completed: {}'.format(e['data']['offset']))
96-
97-
vm.qmp_log('blockdev-del', node_name='backup0')
98-
srv.kill()
99-
vm.shutdown()
75+
with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b):
76+
e = vm.event_wait('BLOCK_JOB_COMPLETED')
77+
log('Backup completed: {}'.format(e['data']['offset']))
78+
vm.qmp_log('blockdev-del', node_name='backup0')
79+
vm.shutdown()

tests/qemu-iotests/264.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
Start NBD server
12
{"execute": "blockdev-add", "arguments": {"driver": "raw", "file": {"driver": "nbd", "reconnect-delay": 10, "server": {"path": "TEST_DIR/PID-nbd-sock", "type": "unix"}}, "node-name": "backup0"}}
23
{"return": {}}
34
{"execute": "blockdev-backup", "arguments": {"device": "drive0", "speed": 1048576, "sync": "full", "target": "backup0"}}
@@ -11,3 +12,4 @@ Start NBD server
1112
Backup completed: 5242880
1213
{"execute": "blockdev-del", "arguments": {"node-name": "backup0"}}
1314
{"return": {}}
15+
Kill NBD server

tests/qemu-iotests/iotests.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
import struct
2929
import subprocess
3030
import sys
31+
import time
3132
from typing import (Any, Callable, Dict, Iterable,
3233
List, Optional, Sequence, Tuple, TypeVar)
3334
import unittest
3435

36+
from contextlib import contextmanager
37+
3538
# pylint: disable=import-error, wrong-import-position
3639
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
3740
from qemu import qtest
@@ -270,9 +273,30 @@ def qemu_nbd_early_pipe(*args):
270273

271274
return subp.returncode, output if subp.returncode else ''
272275

276+
@contextmanager
273277
def qemu_nbd_popen(*args):
274-
'''Run qemu-nbd in daemon mode and return the parent's exit code'''
275-
return subprocess.Popen(qemu_nbd_args + ['--persistent'] + list(args))
278+
'''Context manager running qemu-nbd within the context'''
279+
pid_file = file_path("pid")
280+
281+
cmd = list(qemu_nbd_args)
282+
cmd.extend(('--persistent', '--pid-file', pid_file))
283+
cmd.extend(args)
284+
285+
log('Start NBD server')
286+
p = subprocess.Popen(cmd)
287+
try:
288+
while not os.path.exists(pid_file):
289+
if p.poll() is not None:
290+
raise RuntimeError(
291+
"qemu-nbd terminated with exit code {}: {}"
292+
.format(p.returncode, ' '.join(cmd)))
293+
294+
time.sleep(0.01)
295+
yield
296+
finally:
297+
log('Kill NBD server')
298+
p.kill()
299+
p.wait()
276300

277301
def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt):
278302
'''Return True if two image files are identical'''

0 commit comments

Comments
 (0)