1# SPDX-License-Identifier: GPL-2.0-or-later 2# 3# Decorators useful in functional tests 4 5import os 6import platform 7from unittest import skipUnless 8 9from .cmd import which 10 11''' 12Decorator to skip execution of a test if the list 13of command binaries is not available in $PATH. 14Example: 15 16 @skipIfMissingCommands("mkisofs", "losetup") 17''' 18def skipIfMissingCommands(*args): 19 def has_cmds(cmdlist): 20 for cmd in cmdlist: 21 if not which(cmd): 22 return False 23 return True 24 25 return skipUnless(lambda: has_cmds(args), 26 '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(lambda: 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 a test if the list 91of python imports is not available. 92Example: 93 94 @skipIfMissingImports("numpy", "cv2") 95''' 96def skipIfMissingImports(*args): 97 def has_imports(importlist): 98 for impname in importlist: 99 try: 100 import impname 101 except ImportError: 102 return False 103 return True 104 105 return skipUnless(lambda: has_imports(args), 106 'required import(s) "%s" not installed' % 107 ", ".join(args)) 108