Skip to content

selftest adjacent tests - #98

Open
r41k0u wants to merge 5 commits into
masterfrom
tests/selftest-port-spike
Open

selftest adjacent tests#98
r41k0u wants to merge 5 commits into
masterfrom
tests/selftest-port-spike

Conversation

@r41k0u

@r41k0u r41k0u commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Ports some tests from linux kernel's bpf selftests to PythonBPF, based on https://claude.ai/code/artifact/37744cf3-ce6a-42c5-b5bf-88ead0c275d0

varun-r-mallya and others added 5 commits September 1, 2026 12:47
Ports that import from vmlinux need the same treatment as
tests/passing_tests/vmlinux/ -- skipped, not failed, when no vmlinux.py has been
generated for the running kernel. Without this they fail outright wherever one
is absent, CI included.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ports of programs from tools/testing/selftests/bpf/progs/ in the Linux tree,
each naming its upstream original in a header comment.

    tracing/tracepoint_sched_switch.py   test_tracepoint.c
    tracing/get_cgroup_id.py             get_cgroup_id_kern.c
    tracing/autoattach.py                test_autoattach.c

Deliberately a small spike rather than bulk coverage. The three sample different
global-variable shapes, since substituting for globals is what porting the rest
of the corpus will mostly consist of: none at all (the control case), a scalar
read plus a scalar write, and two flags written from two programs on two
different attach points.

They also widen the range of program types under test.
tracepoint/sched/sched_switch and raw_tp/sys_enter were previously unexercised;
@section writes its string straight into the ELF with no allowlist, so that
pass-through had only ever been tested against a handful of types.

Only the BPF half of each selftest is ported -- upstream pairs every program
with a userspace driver in prog_tests/ that loads and asserts, whereas this
framework compiles and verifies but never runs. tests/README.md now says so
explicitly, along with the WORKAROUND(globals) convention marking each map
substituted for a global.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ported faithfully from test_perf_skip.c, which reads the sampled instruction
pointer out of a perf_event context: ctx.regs.ip. That is two levels of struct
field access and PythonBPF supports one, so this lands as a strict expected
failure describing the gap.

_allocate_for_attribute in allocation_pass.py declines to allocate unless the
attribute's base is a plain Name, so the nested form is skipped. One level on
the same context works today -- ctx.sample_period compiles and llc's fine.

Worth noting for whoever picks this up: the failure surfaces as
'SyntaxError: Undefined variable actual', naming the assignment target rather
than the nested access responsible. The allocation pass declines quietly and the
expression pass then trips over the missing symbol.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The four ports were the experiment; this is the result. Covers whether
LLM-assisted porting is worth continuing (yes, in feature-sized increments), what
a passing port actually proves (a compiler assertion, not a behavioural one), and
the four distinct global-variable shapes the spike turned up.

Includes the finding that libbpf implements globals as single-element
BPF_MAP_TYPE_ARRAY maps, so a one-element ArrayMap -- not a HashMap -- is the
structurally faithful stand-in, and that the ELF half of global support already
works today via the machinery behind @bpfglobal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants