test: Aprsme.Is reconnect success + connect-failure paths

This commit is contained in:
Graham McIntire 2026-04-24 08:04:16 -05:00
parent 795270c666
commit f7a331b708
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -591,6 +591,82 @@ defmodule Aprsme.IsTest do
end
end
describe "handle_info(:reconnect) with mocked connection" do
# Start a listener, temporarily swap APRS-IS config to point at it,
# then trigger :reconnect so Aprsme.Is opens a real TCP connection.
setup do
{:ok, listen} = :gen_tcp.listen(0, [:binary, active: false, reuseaddr: true])
{:ok, port} = :inet.port(listen)
# Spawn an acceptor that reads the login string and closes.
spawn_link(fn ->
case :gen_tcp.accept(listen, 5_000) do
{:ok, srv} ->
_ = :gen_tcp.recv(srv, 0, 1_000)
_ = :gen_tcp.close(srv)
_ ->
:ok
end
end)
original_disabled = Application.get_env(:aprsme, :disable_aprs_connection, false)
original_env = Application.get_env(:aprsme, :env)
Application.put_env(:aprsme, :disable_aprs_connection, false)
Application.put_env(:aprsme, :env, :dev)
on_exit(fn ->
Application.put_env(:aprsme, :disable_aprs_connection, original_disabled)
Application.put_env(:aprsme, :env, original_env)
_ = :gen_tcp.close(listen)
end)
{:ok, port: port}
end
test "reconnect succeeds and updates socket/timers", %{port: port} do
state = build_state(%{server: ~c"127.0.0.1", port: port, socket: nil, timer: nil, keepalive_timer: nil})
capture_log(fn ->
assert {:noreply, new_state} = Aprsme.Is.handle_info(:reconnect, state)
assert is_port(new_state.socket) or is_tuple(new_state.socket)
assert is_reference(new_state.timer)
assert is_reference(new_state.keepalive_timer)
refute new_state.backpressure_active
# Cleanup
if new_state.socket, do: :gen_tcp.close(new_state.socket)
if new_state.timer, do: Process.cancel_timer(new_state.timer)
if new_state.keepalive_timer, do: Process.cancel_timer(new_state.keepalive_timer)
end)
end
end
describe "handle_info(:reconnect) when connect fails" do
test "schedules another reconnect attempt on connection error" do
# Port 1 should always refuse or fail — triggers the connect-error branch.
original_disabled = Application.get_env(:aprsme, :disable_aprs_connection, false)
original_env = Application.get_env(:aprsme, :env)
Application.put_env(:aprsme, :disable_aprs_connection, false)
Application.put_env(:aprsme, :env, :dev)
on_exit(fn ->
Application.put_env(:aprsme, :disable_aprs_connection, original_disabled)
Application.put_env(:aprsme, :env, original_env)
end)
state = build_state(%{server: ~c"127.0.0.1", port: 1, socket: nil, timer: nil, keepalive_timer: nil})
capture_log(fn ->
assert {:noreply, same_state} = Aprsme.Is.handle_info(:reconnect, state)
assert same_state == state
end)
end
end
describe "handle_info({:backpressure, _}) with active socket" do
setup do
{client, _listen, cleanup} = loopback_socket()