Let's check it out!
Software
Follow all instructions from the previous post to install CLion and VS Code on Ubuntu Linux. Also install the following components for low level C code unit testing, mocking and integration: Unity, CMock, Ceedling.
Unity | Unit testing framework built for C projects with a focus on working with embedded toolchains |
CMock | Mock and stub generator and runtime for unit testing C designed to work smoothly with Unity |
Ceedling | Build system for C projects using Ruby Rake [make] build system to integrate Unity + CMock |
Pre-requisites
As above, Ceedling requires Ruby installed otherwise sudo: gem: command not found errors may be thrown. Also, CMock requires Ruby bundle be installed otherwise Command 'bundle' not found errors may be thrown.
sudo apt install ruby | sudo apt install ruby-bundler |
Unity
Unity is a unit testing framework built for C, with a focus on working with embedded toolchains, which we would like to try and leverage for BPF development. Follow instructions here to install and configure Unity.
git clone git@github.com:ThrowTheSwitch/Unity.git cd Unity cmake . make sudo make install sudo cp libunity.a /usr/local/lib sudo cp src/unity*.h /usr/local/include/unity |
CMock
CMock is a mock and stub generator designed to work smoothly with Unity. CMock automagically parses the C headers and creates useful mock interfaces used for unit testing. Follow instructions here to install CMock.
git clone --recursive https://github.com/throwtheswitch/cmock.git cd cmock bundle install |
Ceedling
Ceedling is a build system for C projects using Ruby Rake [make] build system. Ceedling also makes TDD Test Driven Development simple by integrating CMock + Unity. Follow instructions here to install Ceedling.
ruby -v sudo gem install ceedling |
Hello Unity
In the previous post, examples installed the libbpf C-based library. Therefore, extend an example and write tests that invoke simple libbpf APIs, for example, libbpf_num_possible_cpus directly using Unity framework.
Launch CLion | New Project | C Executable | Location: /home/stevepro/HelloUnity | Language std: C11
Create
Organize src and test directory structure. Install libbpf beneath src folder. Rename main.c to all_tests.c and move beneath test folder. Update all prod and unit test code. Complete CMakeLists.txt to include library files:
cmake_minimum_required(VERSION 3.19) project(HelloUnity C) set(CMAKE_C_STANDARD 11) include_directories(src/ /usr/local/include/unity/ src/include/libbpf/src) link_directories(/usr/local/lib/ src/include/libbpf/src/amd64) file(GLOB CODE_FILES src/*.c) file(GLOB TEST_FILES test/*.c) add_executable(HelloUnity ${CODE_FILES} ${TEST_FILES} ) target_link_libraries(HelloUnity unity bpf elf z) |
Edit configurations | Run with root privileges | Set breakpoints | Press F5 to debug step thru source code.
Hello CMock
At the time of writing, there is currently no way to debug BPF programs' source code interactively. Therefore, we would like to attempt to mock BPF programs or at least underlying C sourc code somehow using CMock.
Follow the example Spin up CMock. This article uses Ceedling to automate project setup and generate mocks but we will complete the following manually first to better understand the process. Original code found here.
Open folder /home/stevepro/HelloCMock. Copy inc/rectangle.h + project.yml. Execute mock command:
ruby ~/GitHub/ThrowTheSwitch/cmock/lib/cmock.rb -oproject.yml inc/rectangle.h |
This creates mocks folder two corresponding files: mock_rectangle.h and mock_rectangle.c. Notice we did not attempt to use CLion as is not currently integrated; any attempt may produce Multiple Definition issue!
Hello Ceedling
Complete previous example but this time try Ceedling using the article as a guideline: Launch the Terminal:
cd $HOME ceedling new HelloCeedling |
Copy all project files into src and test directories. Include inc and update project.yml with the inc directory:
:paths: :test: - +:test/** - -:test/support :source: - src/** :include: - inc/** :support: - test/support :libraries: []
Run tests manually simply by typing ceedling
Debug tests interactively with GDB as follows: Launch VS Code. Press F5 to add launch.json file to complete:
{ "version": "0.2.0", "configurations": [ { "name": "ceedling_gdb", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/test/out/test_shape_container.out", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }Set breakpoint in test_shape_container.c | Press F5 to debug step thru source code:
Summary
According to ChatGPT, eBPF is versatile technology that allows safe and efficient code execution within the Linux kernel without requiring modification of kernel code. This feature makes it attractive for applications including network packet filtering, security, logging + tracing, monitoring, and performance optimization.
In summary, while eBPF is a valuable addition to the Linux ecosystem, it is not expected to replace kernel development. Instead, eBPF complements this by currently providing a flexible and efficient way to extend specific kernel features. Therefore, it will be interesting to see if this technology is dominant in the future.