test/assembler: fix nbd race

The nbd device might not be ready after `qemu-nbd --connect` returns,
leading to access errors such as this further down:

    sfdisk: cannot open /dev/nbd12: Inappropriate ioctl for device

Fix this by polling the device with `nbd-client --check <device>`.

Also, the nbd device might not be released after `qemu-nbd --disconnect`
returns. Fix this by using `nbd-client --disconnect`, which waits.

This introduces a new test dependency on nbd-client (in the ndb package
on Fedora).
This commit is contained in:
Lars Karlitski 2019-12-18 09:49:24 +01:00
parent 5b77048e97
commit 59bdca86ac
2 changed files with 10 additions and 1 deletions

View file

@ -27,7 +27,7 @@ jobs:
before_install: sudo apt-get install -y systemd-container yum qemu-kvm
script: sudo env "PATH=$PATH" "OSBUILD_TEST_BUILD_ENV=samples/f27-build-from-ubuntu1804.json" python3 -m unittest -v test.test_boot
- name: assemblers
before_install: sudo apt-get install -y systemd-container yum tar qemu-utils
before_install: sudo apt-get install -y systemd-container yum tar qemu-utils nbd-client
script: sudo env "PATH=$PATH" "OSBUILD_TEST_BUILD_ENV=samples/f27-build-from-ubuntu1804.json" python3 -m unittest -v test.test_assemblers
- name: stage-tests
before_install: sudo apt-get install -y systemd-container yum

View file

@ -7,6 +7,7 @@ import os
import subprocess
import tempfile
import uuid
import time
from . import osbuildtest
@ -135,9 +136,17 @@ def nbd_connect(image):
r = subprocess.run(["qemu-nbd", "--connect", device, "--read-only", image], check=False).returncode
if r == 0:
try:
# qemu-nbd doesn't wait for the device to be ready
for _ in range(100):
if subprocess.run(["nbd-client", "--check", device], check=False, stdout=subprocess.DEVNULL).returncode == 0:
break
time.sleep(0.2)
yield device
finally:
# qemu-nbd doesn't wait until the device is released. nbd-client does
subprocess.run(["qemu-nbd", "--disconnect", device], check=True, stdout=subprocess.DEVNULL)
subprocess.run(["nbd-client", "--disconnect", device], check=False, stdout=subprocess.DEVNULL)
break
else:
raise RuntimeError("no free network block device")