Skip to content

Commit 09e9e8f

Browse files
authored
Merge pull request #1361 from sancppp/ebpf_ut
eBPF unit test: add workload sockops ut
2 parents 96ada9e + 72c7022 commit 09e9e8f

File tree

5 files changed

+571
-25
lines changed

5 files changed

+571
-25
lines changed

hack/run-ebpf-ut.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ ROOT_DIR=$(git rev-parse --show-toplevel)
44

55
. $ROOT_DIR/hack/utils.sh
66

7-
DOCKER_EBPF_TEST_COMMAND="make -C /kmesh/test/bpf_ut run"
8-
LOCAL_EBPF_TEST_COMMAND="make -C $ROOT_DIR/test/bpf_ut run"
7+
DOCKER_EBPF_TEST_COMMAND="make -C /kmesh/test/bpf_ut clean;make -C /kmesh/test/bpf_ut run"
8+
LOCAL_EBPF_TEST_COMMAND="make -C $ROOT_DIR/test/bpf_ut clean;make -C $ROOT_DIR/test/bpf_ut run"
99

1010
function docker_run_ebpf_ut() {
1111
local container_id=$1

test/bpf_ut/Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ CLANG_FLAGS += -MD
2626

2727
.PHONY: all clean run
2828

29-
TEST_OBJECTS = xdp_shutdown_in_userspace_test.o xdp_authz_offload_test.o
29+
all: xdp_shutdown_in_userspace_test.o xdp_authz_offload_test.o workload_sockops_test.o
3030

3131
XDP_FLAGS = -I$(ROOT_DIR)/bpf/kmesh/ -I$(ROOT_DIR)/bpf/kmesh/workload/include -I$(ROOT_DIR)/api/v2-c
32-
xdp_%.o: xdp_%.c clean
32+
xdp_%.o: xdp_%.c
3333
$(QUIET) $(CLANG) $(CLANG_FLAGS) $(XDP_FLAGS) -c $< -o $@
3434

35-
36-
all: $(TEST_OBJECTS)
35+
WORKLOAD_SOCKOPS_FLAGS = -I$(ROOT_DIR)/bpf/kmesh/ -I$(ROOT_DIR)/bpf/kmesh/probes -I$(ROOT_DIR)/bpf/kmesh/workload/include -I$(ROOT_DIR)/api/v2-c
36+
workload_sockops_test.o: workload_sockops_test.c
37+
$(QUIET) $(CLANG) $(CLANG_FLAGS) $(WORKLOAD_SOCKOPS_FLAGS) -c $< -o $@
3738

3839
clean:
3940
$(QUIET) rm -f $(wildcard *.o)
@@ -70,7 +71,6 @@ ifdef BPF_TEST_FILE
7071
endif
7172

7273
run: all
73-
$(QUIET)echo "rebuild and run bpf tests"
7474
$(GO) test ./bpftest -bpf-ut-path $(ROOT_DIR)/test/bpf_ut $(BPF_TEST_FLAGS)
7575

7676
-include $(TEST_OBJECTS:.o=.d)

test/bpf_ut/bpftest/bpf_test.go

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"google.golang.org/protobuf/proto"
3939

4040
"kmesh.net/kmesh/pkg/bpf/factory"
41+
"kmesh.net/kmesh/pkg/constants"
4142
"kmesh.net/kmesh/pkg/logger"
4243
"kmesh.net/kmesh/pkg/utils"
4344
)
@@ -47,17 +48,21 @@ var (
4748
dumpCtx = flag.Bool("dump-ctx", false, "If set, the program context will be dumped after a CHECK and SETUP run.")
4849
)
4950

50-
type unitTest struct {
51+
type IunitTest interface {
52+
run() func(t *testing.T)
53+
}
54+
55+
type unitTest_BPF_PROG_TEST_RUN struct {
5156
name string
5257
setupInUserSpace func(t *testing.T, coll *ebpf.Collection) // Builds test environment in user space, used for operations that cannot be completed in kernel space (e.g., cannot pass the eBPF verifier)
5358
}
5459

55-
type unitTests struct {
60+
type unitTests_BPF_PROG_TEST_RUN struct {
5661
objFilename string
57-
uts []unitTest
62+
uts []unitTest_BPF_PROG_TEST_RUN
5863
}
5964

60-
func (uts *unitTests) run() func(t *testing.T) {
65+
func (uts *unitTests_BPF_PROG_TEST_RUN) run() func(t *testing.T) {
6166
return func(t *testing.T) {
6267
for _, ut := range uts.uts {
6368
t.Run(ut.name, func(t *testing.T) {
@@ -67,6 +72,27 @@ func (uts *unitTests) run() func(t *testing.T) {
6772
}
6873
}
6974

75+
type unitTest_BUILD_CONTEXT struct {
76+
name string
77+
workFunc func(t *testing.T, cgroupPath, elfPath string)
78+
}
79+
80+
type unitTests_BUILD_CONTEXT struct {
81+
objFilename string
82+
uts []unitTest_BUILD_CONTEXT
83+
}
84+
85+
func (uts *unitTests_BUILD_CONTEXT) run() func(t *testing.T) {
86+
return func(t *testing.T) {
87+
for _, ut := range uts.uts {
88+
t.Run(ut.name, func(t *testing.T) {
89+
if ut.workFunc != nil {
90+
ut.workFunc(t, constants.Cgroup2Path, uts.objFilename)
91+
}
92+
})
93+
}
94+
}
95+
}
7096
func TestBPF(t *testing.T) {
7197
if testPath == nil || *testPath == "" {
7298
t.Skip("Set -bpf-ut-path to run BPF tests")
@@ -81,7 +107,7 @@ func TestBPF(t *testing.T) {
81107

82108
// common functions
83109

84-
func loadAndRunSpec(t *testing.T, objFilename string, tt *unitTest) {
110+
func loadAndRunSpec(t *testing.T, objFilename string, tt *unitTest_BPF_PROG_TEST_RUN) {
85111
elfPath := path.Join(*testPath, objFilename)
86112
t.Logf("Running test %s", elfPath)
87113

@@ -130,18 +156,16 @@ func loadAndRunSpec(t *testing.T, objFilename string, tt *unitTest) {
130156
}
131157

132158
// Ensure test that has a jump program also has a check program
133-
if programs.checkProg == nil {
159+
if programs.jumpProg != nil && programs.checkProg == nil {
134160
t.Fatalf(
135161
"File '%s' contains a jump program in section '%s' but no check program.",
136162
elfPath,
137163
tt.name,
138164
)
139165
}
140166

141-
if !utils.KernelVersionLowerThan5_13() {
142-
// TODO: use t.Context() instead of context.Background() when go 1.24 is required
143-
logger.StartLogReader(context.Background(), coll.Maps["km_log_event"])
144-
}
167+
startLogReader(coll)
168+
145169
if tt.setupInUserSpace != nil {
146170
tt.setupInUserSpace(t, coll)
147171
}
@@ -150,6 +174,13 @@ func loadAndRunSpec(t *testing.T, objFilename string, tt *unitTest) {
150174
subTest(t, programs, coll.Maps[suiteResultMap])
151175
}
152176

177+
func startLogReader(coll *ebpf.Collection) {
178+
if !utils.KernelVersionLowerThan5_13() {
179+
// TODO: use t.Context() instead of context.Background() when go 1.24 is required
180+
logger.StartLogReader(context.Background(), coll.Maps["km_log_event"])
181+
}
182+
}
183+
153184
// loadAndPrepSpec loads an eBPF Collection Specification from the provided ELF file
154185
// and prepares it for testing. It disables pinning for all maps to avoid interference
155186
// between tests. Additionally, it filters out programs that don't support BPF_PROG_RUN,
@@ -177,7 +208,7 @@ func loadAndPrepSpec(t *testing.T, elfPath string) *ebpf.CollectionSpec {
177208
for n, p := range spec.Programs {
178209
switch p.Type {
179210
// https://docs.ebpf.io/linux/syscall/BPF_PROG_TEST_RUN/
180-
case ebpf.XDP, ebpf.SchedACT, ebpf.SchedCLS, ebpf.SocketFilter, ebpf.CGroupSKB:
211+
case ebpf.XDP, ebpf.SchedACT, ebpf.SchedCLS, ebpf.SocketFilter, ebpf.CGroupSKB, ebpf.SockOps:
181212
continue
182213
}
183214

@@ -192,11 +223,15 @@ func loadAndPrepSpec(t *testing.T, elfPath string) *ebpf.CollectionSpec {
192223
// based on the provided GlobalBpfConfig. It sets the log level and authorization
193224
// offload settings.
194225
func setBpfConfig(t *testing.T, coll *ebpf.Collection, config *factory.GlobalBpfConfig) {
195-
if err := coll.Variables["bpf_log_level"].Set(&config.BpfLogLevel); err != nil {
196-
t.Fatalf("failed to set bpf_log_level: %v", err)
226+
if v, ok := coll.Variables["bpf_log_level"]; ok {
227+
if err := v.Set(&config.BpfLogLevel); err != nil {
228+
t.Fatalf("failed to set bpf_log_level: %v", err)
229+
}
197230
}
198-
if err := coll.Variables["authz_offload"].Set(&config.AuthzOffload); err != nil {
199-
t.Fatalf("failed to set authz_offload: %v", err)
231+
if v, ok := coll.Variables["authz_offload"]; ok {
232+
if err := v.Set(&config.AuthzOffload); err != nil {
233+
t.Fatalf("failed to set authz_offload: %v", err)
234+
}
200235
}
201236
}
202237

0 commit comments

Comments
 (0)