From b28ad1ea42af4fda6b1dde7e83867fc1c49ef16b Mon Sep 17 00:00:00 2001 From: Mahe Tardy Date: Fri, 2 Aug 2024 16:54:20 +0200 Subject: [PATCH] bpf: fix prepend_name unit tests for new buffer length Signed-off-by: Mahe Tardy --- Makefile | 4 ++- bpf/tests/prepend_name_test.c | 2 +- bpf/tests/prepend_name_test.go | 61 +++++++++++++++++++++++----------- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 11e8a876eb0..dcc94a6df20 100644 --- a/Makefile +++ b/Makefile @@ -264,8 +264,10 @@ test: tester-progs tetragon-bpf ## Run Go tests. tester-progs: ## Compile helper programs for unit testing. $(MAKE) -C $(TESTER_PROGS_DIR) +## bpf-test: ## run BPF tests. +## bpf-test BPFGOTESTFLAGS="-v": ## run BPF tests with verbose. .PHONY: bpf-test -bpf-test: ## Run BPF tests. +bpf-test: $(MAKE) -C ./bpf run-test .PHONY: verify diff --git a/bpf/tests/prepend_name_test.c b/bpf/tests/prepend_name_test.c index c4bbf2881fb..3bec8c4e98c 100644 --- a/bpf/tests/prepend_name_test.c +++ b/bpf/tests/prepend_name_test.c @@ -13,7 +13,7 @@ char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; -#define TEST_MAX_BUF_LEN 256 +#define TEST_MAX_BUF_LEN 4096 #define NAME_MAX 255 struct test_prepend_name_state_map_value { diff --git a/bpf/tests/prepend_name_test.go b/bpf/tests/prepend_name_test.go index 93e69d2298f..525418a8a95 100644 --- a/bpf/tests/prepend_name_test.go +++ b/bpf/tests/prepend_name_test.go @@ -18,7 +18,7 @@ import ( const ( // those constants must be synchronized with the BPF code - MAX_BUF_LEN = 256 + MAX_BUF_LEN = 4096 NAME_MAX = 255 testPrependNameStateMapName = "test_prepend_name_state_map" programName = "test_prepend_name" @@ -232,44 +232,67 @@ func Test_PrependName(t *testing.T) { assert.Equal(t, "sr/bin/cat", state.BufferToString()) }) - SetupLongDentry := func() string { - // length is 239 - const longDentry = "pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil" + // length is 239 + const longDentry = "pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil_pizza_tomato_mozzarella_basil" + + t.Run("MaxSizeBufMedium", func(t *testing.T) { + const bufsize = 256 + state.ResetStateWithBuflen(bufsize) err = state.UpdateDentry(longDentry) assert.NoError(t, err) code := runPrependName() assert.Equal(t, 0, code) assert.Equal(t, "/"+longDentry, state.BufferToString()) - return longDentry - } - - t.Run("MaxSizeBufFull", func(t *testing.T) { - state.ResetStateWithBuflen(MAX_BUF_LEN) - - longDentry := SetupLongDentry() // length is 15, so 239 + 15 + 2 slash chars = 256 err = state.UpdateDentry("favorite_recipe") assert.NoError(t, err) - code := runPrependName() + code = runPrependName() assert.Equal(t, 0, code) assert.Equal(t, "/favorite_recipe"+"/"+longDentry, state.BufferToString()) - assert.Equal(t, MAX_BUF_LEN, len(state.BufferToString())) + assert.Equal(t, bufsize, len(state.BufferToString())) }) - t.Run("MaxSizeBufTooSmall", func(t *testing.T) { + t.Run("MaxSizeBufFull", func(t *testing.T) { + maxDentry := strings.Repeat("a", NAME_MAX) state.ResetStateWithBuflen(MAX_BUF_LEN) - longDentry := SetupLongDentry() + var expectedState string + // (len("/") + 255) * 16 = 4096 + for range 16 { + err = state.UpdateDentry(maxDentry) + assert.NoError(t, err) + code := runPrependName() + assert.Equal(t, 0, code) + expectedState += "/" + maxDentry + assert.Equal(t, expectedState, state.BufferToString()) + } + }) + + t.Run("MaxSizeBufTooSmall", func(t *testing.T) { + largeDentry := strings.Repeat("a", 240) + state.ResetStateWithBuflen(MAX_BUF_LEN) - // length is 16 with the "s" of "recipes", so 240 + 15 + 2 slash chars = 257 - err = state.UpdateDentry("favorite_recipes") + var expectedState string + // (len("/") + 240) * 16 = 3856 + for range 16 { + err = state.UpdateDentry(largeDentry) + assert.NoError(t, err) + code := runPrependName() + assert.Equal(t, 0, code) + expectedState = "/" + largeDentry + expectedState + assert.Equal(t, expectedState, state.BufferToString()) + } + // at this stage, there should be 240 chars left in the buf which leaves + // no space for the remaining root slash character + err = state.UpdateDentry(largeDentry) assert.NoError(t, err) code := runPrependName() assert.Equal(t, -int(unix.ENAMETOOLONG), code) - assert.Equal(t, "favorite_recipes"+"/"+longDentry, state.BufferToString()) - assert.Equal(t, MAX_BUF_LEN, len(state.BufferToString())) + // note that I intentionally don't add the '/' char + expectedState = largeDentry + expectedState + assert.Equal(t, expectedState, state.BufferToString()) }) t.Run("MaxSizeBufNormalUse", func(t *testing.T) {