mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
5.4 KiB
146 lines
5.4 KiB
#!/usr/bin/env bash
|
|
#
|
|
# run-unit-tests-asan-coverage.bash — runs every executable under
|
|
# test/tap/tests/unit/ and captures an LCOV+HTML coverage report.
|
|
#
|
|
# Designed to be invoked INSIDE the ubuntu24_dbg_build container that
|
|
# `make ubuntu24-tap` produces (or any container with the ProxySQL
|
|
# build toolchain + the source bind-mounted at /opt/proxysql). The
|
|
# CI workflow `.github/workflows/CI-unit-tests-asan-coverage.yml` is
|
|
# a thin wrapper that does:
|
|
#
|
|
# docker compose run --rm --entrypoint bash ubuntu24_dbg_build \
|
|
# -lc 'cd /opt/proxysql && \
|
|
# test/infra/control/run-unit-tests-asan-coverage.bash'
|
|
#
|
|
# Local repro is the same command — both paths share this script as
|
|
# the single source of truth.
|
|
#
|
|
# Preconditions:
|
|
# * cwd is the repository root (the script cd's there from $0 if not).
|
|
# * lib/, src/, and test/tap/tests/unit/ have been built with
|
|
# WITHASAN=1 WITHGCOV=1 NOJEMALLOC=1 PROXYSQLGENAI=1 (the make
|
|
# target `ubuntu24-tap` does this when invoked with those flags).
|
|
# * The container has apt — we install lcov + libprotobuf-dev on
|
|
# demand if missing (the build image is package-build-focused
|
|
# and ships neither). libprotobuf provides the runtime
|
|
# libprotobuf.so.32 the chassis-tier *-t binaries dlopen.
|
|
#
|
|
# Outputs (under cwd, visible on the host via the bind mount):
|
|
# * coverage/lcov.info — merged + filtered LCOV report
|
|
# * coverage/html/ — genhtml-rendered HTML report
|
|
# * unit-test-logs/<name>.log — stdout+stderr per failed test
|
|
#
|
|
# Exit status: 0 if all unit tests passed, 1 otherwise. Coverage
|
|
# capture runs regardless.
|
|
|
|
set -eu
|
|
|
|
# Ensure cwd is repo root no matter where we were invoked from.
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
REPO_ROOT="$( cd "${SCRIPT_DIR}/../../.." && pwd )"
|
|
cd "${REPO_ROOT}"
|
|
|
|
# ASAN_OPTIONS: caller can override (e.g. tighter halt_on_error). The
|
|
# default mirrors the values the CI workflow passes through and the
|
|
# values include/makefiles_vars.mk's WASAN block was tuned against.
|
|
export ASAN_OPTIONS="${ASAN_OPTIONS:-detect_leaks=0:abort_on_error=1:symbolize=1:print_stacktrace=1:halt_on_error=1}"
|
|
|
|
# Install runtime deps only if missing — keeps the script idempotent
|
|
# for repeated local runs and skips the apt round-trip when re-running
|
|
# inside an already-prepared container.
|
|
if ! command -v lcov >/dev/null 2>&1 || ! command -v genhtml >/dev/null 2>&1 \
|
|
|| ! ldconfig -p | grep -q libprotobuf\\.so; then
|
|
echo "==> Installing missing runtime deps (lcov, libprotobuf-dev)"
|
|
apt-get update -qq
|
|
apt-get install -y --no-install-recommends lcov libprotobuf-dev
|
|
fi
|
|
|
|
mkdir -p coverage unit-test-logs
|
|
|
|
echo "==> Capturing baseline coverage snapshot (--initial)"
|
|
# A baseline pass over all .gcno files seeds the report with zero
|
|
# coverage for every instrumented source line, so unrun code paths
|
|
# show as 0% in the merged report (rather than being absent
|
|
# entirely).
|
|
lcov --quiet --capture --initial \
|
|
--directory lib --directory src \
|
|
--output-file coverage/lcov-base.info \
|
|
--ignore-errors gcov,source || true
|
|
|
|
echo "==> Running unit tests under ASAN"
|
|
# Iterate every executable under test/tap/tests/unit/. We
|
|
# deliberately do NOT use run-tests-isolated.bash here: its
|
|
# dual-directory test discovery (test/tap/tests/ in addition to
|
|
# .../unit/) picks up integration tests misclassified as unit tests
|
|
# in groups.json (e.g. unit-strip_schema_from_query-t). Using the
|
|
# directory listing keeps the test set scoped to actual unit tests.
|
|
FAILED=()
|
|
PASSED=0
|
|
shopt -s nullglob
|
|
pushd test/tap/tests/unit >/dev/null
|
|
for t in *-t; do
|
|
[ -x "./${t}" ] || continue
|
|
log="${REPO_ROOT}/unit-test-logs/${t}.log"
|
|
echo "::group::${t}"
|
|
if ./"${t}" > "${log}" 2>&1; then
|
|
PASSED=$((PASSED + 1))
|
|
echo "PASS: ${t}"
|
|
else
|
|
rc=$?
|
|
FAILED+=("${t} (rc=${rc})")
|
|
echo "FAIL: ${t} (rc=${rc})"
|
|
tail -n 80 "${log}"
|
|
fi
|
|
echo "::endgroup::"
|
|
done
|
|
popd >/dev/null
|
|
|
|
echo
|
|
echo "===================================================================="
|
|
echo "Unit test summary: ${PASSED} passed, ${#FAILED[@]} failed"
|
|
echo "===================================================================="
|
|
test_rc=0
|
|
if [ ${#FAILED[@]} -gt 0 ]; then
|
|
printf " %s\n" "${FAILED[@]}"
|
|
test_rc=1
|
|
fi
|
|
|
|
echo "==> Capturing post-test coverage"
|
|
lcov --quiet --capture \
|
|
--directory lib --directory src \
|
|
--output-file coverage/lcov-tests.info \
|
|
--ignore-errors gcov,source,mismatch || true
|
|
|
|
if [ -s coverage/lcov-base.info ] && [ -s coverage/lcov-tests.info ]; then
|
|
lcov --quiet \
|
|
--add-tracefile coverage/lcov-base.info \
|
|
--add-tracefile coverage/lcov-tests.info \
|
|
--output-file coverage/lcov.info \
|
|
--ignore-errors mismatch || true
|
|
elif [ -s coverage/lcov-tests.info ]; then
|
|
cp coverage/lcov-tests.info coverage/lcov.info
|
|
fi
|
|
|
|
if [ -s coverage/lcov.info ]; then
|
|
# Filter out third-party / generated paths so the report stays
|
|
# focused on ProxySQL's own lib/ and src/.
|
|
lcov --quiet --remove coverage/lcov.info \
|
|
"/usr/*" "*/deps/*" "*/test/*" \
|
|
--output-file coverage/lcov.info \
|
|
--ignore-errors unused || true
|
|
|
|
genhtml --quiet \
|
|
--output-directory coverage/html \
|
|
--title "ProxySQL unit tests coverage" \
|
|
--demangle-cpp \
|
|
--legend \
|
|
coverage/lcov.info \
|
|
--ignore-errors source,category || true
|
|
|
|
echo "==> Coverage summary"
|
|
lcov --summary coverage/lcov.info || true
|
|
fi
|
|
|
|
exit "${test_rc}"
|