5 This contains constant definitions, helpers, and a Requirements class that can
6 be used to help with running fio tests.
14 import multiprocessing
24 'stderr_empty': False,
29 'stderr_empty': False,
34 def get_file(filename):
35 """Safely read a file."""
40 with open(filename, "r", encoding=locale.getpreferredencoding()) as output_file:
41 file_data = output_file.read()
45 return file_data, success
49 """Requirements consists of multiple run environment characteristics.
50 These are to determine if a particular test can be run"""
64 def __init__(self, fio_root, args):
65 Requirements._not_macos = platform.system() != "Darwin"
66 Requirements._not_windows = platform.system() != "Windows"
67 Requirements._linux = platform.system() == "Linux"
69 if Requirements._linux:
70 config_file = os.path.join(fio_root, "config-host.h")
71 contents, success = get_file(config_file)
73 print(f"Unable to open {config_file} to check requirements")
74 Requirements._zbd = True
76 Requirements._zbd = "CONFIG_HAS_BLKZONED" in contents
77 Requirements._libaio = "CONFIG_LIBAIO" in contents
79 contents, success = get_file("/proc/kallsyms")
81 print("Unable to open '/proc/kallsyms' to probe for io_uring support")
83 Requirements._io_uring = "io_uring_setup" in contents
85 Requirements._root = os.geteuid() == 0
86 if Requirements._zbd and Requirements._root:
88 subprocess.run(["modprobe", "null_blk"],
89 stdout=subprocess.PIPE,
90 stderr=subprocess.PIPE)
91 if os.path.exists("/sys/module/null_blk/parameters/zoned"):
92 Requirements._zoned_nullb = True
96 if platform.system() == "Windows":
97 utest_exe = "unittest.exe"
99 utest_exe = "unittest"
100 unittest_path = os.path.join(fio_root, "unittests", utest_exe)
101 Requirements._unittests = os.path.exists(unittest_path)
103 Requirements._cpucount4 = multiprocessing.cpu_count() >= 4
104 Requirements._nvmecdev = args.nvmecdev
109 Requirements.io_uring,
112 Requirements.zoned_nullb,
113 Requirements.not_macos,
114 Requirements.not_windows,
115 Requirements.unittests,
116 Requirements.cpucount4,
117 Requirements.nvmecdev,
121 logging.debug("Requirements: Requirement '%s' met? %s", desc, value)
125 """Are we running on Linux?"""
126 return Requirements._linux, "Linux required"
130 """Is libaio available?"""
131 return Requirements._libaio, "libaio required"
135 """Is io_uring available?"""
136 return Requirements._io_uring, "io_uring required"
140 """Is ZBD support available?"""
141 return Requirements._zbd, "Zoned block device support required"
145 """Are we running as root?"""
146 return Requirements._root, "root required"
149 def zoned_nullb(cls):
150 """Are zoned null block devices available?"""
151 return Requirements._zoned_nullb, "Zoned null block device support required"
155 """Are we running on a platform other than macOS?"""
156 return Requirements._not_macos, "platform other than macOS required"
159 def not_windows(cls):
160 """Are we running on a platform other than Windws?"""
161 return Requirements._not_windows, "platform other than Windows required"
165 """Were unittests built?"""
166 return Requirements._unittests, "Unittests support required"
170 """Do we have at least 4 CPUs?"""
171 return Requirements._cpucount4, "4+ CPUs required"
175 """Do we have an NVMe character device to test?"""
176 return Requirements._nvmecdev, "NVMe character device test target required"