1# SPDX-License-Identifier: GPL-2.0-or-later 2# 3# Decorators useful in functional tests 4 5import importlib 6import os 7import platform 8from unittest import skipUnless 9 10from .cmd import which 11 12''' 13Decorator to skip execution of a test if the list 14of command binaries is not available in $PATH. 15Example: 16 17 @skipIfMissingCommands("mkisofs", "losetup") 18''' 19def skipIfMissingCommands(*args): 20 has_cmds = True 21 for cmd in args: 22 if not which(cmd): 23 has_cmds = False 24 break 25 26 return skipUnless(has_cmds, 'required command(s) "%s" not installed' % 27 ", ".join(args)) 28 29''' 30Decorator to skip execution of a test if the current 31host machine does not match one of the permitted 32machines. 33Example 34 35 @skipIfNotMachine("x86_64", "aarch64") 36''' 37def skipIfNotMachine(*args): 38 return skipUnless(platform.machine() in args, 39 'not running on one of the required machine(s) "%s"' % 40 ", ".join(args)) 41 42''' 43Decorator to skip execution of flaky tests, unless 44the $QEMU_TEST_FLAKY_TESTS environment variable is set. 45A bug URL must be provided that documents the observed 46failure behaviour, so it can be tracked & re-evaluated 47in future. 48 49Historical tests may be providing "None" as the bug_url 50but this should not be done for new test. 51 52Example: 53 54 @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/NNN") 55''' 56def skipFlakyTest(bug_url): 57 if bug_url is None: 58 bug_url = "FIXME: reproduce flaky test and file bug report or remove" 59 return skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 60 f'Test is unstable: {bug_url}') 61 62''' 63Decorator to skip execution of tests which are likely 64to execute untrusted commands on the host, or commands 65which process untrusted code, unless the 66$QEMU_TEST_ALLOW_UNTRUSTED_CODE env var is set. 67Example: 68 69 @skipUntrustedTest() 70''' 71def skipUntrustedTest(): 72 return skipUnless(os.getenv('QEMU_TEST_ALLOW_UNTRUSTED_CODE'), 73 'Test runs untrusted code / processes untrusted data') 74 75''' 76Decorator to skip execution of tests which need large 77data storage (over around 500MB-1GB mark) on the host, 78unless the $QEMU_TEST_ALLOW_LARGE_STORAGE environment 79variable is set 80 81Example: 82 83 @skipBigDataTest() 84''' 85def skipBigDataTest(): 86 return skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'), 87 'Test requires large host storage space') 88 89''' 90Decorator to skip execution of tests which have a really long 91runtime (and might e.g. time out if QEMU has been compiled with 92debugging enabled) unless the $QEMU_TEST_ALLOW_SLOW 93environment variable is set 94 95Example: 96 97 @skipSlowTest() 98''' 99def skipSlowTest(): 100 return skipUnless(os.getenv('QEMU_TEST_ALLOW_SLOW'), 101 'Test has a very long runtime and might time out') 102 103''' 104Decorator to skip execution of a test if the list 105of python imports is not available. 106Example: 107 108 @skipIfMissingImports("numpy", "cv2") 109''' 110def skipIfMissingImports(*args): 111 has_imports = True 112 for impname in args: 113 try: 114 importlib.import_module(impname) 115 except ImportError: 116 has_imports = False 117 break 118 119 return skipUnless(has_imports, 'required import(s) "%s" not installed' % 120 ", ".join(args)) 121