Profile coverage of functional tests without instrumenting your binaries.
xcover
(pronounced 'cross cover') enables to profile functional test coverage, by leveraging kernel instrumentation to probe functions in userland, and it's cross language.
This makes possible to measure coverage on ELF binaries without ecosystem-specific instrumentation like Go cover or LLVM cov require.
xcover is a functional test coverage profiler
xcover is a functional test coverage profiler.
Run the 'run' command to run the profiler that will trace all the functions of the tracee program. Wait for the profiler to be ready before running your tests, with the 'wait' command. Once the profiler is ready to trace all the functions, you can start running your tests. At the end of your tests, the profiler can be stopped and a report being collected.
-h, --help help for xcover
--log-level string Log level (trace, debug, info, warn, error, fatal, panic) (default "info")
- xcover run - Run the coverage profiling for a program
- xcover status - Check the the xcover profiler status
- xcover stop - Stop the xcover profiler daemon
- xcover wait - Wait for the xcover profiler to be ready
xcover run --pid PID
xcover run --path EXE_PATH
For including specific functions:
xcover run --path EXE_PATH --include "^github.com/maxgio92/xcover"
or excluding some:
xcover run --path EXE_PATH --exclude "^runtime.|^internal"
You can run the profiler as daemon with the --detach
flag:
$ xcover run --detach --path /path/to/bin
Check the status with the status
command:
$ xcover status
xcover is running (PID 1234)
And stop it with the stop
command:
$ xcover stop
xcover is stopped
A coverage report is generated by default, and can be controlled with the run
command's --report
flag.
The report is provided in JSON format and contains
- the functions that have been traced
- the functions acknowledged
- the coverage by function percentage
- the executable path
type CoverageReport struct {
FuncsTraced []string `json:"funcs_traced"`
FuncsAck []string `json:"funcs_ack"`
CovByFunc float64 `json:"cov_by_func"`
ExePath string `json:"exe_path"`
}
For instance:
$ xcover run --path myapp --verbose=false --report
`^C5:02PM INF written report to xcover-report.json`
$ cat xcover-report.json | jq '.cov_by_func'
15.601900739176347
It is possible to synchronize on the xcover
readiness, meaning that userspace can proceed executing the tests because xcover is ready to trace them all.
You can use the wait
command to wait for the xcover
profiler to be ready:
$ xcover run --detach --path /path/to/bin
$ xcover wait
1:30PM INF waiting for the profiler to be ready
1:30PM INF profiler is ready
$ /path/to/bin test_1
$ /path/to/bin test_2
$ /path/to/bin test_3
$ xcover stop
and collect the coverage as xcover-report.json
.
A full example of usage is described below:
$ xcover run --detach --path /path/to/bin
$ xcover wait
xcover is ready
$ /path/to/bin test1
$ /path/to/bin test2
$ /path/to/bin test3
$ xcover stop
xcover is stopped
$ cat xcover_report.json | jq .cov_by_func
89.9786897
bpftool
(to generate vmlinux.h for CORE)clang
go
libbf-dev
By default it statically compile xcover with libbfgo, and libbpfgo with libbpf.
make xcover
make xcover/bpf
make xcover/frontend
make test