diff --git a/.github/scripts/setup.sh b/.github/scripts/setup.sh new file mode 100755 index 0000000..0c78186 --- /dev/null +++ b/.github/scripts/setup.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -euo pipefail + +BPFTRACE_VERSION=${BPFTRACE_VERSION:-0.22.1} + +# Assume sudo in this script + +# Install dependencies +apt update && apt install -y make file gawk libfuse2t64 + +# Download bpftrace release +BIN_DIR=/usr/local/bin +mkdir -p $BIN_DIR +curl -L -o bpftrace https://github.com/bpftrace/bpftrace/releases/download/v${BPFTRACE_VERSION}/bpftrace +chmod +x bpftrace +mv bpftrace $BIN_DIR +bpftrace --version + +# mount tracefs to avoid warnings from bpftrace +grep -q tracefs /proc/mounts || mount -t tracefs tracefs /sys/kernel/tracing diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..5d658f0 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,31 @@ +name: USDT CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install prerequisites + run: sudo .github/scripts/setup.sh + + - name: Build (static) + run: make SHARED=0 -C tests -j$(nproc) build + + - name: Build (shared) + run: make SHARED=1 -C tests -j$(nproc) build + + - name: Test (static) + run: make SHARED=0 -C tests test + + - name: Test (shared) + run: make SHARED=1 -C tests test + diff --git a/tests/Makefile b/tests/Makefile index 1d10c14..e397ad2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -38,13 +38,13 @@ endif NONTESTS = tester common TESTS := $(filter-out $(NONTESTS), \ - $(shell ls *.{c,cpp} 2>/dev/null | grep -v '^lib' | \ - ${AWK} '{split($$0, p, /[^A-Za-z_]+/); print p[1]}' | \ + $(shell ls *.c *.cpp 2>/dev/null | grep -v '^lib' | \ + ${AWK} '{split($$0, p, /[^A-Za-z_]+/); print p[1]}' | \ sort | uniq \ ) \ ) LIBS := $(filter-out $(NONTESTS), \ - $(shell ls lib*.{c,cpp} 2>/dev/null | \ + $(shell ls lib*.c lib*.cpp 2>/dev/null | \ ${AWK} '{split($$0, p, /[^A-Za-z_]+/); print substr(p[1], 4)}' | \ sort | uniq \ ) \ diff --git a/tests/prepare-bt-script.awk b/tests/prepare-bt-script.awk index 55eaeb3..254187f 100644 --- a/tests/prepare-bt-script.awk +++ b/tests/prepare-bt-script.awk @@ -46,6 +46,8 @@ } END { - if (has_contents) + if (has_contents) { + printf("uretprobe:%s:main { exit(); }\n", OUTPUT "/" TEST); printf("END { printf(\"DONE!\\n\"); }\n"); + } } diff --git a/tests/run_test.sh b/tests/run_test.sh index ea4389a..90c90e5 100755 --- a/tests/run_test.sh +++ b/tests/run_test.sh @@ -69,36 +69,44 @@ if [ -s "$TEST_BTSCRIPT" ]; then bt_pid=$! bt_pgid="$(ps -opgid= "$bt_pid" | tr -d ' ')" + dump_bt_output() { + echo "BPFTRACE SCRIPT:" + cat "$TEST_BTSCRIPT" + echo "BPFTRACE OUTPUT:" + cat "$TEST_BTOUT_RAW" + } + + wait_for_bpftrace() { + local bt_start=$(date +%s) + local stop_word="$1" + local msg="$2" + while true; do + local bt_elapsed=$(( $(date +%s) - bt_start )) + if grep -q "$stop_word" "$TEST_BTOUT_RAW"; then + break + elif [ "$bt_elapsed" -ge "$TIMEOUT" ]; then + sudo kill -KILL -$bt_pgid 2>/dev/null + echo "BPFTRACE ${msg} TIMEOUT!" + dump_bt_output + exit 1 + elif ! kill -s 0 "$bt_pid"; then + echo "BPFTRACE ${msg} FAILURE!" + dump_bt_output + exit 1 + else + sleep 0.2 + fi + done + } + # wait for bpftrace to finish attachment - bt_start=$(date +%s) - while true; do - bt_elapsed=$(( $(date +%s) - bt_start )) - if grep -q "STARTED!" "$TEST_BTOUT_RAW"; then - break - elif [ "$bt_elapsed" -ge "$TIMEOUT" ]; then - sudo kill -KILL -$bt_pgid 2>/dev/null - echo "BPFTRACE STARTUP TIMEOUT!" - echo "BPFTRACE SCRIPT:" - cat "$TEST_BTSCRIPT" - echo "BPFTRACE OUTPUT:" - cat "$TEST_BTOUT_RAW" - exit 1 - elif ! kill -s 0 "$bt_pid"; then - echo "BPFTRACE STARTUP FAILURE!" - echo "BPFTRACE SCRIPT:" - cat "$TEST_BTSCRIPT" - echo "BPFTRACE OUTPUT:" - cat "$TEST_BTOUT_RAW" - exit 1 - else - sleep 0.2 - fi - done + wait_for_bpftrace "STARTED!" "STARTUP" # get test output while bpftrace is attached $TEST_BIN &>"$TEST_OUT" - sudo kill -INT -$bt_pgid 2>/dev/null + # wait for bpftrace to terminate + wait_for_bpftrace "DONE!" "RUNNING" $awk '/STARTED!/ {flag=1; next} /DONE!/ {flag=0} flag' $TEST_BTOUT_RAW > $TEST_BTOUT if ! $awk -f check-match.awk $TEST_BTOUT_SPEC $TEST_BTOUT; then