Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests(test/drivers): extend modern bpf test framework to all drivers (part 1) #799

Merged
merged 7 commits into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 52 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,9 @@ jobs:
KERNELDIR=/lib/modules/$(ls /lib/modules)/build make -j4
make run-unit-tests

build-and-test-modern-bpf-x86:
name: build-and-test-modern-bpf-x86 😇 (bundled_deps)
# This job checks that we correctly run `scap-open` for all the 3 drivers.
test-scap-open-x86:
name: test-scap-open-x86 😆 (bundled_deps)
runs-on: ubuntu-22.04
needs: paths-filter
if: needs.paths-filter.outputs.driver_changed == 'true' || needs.paths-filter.outputs.libscap_changed == 'true'
Expand All @@ -177,28 +178,65 @@ jobs:
- name: Install deps ⛓️
run: |
sudo apt update
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 git pkg-config autoconf automake libtool libelf-dev libcap-dev
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 llvm-14 git pkg-config autoconf automake libtool libelf-dev libcap-dev linux-headers-$(uname -r)
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 90
sudo update-alternatives --install /usr/bin/llvm-strip llvm-strip /usr/bin/llvm-strip-14 90
sudo update-alternatives --install /usr/bin/llc llc /usr/bin/llc-14 90

- name: Build scap-open 🏗️
- name: Build scap-open and drivers 🏗️
run: |
mkdir -p build
cd build && cmake -DUSE_BUNDLED_DEPS=ON -DBUILD_LIBSCAP_MODERN_BPF=ON -DBUILD_MODERN_BPF_TEST=ON -DMODERN_BPF_DEBUG_MODE=ON -DBUILD_LIBSCAP_GVISOR=OFF ../
cd build && cmake -DUSE_BUNDLED_DEPS=ON -DBUILD_LIBSCAP_MODERN_BPF=ON -DBUILD_LIBSCAP_GVISOR=OFF -DBUILD_BPF=True -DCREATE_TEST_TARGETS=Off ../
make scap-open
make driver bpf

- name: Run scap-open 🏎️
- name: Run scap-open with modern bpf 🏎️
run: |
cd build
sudo ./libscap/examples/01-open/scap-open --modern_bpf --num_events 0

- name: Build bpf_test 🏗
- name: Run scap-open with bpf 🏎
run: |
cd build
make bpf_test
sudo ./libscap/examples/01-open/scap-open --bpf ./driver/bpf/probe.o --num_events 0

- name: Running tests 🧪
- name: Run scap-open with kmod 🏎️
run: |
cd build
sudo ./test/modern_bpf/bpf_test --verbose
sudo insmod ./driver/scap.ko
sudo ./libscap/examples/01-open/scap-open --kmod --num_events 0
sudo rmmod scap

build-and-test-modern-bpf-x86:
name: build-and-test-modern-bpf-x86 😇 (bundled_deps)
runs-on: ubuntu-22.04
needs: paths-filter
if: needs.paths-filter.outputs.driver_changed == 'true' || needs.paths-filter.outputs.libscap_changed == 'true'
steps:

- name: Checkout Libs ⤵️
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Install deps ⛓️
run: |
sudo apt update
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential git pkg-config autoconf automake libelf-dev libcap-dev linux-headers-$(uname -r) clang-14 llvm-14 libtool
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 90
sudo update-alternatives --install /usr/bin/llvm-strip llvm-strip /usr/bin/llvm-strip-14 90
sudo update-alternatives --install /usr/bin/llc llc /usr/bin/llc-14 90

- name: Build drivers tests 🏗️
run: |
mkdir -p build
cd build && cmake -DUSE_BUNDLED_DEPS=ON -DENABLE_DRIVERS_TESTS=ON -DBUILD_LIBSCAP_MODERN_BPF=ON -DMODERN_BPF_DEBUG_MODE=ON -DBUILD_BPF=True -DBUILD_LIBSCAP_GVISOR=OFF ../
make drivers_test

- name: Run drivers_test with modern bpf 🏎️
run: |
cd build
sudo ./test/drivers/drivers_test -m

build-modern-bpf-arm64:
name: build-modern-bpf-arm64 🙃 (system_deps)
Expand Down Expand Up @@ -227,9 +265,9 @@ jobs:
git config --global --add safe.directory ${{ github.workspace }}
.github/install-deps.sh
mkdir -p build
cd build && cmake -DUSE_BUNDLED_DEPS=OFF -DBUILD_LIBSCAP_MODERN_BPF=ON -DBUILD_MODERN_BPF_TEST=ON -DMODERN_BPF_DEBUG_MODE=ON -DBUILD_LIBSCAP_GVISOR=OFF ../
cd build && cmake -DUSE_BUNDLED_DEPS=OFF -DENABLE_DRIVERS_TESTS=ON -DBUILD_LIBSCAP_MODERN_BPF=ON -DMODERN_BPF_DEBUG_MODE=ON -DBUILD_LIBSCAP_GVISOR=OFF ../
make scap-open
make bpf_test
make drivers_test

build-modern-bpf-s390x:
name: build-modern-bpf-s390x 😁 (system_deps)
Expand Down Expand Up @@ -258,9 +296,8 @@ jobs:
git config --global --add safe.directory ${{ github.workspace }}
.github/install-deps.sh
mkdir -p build
cd build && cmake -DUSE_BUNDLED_DEPS=OFF -DBUILD_LIBSCAP_MODERN_BPF=ON -DBUILD_MODERN_BPF_TEST=ON -DMODERN_BPF_DEBUG_MODE=ON -DBUILD_LIBSCAP_GVISOR=OFF ../
make scap-open
make bpf_test
cd build && cmake -DUSE_BUNDLED_DEPS=OFF -DENABLE_DRIVERS_TESTS=ON -DBUILD_LIBSCAP_MODERN_BPF=ON -DMODERN_BPF_DEBUG_MODE=ON -DBUILD_LIBSCAP_GVISOR=OFF ../
make drivers_test

build-libs-driverkit:
name: build-libs-driverkit
Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ option(USE_BUNDLED_DEPS "Enable bundled dependencies instead of using the system
option(MINIMAL_BUILD "Produce a minimal build with only the essential features (no eBPF probe driver, no kubernetes, no mesos, no marathon and no container metadata)" OFF)
option(MUSL_OPTIMIZED_BUILD "Enable if you want a musl optimized build" OFF)
option(USE_BUNDLED_DRIVER "Use the driver/ subdirectory in the build process (only available in Linux)" ON)
option(ENABLE_DRIVERS_TESTS "Enable driver tests (bpf, kernel module, modern bpf)" OFF)

include(GNUInstallDirs)

Expand Down Expand Up @@ -94,4 +95,8 @@ if(CREATE_TEST_TARGETS AND NOT WIN32)
)

add_subdirectory(test/e2e)

if(ENABLE_DRIVERS_TESTS)
add_subdirectory(test/drivers)
endif()
endif()
38 changes: 17 additions & 21 deletions test/modern_bpf/CMakeLists.txt → test/drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
message(STATUS "Modern BPF tests build enabled")

include_directories(../userspace/common)
message(STATUS "Drivers tests build enabled")

## Syscall_exit suite files.
file(GLOB_RECURSE SYSCALL_EXIT_TEST_SUITE ${CMAKE_CURRENT_SOURCE_DIR}/test_suites/syscall_exit_suite/*.cpp)
Expand All @@ -11,48 +9,46 @@ file(GLOB_RECURSE SYSCALL_ENTER_TEST_SUITE ${CMAKE_CURRENT_SOURCE_DIR}/test_suit
## Generic tracepoints suite files.
file(GLOB_RECURSE GENERIC_TRACEPOINTS_TEST_SUITE ${CMAKE_CURRENT_SOURCE_DIR}/test_suites/generic_tracepoints_suite/*.cpp)

## Local suite files. (Not enabled by default)
if(BUILD_ENHANCED_MODERN_BPF_TEST)
file(GLOB_RECURSE LOCAL_TEST_SUITE ${CMAKE_CURRENT_SOURCE_DIR}/test_suites/local_suite/*.cpp)
endif()
## Actions suite files
file(GLOB_RECURSE ACTIONS_TEST_SUITE ${CMAKE_CURRENT_SOURCE_DIR}/test_suites/actions_suite/*.cpp)

set(MODERN_BPF_TEST_SOURCES
set(DRIVERS_TEST_SOURCES
./start_tests.cpp
./event_class/event_class.cpp
./flags/capabilities.cpp
./helpers/proc_parsing.cpp
"${SYSCALL_EXIT_TEST_SUITE}"
"${SYSCALL_ENTER_TEST_SUITE}"
"${GENERIC_TRACEPOINTS_TEST_SUITE}"
"${LOCAL_TEST_SUITE}"
"${ACTIONS_TEST_SUITE}"
)

set(MODERN_BPF_TEST_INCLUDE
set(DRIVERS_TEST_INCLUDE
PRIVATE
../../userspace/common
"${GTEST_INCLUDE}"
"${LIBSCAP_DIR}/driver/"
"${LIBSCAP_DIR}/userspace/libscap"
)

set(MODERN_BPF_TEST_LINK_LIBRARIES
PRIVATE
pman
scap_event_schema
set(DRIVERS_TEST_LINK_LIBRARIES
scap
"${GTEST_LIB}"
"${GTEST_MAIN_LIB}"
)

set(MODERN_BPF_TEST_DEPENDECIES
pman
set(DRIVERS_TEST_DEPENDECIES
scap
)

if(USE_BUNDLED_GTEST)
list(APPEND
MODERN_BPF_TEST_DEPENDECIES
DRIVERS_TEST_DEPENDECIES
gtest
)
endif()

add_executable(bpf_test ${MODERN_BPF_TEST_SOURCES})
target_include_directories(bpf_test ${MODERN_BPF_TEST_INCLUDE})
target_link_libraries(bpf_test ${MODERN_BPF_TEST_LINK_LIBRARIES})
add_dependencies(bpf_test ${MODERN_BPF_TEST_DEPENDECIES})
add_executable(drivers_test ${DRIVERS_TEST_SOURCES})
target_include_directories(drivers_test ${DRIVERS_TEST_INCLUDE})
target_link_libraries(drivers_test ${DRIVERS_TEST_LINK_LIBRARIES})
add_dependencies(drivers_test ${DRIVERS_TEST_DEPENDECIES})
93 changes: 93 additions & 0 deletions test/drivers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Drivers tests

## Rationale

This test suite should allow you to check the behavior of our 3 drivers: `modern_bpf`, `bpf`, `kernel module`. To assert against the output of our drivers we use the so-called `scap-engines`.
You don't have to build all the engines if you want to assert only some of the drivers, for example, the minimal build command is:

```bash
cmake -DUSE_BUNDLED_DEPS=On -DENABLE_DRIVERS_TESTS=On -DBUILD_LIBSCAP_GVISOR=Off -DCREATE_TEST_TARGETS=On ..
```

In this case, only the `kmod` engine will be built and you can assert only the behavior of the kernel module. If you want to assert also the bpf probe you have to add `-DBUILD_BPF=True`, while if you want to add the modern bpf probe engine you have to use `-DBUILD_LIBSCAP_MODERN_BPF=On`.
Copy link
Contributor

Choose a reason for hiding this comment

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

I dream a future where:

  • no driver is built by default
  • we use same naming for the cmake options to enable drivers, like DBUILD_LIBSCAP_MODERN_BPF, DBUILD_LIBSCAP_BPF and DBUILD_LIBSCAP_KMOD

Copy link
Member Author

Choose a reason for hiding this comment

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

you are a dreamer my friend!


## Usage Example

Let's build all the 3 engines:

```bash
cmake -DUSE_BUNDLED_DEPS=On -DENABLE_DRIVERS_TESTS=On -DBUILD_LIBSCAP_GVISOR=Off -DBUILD_BPF=True -DBUILD_LIBSCAP_MODERN_BPF=On -DCREATE_TEST_TARGETS=On ..
make drivers_test
```

Now all the engines should be built, but if you want to assert against the kmod or the bpf probe you have to build them:

```bash
make driver bpf
```

> __NOTE__: the modern bpf probe is bundled inside its engine so every time you type `make drivers_test` it will be automatically compiled without any additional command.

We are ready to run our tests:

```
sudo ./test/drivers/drivers_test -k
```

The `-k` option stands for kmod, so you are running all the tests against the kmod. Some other available options are:

- `-k` to run tests against the kernel module.
- `-m` to run tests against the modern bpf probe.
- `-b` to run tests against the bpf probe.
- `-d` to change the dimension of shared buffers between userspace and kernel. (advanced use case)

> __NOTE__: you can assert only one driver at time so you cannot run tests with more than one engine option `sudo ./test/drivers/drivers_test -k -m` ⚠️
Andreagit97 marked this conversation as resolved.
Show resolved Hide resolved

Another important thing to know is that by default when you provide the `-k` option, tests will search under `./driver/scap.ko` for a valid kernel module (this is the default location when you type `make driver`) same for the bpf probe (`.driver/bpf/probe.o`) so if you run tests in the build directory you shouldn't have issues. If you run tests outside the build directory you should provide also the path with the option (`sudo ./test/drivers/drivers_test -k <path_to_the_kmod>`, same for bpf). The modern bpf probe is bundled so no need for explicit paths!

This is the suggested flow to run tests 👇

From repo root `/libs` type:

```bash
rm -rf build
mkdir build && cd build
cmake -DUSE_BUNDLED_DEPS=On -DENABLE_DRIVERS_TESTS=On -DBUILD_LIBSCAP_GVISOR=Off -DBUILD_BPF=True -DBUILD_LIBSCAP_MODERN_BPF=On -DCREATE_TEST_TARGETS=On ..
make drivers_test
make driver bpf
sudo ./test/drivers/drivers_test <option>
```

## Advanced Usage

Here there is a useful reference to GoogleTest doc describing the [advanced run options](https://github.com/google/googletest/blob/main/docs/advanced.md#running-a-subset-of-the-tests).

- Type the following command to get all Test Suites with all available test cases for the modern probe:

```bash
sudo ./test/drivers/drivers_test -m --gtest_list_tests
```

- Type the following command to run a specific Test Case (for example, here we test the close exit event in the test suite `SyscallExit` for the modern probe):

```bash
sudo ./test/drivers/drivers_test -m --gtest_filter='SyscallExit.mkdirX'
```

- Run an entire test suite (here `SyscallExit`)

```bash
sudo ./test/drivers/drivers_test -m --gtest_filter='SyscallExit.*'
```

- Stop at the first test that fails:

```bash
sudo ./test/drivers/drivers_test -m --gtest_break_on_failure
```

- Avoid running some specific tests

```bash
sudo ./test/drivers/drivers_test -m --gtest_filter=-'SyscallExit.mkdirX'
```
Loading