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

feat: add kunit framework #331

Merged
merged 4 commits into from
Jan 23, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/cppcheck-differential.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:

- name: Upload Cppcheck report
if: ${{ steps.add-kmod.outputs.filtered-full-paths != '' }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: cppcheck-report
path: cppcheck-report.txt
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ log
*.log
coverage_report_agnocastlib
.vscode
agnocast_kmod_coverage_report
8 changes: 8 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@ repos:
hooks:
- id: markdownlint
args: [-c, .markdownlint.yaml, --fix]

- repo: local
hooks:
- id: kunit
name: Run KUnit tests
entry: scripts/run_kunit
language: system
types: [c]
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,24 @@ You can build, test and generate the coverage report by following:
bash scripts/test_and_create_report
```

## (For developer) Kernel Module Test

A custom kernel with the following CONFIG enabled is required to run KUnit Test and obtain the coverage report (sample custom kernel is placed [here](https://drive.google.com/drive/folders/1sd8ROusgxhnEDOO0hbze3F5y47qtIdcM?usp=drive_link)).

- `CONFIG_KUNIT=y`
- `CONFIG_GCOV_KERNEL=y`

If booting with the custom kernel, the following script can be used to run unit tests on kernel modules and generate coverage reports.

```bash
bash script/run_kunit
```

You can also use [pre-commit](#for-developer-setup-pre-commit).

## (For developer) Setup pre-commit

The following command allows `clang-format` and `markdownlint` to be run before each commit.
The following command allows `clang-format`, `markdownlint`, and [KUNIT Test](./kmod/agnocast_kunit.c) to be run before each commit.

```bash
bash scripts/setup
Expand Down
8 changes: 8 additions & 0 deletions kmod/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ ifeq ($(shell expr $(KERNEL_MAJOR) \< 6 \| $(KERNEL_MAJOR) = 6 \& $(KERNEL_MINOR
CFLAGS_agnocast.o += -Wno-declaration-after-statement
endif

# For KUnit
ifeq ($(CONFIG_KUNIT),y)
obj-m += agnocast_kunit.o
endif
ifeq ($(CONFIG_GCOV_KERNEL),y)
CFLAGS_agnocast.o += -fprofile-arcs -ftest-coverage
CFLAGS_agnocast_kunit.o += -fprofile-arcs -ftest-coverage
endif

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Expand Down
22 changes: 22 additions & 0 deletions kmod/agnocast_kunit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "agnocast.h"

#include <kunit/test.h>

MODULE_LICENSE("Dual BSD/GPL");

static void agnocast_sample_test_case(struct kunit * test)
{
KUNIT_EXPECT_EQ(test, 1 + 1, 2);
}

struct kunit_case agnocast_test_cases[] = {
KUNIT_CASE(agnocast_sample_test_case),
{},
};

struct kunit_suite agnocast_test_suite = {
.name = "agnocast_test_suite",
.test_cases = agnocast_test_cases,
};

kunit_test_suite(agnocast_test_suite);
39 changes: 39 additions & 0 deletions scripts/run_kunit
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

### Validation
if [ -f "/boot/config-$(uname -r)" ]; then
CONFIG_FILE="/boot/config-$(uname -r)"
elif [ -f "/proc/config.gz" ]; then
zcat /proc/config.gz >/tmp/config-$(uname -r)
CONFIG_FILE="/tmp/config-$(uname -r)"
else
echo "Kernel config file not found!"
exit 1
fi

if ! grep -q "CONFIG_KUNIT=y" $CONFIG_FILE; then
echo "Skipping KUnit tests as CONFIG_KUNIT is not enabled."
exit 0
fi

### Run KUnit tests
AGNOCAST_DIR=$(realpath "$(dirname $(readlink -f $0))/..")

AGNOCAST_KMOD_PATH=$AGNOCAST_DIR/kmod

if [ -z "$AGNOCAST_KMOD_PATH" ]; then
echo "Usage: create_coverage_report <agnocast_kmod_path>"
exit 1
fi

cd $AGNOCAST_KMOD_PATH
make clean
make
sudo insmod $AGNOCAST_KMOD_PATH/agnocast_kunit.ko
sudo rmmod agnocast_kunit

sudo lcov --capture --directory /sys/kernel/debug/gcov/$AGNOCAST_KMOD_PATH --output-file $AGNOCAST_DIR/coverage.info
sudo lcov --remove $AGNOCAST_DIR/coverage.info "*linux*" "*kunit*" --output-file $AGNOCAST_DIR/coverage_filtered.info
genhtml $AGNOCAST_DIR/coverage_filtered.info --output-directory $AGNOCAST_DIR/agnocast_kmod_coverage_report
rm -f $AGNOCAST_DIR/coverage.info $AGNOCAST_DIR/coverage_filtered.info $AGNOCAST_KMOD_PATH/*.gcno
echo "Please open agnocast_kmod_coverage_report/index.html in your web browser."