Skip to content

Commit

Permalink
ci: minimal testing worklow
Browse files Browse the repository at this point in the history
Add scripts to setup and run the tests on CI.

===

Note on bpftrace

Using bpftrace -c doesn't work for these tests, when there are
tracepoints refering to dynamic libraries. This is because the .so is
not loaded yet when bpftrace attempts to attach.

In run_test.sh bpftrace terminates at the end of target test
program. After that test output is compared.
  • Loading branch information
theihor committed Jan 23, 2025
1 parent e09e184 commit 8186b92
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 31 deletions.
21 changes: 21 additions & 0 deletions .github/scripts/setup.sh
Original file line number Diff line number Diff line change
@@ -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
31 changes: 31 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -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

Empty file added tests/DENYLIST
Empty file.
7 changes: 3 additions & 4 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
) \
Expand Down Expand Up @@ -128,5 +128,4 @@ $(foreach lib, $(LIBS), $(eval $(call BUILD_RULE_LIB,$(lib))))
$(BUILD_TARGETS): build-%: $(OBJDIR)/%

$(TEST_TARGETS): test-%: build-%
$(call msg,TESTING,$(if $(filter 1,$(SHARED)),shared/,static/)$(patsubst test-%,%,$@))
$(Q)./run_test.sh $(OBJDIR) $(patsubst test-%,%,$@)
6 changes: 4 additions & 2 deletions tests/prepare-bt-script.awk
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@

# Emit corresponding bpftrace probe spec:
# U:./test:group:name { printf("%s: some %s fmt %d spec %d\n", probe, str(arg0), (int)arg1, arg2 - 10); }
printf("U:%s:%s:%s { printf(\"%s%s:%s: %s\\n\"%s); }\n",
printf("usdt:%s:%s:%s { printf(\"%s%s:%s: %s\\n\"%s); }\n",
path, group, name,
probe[1] == "lib" ? "lib:" : "", group, name,
fmt, args == "" ? "" : ", " args);
}

END {
if (has_contents)
if (has_contents) {
printf("uretprobe:%s:main { exit(); }\n", OUTPUT "/" TEST);
printf("END { printf(\"DONE!\\n\"); }\n");
}
}
67 changes: 42 additions & 25 deletions tests/run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ TEST=$2
TEST_BIN="$1/$2"
TEST_LIB="$1/lib$2.so"

TEST_ID=$(realpath --relative-to="$OUTPUT/.." "$TEST_BIN")

if grep -q "$TEST_ID" DENYLIST; then
echo "run_test.sh: SKIPPING $TEST_ID"
exit 0
else
echo "run_test.sh: TESTING $TEST_ID"
fi

TEST_USDTS_SPEC=$TEST_BIN.exp_usdts.txt
TEST_USDTS_OUT=$TEST_BIN.act_usdts.txt
TEST_PRE_SPEC=$TEST_BIN.exp_pre_out.txt
Expand Down Expand Up @@ -69,36 +78,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
Expand Down

0 comments on commit 8186b92

Please sign in to comment.