xref: /openbmc/qemu/tests/functional/qemu_test/decorators.py (revision 257de641e091f4f5063298b9d717f3f15f8917f2)
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 a test if the list
91of python imports is not available.
92Example:
93
94  @skipIfMissingImports("numpy", "cv2")
95'''
96def skipIfMissingImports(*args):
97    has_imports = True
98    for impname in args:
99        try:
100            importlib.import_module(impname)
101        except ImportError:
102            has_imports = False
103            break
104
105    return skipUnless(has_imports, 'required import(s) "%s" not installed' %
106                                   ", ".join(args))
107