decorators.py 3.2 KB

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