AtlatestRepositorysigil-audio
sigil-audio / tree / testdl-search-test.sh
1
#!/bin/sh2
# dl-search-test.sh - the dlopen resolver against fake Guix and Nix profiles3
# (sigil-desktop: the interposed dlopen; sigil-audio: the named resolver,4
# the probe calls whichever the -D configuration below selects).5
#6
# Builds a probe from src/c/dl-search.c, a throwaway shared object, and a7
# temp HOME holding an empty ~/.guix-home/profile/lib and a8
# ~/.nix-profile/lib that has the object; then asserts, in order:9
# 1. the plain loader cannot find the soname (the control: the fallback10
# is what resolves it, not LD_LIBRARY_PATH or the cache)11
# 2. it resolves, from the Nix profile, with the Guix row walked first12
# and empty (both distributions' rows are live at once)13
# 3. with a copy in the Guix profile too, the Guix row wins (first hit)14
# and the trace names it15
# 4. IN_NIX_SHELL + buildInputs resolves ahead of every profile, and the16
# same buildInputs without IN_NIX_SHELL resolves nothing17
# 5. SIGIL_LIBRARY_PATH resolves ahead of everything18
# Any assertion failing exits 1. Needs a C compiler: $CC, or the pinned19
# zig under ~/.sigil/toolchain/zig, or cc.20
set -u21
cd "$(dirname "$0")/.." || exit 222
if [ -n "${CC:-}" ]; then :23
elif [ -x "$HOME/.sigil/toolchain/zig/zig" ]; then CC="$HOME/.sigil/toolchain/zig/zig cc"24
elif command -v cc >/dev/null 2>&1; then CC=cc25
else echo "SETUP-FAILED: no C compiler (set CC)"; exit 2; fi26
T=$(mktemp -d) || exit 227
trap 'rm -rf "$T"' EXIT28
FAKE=libsigildlsearchfake.so.729
printf 'int sigil_fake_answer(void) { return 42; }\n' > "$T/fake.c"30
$CC -shared -fPIC -o "$T/$FAKE" "$T/fake.c" || { echo "SETUP-FAILED: cannot build the fake library"; exit 2; }31
$CC -o "$T/probe" -DSIGIL_DL_SEARCH_OPEN=sigil_audio_dl_open -DSIGIL_DL_SEARCH_SUMMARY=sigil_audio_dlopen_search_summary -DSIGIL_DL_SEARCH_TAG=\"sigil-audio\" -DSIGIL_DL_SEARCH_VERBOSE_ENV=\"SIGIL_AUDIO_VERBOSE\" -DSIGIL_DL_SEARCH_INTERPOSE=0 test/dl-search-probe.c src/c/dl-search.c -ldl || { echo "SETUP-FAILED: cannot build the probe"; exit 2; }32
H="$T/home"; mkdir -p "$H/.guix-home/profile/lib" "$H/.nix-profile/lib" "$T/nixstore/foo-1.0/lib"33
cp "$T/$FAKE" "$H/.nix-profile/lib/"34
fails=035
pass() { echo "PASS $1: $2"; }36
fail() { echo "FAIL $1: $2"; fails=$((fails + 1)); }37
run() { # name, expected-substring-of-stdout, env assignments...38
name=$1; want=$2; shift 239
out=$(env -i HOME="$H" USER=sigiltest SIGIL_AUDIO_VERBOSE=1 "$@" "$T/probe" "$FAKE" 2>&1)40
case "$out" in *"$want"*) pass "$name" "$want";; *) fail "$name" "wanted [$want], got: $out";; esac41
}42
# 1. control: HOME with no profile dirs at all43
mkdir -p "$T/emptyhome"44
run control "UNRESOLVED $FAKE" HOME="$T/emptyhome"45
# 2. Nix profile only (the Guix row exists and is empty)46
run nix-profile "found via HOME/.nix-profile/lib as $H/.nix-profile/lib/$FAKE"47
# 3. both: Guix Home first48
cp "$T/$FAKE" "$H/.guix-home/profile/lib/"49
run first-hit-wins "found via HOME/.guix-home/profile/lib as $H/.guix-home/profile/lib/$FAKE"50
# 4. nix-shell inputs beat the profiles51
cp "$T/$FAKE" "$T/nixstore/foo-1.0/lib/"52
run nix-shell "found via buildInputs/lib as $T/nixstore/foo-1.0/lib/$FAKE" IN_NIX_SHELL=impure buildInputs="$T/nixstore/bar-2.0 $T/nixstore/foo-1.0"53
# 4b. the nix-shell rows apply only under IN_NIX_SHELL: same buildInputs, no54
# IN_NIX_SHELL, no copies in the profiles -> unresolved55
rm -f "$H/.guix-home/profile/lib/$FAKE" "$H/.nix-profile/lib/$FAKE"56
run nix-shell-gated "UNRESOLVED $FAKE" buildInputs="$T/nixstore/foo-1.0"57
cp "$T/$FAKE" "$H/.nix-profile/lib/"58
# 5. the override beats everything59
mkdir -p "$T/override"; cp "$T/$FAKE" "$T/override/"60
run override "found via SIGIL_LIBRARY_PATH as $T/override/$FAKE" SIGIL_LIBRARY_PATH="/nonexistent:$T/override" IN_NIX_SHELL=impure buildInputs="$T/nixstore/foo-1.0"61
# provenance: the file must be the one src/c/DL-SEARCH-ORIGIN.md records (the62
# same hash is recorded in the other repository that carries a copy)63
want=$(grep -E '^ [0-9a-f]{64}$' src/c/DL-SEARCH-ORIGIN.md 2>/dev/null | tr -d ' ')64
have=$(sha256sum src/c/dl-search.c | cut -d' ' -f1)65
if [ -z "$want" ]; then fail provenance "src/c/DL-SEARCH-ORIGIN.md missing or without a recorded sha256"66
elif [ "$want" = "$have" ]; then pass provenance "dl-search.c matches the hash in DL-SEARCH-ORIGIN.md"67
else fail provenance "dl-search.c sha256 $have, DL-SEARCH-ORIGIN.md records $want: re-record it here and copy both to the other repository"; fi68
# the trace names the stores present on this machine69
out=$(env -i HOME="$H" USER=sigiltest SIGIL_AUDIO_VERBOSE=1 "$T/probe" "$FAKE" 2>&1)70
case "$out" in *"(/gnu/store "*", /nix/store "*")"*) pass trace-stores "$(echo "$out" | grep -o '(/gnu/store [a-z]*, /nix/store [a-z]*)' | head -1)";; *) fail trace-stores "no store note in: $out";; esac71
if [ $fails -eq 0 ]; then echo "GREEN: dl-search"; exit 0; else echo "RED: $fails failed"; exit 1; fi