AtlatestRepositorysigil-audio

sigil-audio / tree / testdl-search-test.sh

1#!/bin/sh
2# dl-search-test.sh - the dlopen resolver against fake Guix and Nix profiles
3# (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 a
7# temp HOME holding an empty ~/.guix-home/profile/lib and a
8# ~/.nix-profile/lib that has the object; then asserts, in order:
9# 1. the plain loader cannot find the soname (the control: the fallback
10# is what resolves it, not LD_LIBRARY_PATH or the cache)
11# 2. it resolves, from the Nix profile, with the Guix row walked first
12# 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 it
15# 4. IN_NIX_SHELL + buildInputs resolves ahead of every profile, and the
16# same buildInputs without IN_NIX_SHELL resolves nothing
17# 5. SIGIL_LIBRARY_PATH resolves ahead of everything
18# Any assertion failing exits 1. Needs a C compiler: $CC, or the pinned
19# zig under ~/.sigil/toolchain/zig, or cc.
20set -u
21cd "$(dirname "$0")/.." || exit 2
22if [ -n "${CC:-}" ]; then :
23elif [ -x "$HOME/.sigil/toolchain/zig/zig" ]; then CC="$HOME/.sigil/toolchain/zig/zig cc"
24elif command -v cc >/dev/null 2>&1; then CC=cc
25else echo "SETUP-FAILED: no C compiler (set CC)"; exit 2; fi
26T=$(mktemp -d) || exit 2
27trap 'rm -rf "$T"' EXIT
28FAKE=libsigildlsearchfake.so.7
29printf '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; }
32H="$T/home"; mkdir -p "$H/.guix-home/profile/lib" "$H/.nix-profile/lib" "$T/nixstore/foo-1.0/lib"
33cp "$T/$FAKE" "$H/.nix-profile/lib/"
34fails=0
35pass() { echo "PASS $1: $2"; }
36fail() { echo "FAIL $1: $2"; fails=$((fails + 1)); }
37run() { # name, expected-substring-of-stdout, env assignments...
38 name=$1; want=$2; shift 2
39 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";; esac
42# 1. control: HOME with no profile dirs at all
43mkdir -p "$T/emptyhome"
44run control "UNRESOLVED $FAKE" HOME="$T/emptyhome"
45# 2. Nix profile only (the Guix row exists and is empty)
46run nix-profile "found via HOME/.nix-profile/lib as $H/.nix-profile/lib/$FAKE"
47# 3. both: Guix Home first
48cp "$T/$FAKE" "$H/.guix-home/profile/lib/"
49run first-hit-wins "found via HOME/.guix-home/profile/lib as $H/.guix-home/profile/lib/$FAKE"
50# 4. nix-shell inputs beat the profiles
51cp "$T/$FAKE" "$T/nixstore/foo-1.0/lib/"
52run 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, no
54# IN_NIX_SHELL, no copies in the profiles -> unresolved
55rm -f "$H/.guix-home/profile/lib/$FAKE" "$H/.nix-profile/lib/$FAKE"
56run nix-shell-gated "UNRESOLVED $FAKE" buildInputs="$T/nixstore/foo-1.0"
57cp "$T/$FAKE" "$H/.nix-profile/lib/"
58# 5. the override beats everything
59mkdir -p "$T/override"; cp "$T/$FAKE" "$T/override/"
60run 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 (the
62# same hash is recorded in the other repository that carries a copy)
63want=$(grep -E '^ [0-9a-f]{64}$' src/c/DL-SEARCH-ORIGIN.md 2>/dev/null | tr -d ' ')
64have=$(sha256sum src/c/dl-search.c | cut -d' ' -f1)
65if [ -z "$want" ]; then fail provenance "src/c/DL-SEARCH-ORIGIN.md missing or without a recorded sha256"
66elif [ "$want" = "$have" ]; then pass provenance "dl-search.c matches the hash in DL-SEARCH-ORIGIN.md"
67else fail provenance "dl-search.c sha256 $have, DL-SEARCH-ORIGIN.md records $want: re-record it here and copy both to the other repository"; fi
68# the trace names the stores present on this machine
69out=$(env -i HOME="$H" USER=sigiltest SIGIL_AUDIO_VERBOSE=1 "$T/probe" "$FAKE" 2>&1)
70case "$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";; esac
71if [ $fails -eq 0 ]; then echo "GREEN: dl-search"; exit 0; else echo "RED: $fails failed"; exit 1; fi