diff --git a/deploys/test/nonprod-call-evidence.sh b/deploys/test/nonprod-call-evidence.sh index 713525f..9380989 100755 --- a/deploys/test/nonprod-call-evidence.sh +++ b/deploys/test/nonprod-call-evidence.sh @@ -91,11 +91,8 @@ require_call_window() { fi } require_call_window -if [[ "$interface" == any ]]; then - default_interface="$(ip route show default 2>/dev/null | awk 'NR == 1 {for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}')" - [[ -n "$default_interface" ]] && interface="$default_interface" -fi - +# "any" includes both provider SIP and the local Asterisk ExternalMedia RTP. +# Reducing it to the default-route NIC silently omits loopback media. if [[ -z "$evidence_dir" ]]; then evidence_dir="/var/lib/sip-go-agent/evidence/$call_id" fi diff --git a/internal/config/nonprod_evidence_cleanup_test.go b/internal/config/nonprod_evidence_cleanup_test.go index 005a731..8177e36 100644 --- a/internal/config/nonprod_evidence_cleanup_test.go +++ b/internal/config/nonprod_evidence_cleanup_test.go @@ -51,9 +51,9 @@ func TestNonprodUserAsteriskScopeUsesUserServiceAndConfiguredCLI(t *testing.T) { write("date", "if [ \"${TZ-}\" = Asia/Shanghai ] && [ \"$1\" = +%H%M ]; then echo 1000; else exec /usr/bin/date \"$@\"; fi\n") write("runuser", "[ \"$1\" = -u ] && [ \"$3\" = -- ] || exit 99\nshift 3\nexec \"$@\"\n") write("systemctl", "[ \"$1\" = --user ] && [ \"$3\" = go-sip-asterisk.service ] || exit 99\nprintf '%s\\n' \"$2\" >>\"$TEST_SERVICE_LOG\"\ncase \"$2\" in is-enabled) echo enabled;; is-active) echo active;; *) exit 99;; esac\n") - write("ip", "echo 'lo UNKNOWN 127.0.0.1/8'\n") + write("ip", "echo 'default via 192.0.2.1 dev eth0'\n") write("ss", "echo 'udp 127.0.0.1:5060'\n") - write("tcpdump", "case \" $* \" in *' -c 1 '*) exit 124;; esac\nexit 99\n") + write("tcpdump", "printf '%s\\n' \"$*\" >>\"$TEST_CAPTURE_ARGS\"\ncase \" $* \" in *' -c 1 '*) exit 124;; esac\nexit 99\n") asterisk := write("asterisk", "[ \"$1\" = -C ] && [ \"$2\" = \"$TEST_CONFIG\" ] && [ \"$3\" = -rx ] || exit 98\nprintf '%s\\n' \"$4\" >>\"$TEST_CLI_LOG\"\ncase \"$4\" in 'module show like res_ari.so') echo 'res_ari.so Asterisk REST Interface 0 Running';; 'http show status') echo 'Server Enabled and Bound to 127.0.0.1:8088'; echo '/ari/...';; 'pjsip show endpoint '*) echo 'Endpoint: not-loaded';; *) exit 97;; esac\n") root := t.TempDir() configFile := filepath.Join(root, "asterisk.conf") @@ -66,13 +66,14 @@ func TestNonprodUserAsteriskScopeUsesUserServiceAndConfiguredCLI(t *testing.T) { } serviceLog := filepath.Join(root, "service-checked") cliLog := filepath.Join(root, "cli-checked") + captureArgs := filepath.Join(root, "capture-args") command := exec.Command("bash", "../../deploys/test/nonprod-call-evidence.sh", "--environment", "mock", "--asterisk-scope", "user", "--trunk", "provider-primary", "--target", "15003164745", "--run-as", currentUser.Username, - "--interface", "lo", "--recording-dir", filepath.Join(root, "recordings"), "--evidence-dir", filepath.Join(root, "evidence"), + "--interface", "any", "--recording-dir", filepath.Join(root, "recordings"), "--evidence-dir", filepath.Join(root, "evidence"), "--attempt-ledger", filepath.Join(root, "attempts.tsv"), "--preflight-only", "--", "/bin/true") command.Env = append(os.Environ(), "PATH="+tools+":"+os.Getenv("PATH"), "ASTERISK_BIN="+asterisk, "ASTERISK_CONFIG="+configFile, "ASTERISK_LIBRARY_PATH="+tools, "TCPDUMP_BIN="+filepath.Join(tools, "tcpdump"), "TEST_CONFIG="+configFile, - "TEST_SERVICE_LOG="+serviceLog, "TEST_CLI_LOG="+cliLog) + "TEST_SERVICE_LOG="+serviceLog, "TEST_CLI_LOG="+cliLog, "TEST_CAPTURE_ARGS="+captureArgs) output, err := command.CombinedOutput() if err == nil || !strings.Contains(string(output), "PJSIP endpoint unavailable") { t.Fatalf("missing user-service endpoint must block before dialing: err=%v output=%s", err, output) @@ -81,6 +82,10 @@ func TestNonprodUserAsteriskScopeUsesUserServiceAndConfiguredCLI(t *testing.T) { if err != nil || !strings.Contains(string(serviceChecks), "is-enabled\nis-active\n") { t.Fatalf("user service status was not verified: %v %q", err, serviceChecks) } + actualCapture, err := os.ReadFile(captureArgs) + if err != nil || !strings.Contains(string(actualCapture), "-i any ") { + t.Fatalf("preflight must capture both external SIP and loopback RTP: err=%v args=%q", err, actualCapture) + } cliChecks, err := os.ReadFile(cliLog) if err != nil || !strings.Contains(string(cliChecks), "module show like res_ari.so\nhttp show status\npjsip show endpoint provider-primary\n") { t.Fatalf("configured user Asterisk CLI was not used: %v %q", err, cliChecks)