Skip to content

Commit 6b76b74

Browse files
add CI workflow to run the test suite
Runs make test on every push to master and every pull_request. Kernel verifier tests need passwordless sudo and a kernel with BTF/BPF enabled, which isn't guaranteed on every runner, so the workflow probes for working sudo first and only attempts them if it's there. Ubuntu's default apt packages need three adjustments to actually run this: bpftool is a virtual package provided by linux-tools-generic whose binary needs to be found and put on PATH manually; ctypeslib2's clang bindings default to the latest PyPI release, which doesn't match Ubuntu's libclang-16, so pin to clang==16.0.6 (older bindings stay forward-compatible with a newer system libclang); and llvmlite>=0.49 emits IR using the 'captures(none)' attribute spelling, matching the LLVM 22.1.0 it bundles internally, which Ubuntu's default LLVM 18 (and even 19) can't parse - install a matching-generation LLVM 22 from apt.llvm.org instead of the distro default. Also add ctypeslib2 and a pinned clang to the test extra: make test now regenerates vmlinux.py via tools/vmlinux-gen.py, which needs clang2py, and that dependency was previously only installed ad hoc in local dev venvs.
1 parent 5c05b11 commit 6b76b74

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Runs the pytest suite (IR generation + LLC compilation). Kernel verifier
2+
# tests additionally need passwordless sudo and a kernel with BTF/BPF
3+
# enabled, which isn't guaranteed on every runner, so we probe for working
4+
# sudo first and only attempt them if it's there.
5+
#
6+
# `push` is scoped to master only: branches here live in this repo rather
7+
# than forks, so a push to a branch with an open PR would otherwise fire
8+
# both `push` and `pull_request` for the same commit, running everything
9+
# twice. `pull_request` covers feature branches; `push` still gives master
10+
# a post-merge check.
11+
12+
name: Test
13+
14+
on:
15+
workflow_dispatch:
16+
push:
17+
branches: [master]
18+
pull_request:
19+
20+
jobs:
21+
test:
22+
name: Test
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v7
26+
27+
- uses: actions/setup-python@v7
28+
with:
29+
python-version: "3.12"
30+
31+
- name: Install system dependencies
32+
run: |
33+
sudo apt-get update
34+
sudo apt-get install -y lsb-release wget software-properties-common gnupg linux-tools-common linux-tools-generic
35+
36+
# Ubuntu's default `llvm`/`clang` packages (LLVM 18 on noble) are
37+
# too old to assemble the IR llvmlite>=0.49 emits: llvmlite's
38+
# ArgumentAttributes only knows the 'captures(none)' spelling of
39+
# the renamed 'nocapture' attribute, matching the LLVM 22.1.0 it
40+
# bundles internally - and an llc from an older LLVM (verified:
41+
# 19 still rejects it as a parse error) can't read that attribute
42+
# in the .ll text. Install a matching-generation LLVM from
43+
# apt.llvm.org instead of the distro default, and make its tools
44+
# the ones found on PATH.
45+
wget https://apt.llvm.org/llvm.sh
46+
chmod +x llvm.sh
47+
sudo ./llvm.sh 22 all
48+
sudo ln -sf /usr/bin/clang-22 /usr/local/bin/clang
49+
sudo ln -sf /usr/bin/llc-22 /usr/local/bin/llc
50+
clang --version
51+
llc --version
52+
53+
# bpftool isn't an installable package by itself on Ubuntu: it's a
54+
# virtual package provided by linux-tools-common + a kernel-flavor
55+
# linux-tools-<flavor> package. The runner's exact kernel version
56+
# has no matching linux-tools-<version> package, so the
57+
# update-alternatives symlink for `bpftool` doesn't get set up;
58+
# find whatever binary the generic-flavor package installed and
59+
# put it on PATH ourselves.
60+
bpftool_bin=$(sudo find /usr/lib/linux-tools* -name bpftool -type f 2>/dev/null | head -1)
61+
if [ -z "$bpftool_bin" ]; then
62+
echo "::error::Could not find a bpftool binary after installing linux-tools-generic"
63+
exit 1
64+
fi
65+
sudo ln -sf "$bpftool_bin" /usr/local/bin/bpftool
66+
bpftool version
67+
68+
- name: Install uv
69+
run: pip install uv
70+
71+
- name: Install project
72+
run: uv pip install --system -e ".[test]"
73+
74+
- name: Run test suite
75+
run: make test
76+
77+
- name: Check whether sudo is usable
78+
id: sudo-check
79+
run: |
80+
if sudo -n true 2>/dev/null; then
81+
echo "Passwordless sudo is available."
82+
echo "available=true" >> "$GITHUB_OUTPUT"
83+
else
84+
echo "No passwordless sudo on this runner; kernel verifier tests will be skipped."
85+
echo "available=false" >> "$GITHUB_OUTPUT"
86+
fi
87+
88+
- name: Run kernel verifier tests
89+
if: steps.sudo-check.outputs.available == 'true'
90+
run: |
91+
sudo -v
92+
make test-verifier

pyproject.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ docs = [
4444
test = [
4545
"pytest>=8.0",
4646
"pytest-cov>=5.0",
47+
"ctypeslib2",
48+
# Pinned rather than left to ctypeslib2's own (unpinned) dependency: pip
49+
# installs the latest release by default, and its libclang API surface
50+
# can be newer than the system libclang (e.g. Ubuntu 24.04 ships
51+
# libclang-16), which fails with a LibclangError about an undefined
52+
# symbol. Older bindings against a newer libclang stay compatible, so
53+
# pin to an old-enough release instead of pinning apt's libclang.
54+
"clang==16.0.6",
4755
]
4856

4957
[tool.setuptools.packages.find]

0 commit comments

Comments
 (0)