1c3e24cffSThomas Huth.. _checkfunctional-ref: 2c3e24cffSThomas Huth 3c3e24cffSThomas HuthFunctional testing with Python 4c3e24cffSThomas Huth============================== 5c3e24cffSThomas Huth 6c3e24cffSThomas HuthThe ``tests/functional`` directory hosts functional tests written in 7c3e24cffSThomas HuthPython. They are usually higher level tests, and may interact with 8c3e24cffSThomas Huthexternal resources and with various guest operating systems. 9c3e24cffSThomas HuthThe functional tests have initially evolved from the Avocado tests, so there 10c3e24cffSThomas Huthis a lot of similarity to those tests here (see :ref:`checkavocado-ref` for 11c3e24cffSThomas Huthdetails about the Avocado tests). 12c3e24cffSThomas Huth 13c3e24cffSThomas HuthThe tests should be written in the style of the Python `unittest`_ framework, 14c3e24cffSThomas Huthusing stdio for the TAP protocol. The folder ``tests/functional/qemu_test`` 15c3e24cffSThomas Huthprovides classes (e.g. the ``QemuBaseTest``, ``QemuUserTest`` and the 16c3e24cffSThomas Huth``QemuSystemTest`` classes) and utility functions that help to get your test 17c3e24cffSThomas Huthinto the right shape, e.g. by replacing the 'stdout' python object to redirect 18c3e24cffSThomas Huththe normal output of your test to stderr instead. 19c3e24cffSThomas Huth 20c3e24cffSThomas HuthNote that if you don't use one of the QemuBaseTest based classes for your 21c3e24cffSThomas Huthtest, or if you spawn subprocesses from your test, you have to make sure 22c3e24cffSThomas Huththat there is no TAP-incompatible output written to stdio, e.g. either by 23c3e24cffSThomas Huthprefixing every line with a "# " to mark the output as a TAP comment, or 24c3e24cffSThomas Huthe.g. by capturing the stdout output of subprocesses (redirecting it to 25c3e24cffSThomas Huthstderr is OK). 26c3e24cffSThomas Huth 27c3e24cffSThomas HuthTests based on ``qemu_test.QemuSystemTest`` can easily: 28c3e24cffSThomas Huth 29c3e24cffSThomas Huth * Customize the command line arguments given to the convenience 30c3e24cffSThomas Huth ``self.vm`` attribute (a QEMUMachine instance) 31c3e24cffSThomas Huth 32c3e24cffSThomas Huth * Interact with the QEMU monitor, send QMP commands and check 33c3e24cffSThomas Huth their results 34c3e24cffSThomas Huth 35c3e24cffSThomas Huth * Interact with the guest OS, using the convenience console device 36c3e24cffSThomas Huth (which may be useful to assert the effectiveness and correctness of 37c3e24cffSThomas Huth command line arguments or QMP commands) 38c3e24cffSThomas Huth 39c3e24cffSThomas Huth * Download (and cache) remote data files, such as firmware and kernel 40c3e24cffSThomas Huth images 41c3e24cffSThomas Huth 42c3e24cffSThomas HuthRunning tests 43c3e24cffSThomas Huth------------- 44c3e24cffSThomas Huth 45c3e24cffSThomas HuthYou can run the functional tests simply by executing: 46c3e24cffSThomas Huth 47c3e24cffSThomas Huth.. code:: 48c3e24cffSThomas Huth 49c3e24cffSThomas Huth make check-functional 50c3e24cffSThomas Huth 51c3e24cffSThomas HuthIt is also possible to run tests for a certain target only, for example 52c3e24cffSThomas Huththe following line will only run the tests for the x86_64 target: 53c3e24cffSThomas Huth 54c3e24cffSThomas Huth.. code:: 55c3e24cffSThomas Huth 56c3e24cffSThomas Huth make check-functional-x86_64 57c3e24cffSThomas Huth 58c3e24cffSThomas HuthTo run a single test file without the meson test runner, you can also 59c3e24cffSThomas Huthexecute the file directly by specifying two environment variables first, 60c3e24cffSThomas Huththe PYTHONPATH that has to include the python folder and the tests/functional 61c3e24cffSThomas Huthfolder of the source tree, and QEMU_TEST_QEMU_BINARY that has to point 62*4a722d2eSThomas Huthto the QEMU binary that should be used for the test. The current working 63*4a722d2eSThomas Huthdirectory should be your build folder. For example:: 64c3e24cffSThomas Huth 65c3e24cffSThomas Huth $ export PYTHONPATH=../python:../tests/functional 66c3e24cffSThomas Huth $ export QEMU_TEST_QEMU_BINARY=$PWD/qemu-system-x86_64 67*4a722d2eSThomas Huth $ pyvenv/bin/python3 ../tests/functional/test_file.py 68c3e24cffSThomas Huth 69dbaaef7dSDaniel P. BerrangéThe test framework will automatically purge any scratch files created during 70dbaaef7dSDaniel P. Berrangéthe tests. If needing to debug a failed test, it is possible to keep these 71dbaaef7dSDaniel P. Berrangéfiles around on disk by setting ```QEMU_TEST_KEEP_SCRATCH=1``` as an env 72dbaaef7dSDaniel P. Berrangévariable. Any preserved files will be deleted the next time the test is run 73dbaaef7dSDaniel P. Berrangéwithout this variable set. 74dbaaef7dSDaniel P. Berrangé 75c3e24cffSThomas HuthOverview 76c3e24cffSThomas Huth-------- 77c3e24cffSThomas Huth 78c3e24cffSThomas HuthThe ``tests/functional/qemu_test`` directory provides the ``qemu_test`` 79c3e24cffSThomas HuthPython module, containing the ``qemu_test.QemuSystemTest`` class. 80c3e24cffSThomas HuthHere is a simple usage example: 81c3e24cffSThomas Huth 82c3e24cffSThomas Huth.. code:: 83c3e24cffSThomas Huth 84c3e24cffSThomas Huth #!/usr/bin/env python3 85c3e24cffSThomas Huth 86c3e24cffSThomas Huth from qemu_test import QemuSystemTest 87c3e24cffSThomas Huth 88c3e24cffSThomas Huth class Version(QemuSystemTest): 89c3e24cffSThomas Huth 90c3e24cffSThomas Huth def test_qmp_human_info_version(self): 91c3e24cffSThomas Huth self.vm.launch() 92c3e24cffSThomas Huth res = self.vm.cmd('human-monitor-command', 93c3e24cffSThomas Huth command_line='info version') 94c3e24cffSThomas Huth self.assertRegex(res, r'^(\d+\.\d+\.\d)') 95c3e24cffSThomas Huth 96c3e24cffSThomas Huth if __name__ == '__main__': 97c3e24cffSThomas Huth QemuSystemTest.main() 98c3e24cffSThomas Huth 99c3e24cffSThomas HuthBy providing the "hash bang" line at the beginning of the script, marking 100c3e24cffSThomas Huththe file as executable and by calling into QemuSystemTest.main(), the test 101c3e24cffSThomas Huthcan also be run stand-alone, without a test runner. OTOH when run via a test 102c3e24cffSThomas Huthrunner, the QemuSystemTest.main() function takes care of running the test 103c3e24cffSThomas Huthfunctions in the right fassion (e.g. with TAP output that is required by the 104c3e24cffSThomas Huthmeson test runner). 105c3e24cffSThomas Huth 106c3e24cffSThomas HuthThe ``qemu_test.QemuSystemTest`` base test class 107c3e24cffSThomas Huth^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 108c3e24cffSThomas Huth 109c3e24cffSThomas HuthThe ``qemu_test.QemuSystemTest`` class has a number of characteristics 110c3e24cffSThomas Huththat are worth being mentioned. 111c3e24cffSThomas Huth 112c3e24cffSThomas HuthFirst of all, it attempts to give each test a ready to use QEMUMachine 113c3e24cffSThomas Huthinstance, available at ``self.vm``. Because many tests will tweak the 114c3e24cffSThomas HuthQEMU command line, launching the QEMUMachine (by using ``self.vm.launch()``) 115c3e24cffSThomas Huthis left to the test writer. 116c3e24cffSThomas Huth 117c3e24cffSThomas HuthThe base test class has also support for tests with more than one 118c3e24cffSThomas HuthQEMUMachine. The way to get machines is through the ``self.get_vm()`` 119c3e24cffSThomas Huthmethod which will return a QEMUMachine instance. The ``self.get_vm()`` 120c3e24cffSThomas Huthmethod accepts arguments that will be passed to the QEMUMachine creation 121c3e24cffSThomas Huthand also an optional ``name`` attribute so you can identify a specific 122c3e24cffSThomas Huthmachine and get it more than once through the tests methods. A simple 123c3e24cffSThomas Huthand hypothetical example follows: 124c3e24cffSThomas Huth 125c3e24cffSThomas Huth.. code:: 126c3e24cffSThomas Huth 127c3e24cffSThomas Huth from qemu_test import QemuSystemTest 128c3e24cffSThomas Huth 129c3e24cffSThomas Huth class MultipleMachines(QemuSystemTest): 130c3e24cffSThomas Huth def test_multiple_machines(self): 131c3e24cffSThomas Huth first_machine = self.get_vm() 132c3e24cffSThomas Huth second_machine = self.get_vm() 133c3e24cffSThomas Huth self.get_vm(name='third_machine').launch() 134c3e24cffSThomas Huth 135c3e24cffSThomas Huth first_machine.launch() 136c3e24cffSThomas Huth second_machine.launch() 137c3e24cffSThomas Huth 138c3e24cffSThomas Huth first_res = first_machine.cmd( 139c3e24cffSThomas Huth 'human-monitor-command', 140c3e24cffSThomas Huth command_line='info version') 141c3e24cffSThomas Huth 142c3e24cffSThomas Huth second_res = second_machine.cmd( 143c3e24cffSThomas Huth 'human-monitor-command', 144c3e24cffSThomas Huth command_line='info version') 145c3e24cffSThomas Huth 146c3e24cffSThomas Huth third_res = self.get_vm(name='third_machine').cmd( 147c3e24cffSThomas Huth 'human-monitor-command', 148c3e24cffSThomas Huth command_line='info version') 149c3e24cffSThomas Huth 150c3e24cffSThomas Huth self.assertEqual(first_res, second_res, third_res) 151c3e24cffSThomas Huth 152c3e24cffSThomas HuthAt test "tear down", ``qemu_test.QemuSystemTest`` handles all the QEMUMachines 153c3e24cffSThomas Huthshutdown. 154c3e24cffSThomas Huth 155c3e24cffSThomas HuthQEMUMachine 156c3e24cffSThomas Huth----------- 157c3e24cffSThomas Huth 158c3e24cffSThomas HuthThe QEMUMachine API is already widely used in the Python iotests, 159c3e24cffSThomas Huthdevice-crash-test and other Python scripts. It's a wrapper around the 160c3e24cffSThomas Huthexecution of a QEMU binary, giving its users: 161c3e24cffSThomas Huth 162c3e24cffSThomas Huth * the ability to set command line arguments to be given to the QEMU 163c3e24cffSThomas Huth binary 164c3e24cffSThomas Huth 165c3e24cffSThomas Huth * a ready to use QMP connection and interface, which can be used to 166c3e24cffSThomas Huth send commands and inspect its results, as well as asynchronous 167c3e24cffSThomas Huth events 168c3e24cffSThomas Huth 169c3e24cffSThomas Huth * convenience methods to set commonly used command line arguments in 170c3e24cffSThomas Huth a more succinct and intuitive way 171c3e24cffSThomas Huth 172c3e24cffSThomas HuthQEMU binary selection 173c3e24cffSThomas Huth^^^^^^^^^^^^^^^^^^^^^ 174c3e24cffSThomas Huth 175c3e24cffSThomas HuthThe QEMU binary used for the ``self.vm`` QEMUMachine instance will 176c3e24cffSThomas Huthprimarily depend on the value of the ``qemu_bin`` class attribute. 177c3e24cffSThomas HuthIf it is not explicitly set by the test code, its default value will 178c3e24cffSThomas Huthbe the result the QEMU_TEST_QEMU_BINARY environment variable. 179c3e24cffSThomas Huth 1801a8755a5SDaniel P. BerrangéDebugging hung QEMU 1811a8755a5SDaniel P. Berrangé^^^^^^^^^^^^^^^^^^^ 1821a8755a5SDaniel P. Berrangé 1831a8755a5SDaniel P. BerrangéWhen test cases go wrong it may be helpful to debug a stalled QEMU 1841a8755a5SDaniel P. Berrangéprocess. While the QEMUMachine class owns the primary QMP monitor 1851a8755a5SDaniel P. Berrangésocket, it is possible to request a second QMP monitor be created 1861a8755a5SDaniel P. Berrangéby setting the ``QEMU_TEST_QMP_BACKDOOR`` env variable to refer 1871a8755a5SDaniel P. Berrangéto a UNIX socket name. The ``qmp-shell`` command can then be 1881a8755a5SDaniel P. Berrangéattached to the stalled QEMU to examine its live state. 1891a8755a5SDaniel P. Berrangé 190c3e24cffSThomas HuthAttribute reference 191c3e24cffSThomas Huth------------------- 192c3e24cffSThomas Huth 193c3e24cffSThomas HuthQemuBaseTest 194c3e24cffSThomas Huth^^^^^^^^^^^^ 195c3e24cffSThomas Huth 196c3e24cffSThomas HuthThe following attributes are available on any ``qemu_test.QemuBaseTest`` 197c3e24cffSThomas Huthinstance. 198c3e24cffSThomas Huth 199c3e24cffSThomas Hutharch 200c3e24cffSThomas Huth"""" 201c3e24cffSThomas Huth 202c3e24cffSThomas HuthThe target architecture of the QEMU binary. 203c3e24cffSThomas Huth 204c3e24cffSThomas HuthTests are also free to use this attribute value, for their own needs. 205c3e24cffSThomas HuthA test may, for instance, use this value when selecting the architecture 206c3e24cffSThomas Huthof a kernel or disk image to boot a VM with. 207c3e24cffSThomas Huth 208c3e24cffSThomas Huthqemu_bin 209c3e24cffSThomas Huth"""""""" 210c3e24cffSThomas Huth 211c3e24cffSThomas HuthThe preserved value of the ``QEMU_TEST_QEMU_BINARY`` environment 212c3e24cffSThomas Huthvariable. 213c3e24cffSThomas Huth 214c3e24cffSThomas HuthQemuUserTest 215c3e24cffSThomas Huth^^^^^^^^^^^^ 216c3e24cffSThomas Huth 217c3e24cffSThomas HuthThe QemuUserTest class can be used for running an executable via the 218c3e24cffSThomas Huthusermode emulation binaries. 219c3e24cffSThomas Huth 220c3e24cffSThomas HuthQemuSystemTest 221c3e24cffSThomas Huth^^^^^^^^^^^^^^ 222c3e24cffSThomas Huth 223c3e24cffSThomas HuthThe QemuSystemTest class can be used for running tests via one of the 224c3e24cffSThomas Huthqemu-system-* binaries. 225c3e24cffSThomas Huth 226c3e24cffSThomas Huthvm 227c3e24cffSThomas Huth"" 228c3e24cffSThomas Huth 229c3e24cffSThomas HuthA QEMUMachine instance, initially configured according to the given 230c3e24cffSThomas Huth``qemu_bin`` parameter. 231c3e24cffSThomas Huth 232c3e24cffSThomas Huthcpu 233c3e24cffSThomas Huth""" 234c3e24cffSThomas Huth 235c3e24cffSThomas HuthThe cpu model that will be set to all QEMUMachine instances created 236c3e24cffSThomas Huthby the test. 237c3e24cffSThomas Huth 238c3e24cffSThomas Huthmachine 239c3e24cffSThomas Huth""""""" 240c3e24cffSThomas Huth 241c3e24cffSThomas HuthThe machine type that will be set to all QEMUMachine instances created 242c3e24cffSThomas Huthby the test. By using the set_machine() function of the QemuSystemTest 243c3e24cffSThomas Huthclass to set this attribute, you can automatically check whether the 244c3e24cffSThomas Huthmachine is available to skip the test in case it is not built into the 245c3e24cffSThomas HuthQEMU binary. 246c3e24cffSThomas Huth 247c3e24cffSThomas HuthAsset handling 248c3e24cffSThomas Huth-------------- 249c3e24cffSThomas Huth 250c3e24cffSThomas HuthMany functional tests download assets (e.g. Linux kernels, initrds, 251c3e24cffSThomas Huthfirmware images, etc.) from the internet to be able to run tests with 252c3e24cffSThomas Huththem. This imposes additional challenges to the test framework. 253c3e24cffSThomas Huth 254c3e24cffSThomas HuthFirst there is the the problem that some people might not have an 255c3e24cffSThomas Huthunconstrained internet connection, so such tests should not be run by 256c3e24cffSThomas Huthdefault when running ``make check``. To accomplish this situation, 257c3e24cffSThomas Huththe tests that download files should only be added to the "thorough" 258c3e24cffSThomas Huthspeed mode in the meson.build file, while the "quick" speed mode is 259c3e24cffSThomas Huthfine for functional tests that can be run without downloading files. 260c3e24cffSThomas Huth``make check`` then only runs the quick functional tests along with 261c3e24cffSThomas Huththe other quick tests from the other test suites. If you choose to 262c3e24cffSThomas Huthrun only run ``make check-functional``, the "thorough" tests will be 263c3e24cffSThomas Huthexecuted, too. And to run all functional tests along with the others, 264c3e24cffSThomas Huthyou can use something like:: 265c3e24cffSThomas Huth 266c3e24cffSThomas Huth make -j$(nproc) check SPEED=thorough 267c3e24cffSThomas Huth 268c3e24cffSThomas HuthThe second problem with downloading files from the internet are time 269c3e24cffSThomas Huthconstraints. The time for downloading files should not be taken into 270c3e24cffSThomas Huthaccount when the test is running and the timeout of the test is ticking 271c3e24cffSThomas Huth(since downloading can be very slow, depending on the network bandwidth). 272c3e24cffSThomas HuthThis problem is solved by downloading the assets ahead of time, before 273c3e24cffSThomas Huththe tests are run. This pre-caching is done with the qemu_test.Asset 274c3e24cffSThomas Huthclass. To use it in your test, declare an asset in your test class with 275c3e24cffSThomas Huthits URL and SHA256 checksum like this:: 276c3e24cffSThomas Huth 277c3e24cffSThomas Huth ASSET_somename = ( 278c3e24cffSThomas Huth ('https://www.qemu.org/assets/images/qemu_head_200.png'), 279c3e24cffSThomas Huth '34b74cad46ea28a2966c1d04e102510daf1fd73e6582b6b74523940d5da029dd') 280c3e24cffSThomas Huth 281c3e24cffSThomas HuthIn your test function, you can then get the file name of the cached 282c3e24cffSThomas Huthasset like this:: 283c3e24cffSThomas Huth 284c3e24cffSThomas Huth def test_function(self): 285c3e24cffSThomas Huth file_path = self.ASSET_somename.fetch() 286c3e24cffSThomas Huth 287c3e24cffSThomas HuthThe pre-caching will be done automatically when running 288c3e24cffSThomas Huth``make check-functional`` (but not when running e.g. 289c3e24cffSThomas Huth``make check-functional-<target>``). In case you just want to download 290c3e24cffSThomas Huththe assets without running the tests, you can do so by running:: 291c3e24cffSThomas Huth 292c3e24cffSThomas Huth make precache-functional 293c3e24cffSThomas Huth 294c3e24cffSThomas HuthThe cache is populated in the ``~/.cache/qemu/download`` directory by 295c3e24cffSThomas Huthdefault, but the location can be changed by setting the 296c3e24cffSThomas Huth``QEMU_TEST_CACHE_DIR`` environment variable. 297c3e24cffSThomas Huth 298c3e24cffSThomas HuthSkipping tests 299c3e24cffSThomas Huth-------------- 300c3e24cffSThomas Huth 301c3e24cffSThomas HuthSince the test framework is based on the common Python unittest framework, 302c3e24cffSThomas Huthyou can use the usual Python decorators which allow for easily skipping 303c3e24cffSThomas Huthtests running under certain conditions, for example, on the lack of a binary 304c3e24cffSThomas Huthon the test system or when the running environment is a CI system. For further 305c3e24cffSThomas Huthinformation about those decorators, please refer to: 306c3e24cffSThomas Huth 307c3e24cffSThomas Huth https://docs.python.org/3/library/unittest.html#skipping-tests-and-expected-failures 308c3e24cffSThomas Huth 309c3e24cffSThomas HuthWhile the conditions for skipping tests are often specifics of each one, there 310c3e24cffSThomas Huthare recurring scenarios identified by the QEMU developers and the use of 311c3e24cffSThomas Huthenvironment variables became a kind of standard way to enable/disable tests. 312c3e24cffSThomas Huth 313c3e24cffSThomas HuthHere is a list of the most used variables: 314c3e24cffSThomas Huth 315c3e24cffSThomas HuthQEMU_TEST_ALLOW_LARGE_STORAGE 316c3e24cffSThomas Huth^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 317c3e24cffSThomas HuthTests which are going to fetch or produce assets considered *large* are not 318c3e24cffSThomas Huthgoing to run unless that ``QEMU_TEST_ALLOW_LARGE_STORAGE=1`` is exported on 319c3e24cffSThomas Huththe environment. 320c3e24cffSThomas Huth 321c3e24cffSThomas HuthThe definition of *large* is a bit arbitrary here, but it usually means an 322c3e24cffSThomas Huthasset which occupies at least 1GB of size on disk when uncompressed. 323c3e24cffSThomas Huth 324c3e24cffSThomas HuthQEMU_TEST_ALLOW_UNTRUSTED_CODE 325c3e24cffSThomas Huth^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 326c3e24cffSThomas HuthThere are tests which will boot a kernel image or firmware that can be 327c3e24cffSThomas Huthconsidered not safe to run on the developer's workstation, thus they are 328c3e24cffSThomas Huthskipped by default. The definition of *not safe* is also arbitrary but 329c3e24cffSThomas Huthusually it means a blob which either its source or build process aren't 330c3e24cffSThomas Huthpublic available. 331c3e24cffSThomas Huth 332c3e24cffSThomas HuthYou should export ``QEMU_TEST_ALLOW_UNTRUSTED_CODE=1`` on the environment in 333c3e24cffSThomas Huthorder to allow tests which make use of those kind of assets. 334c3e24cffSThomas Huth 335c3e24cffSThomas HuthQEMU_TEST_FLAKY_TESTS 336c3e24cffSThomas Huth^^^^^^^^^^^^^^^^^^^^^ 337c3e24cffSThomas HuthSome tests are not working reliably and thus are disabled by default. 338c3e24cffSThomas HuthThis includes tests that don't run reliably on GitLab's CI which 339c3e24cffSThomas Huthusually expose real issues that are rarely seen on developer machines 340c3e24cffSThomas Huthdue to the constraints of the CI environment. If you encounter a 341c3e24cffSThomas Huthsimilar situation then raise a bug and then mark the test as shown on 342c3e24cffSThomas Huththe code snippet below: 343c3e24cffSThomas Huth 344c3e24cffSThomas Huth.. code:: 345c3e24cffSThomas Huth 346c3e24cffSThomas Huth # See https://gitlab.com/qemu-project/qemu/-/issues/nnnn 347c3e24cffSThomas Huth @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') 348c3e24cffSThomas Huth def test(self): 349c3e24cffSThomas Huth do_something() 350c3e24cffSThomas Huth 351c3e24cffSThomas HuthTests should not live in this state forever and should either be fixed 352c3e24cffSThomas Huthor eventually removed. 353c3e24cffSThomas Huth 354c3e24cffSThomas Huth 355c3e24cffSThomas Huth.. _unittest: https://docs.python.org/3/library/unittest.html 356