* Silence warnings from the undefined-behaviour sanitizer
* Many small improvements to various functional tests * Remove remainders from storing avocado artifacts in the Gitlab CI * Keep more meson log files as artifacts in the Gitlab CI instead * Re-enable -fzero-call-used-regs on OpenBSD -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmjAMK4RHHRodXRoQHJl ZGhhdC5jb20ACgkQLtnXdP5wLbX4ohAAl3AomPjCeCUEbwJqD0I8eSUeKKDNGbbI pwyEjg+e1nptqT7RVeS2EMKUAGT5dasZqjoMRMNS+PywCzDjkKPIjAZdatPMKMx2 YK56qVaMcUKSDdpb/P091Bn8LLBX8kx8J0TpiRCvGH5KsflamMW7sVrAdn9X2lrM yTFN65asbbgfRWDW8qzXxX7JHdQZ1xwJiWSiJicTHzLRSoA4Ud6ymQxJyESgDUGs 44j1ieCrA7itbcUSIzYmEbcw0BgjaXSOUMXkUyZZ4GtQA7q5IVi+6iJm/3lbKEvA Wu3zPk1FeK6iyVGSn/fcaQfGEjTUI7zbOLN0Ub1ob9N3jO5z7EdUe7DjY2BF6L8y 4KYjWOcCWYL5BGNdi6ilaIk8l5sB1Vw/wIONdgqtcBJs0syiSzGqLmVttHIQlmI3 4tADDnINAUYi7T7q2/0F9VZB89TY7W7zAYrypTMzTIbGwEHgBj+4kq5DsplTfkg4 LG+Vplv04NAmdgPndCj/AQ9y9ZtFjmZwuF0drLOSXFGzzfTv0g5YT3HQBbQ3gHsM tjeU5RSwHjr3OfvNWE1U/CIbu0Qa3CJcnco8JP5NIGCw8I0lHOnqsVq/1EC6PnGM 3QYvSd/z4jMO+5pXlMUQ52Lc7IRVTL8SVJf723gPV9TcV/EwLYtlv2s41GVqPwLM e+KxAirDD9c= =fJQL -----END PGP SIGNATURE----- Merge tag 'pull-request-2025-09-09' of https://gitlab.com/thuth/qemu into staging * Silence warnings from the undefined-behaviour sanitizer * Many small improvements to various functional tests * Remove remainders from storing avocado artifacts in the Gitlab CI * Keep more meson log files as artifacts in the Gitlab CI instead * Re-enable -fzero-call-used-regs on OpenBSD # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCgAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmjAMK4RHHRodXRoQHJl # ZGhhdC5jb20ACgkQLtnXdP5wLbX4ohAAl3AomPjCeCUEbwJqD0I8eSUeKKDNGbbI # pwyEjg+e1nptqT7RVeS2EMKUAGT5dasZqjoMRMNS+PywCzDjkKPIjAZdatPMKMx2 # YK56qVaMcUKSDdpb/P091Bn8LLBX8kx8J0TpiRCvGH5KsflamMW7sVrAdn9X2lrM # yTFN65asbbgfRWDW8qzXxX7JHdQZ1xwJiWSiJicTHzLRSoA4Ud6ymQxJyESgDUGs # 44j1ieCrA7itbcUSIzYmEbcw0BgjaXSOUMXkUyZZ4GtQA7q5IVi+6iJm/3lbKEvA # Wu3zPk1FeK6iyVGSn/fcaQfGEjTUI7zbOLN0Ub1ob9N3jO5z7EdUe7DjY2BF6L8y # 4KYjWOcCWYL5BGNdi6ilaIk8l5sB1Vw/wIONdgqtcBJs0syiSzGqLmVttHIQlmI3 # 4tADDnINAUYi7T7q2/0F9VZB89TY7W7zAYrypTMzTIbGwEHgBj+4kq5DsplTfkg4 # LG+Vplv04NAmdgPndCj/AQ9y9ZtFjmZwuF0drLOSXFGzzfTv0g5YT3HQBbQ3gHsM # tjeU5RSwHjr3OfvNWE1U/CIbu0Qa3CJcnco8JP5NIGCw8I0lHOnqsVq/1EC6PnGM # 3QYvSd/z4jMO+5pXlMUQ52Lc7IRVTL8SVJf723gPV9TcV/EwLYtlv2s41GVqPwLM # e+KxAirDD9c= # =fJQL # -----END PGP SIGNATURE----- # gpg: Signature made Tue 09 Sep 2025 14:50:38 BST # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "thuth@redhat.com" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [undefined] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * tag 'pull-request-2025-09-09' of https://gitlab.com/thuth/qemu: (23 commits) tests/functional: purge scratch dir on test startup tests/functional: avoid tearDown failure when QEMU dies tests/functional: avoid duplicate messages on failures tests/functional: fix infinite loop on console EOF tests/functional: add vm param to cmd.py helpers tests/functional: return output from cmd.py helpers gitlab: prevent duplicated meson log artifacts in test jobs gitlab: include all junit XML files from meson gitlab: always include entire of meson-logs directory gitlab: replace avocado results files with meson results files tests/functional/arm: Update test ASPEED SDK v09.07 for AST2700 vbootrom tests/functional/arm: Update test ASPEED SDK v09.07 for AST2600 tests/functional/arm: Update test ASPEED SDK v09.07 for AST2500 tests/functional/arm: Update test ASPEED SDK v03.02 for AST1030 tests/functional: handle URLError when fetching assets tests/functional: fix formatting of exception args tests/functional: enable force refresh of cached assets tests/functional/m68k: Avoid ResourceWarning in the nextcube test ui/vnc: Fix crash when specifying [vnc] without id in the config file system/physmem: Silence warning from ubsan ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
190d5d7fd7
20 changed files with 137 additions and 64 deletions
|
|
@ -83,14 +83,18 @@
|
|||
|
||||
.native_test_job_template:
|
||||
extends: .common_test_job_template
|
||||
before_script:
|
||||
# Prevent logs from the build job that run earlier
|
||||
# from being duplicated in the test job artifacts
|
||||
- rm -f build/meson-logs/*
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- build/meson-logs/testlog.txt
|
||||
- build/meson-logs
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
junit: build/meson-logs/*.junit.xml
|
||||
|
||||
.functional_test_job_template:
|
||||
extends: .common_test_job_template
|
||||
|
|
@ -104,14 +108,16 @@
|
|||
when: always
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- build/tests/results/latest/results.xml
|
||||
- build/tests/results/latest/test-results
|
||||
- build/meson-logs
|
||||
- build/tests/functional/*/*/*.log
|
||||
reports:
|
||||
junit: build/tests/results/latest/results.xml
|
||||
junit: build/meson-logs/*.junit.xml
|
||||
before_script:
|
||||
- export QEMU_TEST_ALLOW_UNTRUSTED_CODE=1
|
||||
- export QEMU_TEST_CACHE_DIR=${CI_PROJECT_DIR}/functional-cache
|
||||
# Prevent logs from the build job that run earlier
|
||||
# from being duplicated in the test job artifacts
|
||||
- rm -f build/meson-logs/*
|
||||
after_script:
|
||||
- cd build
|
||||
- du -chs ${CI_PROJECT_DIR}/*-cache
|
||||
|
|
|
|||
|
|
@ -613,9 +613,9 @@ gcov:
|
|||
when: always
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- build/meson-logs/testlog.txt
|
||||
- build/meson-logs
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
junit: build/meson-logs/*.junit.xml
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
path: build/coverage.xml
|
||||
|
|
|
|||
|
|
@ -128,6 +128,6 @@
|
|||
when: always
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- build/meson-logs/testlog.txt
|
||||
- build/meson-logs
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
junit: build/meson-logs/*.junit.xml
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
- build/build.ninja
|
||||
- build/meson-logs
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
junit: build/meson-logs/*.junit.xml
|
||||
|
||||
include:
|
||||
- local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-s390x.yml'
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ msys2-64bit:
|
|||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- build/meson-logs/testlog.txt
|
||||
- build/meson-logs
|
||||
reports:
|
||||
junit: "build/meson-logs/testlog.junit.xml"
|
||||
junit: build/meson-logs/*.junit.xml
|
||||
before_script:
|
||||
- Write-Output "Acquiring msys2.exe installer at $(Get-Date -Format u)"
|
||||
- If ( !(Test-Path -Path msys64\var\cache ) ) {
|
||||
|
|
|
|||
|
|
@ -312,6 +312,9 @@ The cache is populated in the ``~/.cache/qemu/download`` directory by
|
|||
default, but the location can be changed by setting the
|
||||
``QEMU_TEST_CACHE_DIR`` environment variable.
|
||||
|
||||
To force the test suite to re-download the cache, even if still valid,
|
||||
set the ``QEMU_TEST_REFRESH_CACHE`` environment variable.
|
||||
|
||||
Skipping tests
|
||||
--------------
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "hw/display/bcm2835_fb.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/irq.h"
|
||||
#include "ui/console.h"
|
||||
#include "framebuffer.h"
|
||||
#include "ui/pixel_ops.h"
|
||||
#include "hw/misc/bcm2835_mbox_defs.h"
|
||||
|
|
|
|||
|
|
@ -1191,7 +1191,7 @@ void mips_malta_init(MachineState *machine)
|
|||
* In little endian mode the 32bit words in the bios are swapped,
|
||||
* a neat trick which allows bi-endian firmware.
|
||||
*/
|
||||
if (!TARGET_BIG_ENDIAN) {
|
||||
if (!TARGET_BIG_ENDIAN && bios_size > 0) {
|
||||
uint32_t *end, *addr;
|
||||
const size_t swapsize = MIN(bios_size, 0x3e0000);
|
||||
addr = rom_ptr(FLASH_ADDRESS, swapsize);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#define BCM2835_FB_H
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
#include "ui/console.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define UPPER_RAM_BASE 0x40000000
|
||||
|
|
|
|||
|
|
@ -709,11 +709,7 @@ hardening_flags = [
|
|||
#
|
||||
# NB: Clang 17 is broken and SEGVs
|
||||
# https://github.com/llvm/llvm-project/issues/75168
|
||||
#
|
||||
# NB2: This clashes with the "retguard" extension of OpenBSD's Clang
|
||||
# https://gitlab.com/qemu-project/qemu/-/issues/2278
|
||||
if host_os != 'openbsd' and \
|
||||
cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
|
||||
if cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
|
||||
name: '-fzero-call-used-regs=used-gpr',
|
||||
args: ['-O2', '-fzero-call-used-regs=used-gpr'])
|
||||
hardening_flags += '-fzero-call-used-regs=used-gpr'
|
||||
|
|
|
|||
|
|
@ -3231,8 +3231,10 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as,
|
|||
}
|
||||
}
|
||||
len -= l;
|
||||
buf += l;
|
||||
addr += l;
|
||||
if (buf) {
|
||||
buf += l;
|
||||
}
|
||||
}
|
||||
return MEMTX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ class AST2x00MachineSDK(QemuSystemTest):
|
|||
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-default-obmc.tar.gz',
|
||||
'f1d53e0be8a404ecce3e105f72bc50fa4e090ad13160ffa91b10a6e0233a9dc6')
|
||||
|
||||
ASSET_SDK_V907_AST2700A1_VBOOROM = Asset(
|
||||
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.07/ast2700-default-obmc.tar.gz',
|
||||
'6e9e0c4b13e0f26040eca3f4a7f17cf09fc0f5c37c820500ff79370cc3c44add')
|
||||
|
||||
def do_ast2700_i2c_test(self):
|
||||
exec_command_and_wait_for_pattern(self,
|
||||
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
|
||||
|
|
@ -127,10 +131,10 @@ class AST2x00MachineSDK(QemuSystemTest):
|
|||
self.verify_openbmc_boot_and_login('ast2700-default')
|
||||
self.do_ast2700_i2c_test()
|
||||
|
||||
def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_06(self):
|
||||
def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_07(self):
|
||||
self.set_machine('ast2700a1-evb')
|
||||
|
||||
self.archive_extract(self.ASSET_SDK_V906_AST2700A1)
|
||||
self.archive_extract(self.ASSET_SDK_V907_AST2700A1_VBOOROM)
|
||||
self.start_ast2700_test_vbootrom('ast2700-default')
|
||||
self.verify_vbootrom_firmware_flow()
|
||||
self.verify_openbmc_boot_and_login('ast2700-default')
|
||||
|
|
|
|||
|
|
@ -12,17 +12,17 @@ from qemu_test import exec_command_and_wait_for_pattern
|
|||
|
||||
class AST1030Machine(LinuxKernelTest):
|
||||
|
||||
ASSET_ZEPHYR_3_00 = Asset(
|
||||
ASSET_ZEPHYR_3_02 = Asset(
|
||||
('https://github.com/AspeedTech-BMC'
|
||||
'/zephyr/releases/download/v00.03.00/ast1030-evb-demo.zip'),
|
||||
'37fe3ecd4a1b9d620971a15b96492a81093435396eeac69b6f3e384262ff555f')
|
||||
'/zephyr/releases/download/v00.03.02/ast1030-evb-demo.zip'),
|
||||
'1ec83caab3ddd5d09481772801be7210e222cb015ce22ec6fffb8a76956dcd4f')
|
||||
|
||||
def test_ast1030_zephyros_3_00(self):
|
||||
def test_ast1030_zephyros_3_02(self):
|
||||
self.set_machine('ast1030-evb')
|
||||
|
||||
kernel_name = "ast1030-evb-demo/zephyr.elf"
|
||||
kernel_name = "ast1030-evb-demo-3/zephyr.elf"
|
||||
kernel_file = self.archive_extract(
|
||||
self.ASSET_ZEPHYR_3_00, member=kernel_name)
|
||||
self.ASSET_ZEPHYR_3_02, member=kernel_name)
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_file, '-nographic')
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ class AST2500Machine(AspeedTest):
|
|||
|
||||
self.do_test_arm_aspeed_buildroot_poweroff()
|
||||
|
||||
ASSET_SDK_V906_AST2500 = Asset(
|
||||
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2500-default-obmc.tar.gz',
|
||||
'542db84645b4efd8aed50385d7f4dd1caff379a987032311cfa7b563a3addb2a')
|
||||
ASSET_SDK_V907_AST2500 = Asset(
|
||||
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.07/ast2500-default-obmc.tar.gz',
|
||||
'd52bcc279a37c8d7679b3e4ef22cc77c36f0f6624c687b37334f798828afb077')
|
||||
|
||||
def test_arm_ast2500_evb_sdk(self):
|
||||
self.set_machine('ast2500-evb')
|
||||
|
||||
self.archive_extract(self.ASSET_SDK_V906_AST2500)
|
||||
self.archive_extract(self.ASSET_SDK_V907_AST2500)
|
||||
|
||||
self.do_test_arm_aspeed_sdk_start(
|
||||
self.scratch_file("ast2500-default", "image-bmc"))
|
||||
|
|
|
|||
|
|
@ -97,14 +97,14 @@ class AST2600Machine(AspeedTest):
|
|||
|
||||
self.do_test_arm_aspeed_buildroot_poweroff()
|
||||
|
||||
ASSET_SDK_V906_AST2600 = Asset(
|
||||
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2600-default-obmc.tar.gz',
|
||||
'768d76e247896ad78c154b9cff4f766da2ce65f217d620b286a4a03a8a4f68f5')
|
||||
ASSET_SDK_V907_AST2600 = Asset(
|
||||
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.07/ast2600-default-obmc.tar.gz',
|
||||
'cb6c08595bcbba1672ce716b068ba4e48eda1ed9abe78a07b30392ba2278feba')
|
||||
|
||||
def test_arm_ast2600_evb_sdk(self):
|
||||
self.set_machine('ast2600-evb')
|
||||
|
||||
self.archive_extract(self.ASSET_SDK_V906_AST2600)
|
||||
self.archive_extract(self.ASSET_SDK_V907_AST2600)
|
||||
|
||||
self.vm.add_args('-device',
|
||||
'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test')
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ class NextCubeMachine(QemuSystemTest):
|
|||
self.check_bootrom_framebuffer(screenshot_path)
|
||||
|
||||
from PIL import Image
|
||||
width, height = Image.open(screenshot_path).size
|
||||
with Image.open(screenshot_path) as image:
|
||||
width, height = image.size
|
||||
self.assertEqual(width, 1120)
|
||||
self.assertEqual(height, 832)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import urllib.request
|
|||
from time import sleep
|
||||
from pathlib import Path
|
||||
from shutil import copyfileobj
|
||||
from urllib.error import HTTPError
|
||||
from urllib.error import HTTPError, URLError
|
||||
|
||||
class AssetError(Exception):
|
||||
def __init__(self, asset, msg, transient=False):
|
||||
|
|
@ -72,6 +72,10 @@ class Asset:
|
|||
return self.hash == hl.hexdigest()
|
||||
|
||||
def valid(self):
|
||||
if os.getenv("QEMU_TEST_REFRESH_CACHE", None) is not None:
|
||||
self.log.info("Force refresh of asset %s", self.url)
|
||||
return False
|
||||
|
||||
return self.cache_file.exists() and self._check(self.cache_file)
|
||||
|
||||
def fetchable(self):
|
||||
|
|
@ -167,9 +171,17 @@ class Asset:
|
|||
raise AssetError(self, "Unable to download: "
|
||||
"HTTP error %d" % e.code)
|
||||
continue
|
||||
except URLError as e:
|
||||
# This is typically a network/service level error
|
||||
# eg urlopen error [Errno 110] Connection timed out>
|
||||
tmp_cache_file.unlink()
|
||||
self.log.error("Unable to download %s: URL error %s",
|
||||
self.url, e.reason)
|
||||
raise AssetError(self, "Unable to download: URL error %s" %
|
||||
e.reason, transient=True)
|
||||
except Exception as e:
|
||||
tmp_cache_file.unlink()
|
||||
raise AssetError(self, "Unable to download: " % e)
|
||||
raise AssetError(self, "Unable to download: %s" % e)
|
||||
|
||||
if not os.path.exists(tmp_cache_file):
|
||||
raise AssetError(self, "Download retries exceeded", transient=True)
|
||||
|
|
|
|||
|
|
@ -45,13 +45,16 @@ def is_readable_executable_file(path):
|
|||
# If end of line is seen, with neither @success or @failure
|
||||
# return False
|
||||
#
|
||||
# In both cases, also return the contents of the line (in bytes)
|
||||
# up to that point.
|
||||
#
|
||||
# If @failure is seen, then mark @test as failed
|
||||
def _console_read_line_until_match(test, vm, success, failure):
|
||||
msg = bytes([])
|
||||
done = False
|
||||
while True:
|
||||
c = vm.console_socket.recv(1)
|
||||
if c is None:
|
||||
if not c:
|
||||
done = True
|
||||
test.fail(
|
||||
f"EOF in console, expected '{success}'")
|
||||
|
|
@ -76,10 +79,23 @@ def _console_read_line_until_match(test, vm, success, failure):
|
|||
except:
|
||||
console_logger.debug(msg)
|
||||
|
||||
return done
|
||||
return done, msg
|
||||
|
||||
def _console_interaction(test, success_message, failure_message,
|
||||
send_string, keep_sending=False, vm=None):
|
||||
"""
|
||||
Interact with the console until either message is seen.
|
||||
|
||||
:param success_message: if this message appears, finish interaction
|
||||
:param failure_message: if this message appears, test fails
|
||||
:param send_string: a string to send to the console before trying
|
||||
to read a new line
|
||||
:param keep_sending: keep sending the send string each time
|
||||
:param vm: the VM to interact with
|
||||
|
||||
:return: The collected output (in bytes form).
|
||||
"""
|
||||
|
||||
assert not keep_sending or send_string
|
||||
assert success_message or send_string
|
||||
|
||||
|
|
@ -101,6 +117,8 @@ def _console_interaction(test, success_message, failure_message,
|
|||
if failure_message is not None:
|
||||
failure_message_b = failure_message.encode()
|
||||
|
||||
out = bytes([])
|
||||
|
||||
while True:
|
||||
if send_string:
|
||||
vm.console_socket.sendall(send_string.encode())
|
||||
|
|
@ -113,14 +131,21 @@ def _console_interaction(test, success_message, failure_message,
|
|||
break
|
||||
continue
|
||||
|
||||
if _console_read_line_until_match(test, vm,
|
||||
success_message_b,
|
||||
failure_message_b):
|
||||
done, line = _console_read_line_until_match(test, vm,
|
||||
success_message_b,
|
||||
failure_message_b)
|
||||
|
||||
out += line
|
||||
|
||||
if done:
|
||||
break
|
||||
|
||||
return out
|
||||
|
||||
def interrupt_interactive_console_until_pattern(test, success_message,
|
||||
failure_message=None,
|
||||
interrupt_string='\r'):
|
||||
interrupt_string='\r',
|
||||
vm=None):
|
||||
"""
|
||||
Keep sending a string to interrupt a console prompt, while logging the
|
||||
console output. Typical use case is to break a boot loader prompt, such:
|
||||
|
|
@ -140,10 +165,13 @@ def interrupt_interactive_console_until_pattern(test, success_message,
|
|||
:param failure_message: if this message appears, test fails
|
||||
:param interrupt_string: a string to send to the console before trying
|
||||
to read a new line
|
||||
:param vm: VM to use
|
||||
|
||||
:return: The collected output (in bytes form).
|
||||
"""
|
||||
assert success_message
|
||||
_console_interaction(test, success_message, failure_message,
|
||||
interrupt_string, True)
|
||||
return _console_interaction(test, success_message, failure_message,
|
||||
interrupt_string, True, vm=vm)
|
||||
|
||||
def wait_for_console_pattern(test, success_message, failure_message=None,
|
||||
vm=None):
|
||||
|
|
@ -155,11 +183,15 @@ def wait_for_console_pattern(test, success_message, failure_message=None,
|
|||
:type test: :class:`qemu_test.QemuSystemTest`
|
||||
:param success_message: if this message appears, test succeeds
|
||||
:param failure_message: if this message appears, test fails
|
||||
:param vm: VM to use
|
||||
|
||||
:return: The collected output (in bytes form).
|
||||
"""
|
||||
assert success_message
|
||||
_console_interaction(test, success_message, failure_message, None, vm=vm)
|
||||
return _console_interaction(test, success_message, failure_message,
|
||||
None, vm=vm)
|
||||
|
||||
def exec_command(test, command):
|
||||
def exec_command(test, command, vm=None):
|
||||
"""
|
||||
Send a command to a console (appending CRLF characters), while logging
|
||||
the content.
|
||||
|
|
@ -167,12 +199,16 @@ def exec_command(test, command):
|
|||
:param test: a test containing a VM.
|
||||
:type test: :class:`qemu_test.QemuSystemTest`
|
||||
:param command: the command to send
|
||||
:param vm: VM to use
|
||||
:type command: str
|
||||
|
||||
:return: The collected output (in bytes form).
|
||||
"""
|
||||
_console_interaction(test, None, None, command + '\r')
|
||||
return _console_interaction(test, None, None, command + '\r', vm=vm)
|
||||
|
||||
def exec_command_and_wait_for_pattern(test, command,
|
||||
success_message, failure_message=None):
|
||||
success_message, failure_message=None,
|
||||
vm=None):
|
||||
"""
|
||||
Send a command to a console (appending CRLF characters), then wait
|
||||
for success_message to appear on the console, while logging the.
|
||||
|
|
@ -184,9 +220,14 @@ def exec_command_and_wait_for_pattern(test, command,
|
|||
:param command: the command to send
|
||||
:param success_message: if this message appears, test succeeds
|
||||
:param failure_message: if this message appears, test fails
|
||||
:param vm: VM to use
|
||||
|
||||
:return: The collected output (in bytes form).
|
||||
"""
|
||||
assert success_message
|
||||
_console_interaction(test, success_message, failure_message, command + '\r')
|
||||
|
||||
return _console_interaction(test, success_message, failure_message,
|
||||
command + '\r', vm=vm)
|
||||
|
||||
def get_qemu_img(test):
|
||||
test.log.debug('Looking for and selecting a qemu-img binary')
|
||||
|
|
|
|||
|
|
@ -205,6 +205,10 @@ class QemuBaseTest(unittest.TestCase):
|
|||
self.outputdir = self.build_file('tests', 'functional',
|
||||
self.arch, self.id())
|
||||
self.workdir = os.path.join(self.outputdir, 'scratch')
|
||||
if os.path.exists(self.workdir):
|
||||
# Purge as safety net in case of unclean termination of
|
||||
# previous test, or use of QEMU_TEST_KEEP_SCRATCH
|
||||
shutil.rmtree(self.workdir)
|
||||
os.makedirs(self.workdir, exist_ok=True)
|
||||
|
||||
self.log_filename = self.log_file('base.log')
|
||||
|
|
@ -251,13 +255,14 @@ class QemuBaseTest(unittest.TestCase):
|
|||
test_output_log = pycotap.LogMode.LogToError)
|
||||
res = unittest.main(module = None, testRunner = tr, exit = False,
|
||||
argv=[sys.argv[0], path] + sys.argv[1:])
|
||||
failed = {}
|
||||
for (test, message) in res.result.errors + res.result.failures:
|
||||
|
||||
if hasattr(test, "log_filename"):
|
||||
if hasattr(test, "log_filename") and not test.id() in failed:
|
||||
print('More information on ' + test.id() + ' could be found here:'
|
||||
'\n %s' % test.log_filename, file=sys.stderr)
|
||||
if hasattr(test, 'console_log_name'):
|
||||
print(' %s' % test.console_log_name, file=sys.stderr)
|
||||
failed[test.id()] = True
|
||||
sys.exit(not res.result.wasSuccessful())
|
||||
|
||||
|
||||
|
|
@ -403,7 +408,10 @@ class QemuSystemTest(QemuBaseTest):
|
|||
|
||||
def tearDown(self):
|
||||
for vm in self._vms.values():
|
||||
vm.shutdown()
|
||||
try:
|
||||
vm.shutdown()
|
||||
except Exception as ex:
|
||||
self.log.error("Failed to teardown VM: %s" % ex)
|
||||
logging.getLogger('console').removeHandler(self._console_log_fh)
|
||||
self._console_log_fh.close()
|
||||
super().tearDown()
|
||||
|
|
|
|||
18
ui/vnc.c
18
ui/vnc.c
|
|
@ -4309,8 +4309,9 @@ void vnc_display_add_client(const char *id, int csock, bool skipauth)
|
|||
}
|
||||
}
|
||||
|
||||
static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
|
||||
static char *vnc_auto_assign_id(QemuOpts *opts)
|
||||
{
|
||||
QemuOptsList *olist = qemu_find_opts("vnc");
|
||||
int i = 2;
|
||||
char *id;
|
||||
|
||||
|
|
@ -4320,23 +4321,18 @@ static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
|
|||
id = g_strdup_printf("vnc%d", i++);
|
||||
}
|
||||
qemu_opts_set_id(opts, id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void vnc_parse(const char *str)
|
||||
{
|
||||
QemuOptsList *olist = qemu_find_opts("vnc");
|
||||
QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str));
|
||||
const char *id;
|
||||
|
||||
if (!opts) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
id = qemu_opts_id(opts);
|
||||
if (!id) {
|
||||
/* auto-assign id if not present */
|
||||
vnc_auto_assign_id(olist, opts);
|
||||
}
|
||||
}
|
||||
|
||||
int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
||||
|
|
@ -4344,7 +4340,11 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
|||
Error *local_err = NULL;
|
||||
char *id = (char *)qemu_opts_id(opts);
|
||||
|
||||
assert(id);
|
||||
if (!id) {
|
||||
/* auto-assign id if not present */
|
||||
id = vnc_auto_assign_id(opts);
|
||||
}
|
||||
|
||||
vnc_display_init(id, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue