[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 024/150] meson: add testsuite Makefile generator
From: |
Paolo Bonzini |
Subject: |
[PULL 024/150] meson: add testsuite Makefile generator |
Date: |
Tue, 18 Aug 2020 10:08:19 -0400 |
Rules to execute tests are generated by a simple Python program
that integrates into the existing "make check" mechanism. This
provides familiarity for developers, and also allows piecewise
conversion of the testsuite Makefiles to meson.
The generated rules are based on QEMU's existing test harness
Makefile and TAP parser.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
Makefile | 6 ++-
scripts/mtest2make.py | 102 +++++++++++++++++++++++++++++++++++++++++
tests/Makefile.include | 1 -
3 files changed, 107 insertions(+), 2 deletions(-)
create mode 100644 scripts/mtest2make.py
diff --git a/Makefile b/Makefile
index 6198236c40..7419d5e19b 100644
--- a/Makefile
+++ b/Makefile
@@ -65,6 +65,10 @@ clean-ctlist:
ninja-clean::
ninja-distclean::
+Makefile.mtest: build.ninja scripts/mtest2make.py
+ $(MESON) introspect --tests | $(PYTHON) scripts/mtest2make.py > $@
+-include Makefile.mtest
+
.git-submodule-status: git-submodule-update config-host.mak
# Check that we're not trying to do an out-of-tree build from
@@ -820,7 +824,7 @@ distclean: clean ninja-distclean
rm -f roms/seabios/config.mak roms/vgabios/config.mak
rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols
rm -rf meson-private meson-logs meson-info compile_commands.json
- rm -f Makefile.ninja ninjatool ninjatool.stamp
+ rm -f Makefile.ninja ninjatool ninjatool.stamp Makefile.mtest
rm -f config.log
rm -f linux-headers/asm
rm -f docs/version.texi
diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py
new file mode 100644
index 0000000000..bdb257bbd9
--- /dev/null
+++ b/scripts/mtest2make.py
@@ -0,0 +1,102 @@
+#! /usr/bin/env python3
+
+# Create Makefile targets to run tests, from Meson's test introspection data.
+#
+# Author: Paolo Bonzini <pbonzini@redhat.com>
+
+from collections import defaultdict
+import json
+import os
+import shlex
+import sys
+
+class Suite(object):
+ def __init__(self):
+ self.tests = list()
+ self.slow_tests = list()
+ self.executables = set()
+
+print('''
+SPEED = quick
+
+# $1 = test command, $2 = test name
+.test-human-tap = $1 < /dev/null | ./scripts/tap-driver.pl --test-name="$2"
$(if $(V),,--show-failures-only)
+.test-human-exitcode = $1 < /dev/null
+.test-tap-tap = $1 < /dev/null | sed "s/^[a-z][a-z]* [0-9]*/& $2/" || true
+.test-tap-exitcode = printf "%s\\n" 1..1 "`$1 < /dev/null > /dev/null || echo
"not "`ok 1 $2"
+.test.print = echo $(if $(V),'$1','Running test $2') >&3
+.test.env = MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))}
+
+# $1 = test name, $2 = test target (human or tap)
+.test.run = $(call .test.print,$(.test.cmd.$1),$(.test.name.$1)) && $(call
.test-$2-$(.test.driver.$1),$(.test.cmd.$1),$(.test.name.$1))
+
+define .test.human_k
+ @exec 3>&1; rc=0; $(foreach TEST, $1, $(call .test.run,$(TEST),human)
|| rc=$$?;) \\
+ exit $$rc
+endef
+define .test.human_no_k
+ $(foreach TEST, $1, @exec 3>&1; $(call .test.run,$(TEST),human)
+)
+endef
+.test.human = \\
+ $(if $(findstring k, $(MAKEFLAGS)), $(.test.human_k),
$(.test.human_no_k))
+
+define .test.tap
+ @exec 3>&1; { $(foreach TEST, $1, $(call .test.run,$(TEST),tap); ) } \\
+ | ./scripts/tap-merge.pl | tee "$@" \\
+ | ./scripts/tap-driver.pl $(if $(V),, --show-failures-only)
+endef
+''')
+
+suites = defaultdict(Suite)
+i = 0
+for test in json.load(sys.stdin):
+ env = ' '.join(('%s=%s' % (shlex.quote(k), shlex.quote(v))
+ for k, v in test['env'].items()))
+ executable = os.path.relpath(test['cmd'][0])
+ if test['workdir'] is not None:
+ test['cmd'][0] = os.path.relpath(test['cmd'][0], test['workdir'])
+ else:
+ test['cmd'][0] = executable
+ cmd = '$(.test.env) %s %s' % (env, ' '.join((shlex.quote(x) for x in
test['cmd'])))
+ if test['workdir'] is not None:
+ cmd = '(cd %s && %s)' % (shlex.quote(test['workdir']), cmd)
+ driver = test['protocol'] if 'protocol' in test else 'exitcode'
+
+ i += 1
+ print('.test.name.%d := %s' % (i, test['name']))
+ print('.test.driver.%d := %s' % (i, driver))
+ print('.test.cmd.%d := %s' % (i, cmd))
+
+ test_suites = test['suite'] or ['default']
+ is_slow = any(s.endswith('-slow') for s in test_suites)
+ for s in test_suites:
+ # The suite name in the introspection info is "PROJECT:SUITE"
+ s = s.split(':')[1]
+ if s.endswith('-slow'):
+ s = s[:-5]
+ if is_slow:
+ suites[s].slow_tests.append(i)
+ else:
+ suites[s].tests.append(i)
+ suites[s].executables.add(executable)
+
+print('.PHONY: check check-report.tap')
+print('check:')
+print('check-report.tap:')
+print('\t@cat $^ | scripts/tap-merge.pl >$@')
+for name, suite in suites.items():
+ executables = ' '.join(suite.executables)
+ slow_test_numbers = ' '.join((str(x) for x in suite.slow_tests))
+ test_numbers = ' '.join((str(x) for x in suite.tests))
+ print('.test.suite-quick.%s := %s' % (name, test_numbers))
+ print('.test.suite-slow.%s := $(.test.suite-quick.%s) %s' % (name, name,
slow_test_numbers))
+ print('check-build: %s' % executables)
+ print('.PHONY: check-%s' % name)
+ print('.PHONY: check-report-%s.tap' % name)
+ print('check: check-%s' % name)
+ print('check-%s: all %s' % (name, executables))
+ print('\t$(call .test.human, $(.test.suite-$(SPEED).%s))' % (name, ))
+ print('check-report.tap: check-report-%s.tap' % name)
+ print('check-report-%s.tap: %s' % (name, executables))
+ print('\t$(call .test.tap, $(.test.suite-$(SPEED).%s))' % (name, ))
diff --git a/tests/Makefile.include b/tests/Makefile.include
index c7e4646ded..ad54100369 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -674,7 +674,6 @@ check-report-unit.tap: $(check-unit-y)
# Reports and overall runs
check-report.tap: $(patsubst %,check-report-qtest-%.tap, $(QTEST_TARGETS))
check-report-unit.tap
- $(call quiet-command, cat $^ | scripts/tap-merge.pl >$@,"GEN","$@")
# FPU Emulation tests (aka softfloat)
#
--
2.26.2
- [PULL 021/150] meson: enable pie, (continued)
- [PULL 021/150] meson: enable pie, Paolo Bonzini, 2020/08/18
- [PULL 022/150] meson: use coverage option, Paolo Bonzini, 2020/08/18
- [PULL 019/150] build-sys: add meson submodule, Paolo Bonzini, 2020/08/18
- [PULL 028/150] contrib/libvhost-user: convert to Meson, Paolo Bonzini, 2020/08/18
- [PULL 029/150] tools/virtiofsd: convert to Meson, Paolo Bonzini, 2020/08/18
- [PULL 027/150] meson: add version.o, Paolo Bonzini, 2020/08/18
- [PULL 030/150] contrib/vhost-user-blk: convert to Meson, Paolo Bonzini, 2020/08/18
- [PULL 034/150] contrib/vhost-user-input: convert to meson, Paolo Bonzini, 2020/08/18
- [PULL 023/150] meson: add sparse support, Paolo Bonzini, 2020/08/18
- [PULL 026/150] meson: add remaining generated tcg trace helpers, Paolo Bonzini, 2020/08/18
- [PULL 024/150] meson: add testsuite Makefile generator,
Paolo Bonzini <=
- [PULL 031/150] vhost-user-scsi: add compatibility for libiscsi 1.9.0, Paolo Bonzini, 2020/08/18
- [PULL 032/150] contrib/vhost-user-scsi: convert to Meson, Paolo Bonzini, 2020/08/18
- [PULL 036/150] contrib/ivshmem: convert to meson, Paolo Bonzini, 2020/08/18
- [PULL 035/150] contrib/vhost-user-gpu: convert to meson, Paolo Bonzini, 2020/08/18
- [PULL 044/150] meson: add qemu-bridge-helper, Paolo Bonzini, 2020/08/18
- [PULL 042/150] meson: add msi generation, Paolo Bonzini, 2020/08/18
- [PULL 046/150] meson: add qemu-edid, Paolo Bonzini, 2020/08/18
- [PULL 038/150] meson: add macos dependencies, Paolo Bonzini, 2020/08/18
- [PULL 025/150] libqemuutil, qapi, trace: convert to meson, Paolo Bonzini, 2020/08/18
- [PULL 033/150] contrib/rdmacm-mux: convert to Meson, Paolo Bonzini, 2020/08/18