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