RFC QEMU validator: A method to specify QEMU crash-test cases
Get series with b4
b4 am [email protected]Versions newest first
- v1 RFC Latest18 patches 14 repliesIn review
Patches in v1 No applies recorded yet
| # | Subject and files | Size | Replies | Applied |
|---|---|---|---|---|
| 1/18 | qmp.py: Make it safe to call close() any timescripts/ | +3 | 0 replies | |
| 2/18 | qmp.py: Fix error handling for Python 3scripts/ | +3 | 1 reply | |
| 3/18 | qmp.py: Cleanly handle unexpectedly closed socketscripts/ | +6 | 1 reply | |
| 4/18 | qemu.py: Make _vm_monitor a methodscripts/ | +11 | 0 replies | |
| 5/18 | qemu.py: Split _base_args()scripts/ | +8 | 1 reply | |
| 6/18 | qemu.py: Move _load_io_log() call to _post_shutdown()scripts/ | +1 | 1 reply | |
| 7/18 | qemu.py: Use wait() logic inside shutdown()scripts/ | +1 | 0 replies | |
| 8/18 | qemu.py: Close _qmp inside _post_shutdown()scripts/ | +4 | 1 reply | |
| 9/18 | qemu.py: Make monitor optionalscripts/ | +15 | 0 replies | |
| 10/18 | qemu.py: Set _launched = False on _post_shutdownscripts/ | +2 | 0 replies | |
| 11/18 | qemu.py: Log crashes inside _post_shutdown()scripts/ | +9 | 1 reply | |
| 12/18 | qemu.py: Only wait for process if it's still runningscripts/ | +2 | 0 replies | |
| 13/18 | qemu.py: 'force' parameter on shutdown()scripts/ | +15 | 0 replies | |
| 14/18 | qemu.py: Don't try to quit cleanly on exceptionsscripts/ | +1 | 0 replies | |
| 15/18 | qemu.py: qmp_obj() methodscripts/ | +3 | 0 replies | |
| 16/18 | qemu.py: is_launched() methodscripts/ | +3 | 0 replies | |
| 17/18 | validator.py scriptscripts/ | +724 | 6 replies | |
| 18/18 | Collection of validator.py test casestests/ tests/ tests/ +4 more | +68 | 0 replies |
Reviews trailers per patch
6 of 18 patches have a Reviewed-by or Acked-by.
| Patch | Philippe Mathieu-Daudé |
|---|---|
| 1/18 | |
| 2/18 | R-b |
| 3/18 | R-b |
| 4/18 | |
| 5/18 | R-b |
| 6/18 | R-b |
| 7/18 | |
| 8/18 | R-b |
| 9/18 | |
| 10/18 | |
| 11/18 | R-b |
| 12/18 | |
| 13/18 | |
| 14/18 | |
| 15/18 | |
| 16/18 | |
| 17/18 | |
| 18/18 |
Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes.
Cover letter [Qemu-devel] [RFC 00/18] QEMU validator: A method to specify QEMU crash-test cases
Rationale
---------
Today we have a few test cases in the QEMU tree that just run QEMU with a few command-line options, run some QMP or HMP commands, and check if QEMU didn't crash.
Some examples:
* scripts/device-crash-test
* The test case suggested by Thomas at:
Subject: [RFC PATCH] tests: Add a device_add/del HMP test
* Some test cases in tests/device-introspect-test.c
* tests/cpu-plug-test.c
* tests/display-vga-test.c
* tests/drive_del-test.c
* tests/machine-none-test.c
* tests/test-hmp.c
* Some device test skeletons: ac97-test.c, e1000-test.c, eepro100-test.c, es1370-test.c, i82801b11-test.c, intel-hda-test.c, ioh3420-test.c, ipoctal232-test.c, ne2000-test.c, nvme-test.c, pcnet-test.c, spapr-phb-test.c, test-netfilter.c, tpci200-test.c, usb-hcd-ohci-test.c, usb-hcd-xhci-test.c, virtio-balloon-test.c, virtio-console-test.c, virtio-serial-test.c, vmxnet3-test.c.
All of those test cases require lots of boilerplate code just to run some combinations of QEMU command-line options and monitor commands.
In addition to that, writing and reviewing test code like the examples above is more complex than it could be. Some past examples from qemu-devel:
* Subject: [RFC 5/6] device-crash-test: Basic device_add support
* Subject: [RFC 6/6] device-crash-test: Multi-device device_add test
* Subject: [RFC PATCH] tests/device-introspect: Test devices with all machines, not only with "none"
The Proposal
------------
This series introduces the scripts/validator.py test runner, and a set of example test specifications in tests/validator.
Each test specification is a YAML file containing the QEMU command-line and monitor commands to run, and can contain variables like $MACHINE, $DEVICE, $CPU, that can be expanded automatically by the test runner.
This way, scripts/device-crash-test can be replaced by a one-line test specification:
command-line: '$QEMU -S -machine $MACHINE,accel=$ACCEL -device $DEVICE'
The device_add/device_del test case written by Thomas can be specified as:
command-line: '$QEMU -S -machine $MACHINE,accel=$ACCEL' monitor-commands:
- qmp:
- execute: 'device_add'
arguments:
driver: '$DEVICE'
id: 'test-device-for-$DEVICE'
- execute: 'device_del'
arguments:
id: 'test-device-for-$DEVICE'
and the test runner will take care of running test cases with with all valid machine-types, device-types, and accelerators.
For other examples, see the last patch in this series ("Collection of validator.py test cases"). Most of the examples replace existing C or Python test cases with simple declarative test specifications.
I expect this to be very useful when somebody is fixing a QEMU crash and just want to add a very simple reproducer to ensure the crash will never be introduced again.
(I actually suggest we _require_ people to include a tests/validator test specifications every time they fix a crash that can be reproduced using just QMP commands).
Features
--------
Current features:
* Automatic variable expansion, as described above
* A simple method to specify defaults (e.g. to test only "-machine none" or only "accel=kvm:tcg" unless running in --full mode)
* A simple method to represent expected failures (it can't replace the device-crash-test whitelist mechanism, yet)
Caveats
-------
The test runner code still needs some clean up. I'm not happy with the current variable enumeration/expansion code, and plan to make it cleaner.
How to test
-----------
You can run all example test cases on /usr/bin/qemu-system-x86_64 with:
$ ./scripts/validator.py tests/validator/* -V QEMU=/usr/bin/qemu-system-x86_64
However, the device-crash-test.yaml test specification still takes too long to run and reports too many false positives. So I suggest doing this instead:
$ ./scripts/validator.py $(ls tests/validator/* | grep -v device-crash-test) \
-V QEMU=/usr/bin/qemu-system-x86_64On my system, this runs ~700 test cases in ~15 seconds.
What's out of scope?
--------------------
The following are _not_ goals of this system:
* Replacing the work done by the Avocado team to support Avocado-based tests.
* Making the YAML test specification a fully-featured imperative language. Anything that requires extra logic still needs to be written in C or Python.
Future Plans
------------
Short term:
* Choose a better name for the test runner
* Support a list of known-failures similar to the whitelist in device-crash-test.
* Replace device-crash-test completely
* "make check" rules
Long term:
* stdout and QMP command output validation.
I plan to use this to write machine-type/guest-ABI compatibility test cases that will detect guest ABI breakage as soon as possible.
* See if the Avocado multiplexer API can be used to implement variable expansion.
* See if we can make some of the features (e.g. automatic variable expansion) available to Python test cases
* Fuzzing QMP commands and QEMU command-line arguments.
* See if code can be shared with the iotests test runner (especially the variable expansion logic)
Eduardo Habkost (18):
qmp.py: Make it safe to call close() any time qmp.py: Fix error handling for Python 3 qmp.py: Cleanly handle unexpectedly closed socket qemu.py: Make _vm_monitor a method
qemu.py: Split _base_args()
qemu.py: Move _load_io_log() call to _post_shutdown() qemu.py: Use wait() logic inside shutdown() qemu.py: Close _qmp inside _post_shutdown() qemu.py: Make monitor optional
qemu.py: Set _launched = False on _post_shutdown qemu.py: Log crashes inside _post_shutdown() qemu.py: Only wait for process if it's still running qemu.py: 'force' parameter on shutdown() qemu.py: Don't try to quit cleanly on exceptions qemu.py: qmp_obj() method
qemu.py: is_launched() method
validator.py script
Collection of validator.py test cases
scripts/qemu.py | 112 +++-- scripts/qmp/qmp.py | 16 +- scripts/validator.py | 724 +++++++++++++++++++++++++++++++++ tests/validator/cpu.yaml | 5 + tests/validator/device-add.yaml | 17 + tests/validator/device-crash-test.yaml | 7 + tests/validator/device-help.yaml | 3 + tests/validator/device-introspect.yaml | 23 ++ tests/validator/device-list.yaml | 10 + tests/validator/just-help.yaml | 3 + 10 files changed, 876 insertions(+), 44 deletions(-) create mode 100755 scripts/validator.py create mode 100644 tests/validator/cpu.yaml create mode 100644 tests/validator/device-add.yaml create mode 100644 tests/validator/device-crash-test.yaml create mode 100644 tests/validator/device-help.yaml create mode 100644 tests/validator/device-introspect.yaml create mode 100644 tests/validator/device-list.yaml create mode 100644 tests/validator/just-help.yaml
Signature · 1 line
2.14.3