Skip to content

test(ebpf): add eBPF program unit tests via BPF_PROG_TEST_RUN#2049

Merged
nddq merged 1 commit intomainfrom
test/ebpf-program-unit-tests
Apr 1, 2026
Merged

test(ebpf): add eBPF program unit tests via BPF_PROG_TEST_RUN#2049
nddq merged 1 commit intomainfrom
test/ebpf-program-unit-tests

Conversation

@nddq
Copy link
Copy Markdown
Member

@nddq nddq commented Feb 13, 2026

Description

Add an eBPF program unit test framework that executes compiled eBPF bytecode in the kernel using BPF_PROG_TEST_RUN (prog.Run() in cilium/ebpf). This validates actual kernel-side packet parsing logic rather than mocking the Go wrapper layer, catching bugs like wrong offsets, missing bounds checks, or incorrect flag handling that would otherwise only surface at runtime in a cluster.

Shared test infrastructure (pkg/plugin/ebpftest/):

  • helpers.go — privilege checks, map pinning removal, generic perf event reader, IP/port byte-order helpers, LPM trie filter map population, program runner
  • packet.go — TCP/UDP/ICMP/ARP packet construction via gopacket with configurable flags, timestamps, and payloads

Packetparser tests (pkg/plugin/packetparser/packetparser_ebpf_test.go) — 25 test functions covering:

  • Packet parsing: TCP flags (all 9 combinations), TCP timestamps, UDP, observation points, packet bytes field
  • Filter map: IP matching produces events, missing IPs produce none
  • Edge cases: runt packets, truncated IP/TCP headers, non-IPv4 (ARP/IPv6), ICMP
  • Conntrack perf events: is_reply across SYN/SYN-ACK/ACK, traffic direction per observation point, conntrack metrics counters, HIGH aggregation suppression, previously_observed_* fields
  • Conntrack map state (direct map reads): entry field initialization after SYN, flag bitmask accumulation across packets, reply packets updating RX-direction fields, is_direction_unknown for mid-stream connections, since-last-report counter accumulation and reset on FIN, lifetime metadata counters with ENABLE_CONNTRACK_METRICS, eviction time extension from SYN timeout to established
  • Recompilation variants: custom dynamic.h via loader.CompileEbpf for DATA_AGGREGATION_LEVEL=HIGH and ENABLE_CONNTRACK_METRICS=1

CI (.github/workflows/test-ebpf.yaml): matrix strategy on amd64 (ubuntu-latest) and arm64 (ubuntu-24.04-arm), compiles eBPF via go generate, runs tests with sudo.

Makefile: make test-ebpf target.

Related Issue

Partially addresses #876 — adds unit test coverage for packetparser eBPF programs. Remaining plugins (dropreason, dns, packetforward, etc.) can follow the same framework.

Checklist

  • I have read the contributing documentation.
  • I signed and signed-off the commits (git commit -S -s ...). See this documentation on signing commits.
  • I have correctly attributed the author(s) of the code.
  • I have tested the changes locally.
  • I have followed the project's style guidelines.
  • I have updated the documentation, if necessary.
  • I have added tests, if applicable.

Screenshots (if applicable) or Testing Completed

All 25 eBPF tests pass locally on Linux amd64 with kernel 6.14.0:

=== RUN   TestEndpointIngressFilter_TCP           PASS (0.27s)
=== RUN   TestAllObservationPoints                 PASS (0.19s)
=== RUN   TestTCPFlags                             PASS (0.19s)
=== RUN   TestTCPTimestamps                        PASS (0.18s)
=== RUN   TestUDPPacket                            PASS (0.17s)
=== RUN   TestFilterMapFiltering                   PASS (0.68s)
=== RUN   TestNonTCPUDP_NoEvent                    PASS (0.68s)
=== RUN   TestNonIPv4_NoEvent                      PASS (1.17s)
=== RUN   TestMalformedPackets                     PASS (0.68s)
=== RUN   TestReturnValue                          PASS (0.57s)
=== RUN   TestPacketBytesField                     PASS (0.18s)
=== RUN   TestConntrackMapUpdated                  PASS (0.18s)
=== RUN   TestConntrackIsReply                     PASS (0.17s)
=== RUN   TestConntrackTrafficDirection            PASS (0.18s)
=== RUN   TestConntrackMetricsEnabled              PASS (0.55s)
=== RUN   TestHighAggregationLevel                 PASS (0.95s)
=== RUN   TestHighAggregationPreviouslyObserved    PASS (0.66s)
=== RUN   TestConntrackEntryCreation               PASS (0.20s)
=== RUN   TestConntrackFlagAccumulation            PASS (0.19s)
=== RUN   TestConntrackReplyUpdatesEntry           PASS (0.19s)
=== RUN   TestConntrackDirectionUnknown            PASS (0.17s)
=== RUN   TestConntrackSinceLastReportAccumulation PASS (0.85s)
=== RUN   TestConntrackCounterResetOnReport        PASS (0.86s)
=== RUN   TestConntrackMetadataCountersInMap       PASS (0.55s)
=== RUN   TestConntrackEvictionTimeExtended        PASS (0.18s)
ok      github.com/microsoft/retina/pkg/plugin/packetparser   14.127s

Lint passes cleanly (make lint — 0 new issues).

Existing unit tests unaffected (different build tag: ebpf vs unit).

Additional Notes

  • Tests use //go:build ebpf && linux — they do not run during make test
  • Requires CAP_BPF + CAP_NET_ADMIN (or root) and Linux kernel >= 5.x
  • The ebpftest package is designed for reuse by other plugin tests (dropreason, dns, etc.)
  • Recompilation tests use loader.CompileEbpf (same as production) and require clang

Please refer to the CONTRIBUTING.md file for more information on how to contribute to this project.

@nddq nddq marked this pull request as ready for review February 13, 2026 16:21
@nddq nddq requested a review from a team as a code owner February 13, 2026 16:21
@nddq nddq requested review from skosuri1 and timraymond February 13, 2026 16:21
@nddq nddq force-pushed the test/ebpf-program-unit-tests branch from 2a83e29 to 6fa7245 Compare March 4, 2026 22:19
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 4, 2026

Retina Code Coverage Report

Total coverage no change

Increased diff

Impacted Files Coverage
pkg/controllers/operator/retinaendpoint/retinaendpoint_controller.go 82.25% ... 83.28% (1.03%) ⬆️

@nddq nddq force-pushed the test/ebpf-program-unit-tests branch 3 times, most recently from 25ef561 to a65bdef Compare April 1, 2026 00:31
@nddq nddq mentioned this pull request Apr 1, 2026
7 tasks
@nddq nddq force-pushed the test/ebpf-program-unit-tests branch from a65bdef to 5eb4fb5 Compare April 1, 2026 01:15
Comment thread pkg/plugin/packetparser/mocks/mock_types_linux.go Outdated
Comment thread pkg/plugin/packetparser/mocks/mock_types_linux.go Outdated
Comment thread pkg/plugin/ebpftest/helpers.go
Add a test framework that executes compiled eBPF programs in the kernel
using BPF_PROG_TEST_RUN with crafted packets, validating actual bytecode
behavior rather than mocking the Go wrapper layer.

Shared infrastructure in pkg/plugin/ebpftest/:
- helpers.go: privilege checks via capability query (CAP_BPF/CAP_SYS_ADMIN),
  map pinning removal, perf event reading, IP/port byte-order helpers,
  filter map population
- packet.go: TCP/UDP/ICMP/ARP packet construction via gopacket

Packetparser tests (25 test functions) covering:
- Packet parsing: TCP flags, timestamps, UDP, observation points
- Filter map: IP matching and rejection
- Malformed packets: runt, truncated IP/TCP, non-IPv4
- Conntrack perf events: is_reply, traffic direction, metrics
- Conntrack map state: entry creation fields, flag accumulation,
  reply updates RX fields, direction-unknown for mid-stream flows,
  since-last-report counter accumulation and reset, lifetime
  metadata counters, eviction time extension
- Recompilation variants: HIGH aggregation suppression,
  ENABLE_CONNTRACK_METRICS

Includes CI workflow (.github/workflows/test-ebpf.yaml) running on
both amd64 and arm64 runners, and a `make test-ebpf` target.

Signed-off-by: Quang Nguyen <nguyenquang@microsoft.com>
@nddq nddq force-pushed the test/ebpf-program-unit-tests branch from 5eb4fb5 to 57e5809 Compare April 1, 2026 16:20
@nddq nddq enabled auto-merge April 1, 2026 16:20
@nddq nddq requested a review from SRodi April 1, 2026 16:21
Copy link
Copy Markdown
Member

@SRodi SRodi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @nddq !

@nddq nddq added this pull request to the merge queue Apr 1, 2026
Merged via the queue into main with commit f8d90fd Apr 1, 2026
32 checks passed
@nddq nddq deleted the test/ebpf-program-unit-tests branch April 1, 2026 18:03
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