Skip to content

Commit 9974491

Browse files
r41k0uclaude
andcommitted
Tests: Load without -d in the verifier tests, and report a timeout properly
-d asks the kernel for the instruction-level verifier log on every load. For loop1, which makes the verifier walk nested loops, that log outgrows libbpf's buffer; the kernel fails the load with ENOSPC, libbpf doubles the buffer and verifies again, and on CI the load ran past the 30s timeout. A rejection still comes with its log without -d, since libbpf retries a failed load at log level 1 and prints it as a warning. The timeout path also returned a bare string where callers expect stdout and stderr, so a timeout surfaced as an AttributeError instead of the timeout. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 77a5ff1 commit 9974491

2 files changed

Lines changed: 18 additions & 9 deletions

File tree

‎tests/framework/verifier.py‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,34 @@
33
from collections import namedtuple
44
from pathlib import Path
55

6+
Output = namedtuple("Output", ["stdout", "stderr"])
67

7-
def verify_object(obj_path: Path) -> tuple[bool, str]:
8-
"""Run bpftool prog load -d to verify a BPF object file against the kernel verifier.
8+
9+
def verify_object(obj_path: Path) -> tuple[bool, Output]:
10+
"""Run bpftool prog load to verify a BPF object file against the kernel verifier.
911
1012
Pins the program temporarily at /sys/fs/bpf/bpf_prog_test_<uuid>, then removes it.
11-
Returns (success, combined_output). Requires sudo / root.
13+
Returns (success, Output(stdout, stderr)). Requires sudo / root.
14+
15+
No -d: it asks the kernel for the full instruction-level log (log level
16+
1+2+4) on every load. For a program that makes the verifier walk a loop that
17+
log outgrows libbpf's buffer, the kernel then fails the load with ENOSPC, and
18+
libbpf doubles the buffer and verifies the whole program again, until the
19+
load takes longer than the timeout. A rejection still comes with its log:
20+
libbpf retries a failed load at log level 1 and prints the log as a warning.
1221
"""
1322
pin_path = f"/sys/fs/bpf/bpf_prog_test_{uuid.uuid4().hex[:8]}"
1423
try:
1524
result = subprocess.run(
16-
["sudo", "bpftool", "prog", "load", "-d", str(obj_path), pin_path],
25+
["sudo", "bpftool", "prog", "load", str(obj_path), pin_path],
1726
capture_output=True,
1827
text=True,
1928
timeout=30,
2029
)
21-
Output = namedtuple("Output", ["stdout", "stderr"])
22-
output = Output(stdout=result.stdout, stderr=result.stderr)
23-
return result.returncode == 0, output
30+
return result.returncode == 0, Output(
31+
stdout=result.stdout, stderr=result.stderr
32+
)
2433
except subprocess.TimeoutExpired:
25-
return False, "bpftool timed out after 30s"
34+
return False, Output(stdout="", stderr="bpftool timed out after 30s")
2635
finally:
2736
subprocess.run(["sudo", "rm", "-f", pin_path], check=False, capture_output=True)

‎tests/test_verifier.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Level 3 — Kernel verifier tests.
33
44
For every passing BPF test file, compiles to a .o and runs:
5-
sudo bpftool prog load -d <file.o> /sys/fs/bpf/bpf_prog_test_<id>
5+
sudo bpftool prog load <file.o> /sys/fs/bpf/bpf_prog_test_<id>
66
77
These tests are opt-in: they require sudo and kernel access, and are gated
88
behind the `verifier` pytest mark. Run with:

0 commit comments

Comments
 (0)