From 785a3f2d777627f39bed44f4ae7a0180d5184109 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 19 Oct 2023 16:37:47 -0400 Subject: tests: Refactor implementation into separate files --- tests/util.sh | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 tests/util.sh (limited to 'tests/util.sh') diff --git a/tests/util.sh b/tests/util.sh new file mode 100644 index 0000000..5131522 --- /dev/null +++ b/tests/util.sh @@ -0,0 +1,189 @@ +#!/hint/bash + +# Copyright © Tavian Barnes +# SPDX-License-Identifier: 0BSD + +## Utility functions + +# Portable realpath(1) +_realpath() ( + cd "$(dirname -- "$1")" + echo "$PWD/$(basename -- "$1")" +) + +# Globals +TESTS=$(_realpath "$TESTS") +if [ "${BUILDDIR-}" ]; then + BIN=$(_realpath "$BUILDDIR/bin") +else + BIN=$(_realpath "$TESTS/../bin") +fi +MKSOCK="$BIN/tests/mksock" +XTOUCH="$BIN/tests/xtouch" +UNAME=$(uname) + +# Standardize the environment +stdenv() { + export LC_ALL=C + export TZ=UTC0 + + local SAN_OPTIONS="halt_on_error=1:log_to_syslog=0" + export ASAN_OPTIONS="$SAN_OPTIONS" + export LSAN_OPTIONS="$SAN_OPTIONS" + export MSAN_OPTIONS="$SAN_OPTIONS" + export TSAN_OPTIONS="$SAN_OPTIONS" + export UBSAN_OPTIONS="$SAN_OPTIONS" + + export LS_COLORS="" + unset BFS_COLORS + + if [ "$UNAME" = Darwin ]; then + # ASan on macOS likes to report + # + # malloc: nano zone abandoned due to inability to preallocate reserved vm space. + # + # to syslog, which as a side effect opens a socket which might take the + # place of one of the standard streams if the process is launched with + # it closed. This environment variable avoids the message. + export MallocNanoZone=0 + fi + + # Close non-standard inherited fds + if [ -d /proc/self/fd ]; then + local fds=/proc/self/fd + else + local fds=/dev/fd + fi + + for fd in "$fds"/*; do + if [ ! -e "$fd" ]; then + continue + fi + + local fd="${fd##*/}" + if ((fd > 2)); then + eval "exec ${fd}<&-" + fi + done + + # Close stdin so bfs doesn't think we're interactive + # dup() the standard fds for logging even when redirected + exec &1 4>&2 +} + +# Drop root priviliges or bail +drop_root() { + if command -v capsh &>/dev/null; then + if capsh --has-p=cap_dac_override &>/dev/null || capsh --has-p=cap_dac_read_search &>/dev/null; then + if [ -n "${BFS_TRIED_DROP:-}" ]; then + color >&2 <&2 <&2 < 0)); then + printf ' %q' "$@" + fi +} + +# Run a command when this (sub)shell exits +defer() { + # Refresh trap state before trap -p + # See https://unix.stackexchange.com/a/556888/56202 + trap -- KILL + + # Check if the EXIT trap is already set + if ! trap -p EXIT | grep -q pop_defers; then + DEFER_CMDS=() + DEFER_LINES=() + DEFER_FILES=() + trap pop_defers EXIT + fi + + DEFER_CMDS+=("$(quote "$@")") + + local line file + read -r line file < <(caller) + DEFER_LINES+=("$line") + DEFER_FILES+=("$file") +} + +# Pop a single command from the defer stack and run it +pop_defer() { + local cmd="${DEFER_CMDS[-1]}" + local file="${DEFER_FILES[-1]}" + local line="${DEFER_LINES[-1]}" + unset "DEFER_CMDS[-1]" + unset "DEFER_FILES[-1]" + unset "DEFER_LINES[-1]" + + local ret=0 + eval "$cmd" || ret=$? + + if ((ret != 0)); then + debug "$file" $line "${RED}error $ret${RST}" "defer $cmd" >&4 + fi + + return $ret +} + +# Run all deferred commands +pop_defers() { + local ret=0 + + while ((${#DEFER_CMDS[@]} > 0)); do + pop_defer || ret=$? + done + + return $ret +} -- cgit v1.2.3