Add native self-hosted instance connection to fluxer_desktop
Trimmed monorepo checkout (fluxer_desktop + packages/voice_engine_v2 + tools/ci) with a "Connect to a Different Server" menu item and popout that lets the desktop app switch to any self-hosted Fluxer instance, plus fixes for well-known discovery on single-domain self-hosted deployments and a false-positive ERR_ABORTED on same-origin client redirects during the switch. Defaults to chat.fluxr.chat and uses an isolated userData directory from the official build.
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
WORK="${FLX_WORK:-/home/parallels/flx-vmtest}"
|
||||
ADDON_SO="${FLX_ADDON_SO:-/home/parallels/flx-target/debug/libfluxer_linux_audio_capture.so}"
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
mkdir -p "$WORK"
|
||||
export XDG_RUNTIME_DIR="$WORK/xdg"
|
||||
mkdir -p "$XDG_RUNTIME_DIR"; chmod 700 "$XDG_RUNTIME_DIR"
|
||||
export PIPEWIRE_RUNTIME_DIR="$XDG_RUNTIME_DIR"
|
||||
export PULSE_RUNTIME_PATH="$XDG_RUNTIME_DIR/pulse"
|
||||
unset DISPLAY WAYLAND_DISPLAY DBUS_SESSION_BUS_ADDRESS
|
||||
|
||||
PIDS=()
|
||||
cleanup() {
|
||||
for p in "${PIDS[@]:-}"; do kill -9 "$p" 2>/dev/null; done
|
||||
pkill -9 -u "$(id -un)" -f "pipewire" 2>/dev/null
|
||||
pkill -9 -u "$(id -un)" -f "wireplumber" 2>/dev/null
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "=== starting private pipewire server (runtime=$XDG_RUNTIME_DIR) ==="
|
||||
pipewire >"$WORK/pipewire.log" 2>&1 & PIDS+=($!)
|
||||
sleep 0.8
|
||||
pipewire-pulse >"$WORK/pipewire-pulse.log" 2>&1 & PIDS+=($!)
|
||||
sleep 0.5
|
||||
wireplumber >"$WORK/wireplumber.log" 2>&1 & PIDS+=($!)
|
||||
|
||||
for _ in $(seq 1 40); do pw-cli info 0 >/dev/null 2>&1 && break; sleep 0.25; done
|
||||
if ! pw-cli info 0 >/dev/null 2>&1; then
|
||||
echo "FATAL: private pipewire did not come up"; cat "$WORK/pipewire.log"; exit 2
|
||||
fi
|
||||
|
||||
echo "=== creating virtual speakers (default sink) ==="
|
||||
pactl load-module module-null-sink sink_name=test_speakers sink_properties='device.description=Test_Speakers' >/dev/null 2>&1
|
||||
pactl set-default-sink test_speakers 2>/dev/null
|
||||
sleep 0.4
|
||||
|
||||
echo "=== generating a real 600s stereo tone ==="
|
||||
TONE="$WORK/tone.wav"
|
||||
[ -f "$TONE" ] || ffmpeg -hide_banner -loglevel error -f lavfi -i "sine=frequency=440:duration=600" -ac 2 -ar 48000 "$TONE" </dev/null
|
||||
export FLX_TONE="$TONE"
|
||||
|
||||
echo "=== spawning 4 external real-app players (outside the harness process tree) ==="
|
||||
pw-play --target test_speakers "$TONE" >/dev/null 2>&1 & PIDS+=($!)
|
||||
pw-play --target test_speakers -P '{ application.name = "Music Player Demo" }' "$TONE" >/dev/null 2>&1 & PIDS+=($!)
|
||||
pw-play --target test_speakers -P '{ application.name = "Fluxer" }' "$TONE" >/dev/null 2>&1 & PIDS+=($!)
|
||||
pw-play --target test_speakers -P '{ node.name = "Fluxer Helper Stream" }' "$TONE" >/dev/null 2>&1 & PIDS+=($!)
|
||||
sleep 1.5
|
||||
|
||||
echo "=== pre-test graph (fluxer sink should be ABSENT) ==="
|
||||
pw-dump | node -e 'const d=JSON.parse(require("fs").readFileSync(0));const f=d.filter(o=>o.type==="PipeWire:Interface:Node"&&/fluxer-screen-share/.test(o.info?.props?.["node.name"]||""));console.log("fluxer sink nodes pre-test:",f.length);'
|
||||
|
||||
echo "=== running napi SYSTEM-capture validation harness ==="
|
||||
export FLX_ADDON_SO="$ADDON_SO" FLX_WORK="$WORK"
|
||||
node "$HERE/pw_graph_validation.mjs"
|
||||
HARNESS_RC=$?
|
||||
|
||||
echo "=== running napi DIRECT (per-process) capture validation harness ==="
|
||||
node "$HERE/direct_capture_validation.mjs"
|
||||
DIRECT_RC=$?
|
||||
[ "$DIRECT_RC" = "0" ] || HARNESS_RC=$DIRECT_RC
|
||||
|
||||
echo "=== post-exit cleanup check (Drop must remove the fluxer sink) ==="
|
||||
sleep 0.8
|
||||
RESIDUAL=$(pw-dump | node -e 'const d=JSON.parse(require("fs").readFileSync(0));const f=d.filter(o=>(o.type==="PipeWire:Interface:Node"&&/fluxer/.test(o.info?.props?.["node.name"]||""))||(o.type==="PipeWire:Interface:Link"&&/fluxer/.test(JSON.stringify(o.info?.props||{}))));console.log(f.length);')
|
||||
if [ "$RESIDUAL" = "0" ]; then
|
||||
echo "PASS no fluxer nodes/links remain after addon process exit (clean teardown)"
|
||||
else
|
||||
echo "FAIL $RESIDUAL residual fluxer objects after addon process exit"
|
||||
HARNESS_RC=1
|
||||
fi
|
||||
|
||||
echo "=== DONE rc=$HARNESS_RC ==="
|
||||
exit $HARNESS_RC
|
||||
Reference in New Issue
Block a user