Skip to content

Commit 3eb89fd

Browse files
committed
conftest: allow setting a minimum kernel version
For a while we've been beating around the bush by having a way to filter out which vmcores we run tests against. But that doesn't help filtering out kernel versions for live tests. Most new functionality doesn't necessarily need to work on UEK4, so we want it to be easy to skip tests below the minimum version. Signed-off-by: Stephen Brennan <[email protected]>
1 parent 2c5fc12 commit 3eb89fd

File tree

1 file changed

+60
-39
lines changed

1 file changed

+60
-39
lines changed

tests/conftest.py

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pathlib import Path
77
from typing import List
88
from typing import Optional
9+
from typing import Tuple
910

1011
import drgn
1112
import pytest
@@ -24,48 +25,14 @@
2425
CTF_FILE: Optional[str] = None
2526

2627
CORE_DIR = Path.cwd() / "vmcores"
28+
KVER: Optional[KernelVersion] = None
29+
PROG: Optional[drgn.Program] = None
2730

2831

2932
@pytest.fixture(scope="session")
3033
def prog() -> drgn.Program:
31-
p = drgn.Program()
32-
if VMCORE:
33-
p.set_core_dump(VMCORE)
34-
elif os.geteuid() == 0:
35-
p.set_kernel()
36-
else:
37-
from drgn.internal.sudohelper import open_via_sudo
38-
39-
p.set_core_dump(open_via_sudo("/proc/kcore", os.O_RDONLY))
40-
if CTF:
41-
try:
42-
from drgn.helpers.linux.ctf import load_ctf
43-
44-
# CTF_FILE may be None here, in which case the default CTF file
45-
# location is used (similar to below, where default DWARF debuginfo
46-
# is loaded if we don't have a path).
47-
load_ctf(p, path=CTF_FILE)
48-
p.cache["using_ctf"] = True
49-
# Mark in-tree modules as having debuginfo, so that the module API
50-
# doesn't attempt to load debuginfo implicitly.
51-
for module in p.modules():
52-
if isinstance(module, MainModule) or module_is_in_tree(module):
53-
module.debug_file_status = ModuleFileStatus.DONT_NEED
54-
except ModuleNotFoundError:
55-
raise Exception("CTF is not supported, cannot run CTF test")
56-
elif DEBUGINFO:
57-
p.load_debug_info(DEBUGINFO)
58-
else:
59-
# Some UEK versions had mismatched vmlinux build IDs due to packaging
60-
# issues. Most have been fixed, but for the remainder, set the main
61-
# module's build ID to None manually, forcing drgn to skip verifying
62-
# build IDs as it finds debuginfo.
63-
ver = KernelVersion.parse(p["UTS_RELEASE"].string_().decode())
64-
if has_vmlinux_build_id_mismatch(ver):
65-
p.create_loaded_modules()
66-
p.main_module().build_id = None
67-
p.load_default_debug_info()
68-
return p
34+
assert PROG is not None
35+
return PROG
6936

7037

7138
@pytest.fixture(scope="session")
@@ -96,7 +63,8 @@ def log_global_env_facts(prog, record_testsuite_property):
9663

9764
@pytest.fixture(scope="session")
9865
def kver(prog):
99-
return KernelVersion.parse(prog["UTS_RELEASE"].string_().decode())
66+
assert KVER is not None
67+
return KVER
10068

10169

10270
def pytest_addoption(parser):
@@ -154,6 +122,9 @@ def pytest_configure(config):
154122
config.addinivalue_line(
155123
"markers", "skip_vmcore(name): skip when debugging this core dump"
156124
)
125+
config.addinivalue_line(
126+
"markers", "kver_min(ver): specify minimum kernel version (x.y.z)"
127+
)
157128

158129
core_dir = config.getoption("vmcore_dir")
159130
if core_dir:
@@ -204,11 +175,54 @@ def pytest_configure(config):
204175
if CTF:
205176
print("TESTING WITH CTF")
206177

178+
global PROG
179+
PROG = drgn.Program()
180+
if VMCORE:
181+
PROG.set_core_dump(VMCORE)
182+
elif os.geteuid() == 0:
183+
PROG.set_kernel()
184+
else:
185+
from drgn.internal.sudohelper import open_via_sudo
186+
187+
PROG.set_core_dump(open_via_sudo("/proc/kcore", os.O_RDONLY))
188+
189+
global KVER
190+
KVER = KernelVersion.parse(PROG["UTS_RELEASE"].string_().decode())
191+
if CTF:
192+
try:
193+
from drgn.helpers.linux.ctf import load_ctf
194+
195+
# CTF_FILE may be None here, in which case the default CTF file
196+
# location is used (similar to below, where default DWARF debuginfo
197+
# is loaded if we don't have a path).
198+
load_ctf(PROG, path=CTF_FILE)
199+
PROG.cache["using_ctf"] = True
200+
# Mark in-tree modules as having debuginfo, so that the module API
201+
# doesn't attempt to load debuginfo implicitly.
202+
for module in PROG.modules():
203+
if isinstance(module, MainModule) or module_is_in_tree(module):
204+
module.debug_file_status = ModuleFileStatus.DONT_NEED
205+
except ModuleNotFoundError:
206+
raise Exception("CTF is not supported, cannot run CTF test")
207+
elif DEBUGINFO:
208+
PROG.load_debug_info(DEBUGINFO)
209+
else:
210+
# Some UEK versions had mismatched vmlinux build IDs due to packaging
211+
# issues. Most have been fixed, but for the remainder, set the main
212+
# module's build ID to None manually, forcing drgn to skip verifying
213+
# build IDs as it finds debuginfo.
214+
if has_vmlinux_build_id_mismatch(KVER):
215+
PROG.create_loaded_modules()
216+
PROG.main_module().build_id = None
217+
PROG.load_default_debug_info()
218+
207219

208220
def pytest_runtest_setup(item: pytest.Item):
209221
skip_live = False
210222
vmcore_pats = []
211223
vmcore_skip_pats = []
224+
kver_min: Tuple[int, ...] = (0,)
225+
assert KVER is not None
212226

213227
for mark in item.iter_markers():
214228
if mark.name == "skip_live":
@@ -217,10 +231,17 @@ def pytest_runtest_setup(item: pytest.Item):
217231
vmcore_pats.append(mark.args[0])
218232
if mark.name == "skip_vmcore":
219233
vmcore_skip_pats.append(mark.args[0])
234+
if mark.name == "kver_min":
235+
kver_min = max(kver_min, tuple(map(int, mark.args[0].split("."))))
220236

221237
if vmcore_pats and vmcore_skip_pats:
222238
raise ValueError("Can't mark a test both: vmcore() and skip_vmcore()")
223239

240+
if KVER.version_tuple < kver_min:
241+
pytest.skip(
242+
f"Skipped test (requires minimum kernel version: {kver_min})"
243+
)
244+
224245
if VMCORE:
225246
if vmcore_pats:
226247
if not any(fnmatch(VMCORE_NAME, p) for p in vmcore_pats):

0 commit comments

Comments
 (0)