FIXTURES="$BATS_TEST_DIRNAME/../fixtures" LIBDIR="$(cd "$BATS_TEST_DIRNAME/../.."/package/kit-busrouter/files/usr/lib/busrouter && pwd)" setup() { export LIB_DIR="$LIBDIR" load '../../package/kit-busrouter/files/usr/lib/busrouter/lib-decide.sh' load '../../package/kit-busrouter/files/usr/lib/busrouter/modem-sim.sh' } @test "modem_signal ubus parse: rsrp=-96 rsrq=-10 sinr=13" { run _modem_parse_ubus < "$FIXTURES/modem-signal-ubus.json" [ "$status" -eq 0 ] rsrp=$(echo "$output" | awk '{print $1}') rsrq=$(echo "$output" | awk '{print $2}') sinr=$(echo "$output" | awk '{print $3}') [ "$rsrp" -eq -96 ] [ "$rsrq" -eq -10 ] [ "$sinr" -eq 13 ] } @test "modem_signal AT parse: rsrp=-97 rsrq=-10 sinr=14 (rsrp rsrq sinr order)" { run _modem_parse_at < "$FIXTURES/modem-signal-at.txt" [ "$status" -eq 0 ] rsrp=$(echo "$output" | awk '{print $1}') rsrq=$(echo "$output" | awk '{print $2}') sinr=$(echo "$output" | awk '{print $3}') [ "$rsrp" -eq -97 ] [ "$rsrq" -eq -10 ] [ "$sinr" -eq 14 ] } @test "modem_signal ubus parse: empty input exits 1" { run _modem_parse_ubus < /dev/null [ "$status" -ne 0 ] [ -z "$output" ] } @test "modem_signal AT parse: empty input exits 1" { run _modem_parse_at < /dev/null [ "$status" -ne 0 ] [ -z "$output" ] } @test "modem_sim_switch: rejects invalid slot" { export MODEM_AT_CMD=/bin/true MODEM_BUS=1-1.2 run modem_sim_switch 3 [ "$status" -eq 1 ] } @test "modem_sim_switch: accepts slot 1" { # Stub gl_modem to emit 'OK' and stub ifdown/ifup mkdir -p "$BATS_TMPDIR/stub" printf '#!/bin/sh echo OK ' > "$BATS_TMPDIR/stub/gl_modem" printf '#!/bin/sh exit 0 ' > "$BATS_TMPDIR/stub/ifdown" printf '#!/bin/sh exit 0 ' > "$BATS_TMPDIR/stub/ifup" chmod +x "$BATS_TMPDIR/stub/gl_modem" "$BATS_TMPDIR/stub/ifdown" "$BATS_TMPDIR/stub/ifup" export PATH="$BATS_TMPDIR/stub:$PATH" export MODEM_AT_CMD=gl_modem MODEM_BUS=1-1.2 run modem_sim_switch 1 [ "$status" -eq 0 ] } # --- Task 4.2: SIM auto-switch --- _sim_make_stub() { mkdir -p "$BATS_TMPDIR/sim_stub" printf '#!/bin/sh case "$*" in *QUIMSLOT\?*) echo "+QUIMSLOT: 1"; echo "OK" ;; *QUIMSLOT=*) echo "OK" ;; *) echo "OK" ;; esac ' > "$BATS_TMPDIR/sim_stub/gl_modem" printf '#!/bin/sh exit 0 ' > "$BATS_TMPDIR/sim_stub/ifdown" printf '#!/bin/sh exit 0 ' > "$BATS_TMPDIR/sim_stub/ifup" chmod +x "$BATS_TMPDIR/sim_stub/gl_modem" "$BATS_TMPDIR/sim_stub/ifdown" "$BATS_TMPDIR/sim_stub/ifup" export PATH="$BATS_TMPDIR/sim_stub:$PATH" export MODEM_AT_CMD=gl_modem MODEM_BUS=1-1.2 export SIM_STATE_DIR="$BATS_TMPDIR/simstate" export SIM_SWITCH_RSRP=-80 # threshold above actual -99 bench value -> easy to trigger export SIM_SWITCH_CYCLES=3 export SIM_SWITCH_COOLDOWN=3600 rm -rf "$BATS_TMPDIR/simstate" mkdir -p "$BATS_TMPDIR/simstate" } @test "sim_check: good signal resets counter and does not switch" { _sim_make_stub # First call with bad signal to set counter to 1 sim_check_and_switch -90 || true bad=$(cat "$SIM_STATE_DIR/sim_bad_cycles" 2>/dev/null || echo 0) [ "$bad" -eq 1 ] # Now good signal resets sim_check_and_switch -70 || true bad=$(cat "$SIM_STATE_DIR/sim_bad_cycles" 2>/dev/null || echo 0) [ "$bad" -eq 0 ] } @test "sim_check: triggers switch after SIM_SWITCH_CYCLES bad cycles" { _sim_make_stub # 2 bad cycles -> no switch yet sim_check_and_switch -90 || true sim_check_and_switch -90 || true [ ! -f "$SIM_STATE_DIR/sim_last_switch" ] # 3rd bad cycle -> switch triggered run sim_check_and_switch -90 [ "$status" -eq 0 ] [ -f "$SIM_STATE_DIR/sim_last_switch" ] } @test "sim_check: cooldown prevents switch within SIM_SWITCH_COOLDOWN" { _sim_make_stub export SIM_SWITCH_COOLDOWN=3600 # Pre-seed a recent switch time date +%s > "$SIM_STATE_DIR/sim_last_switch" run sim_check_and_switch -90 [ "$status" -eq 1 ] # blocked by cooldown }