Accepted
BPF programs run in the kernel, which creates testing challenges:
We needed a testing strategy that:
A mock syscall layer in clj-ebpf.mock simulates BPF operations:
(mock/with-mock-bpf {:mode :recording}
(let [m (maps/create {:type :hash ...})]
(maps/update! m key val)
(is (= val (maps/lookup m key)))))
Mock modes:
:passthrough - Real syscalls (needs root):recording - Record and replay:simulation - Full simulation, no syscallsUse BPF_PROG_TEST_RUN to test programs without attaching:
(let [prog (load-program xdp-prog :xdp)
result (test-run-program prog {:data-in packet})]
(is (= 2 (:retval result)))) ; XDP_PASS
Benefits:
Full integration tests with real BPF operations:
(deftest ^:integration xdp-attach-test
(with-xdp-program [prog "eth0" ...]
(is (some? (:fd prog)))))
Run separately: clojure -X:test :includes [:integration]
clj-ebpf.test-utils provides helpers:
(tu/with-bpf-test-context []
;; Maps and programs auto-cleaned up
(let [m (maps/create ...)]
...))
(tu/with-temp-map [m {:type :hash ...}]
...)
clj-ebpf.generators and clj-ebpf.properties for generative testing:
(defspec dsl-roundtrip 100
(prop/for-all [op gen-alu-op
dst gen-register
imm gen-imm32]
(valid-instruction? (dsl/alu-imm op dst imm))))
test/
clj_ebpf/
mock.clj ; Mock syscall layer
test_utils.clj ; Test fixtures and helpers
generators.clj ; test.check generators
properties.clj ; Property-based tests
*_test.clj ; Unit tests (mock)
integration/ ; Integration tests (real syscalls)
# Unit tests (no privileges needed)
clojure -X:test
# Integration tests (needs root/CAP_BPF)
sudo clojure -X:test :includes '[:integration]'
# All tests
sudo clojure -X:test :includes '[:unit :integration]'
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |