* configure and meson fixes

* "meson test" switch for iotests
 * deprecation of old SGX QAPI
 * unexport InterruptStatsProviderClass-related functions
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmHzwdAUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroOlMwgApVO6T934TwuTOFBs02Tp8KcjcKQq
 5Qf5PrwbsluE8YixJERAFgfxgzbQKL/iHzkP97KoVo3CFFDc1sss7v3mrbbHxbwB
 jiYIgbNjRfBbZq7nNmxf2bcXxTpZYvMNEia0QPyNl1GQ0JS/RFOsEYcyVUPvVmAI
 djeESRyku1OS5bS5veqE2tL+AWDuodjHeW78qi+yIDRPx3jHLRzuGpQ/3KtgMN6o
 d61h5vVrqdxe1HYH/8sh+qU71w7drpNZVYq8PqkZyit/LXgDMyDDOks1XWarrrJE
 9xzNBUNR+B6CuHtNw1DGk4rvsCBV/F0ZVki6guVGoqG8njF3l6xyqRHPbw==
 =2/gW
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging

* configure and meson fixes
* "meson test" switch for iotests
* deprecation of old SGX QAPI
* unexport InterruptStatsProviderClass-related functions

# gpg: Signature made Fri 28 Jan 2022 10:13:36 GMT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini-gitlab/tags/for-upstream:
  configure: fix parameter expansion of --cross-cc-cflags options
  qapi: Cleanup SGX related comments and restore @section-size
  check-block: replace -makecheck with TAP output
  qemu-iotests: require at least an argument to check-block.sh
  build: make check-block a meson test
  scripts/mtest2make: add support for SPEED=thorough
  check-block.sh: passthrough -jN flag of make to -j N flag of check
  meson: Use find_program() to resolve the entitlement.sh script
  exec/cpu: Make host pages variables / macros 'target agnostic'
  meson.build: Use a function from libfdt 1.5.1 for the library check
  intc: Unexport InterruptStatsProviderClass-related functions
  docker: add msitools to Fedora/mingw cross
  build-sys: fix undefined ARCH error
  build-sys: fix a meson deprecation warning

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
staging
Peter Maydell 2022-01-28 14:04:01 +00:00
commit 7a1043cef9
25 changed files with 189 additions and 123 deletions

4
configure vendored
View File

@ -402,7 +402,7 @@ for opt do
;; ;;
--cross-cc-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --cross-cc-FOO option" --cross-cc-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --cross-cc-FOO option"
;; ;;
--cross-cc-cflags-*) cc_arch=${opt#--cross-cc-flags-}; cc_arch=${cc_arch%%=*} --cross-cc-cflags-*) cc_arch=${opt#--cross-cc-cflags-}; cc_arch=${cc_arch%%=*}
eval "cross_cc_cflags_${cc_arch}=\$optarg" eval "cross_cc_cflags_${cc_arch}=\$optarg"
cross_cc_vars="$cross_cc_vars cross_cc_cflags_${cc_arch}" cross_cc_vars="$cross_cc_vars cross_cc_cflags_${cc_arch}"
;; ;;
@ -1328,7 +1328,7 @@ Advanced options (experts only):
--extra-cxxflags=CXXFLAGS append extra C++ compiler flags CXXFLAGS --extra-cxxflags=CXXFLAGS append extra C++ compiler flags CXXFLAGS
--extra-ldflags=LDFLAGS append extra linker flags LDFLAGS --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS
--cross-cc-ARCH=CC use compiler when building ARCH guest test cases --cross-cc-ARCH=CC use compiler when building ARCH guest test cases
--cross-cc-flags-ARCH= use compiler flags when building ARCH guest tests --cross-cc-cflags-ARCH= use compiler flags when building ARCH guest tests
--make=MAKE use specified make [$make] --make=MAKE use specified make [$make]
--python=PYTHON use specified python [$python] --python=PYTHON use specified python [$python]
--sphinx-build=SPHINX use specified sphinx-build [$sphinx_build] --sphinx-build=SPHINX use specified sphinx-build [$sphinx_build]

View File

@ -264,6 +264,19 @@ accepted incorrect commands will return an error. Users should make sure that
all arguments passed to ``device_add`` are consistent with the documented all arguments passed to ``device_add`` are consistent with the documented
property types. property types.
``query-sgx`` return value member ``section-size`` (since 7.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Member ``section-size`` in return value elements with meta-type ``uint64`` is
deprecated. Use ``sections`` instead.
``query-sgx-capabilities`` return value member ``section-size`` (since 7.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Member ``section-size`` in return value elements with meta-type ``uint64`` is
deprecated. Use ``sections`` instead.
System accelerators System accelerators
------------------- -------------------

View File

@ -1324,7 +1324,7 @@ for the architecture in question, for example::
$(configure) --cross-cc-aarch64=aarch64-cc $(configure) --cross-cc-aarch64=aarch64-cc
There is also a ``--cross-cc-flags-ARCH`` flag in case additional There is also a ``--cross-cc-cflags-ARCH`` flag in case additional
compiler flags are needed to build for a given target. compiler flags are needed to build for a given target.
If you have the ability to run containers as the user the build system If you have the ability to run containers as the user the build system

View File

@ -83,7 +83,7 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high)
((high & MAKE_64BIT_MASK(0, 20)) << 32); ((high & MAKE_64BIT_MASK(0, 20)) << 32);
} }
static SGXEPCSectionList *sgx_calc_host_epc_sections(void) static SGXEPCSectionList *sgx_calc_host_epc_sections(uint64_t *size)
{ {
SGXEPCSectionList *head = NULL, **tail = &head; SGXEPCSectionList *head = NULL, **tail = &head;
SGXEPCSection *section; SGXEPCSection *section;
@ -106,6 +106,7 @@ static SGXEPCSectionList *sgx_calc_host_epc_sections(void)
section = g_new0(SGXEPCSection, 1); section = g_new0(SGXEPCSection, 1);
section->node = j++; section->node = j++;
section->size = sgx_calc_section_metric(ecx, edx); section->size = sgx_calc_section_metric(ecx, edx);
*size += section->size;
QAPI_LIST_APPEND(tail, section); QAPI_LIST_APPEND(tail, section);
} }
@ -156,6 +157,7 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp)
{ {
SGXInfo *info = NULL; SGXInfo *info = NULL;
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
uint64_t size = 0;
int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR);
if (fd < 0) { if (fd < 0) {
@ -173,7 +175,8 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp)
info->sgx1 = eax & (1U << 0) ? true : false; info->sgx1 = eax & (1U << 0) ? true : false;
info->sgx2 = eax & (1U << 1) ? true : false; info->sgx2 = eax & (1U << 1) ? true : false;
info->sections = sgx_calc_host_epc_sections(); info->sections = sgx_calc_host_epc_sections(&size);
info->section_size = size;
close(fd); close(fd);
@ -220,12 +223,14 @@ SGXInfo *qmp_query_sgx(Error **errp)
return NULL; return NULL;
} }
SGXEPCState *sgx_epc = &pcms->sgx_epc;
info = g_new0(SGXInfo, 1); info = g_new0(SGXInfo, 1);
info->sgx = true; info->sgx = true;
info->sgx1 = true; info->sgx1 = true;
info->sgx2 = true; info->sgx2 = true;
info->flc = true; info->flc = true;
info->section_size = sgx_epc->size;
info->sections = sgx_get_epc_sections_list(); info->sections = sgx_get_epc_sections_list();
return info; return info;
@ -249,6 +254,8 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict)
info->sgx2 ? "enabled" : "disabled"); info->sgx2 ? "enabled" : "disabled");
monitor_printf(mon, "FLC support: %s\n", monitor_printf(mon, "FLC support: %s\n",
info->flc ? "enabled" : "disabled"); info->flc ? "enabled" : "disabled");
monitor_printf(mon, "size: %" PRIu64 "\n",
info->section_size);
section_list = info->sections; section_list = info->sections;
for (section = section_list; section; section = section->next) { for (section = section_list; section; section = section->next) {

View File

@ -116,8 +116,8 @@ void pic_stat_update_irq(int irq, int level)
} }
} }
bool pic_get_statistics(InterruptStatsProvider *obj, static bool pic_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs) uint64_t **irq_counts, unsigned int *nb_irqs)
{ {
PICCommonState *s = PIC_COMMON(obj); PICCommonState *s = PIC_COMMON(obj);
@ -132,7 +132,7 @@ bool pic_get_statistics(InterruptStatsProvider *obj,
return true; return true;
} }
void pic_print_info(InterruptStatsProvider *obj, Monitor *mon) static void pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
{ {
PICCommonState *s = PIC_COMMON(obj); PICCommonState *s = PIC_COMMON(obj);

View File

@ -76,7 +76,7 @@ static void ioapic_irr_dump(Monitor *mon, const char *name, uint32_t bitmap)
monitor_printf(mon, "\n"); monitor_printf(mon, "\n");
} }
void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s) static void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
{ {
static const char *delm_str[] = { static const char *delm_str[] = {
"fixed", "lowest", "SMI", "...", "NMI", "INIT", "...", "extINT"}; "fixed", "lowest", "SMI", "...", "NMI", "INIT", "...", "extINT"};

View File

@ -234,15 +234,6 @@ extern const TargetPageBits target_page;
#define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE) #define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE)
/* Using intptr_t ensures that qemu_*_page_mask is sign-extended even
* when intptr_t is 32-bit and we are aligning a long long.
*/
extern uintptr_t qemu_host_page_size;
extern intptr_t qemu_host_page_mask;
#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_host_page_size)
#define REAL_HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_real_host_page_size)
/* same as PROT_xxx */ /* same as PROT_xxx */
#define PAGE_READ 0x0001 #define PAGE_READ 0x0001
#define PAGE_WRITE 0x0002 #define PAGE_WRITE 0x0002

View File

@ -7,6 +7,15 @@
#include "exec/hwaddr.h" #include "exec/hwaddr.h"
#endif #endif
/* Using intptr_t ensures that qemu_*_page_mask is sign-extended even
* when intptr_t is 32-bit and we are aligning a long long.
*/
extern uintptr_t qemu_host_page_size;
extern intptr_t qemu_host_page_mask;
#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_host_page_size)
#define REAL_HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_real_host_page_size)
/* The CPU list lock nests outside page_(un)lock or mmap_(un)lock */ /* The CPU list lock nests outside page_(un)lock or mmap_(un)lock */
void qemu_init_cpu_list(void); void qemu_init_cpu_list(void);
void cpu_list_lock(void); void cpu_list_lock(void);

View File

@ -112,7 +112,6 @@ struct IOAPICCommonState {
void ioapic_reset_common(DeviceState *dev); void ioapic_reset_common(DeviceState *dev);
void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s);
void ioapic_stat_update_irq(IOAPICCommonState *s, int irq, int level); void ioapic_stat_update_irq(IOAPICCommonState *s, int irq, int level);
#endif /* QEMU_IOAPIC_INTERNAL_H */ #endif /* QEMU_IOAPIC_INTERNAL_H */

View File

@ -72,8 +72,5 @@ struct PICCommonState {
void pic_reset_common(PICCommonState *s); void pic_reset_common(PICCommonState *s);
ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master); ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master);
void pic_stat_update_irq(int irq, int level); void pic_stat_update_irq(int irq, int level);
bool pic_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs);
void pic_print_info(InterruptStatsProvider *obj, Monitor *mon);
#endif /* QEMU_I8259_INTERNAL_H */ #endif /* QEMU_I8259_INTERNAL_H */

View File

@ -3,8 +3,9 @@ project('qemu', ['c'], meson_version: '>=0.58.2',
'b_staticpic=false', 'stdsplit=false'], 'b_staticpic=false', 'stdsplit=false'],
version: files('VERSION')) version: files('VERSION'))
add_test_setup('quick', exclude_suites: 'slow', is_default: true) add_test_setup('quick', exclude_suites: ['block', 'slow', 'thorough'], is_default: true)
add_test_setup('slow', env: ['G_TEST_SLOW=1', 'SPEED=slow']) add_test_setup('slow', exclude_suites: ['block', 'thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
add_test_setup('thorough', exclude_suites: ['block'], env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
not_found = dependency('', required: false) not_found = dependency('', required: false)
keyval = import('keyval') keyval = import('keyval')
@ -2280,7 +2281,7 @@ if have_system
if fdt.found() and cc.links(''' if fdt.found() and cc.links('''
#include <libfdt.h> #include <libfdt.h>
#include <libfdt_env.h> #include <libfdt_env.h>
int main(void) { fdt_check_full(NULL, 0); return 0; }''', int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
dependencies: fdt) dependencies: fdt)
fdt_opt = 'system' fdt_opt = 'system'
elif fdt_opt == 'system' elif fdt_opt == 'system'
@ -3055,17 +3056,14 @@ foreach target : target_dirs
install_input += meson.current_source_dir() / entitlements install_input += meson.current_source_dir() / entitlements
endif endif
entitlement = find_program('scripts/entitlement.sh')
emulators += {exe['name'] : custom_target(exe['name'], emulators += {exe['name'] : custom_target(exe['name'],
input: build_input, input: build_input,
output: exe['name'], output: exe['name'],
command: [ command: [entitlement, '@OUTPUT@', '@INPUT@'])
files('scripts/entitlement.sh'),
'@OUTPUT@',
'@INPUT@'
])
} }
meson.add_install_script('scripts/entitlement.sh', '--install', meson.add_install_script(entitlement, '--install',
get_option('bindir') / exe['name'], get_option('bindir') / exe['name'],
install_input) install_input)
else else

View File

@ -1207,7 +1207,7 @@
# #
# @memdev: memory backend linked with device # @memdev: memory backend linked with device
# #
# @node: the numa node # @node: the numa node (Since: 7.0)
# #
# Since: 6.2 # Since: 6.2
## ##
@ -1288,7 +1288,7 @@
# #
# @memdev: memory backend linked with device # @memdev: memory backend linked with device
# #
# @node: the numa node # @node: the numa node (Since: 7.0)
# #
# Since: 6.2 # Since: 6.2
## ##

View File

@ -344,9 +344,9 @@
# #
# @node: the numa node # @node: the numa node
# #
# @size: the size of epc section # @size: the size of EPC section
# #
# Since: 6.2 # Since: 7.0
## ##
{ 'struct': 'SGXEPCSection', { 'struct': 'SGXEPCSection',
'data': { 'node': 'int', 'data': { 'node': 'int',
@ -365,7 +365,13 @@
# #
# @flc: true if FLC is supported # @flc: true if FLC is supported
# #
# @sections: The EPC sections info for guest # @section-size: The EPC section size for guest
# Redundant with @sections. Just for backward compatibility.
#
# @sections: The EPC sections info for guest (Since: 7.0)
#
# Features:
# @deprecated: Member @section-size is deprecated. Use @sections instead.
# #
# Since: 6.2 # Since: 6.2
## ##
@ -374,6 +380,8 @@
'sgx1': 'bool', 'sgx1': 'bool',
'sgx2': 'bool', 'sgx2': 'bool',
'flc': 'bool', 'flc': 'bool',
'section-size': { 'type': 'uint64',
'features': [ 'deprecated' ] },
'sections': ['SGXEPCSection']}, 'sections': ['SGXEPCSection']},
'if': 'TARGET_I386' } 'if': 'TARGET_I386' }
@ -390,7 +398,9 @@
# #
# -> { "execute": "query-sgx" } # -> { "execute": "query-sgx" }
# <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true,
# "flc": true, "section-size" : 0 } } # "flc": true, "section-size" : 96468992,
# "sections": [{"node": 0, "size": 67108864},
# {"node": 1, "size": 29360128}]} }
# #
## ##
{ 'command': 'query-sgx', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } { 'command': 'query-sgx', 'returns': 'SGXInfo', 'if': 'TARGET_I386' }
@ -408,7 +418,9 @@
# #
# -> { "execute": "query-sgx-capabilities" } # -> { "execute": "query-sgx-capabilities" }
# <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true,
# "flc": true, "section-size" : 0 } } # "flc": true, "section-size" : 96468992,
# "section" : [{"node": 0, "size": 67108864},
# {"node": 1, "size": 29360128}]} }
# #
## ##
{ 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } { 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 'TARGET_I386' }

View File

@ -83,7 +83,7 @@ if targetos == 'windows'
endif endif
qga_msi = custom_target('QGA MSI', qga_msi = custom_target('QGA MSI',
input: files('installer/qemu-ga.wxs'), input: files('installer/qemu-ga.wxs'),
output: 'qemu-ga-@0@.msi'.format(config_host['ARCH']), output: 'qemu-ga-@0@.msi'.format(host_arch),
depends: deps, depends: deps,
command: [ command: [
find_program('env'), find_program('env'),

View File

@ -23,8 +23,9 @@ class Suite(object):
print(''' print('''
SPEED = quick SPEED = quick
.speed.quick = $(foreach s,$(sort $(filter-out %-slow, $1)), --suite $s) .speed.quick = $(foreach s,$(sort $(filter-out %-slow %-thorough, $1)), --suite $s)
.speed.slow = $(foreach s,$(sort $1), --suite $s) .speed.slow = $(foreach s,$(sort $(filter-out %-thorough, $1)), --suite $s)
.speed.thorough = $(foreach s,$(sort $1), --suite $s)
.mtestargs = --no-rebuild -t 0 .mtestargs = --no-rebuild -t 0
ifneq ($(SPEED), quick) ifneq ($(SPEED), quick)
@ -52,11 +53,14 @@ def process_tests(test, targets, suites):
for s in test_suites: for s in test_suites:
# The suite name in the introspection info is "PROJECT:SUITE" # The suite name in the introspection info is "PROJECT:SUITE"
s = s.split(':')[1] s = s.split(':')[1]
if s == 'slow': if s == 'slow' or s == 'thorough':
continue continue
if s.endswith('-slow'): if s.endswith('-slow'):
s = s[:-5] s = s[:-5]
suites[s].speeds.append('slow') suites[s].speeds.append('slow')
if s.endswith('-thorough'):
s = s[:-9]
suites[s].speeds.append('thorough')
suites[s].deps.update(deps) suites[s].deps.update(deps)
def emit_prolog(suites, prefix): def emit_prolog(suites, prefix):
@ -75,7 +79,7 @@ def emit_prolog(suites, prefix):
print(f'{prefix}-report.junit.xml $(all-{prefix}-xml): {prefix}-report%.junit.xml: run-ninja') print(f'{prefix}-report.junit.xml $(all-{prefix}-xml): {prefix}-report%.junit.xml: run-ninja')
print(f'\t$(MAKE) {prefix}$* MTESTARGS="$(MTESTARGS) --logbase {prefix}-report$*" && ln -f meson-logs/$@ .') print(f'\t$(MAKE) {prefix}$* MTESTARGS="$(MTESTARGS) --logbase {prefix}-report$*" && ln -f meson-logs/$@ .')
def emit_suite(name, suite, prefix): def emit_suite_deps(name, suite, prefix):
deps = ' '.join(suite.deps) deps = ' '.join(suite.deps)
targets = f'{prefix}-{name} {prefix}-report-{name}.junit.xml {prefix} {prefix}-report.junit.xml' targets = f'{prefix}-{name} {prefix}-report-{name}.junit.xml {prefix} {prefix}-report.junit.xml'
print() print()
@ -83,6 +87,10 @@ def emit_suite(name, suite, prefix):
print(f'ifneq ($(filter {prefix}-build {targets}, $(MAKECMDGOALS)),)') print(f'ifneq ($(filter {prefix}-build {targets}, $(MAKECMDGOALS)),)')
print(f'.{prefix}.build-suites += {name}') print(f'.{prefix}.build-suites += {name}')
print(f'endif') print(f'endif')
def emit_suite(name, suite, prefix):
emit_suite_deps(name, suite, prefix)
targets = f'{prefix}-{name} {prefix}-report-{name}.junit.xml {prefix} {prefix}-report.junit.xml'
print(f'ifneq ($(filter {targets}, $(MAKECMDGOALS)),)') print(f'ifneq ($(filter {targets}, $(MAKECMDGOALS)),)')
print(f'.{prefix}.mtest-suites += ' + ' '.join(suite.names(name))) print(f'.{prefix}.mtest-suites += ' + ' '.join(suite.names(name)))
print(f'endif') print(f'endif')
@ -93,6 +101,10 @@ targets = {t['id']: [os.path.relpath(f) for f in t['filename']]
testsuites = defaultdict(Suite) testsuites = defaultdict(Suite)
for test in introspect['tests']: for test in introspect['tests']:
process_tests(test, targets, testsuites) process_tests(test, targets, testsuites)
# HACK: check-block is a separate target so that it runs with --verbose;
# only write the dependencies
emit_suite_deps('block', testsuites['block'], 'check')
del testsuites['block']
emit_prolog(testsuites, 'check') emit_prolog(testsuites, 'check')
for name, suite in testsuites.items(): for name, suite in testsuites.items():
emit_suite(name, suite, 'check') emit_suite(name, suite, 'check')

View File

@ -156,19 +156,9 @@ check:
ifeq ($(CONFIG_TOOLS)$(CONFIG_POSIX),yy) ifeq ($(CONFIG_TOOLS)$(CONFIG_POSIX),yy)
check: check-block check: check-block
export PYTHON check-block: run-ninja
$(if $(MAKE.n),,+)$(MESON) test $(MTESTARGS) $(.mtestargs) --verbose \
ifneq ($(filter check check-block check-build, $(MAKECMDGOALS)),) --logbase iotestslog $(call .speed.$(SPEED), block block-slow block-thorough)
ninja-cmd-goals += \
qemu-img$(EXESUF) \
qemu-io$(EXESUF) \
qemu-nbd$(EXESUF) \
storage-daemon/qemu-storage-daemon$(EXESUF) \
$(filter qemu-system-%, $(ninja-targets))
endif
check-block: $(SRC_PATH)/tests/check-block.sh run-ninja
@$<
endif endif
check-build: run-ninja check-build: run-ninja

View File

@ -1,24 +1,25 @@
#!/bin/sh #!/bin/sh
# Honor the SPEED environment variable, just like we do it for the qtests. if [ "$#" -eq 0 ]; then
if [ "$SPEED" = "slow" ]; then echo "Usage: $0 fmt..." >&2
format_list="raw qcow2" exit 99
group= fi
elif [ "$SPEED" = "thorough" ]; then
format_list="raw qcow2 qed vmdk vpc" # Honor the SPEED environment variable, just like we do it for "meson test"
format_list="$@"
if [ "$SPEED" = "slow" ] || [ "$SPEED" = "thorough" ]; then
group= group=
else else
format_list=qcow2
group="-g auto" group="-g auto"
fi fi
if [ "$#" -ne 0 ]; then skip() {
format_list="$@" echo "1..0 #SKIP $*"
fi exit 0
}
if grep -q "CONFIG_GPROF=y" config-host.mak 2>/dev/null ; then if grep -q "CONFIG_GPROF=y" config-host.mak 2>/dev/null ; then
echo "GPROF is enabled ==> Not running the qemu-iotests." skip "GPROF is enabled ==> Not running the qemu-iotests."
exit 0
fi fi
# Disable tests with any sanitizer except for specific ones # Disable tests with any sanitizer except for specific ones
@ -36,36 +37,30 @@ for j in ${ALLOWED_SANITIZE_FLAGS}; do
done done
if echo ${SANITIZE_FLAGS} | grep -q "\-fsanitize" 2>/dev/null; then if echo ${SANITIZE_FLAGS} | grep -q "\-fsanitize" 2>/dev/null; then
# Have a sanitize flag that is not allowed, stop # Have a sanitize flag that is not allowed, stop
echo "Sanitizers are enabled ==> Not running the qemu-iotests." skip "Sanitizers are enabled ==> Not running the qemu-iotests."
exit 0
fi fi
if [ -z "$(find . -name 'qemu-system-*' -print)" ]; then if [ -z "$(find . -name 'qemu-system-*' -print)" ]; then
echo "No qemu-system binary available ==> Not running the qemu-iotests." skip "No qemu-system binary available ==> Not running the qemu-iotests."
exit 0
fi fi
if ! command -v bash >/dev/null 2>&1 ; then if ! command -v bash >/dev/null 2>&1 ; then
echo "bash not available ==> Not running the qemu-iotests." skip "bash not available ==> Not running the qemu-iotests."
exit 0
fi fi
if LANG=C bash --version | grep -q 'GNU bash, version [123]' ; then if LANG=C bash --version | grep -q 'GNU bash, version [123]' ; then
echo "bash version too old ==> Not running the qemu-iotests." skip "bash version too old ==> Not running the qemu-iotests."
exit 0
fi fi
if ! (sed --version | grep 'GNU sed') > /dev/null 2>&1 ; then if ! (sed --version | grep 'GNU sed') > /dev/null 2>&1 ; then
if ! command -v gsed >/dev/null 2>&1; then if ! command -v gsed >/dev/null 2>&1; then
echo "GNU sed not available ==> Not running the qemu-iotests." skip "GNU sed not available ==> Not running the qemu-iotests."
exit 0
fi fi
else else
# Double-check that we're not using BusyBox' sed which says # Double-check that we're not using BusyBox' sed which says
# that "This is not GNU sed version 4.0" ... # that "This is not GNU sed version 4.0" ...
if sed --version | grep -q 'not GNU sed' ; then if sed --version | grep -q 'not GNU sed' ; then
echo "BusyBox sed not supported ==> Not running the qemu-iotests." skip "BusyBox sed not supported ==> Not running the qemu-iotests."
exit 0
fi fi
fi fi
@ -74,10 +69,17 @@ cd tests/qemu-iotests
# QEMU_CHECK_BLOCK_AUTO is used to disable some unstable sub-tests # QEMU_CHECK_BLOCK_AUTO is used to disable some unstable sub-tests
export QEMU_CHECK_BLOCK_AUTO=1 export QEMU_CHECK_BLOCK_AUTO=1
export PYTHONUTF8=1 export PYTHONUTF8=1
# If make was called with -jN we want to call ./check with -j N. Extract the
# flag from MAKEFLAGS, so that if it absent (or MAKEFLAGS is not defined), JOBS
# would be an empty line otherwise JOBS is prepared string of flag with value:
# "-j N"
# Note, that the following works even if make was called with "-j N" or even
# "--jobs N", as all these variants becomes simply "-jN" in MAKEFLAGS variable.
JOBS=$(echo "$MAKEFLAGS" | sed -n 's/\(^\|.* \)-j\([0-9]\+\)\( .*\|$\)/-j \2/p')
ret=0 ret=0
for fmt in $format_list ; do for fmt in $format_list ; do
${PYTHON} ./check -makecheck -$fmt $group || ret=1 ${PYTHON} ./check $JOBS -tap -$fmt $group || ret=1
done done
exit $ret exit $ret

View File

@ -29,6 +29,7 @@ ENV PACKAGES \
mingw32-pixman \ mingw32-pixman \
mingw32-pkg-config \ mingw32-pkg-config \
mingw32-SDL2 \ mingw32-SDL2 \
msitools \
perl \ perl \
perl-Test-Harness \ perl-Test-Harness \
python3 \ python3 \

View File

@ -26,6 +26,7 @@ ENV PACKAGES \
mingw64-libusbx \ mingw64-libusbx \
mingw64-pixman \ mingw64-pixman \
mingw64-pkg-config \ mingw64-pkg-config \
msitools \
perl \ perl \
perl-Test-Harness \ perl-Test-Harness \
python3 \ python3 \

View File

@ -1,6 +1,7 @@
py3 = import('python').find_installation() py3 = import('python').find_installation()
subdir('bench') subdir('bench')
subdir('qemu-iotests')
test_qapi_outputs = [ test_qapi_outputs = [
'qapi-builtin-types.c', 'qapi-builtin-types.c',

View File

@ -32,8 +32,6 @@ def make_argparser() -> argparse.ArgumentParser:
p.add_argument('-n', '--dry-run', action='store_true', p.add_argument('-n', '--dry-run', action='store_true',
help='show me, do not run tests') help='show me, do not run tests')
p.add_argument('-makecheck', action='store_true',
help='pretty print output for make check')
p.add_argument('-j', dest='jobs', type=int, default=1, p.add_argument('-j', dest='jobs', type=int, default=1,
help='run tests in multiple parallel jobs') help='run tests in multiple parallel jobs')
@ -53,6 +51,8 @@ def make_argparser() -> argparse.ArgumentParser:
p.add_argument('--color', choices=['on', 'off', 'auto'], p.add_argument('--color', choices=['on', 'off', 'auto'],
default='auto', help="use terminal colors. The default " default='auto', help="use terminal colors. The default "
"'auto' value means use colors if terminal stdout detected") "'auto' value means use colors if terminal stdout detected")
p.add_argument('-tap', action='store_true',
help='produce TAP output')
g_env = p.add_argument_group('test environment options') g_env = p.add_argument_group('test environment options')
mg = g_env.add_mutually_exclusive_group() mg = g_env.add_mutually_exclusive_group()
@ -164,7 +164,7 @@ if __name__ == '__main__':
if args.dry_run: if args.dry_run:
print('\n'.join(tests)) print('\n'.join(tests))
else: else:
with TestRunner(env, makecheck=args.makecheck, with TestRunner(env, tap=args.tap,
color=args.color) as tr: color=args.color) as tr:
paths = [os.path.join(env.source_iotests, t) for t in tests] paths = [os.path.join(env.source_iotests, t) for t in tests]
ok = tr.run_tests(paths, args.jobs) ok = tr.run_tests(paths, args.jobs)

View File

@ -0,0 +1,30 @@
if have_tools and targetos != 'windows'
qemu_iotests_binaries = [qemu_img, qemu_io, qemu_nbd, qsd]
qemu_iotests_env = {'PYTHON': python.full_path()}
qemu_iotests_formats = {
'qcow2': 'quick',
'raw': 'slow',
'qed': 'thorough',
'vmdk': 'thorough',
'vpc': 'thorough'
}
foreach k, v : emulators
if k.startswith('qemu-system-')
qemu_iotests_binaries += v
endif
endforeach
foreach format, speed: qemu_iotests_formats
if speed == 'quick'
suites = 'block'
else
suites = ['block-' + speed, speed]
endif
test('qemu-iotests ' + format, sh, args: [files('../check-block.sh'), format],
depends: qemu_iotests_binaries, env: qemu_iotests_env,
protocol: 'tap',
suite: suites,
timeout: 0,
is_parallel: false)
endforeach
endif

View File

@ -287,21 +287,21 @@ class TestEnv(ContextManager['TestEnv']):
def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
self.close() self.close()
def print_env(self) -> None: def print_env(self, prefix: str = '') -> None:
template = """\ template = """\
QEMU -- "{QEMU_PROG}" {QEMU_OPTIONS} {prefix}QEMU -- "{QEMU_PROG}" {QEMU_OPTIONS}
QEMU_IMG -- "{QEMU_IMG_PROG}" {QEMU_IMG_OPTIONS} {prefix}QEMU_IMG -- "{QEMU_IMG_PROG}" {QEMU_IMG_OPTIONS}
QEMU_IO -- "{QEMU_IO_PROG}" {QEMU_IO_OPTIONS} {prefix}QEMU_IO -- "{QEMU_IO_PROG}" {QEMU_IO_OPTIONS}
QEMU_NBD -- "{QEMU_NBD_PROG}" {QEMU_NBD_OPTIONS} {prefix}QEMU_NBD -- "{QEMU_NBD_PROG}" {QEMU_NBD_OPTIONS}
IMGFMT -- {IMGFMT}{imgopts} {prefix}IMGFMT -- {IMGFMT}{imgopts}
IMGPROTO -- {IMGPROTO} {prefix}IMGPROTO -- {IMGPROTO}
PLATFORM -- {platform} {prefix}PLATFORM -- {platform}
TEST_DIR -- {TEST_DIR} {prefix}TEST_DIR -- {TEST_DIR}
SOCK_DIR -- {SOCK_DIR} {prefix}SOCK_DIR -- {SOCK_DIR}
GDB_OPTIONS -- {GDB_OPTIONS} {prefix}GDB_OPTIONS -- {GDB_OPTIONS}
VALGRIND_QEMU -- {VALGRIND_QEMU} {prefix}VALGRIND_QEMU -- {VALGRIND_QEMU}
PRINT_QEMU_OUTPUT -- {PRINT_QEMU} {prefix}PRINT_QEMU_OUTPUT -- {PRINT_QEMU}
""" {prefix}"""
args = collections.defaultdict(str, self.get_env()) args = collections.defaultdict(str, self.get_env())
@ -310,5 +310,5 @@ PRINT_QEMU_OUTPUT -- {PRINT_QEMU}
u = os.uname() u = os.uname()
args['platform'] = f'{u.sysname}/{u.machine} {u.nodename} {u.release}' args['platform'] = f'{u.sysname}/{u.machine} {u.nodename} {u.release}'
args['prefix'] = prefix
print(template.format_map(args)) print(template.format_map(args))

View File

@ -152,10 +152,10 @@ class TestRunner(ContextManager['TestRunner']):
return results return results
def __init__(self, env: TestEnv, makecheck: bool = False, def __init__(self, env: TestEnv, tap: bool = False,
color: str = 'auto') -> None: color: str = 'auto') -> None:
self.env = env self.env = env
self.makecheck = makecheck self.tap = tap
self.last_elapsed = LastElapsedTime('.last-elapsed-cache', env) self.last_elapsed = LastElapsedTime('.last-elapsed-cache', env)
assert color in ('auto', 'on', 'off') assert color in ('auto', 'on', 'off')
@ -185,13 +185,16 @@ class TestRunner(ContextManager['TestRunner']):
""" Print short test info before/after test run """ """ Print short test info before/after test run """
test = os.path.basename(test) test = os.path.basename(test)
if self.makecheck and status != '...': if test_field_width is None:
if status and status != 'pass': test_field_width = 8
status = f' [{status}]'
else:
status = ''
print(f' TEST iotest-{self.env.imgfmt}: {test}{status}') if self.tap:
if status == 'pass':
print(f'ok {self.env.imgfmt} {test}')
elif status == 'fail':
print(f'not ok {self.env.imgfmt} {test}')
elif status == 'not run':
print(f'ok {self.env.imgfmt} {test} # SKIP')
return return
if lasttime: if lasttime:
@ -343,7 +346,7 @@ class TestRunner(ContextManager['TestRunner']):
last_el = self.last_elapsed.get(test) last_el = self.last_elapsed.get(test)
start = datetime.datetime.now().strftime('%H:%M:%S') start = datetime.datetime.now().strftime('%H:%M:%S')
if not self.makecheck: if not self.tap:
self.test_print_one_line(test=test, self.test_print_one_line(test=test,
test_field_width=test_field_width, test_field_width=test_field_width,
status = 'started' if mp else '...', status = 'started' if mp else '...',
@ -372,7 +375,9 @@ class TestRunner(ContextManager['TestRunner']):
notrun = [] notrun = []
casenotrun = [] casenotrun = []
if not self.makecheck: if self.tap:
self.env.print_env('# ')
else:
self.env.print_env() self.env.print_env()
test_field_width = max(len(os.path.basename(t)) for t in tests) + 2 test_field_width = max(len(os.path.basename(t)) for t in tests) + 2
@ -398,8 +403,6 @@ class TestRunner(ContextManager['TestRunner']):
if res.status == 'fail': if res.status == 'fail':
failed.append(name) failed.append(name)
if self.makecheck:
self.env.print_env()
if res.diff: if res.diff:
print('\n'.join(res.diff)) print('\n'.join(res.diff))
elif res.status == 'not run': elif res.status == 'not run':
@ -412,16 +415,16 @@ class TestRunner(ContextManager['TestRunner']):
if res.interrupted: if res.interrupted:
break break
if notrun: if not self.tap:
print('Not run:', ' '.join(notrun)) if notrun:
print('Not run:', ' '.join(notrun))
if casenotrun: if casenotrun:
print('Some cases not run in:', ' '.join(casenotrun)) print('Some cases not run in:', ' '.join(casenotrun))
if failed: if failed:
print('Failures:', ' '.join(failed)) print('Failures:', ' '.join(failed))
print(f'Failed {len(failed)} of {n_run} iotests') print(f'Failed {len(failed)} of {n_run} iotests')
return False else:
else: print(f'Passed all {n_run} iotests')
print(f'Passed all {n_run} iotests') return not failed
return True

View File

@ -103,7 +103,7 @@ if dbus_daemon.found() and config_host.has_key('GDBUS_CODEGEN')
#qtests_i386 += ['dbus-vmstate-test'] #qtests_i386 += ['dbus-vmstate-test']
dbus_vmstate1 = custom_target('dbus-vmstate description', dbus_vmstate1 = custom_target('dbus-vmstate description',
output: ['dbus-vmstate1.h', 'dbus-vmstate1.c'], output: ['dbus-vmstate1.h', 'dbus-vmstate1.c'],
input: meson.source_root() / 'backends/dbus-vmstate1.xml', input: meson.project_source_root() / 'backends/dbus-vmstate1.xml',
command: [config_host['GDBUS_CODEGEN'], command: [config_host['GDBUS_CODEGEN'],
'@INPUT@', '@INPUT@',
'--interface-prefix', 'org.qemu', '--interface-prefix', 'org.qemu',