faster tests
This commit is contained in:
parent
fa0eb7704b
commit
ec0a64cf5f
12 changed files with 86 additions and 86 deletions
|
|
@ -61,6 +61,16 @@ config :aprsme,
|
|||
|
||||
# Disable automatic migrations during tests
|
||||
config :aprsme, auto_migrate: false
|
||||
config :aprsme, device_cache_initial_load_delay_ms: 0
|
||||
|
||||
# Short Req timeouts so HTTP calls fail fast without real network access.
|
||||
# retry: false prevents Req's default exponential backoff (1s+2s+4s=7s).
|
||||
config :aprsme, device_id_req_opts: [connect_options: [timeout: 50], receive_timeout: 50, retry: false]
|
||||
config :aprsme, election_initial_delay_ms: 0
|
||||
|
||||
# Speed up time-sensitive delays in test environment
|
||||
config :aprsme, is_call_timeout_ms: 100
|
||||
config :aprsme, is_init_delay_ms: 0
|
||||
|
||||
# Only in tests, remove the complexity from the password hashing algorithm
|
||||
config :bcrypt_elixir, :log_rounds, 1
|
||||
|
|
|
|||
|
|
@ -81,7 +81,11 @@ defmodule Aprsme.Cluster.LeaderElection do
|
|||
# Non-clustered mode: elect immediately.
|
||||
defp schedule_initial_election(false) do
|
||||
Logger.info("Clustering disabled - proceeding with immediate leader election")
|
||||
Process.send_after(self(), :attempt_election, 100)
|
||||
delay = Application.get_env(:aprsme, :election_initial_delay_ms, 100)
|
||||
|
||||
if delay == 0,
|
||||
do: send(self(), :attempt_election),
|
||||
else: Process.send_after(self(), :attempt_election, delay)
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -100,7 +104,7 @@ defmodule Aprsme.Cluster.LeaderElection do
|
|||
else
|
||||
Logger.info("Cluster formed with #{length(connected_nodes)} other nodes: #{inspect(connected_nodes)}")
|
||||
Logger.info("Proceeding with leader election")
|
||||
Process.send_after(self(), :attempt_election, 100)
|
||||
schedule_election_attempt()
|
||||
{:noreply, %{state | election_forced: true}}
|
||||
end
|
||||
end
|
||||
|
|
@ -123,7 +127,7 @@ defmodule Aprsme.Cluster.LeaderElection do
|
|||
)
|
||||
end
|
||||
|
||||
Process.send_after(self(), :attempt_election, 100)
|
||||
schedule_election_attempt()
|
||||
{:noreply, %{state | election_forced: true}}
|
||||
else
|
||||
{:noreply, state}
|
||||
|
|
@ -157,7 +161,7 @@ defmodule Aprsme.Cluster.LeaderElection do
|
|||
# Re-attempt election if we're not leader
|
||||
_ =
|
||||
if not state.is_leader do
|
||||
Process.send_after(self(), :attempt_election, 100)
|
||||
schedule_election_attempt()
|
||||
end
|
||||
|
||||
# Schedule next check
|
||||
|
|
@ -198,6 +202,14 @@ defmodule Aprsme.Cluster.LeaderElection do
|
|||
# Verify that a node which thinks it's leader still holds the :global registration.
|
||||
# After :global conflict resolution (e.g. two partitions merging), the losing PID
|
||||
# is silently unregistered — this detects that and steps down.
|
||||
defp schedule_election_attempt do
|
||||
delay = Application.get_env(:aprsme, :election_initial_delay_ms, 100)
|
||||
|
||||
if delay == 0,
|
||||
do: send(self(), :attempt_election),
|
||||
else: Process.send_after(self(), :attempt_election, delay)
|
||||
end
|
||||
|
||||
defp verify_leadership(%{is_leader: true} = state) do
|
||||
case :global.whereis_name(@election_key) do
|
||||
pid when pid == self() ->
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ defmodule Aprsme.DeviceCache do
|
|||
@impl true
|
||||
def init(_) do
|
||||
# Delay initial load to allow Redis connections to establish
|
||||
Process.send_after(self(), :initial_load, 1_000)
|
||||
Process.send_after(self(), :initial_load, Application.get_env(:aprsme, :device_cache_initial_load_delay_ms, 1_000))
|
||||
|
||||
{:ok, %{initial_load_done: false}}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -155,7 +155,9 @@ defmodule Aprsme.DeviceIdentification do
|
|||
@doc false
|
||||
# Exposed for testing via URL injection.
|
||||
def fetch_devices_from_url(url \\ @url) do
|
||||
case Req.get(url) do
|
||||
req_opts = Application.get_env(:aprsme, :device_id_req_opts, [])
|
||||
|
||||
case Req.get(url, req_opts) do
|
||||
{:ok, %Req.Response{status: 200, body: body}} ->
|
||||
upsert_devices(body)
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ defmodule Aprsme.Is do
|
|||
Process.flag(:trap_exit, true)
|
||||
|
||||
# Add a small delay to prevent rapid reconnection attempts
|
||||
Process.sleep(2000)
|
||||
Process.sleep(Application.get_env(:aprsme, :is_init_delay_ms, 2_000))
|
||||
|
||||
# Get startup parameters
|
||||
server = Application.get_env(:aprsme, :aprs_is_server, ~c"dallas.aprs2.net")
|
||||
|
|
@ -132,7 +132,7 @@ defmodule Aprsme.Is do
|
|||
defp status_from(nil), do: disconnected_status(nil)
|
||||
|
||||
defp status_from(pid) when is_pid(pid) do
|
||||
GenServer.call(__MODULE__, :get_status, 5000)
|
||||
GenServer.call(__MODULE__, :get_status, Application.get_env(:aprsme, :is_call_timeout_ms, 5_000))
|
||||
catch
|
||||
# GenServer exists but isn't responding — treat as disconnected but
|
||||
# fall back to the rotate.aprs2.net default server string.
|
||||
|
|
|
|||
|
|
@ -79,12 +79,12 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
# Start a minimal LeaderElection to prevent crashes
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, _} = LeaderElection.start_link([])
|
||||
Process.sleep(150)
|
||||
LeaderElection.leader?()
|
||||
:ok
|
||||
end
|
||||
|
||||
test "subscribes to leadership changes" do
|
||||
{:ok, _pid} = ConnectionManager.start_link([])
|
||||
{:ok, pid} = ConnectionManager.start_link([])
|
||||
|
||||
# Verify subscription by publishing a test message
|
||||
Phoenix.PubSub.broadcast(
|
||||
|
|
@ -93,8 +93,8 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
{:leadership_change, :test_node, false}
|
||||
)
|
||||
|
||||
# Give time for message processing
|
||||
Process.sleep(50)
|
||||
# Sync with the GenServer so the broadcast has been processed.
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Process should still be alive after receiving message
|
||||
assert Process.whereis(ConnectionManager)
|
||||
|
|
@ -103,8 +103,8 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
test "schedules initial state check" do
|
||||
{:ok, pid} = ConnectionManager.start_link([])
|
||||
|
||||
# With delay set to 0 in test config, the check fires immediately
|
||||
Process.sleep(50)
|
||||
# Sync so the initial check (delay=0 in test config) has fired.
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Process should still be alive
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -116,8 +116,7 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
# Start LeaderElection in non-clustered mode so it becomes leader
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, _} = LeaderElection.start_link([])
|
||||
# Wait for election (100ms timer + processing)
|
||||
Process.sleep(150)
|
||||
LeaderElection.leader?()
|
||||
|
||||
# Start ConnectionManager
|
||||
{:ok, pid} = ConnectionManager.start_link([])
|
||||
|
|
@ -125,18 +124,16 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
end
|
||||
|
||||
test "handles initial state check when leader", %{pid: pid} do
|
||||
# Send initial state check
|
||||
send(pid, :check_initial_state)
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should handle without crashing
|
||||
assert Process.alive?(pid)
|
||||
end
|
||||
|
||||
test "handles initial state check when not leader", %{pid: pid} do
|
||||
# Send initial state check
|
||||
send(pid, :check_initial_state)
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should handle without crashing
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -148,18 +145,16 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
# Ensure LeaderElection is started
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, _} = LeaderElection.start_link([])
|
||||
Process.sleep(150)
|
||||
LeaderElection.leader?()
|
||||
|
||||
{:ok, pid} = ConnectionManager.start_link([])
|
||||
# With delay=0, initial check fires immediately; just wait for processing
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
{:ok, pid: pid}
|
||||
end
|
||||
|
||||
test "starts connection when becoming leader", %{pid: pid} do
|
||||
# Send leadership change - this node became leader
|
||||
send(pid, {:leadership_change, node(), true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should handle the message without crashing
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -168,11 +163,11 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
test "stops connection when losing leadership", %{pid: pid} do
|
||||
# First become leader and start connection
|
||||
send(pid, {:leadership_change, node(), true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Then lose leadership
|
||||
send(pid, {:leadership_change, node(), false})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should handle the message without crashing
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -181,9 +176,8 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
test "ignores leadership changes for other nodes", %{pid: pid} do
|
||||
other_node = :other@host
|
||||
|
||||
# Send leadership change for another node
|
||||
send(pid, {:leadership_change, other_node, true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should not affect this node
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -192,10 +186,10 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
test "does not start connection twice", %{pid: pid} do
|
||||
# Become leader twice
|
||||
send(pid, {:leadership_change, node(), true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
send(pid, {:leadership_change, node(), true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should handle duplicate leadership without issues
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -207,18 +201,16 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
# Ensure LeaderElection is started
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, _} = LeaderElection.start_link([])
|
||||
Process.sleep(150)
|
||||
LeaderElection.leader?()
|
||||
|
||||
{:ok, pid} = ConnectionManager.start_link([])
|
||||
# With delay=0, initial check fires immediately; just wait for processing
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
{:ok, pid: pid}
|
||||
end
|
||||
|
||||
test "handles IsSupervisor already started error", %{pid: pid} do
|
||||
# Try to become leader
|
||||
send(pid, {:leadership_change, node(), true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should handle gracefully even if IsSupervisor fails to start
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -233,9 +225,8 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
end
|
||||
end
|
||||
|
||||
# Send leadership change
|
||||
send(pid, {:leadership_change, node(), true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Should handle failure gracefully
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -278,26 +269,25 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
# Ensure LeaderElection is started
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, _} = LeaderElection.start_link([])
|
||||
Process.sleep(150)
|
||||
LeaderElection.leader?()
|
||||
|
||||
{:ok, pid} = ConnectionManager.start_link([])
|
||||
{:ok, pid: pid}
|
||||
end
|
||||
|
||||
test "full lifecycle - become leader, lose leadership", %{pid: pid} do
|
||||
# With delay=0, initial check fires immediately; just wait for processing
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Become leader
|
||||
send(pid, {:leadership_change, node(), true})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Verify connection started (check state indirectly)
|
||||
assert Process.alive?(pid)
|
||||
|
||||
# Lose leadership
|
||||
send(pid, {:leadership_change, node(), false})
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Verify still alive after stopping connection
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -329,7 +319,7 @@ defmodule Aprsme.Cluster.ConnectionManagerTest do
|
|||
case Process.whereis(LeaderElection) do
|
||||
nil ->
|
||||
{:ok, _} = LeaderElection.start_link([])
|
||||
Process.sleep(200)
|
||||
LeaderElection.leader?()
|
||||
|
||||
_pid ->
|
||||
:ok
|
||||
|
|
|
|||
|
|
@ -54,10 +54,7 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
# Ensure clustering is disabled
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, pid} = LeaderElection.start_link([])
|
||||
|
||||
# Give time for election to occur
|
||||
Process.sleep(200)
|
||||
|
||||
LeaderElection.leader?()
|
||||
{:ok, pid: pid}
|
||||
end
|
||||
|
||||
|
|
@ -75,7 +72,7 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
setup do
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, _pid} = LeaderElection.start_link([])
|
||||
Process.sleep(200)
|
||||
LeaderElection.leader?()
|
||||
:ok
|
||||
end
|
||||
|
||||
|
|
@ -104,7 +101,7 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
setup do
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, _pid} = LeaderElection.start_link([])
|
||||
Process.sleep(200)
|
||||
LeaderElection.leader?()
|
||||
:ok
|
||||
end
|
||||
|
||||
|
|
@ -154,9 +151,7 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
|
||||
test "handles termination gracefully when leader" do
|
||||
{:ok, pid} = LeaderElection.start_link([])
|
||||
Process.sleep(200)
|
||||
|
||||
# Verify it's the leader
|
||||
# Sync so the 0-delay election fires before we assert leader status.
|
||||
assert LeaderElection.leader?() == true
|
||||
|
||||
# Stop the process
|
||||
|
|
@ -196,7 +191,7 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
# For now, we just verify the module handles conflicts without crashing
|
||||
|
||||
{:ok, pid1} = LeaderElection.start_link([])
|
||||
Process.sleep(100)
|
||||
LeaderElection.leader?()
|
||||
|
||||
# Try to register another process with the same key
|
||||
# This should fail or trigger conflict resolution
|
||||
|
|
@ -204,7 +199,8 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
:global.register_name(@election_key, self())
|
||||
end)
|
||||
|
||||
Process.sleep(100)
|
||||
# Brief pause for the spawned process to attempt registration.
|
||||
Process.sleep(10)
|
||||
|
||||
# Original process should still be alive
|
||||
assert Process.alive?(pid1)
|
||||
|
|
@ -260,7 +256,6 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
setup do
|
||||
Application.put_env(:aprsme, :cluster_enabled, false)
|
||||
{:ok, pid} = LeaderElection.start_link([])
|
||||
Process.sleep(200)
|
||||
assert LeaderElection.leader?() == true
|
||||
{:ok, pid: pid}
|
||||
end
|
||||
|
|
@ -309,14 +304,13 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
# Lose the registration
|
||||
:global.unregister_name(@election_key)
|
||||
|
||||
# Force check — should step down
|
||||
# Force check — should step down and immediately queue :attempt_election.
|
||||
send(pid, :check_leadership)
|
||||
state = :sys.get_state(pid)
|
||||
assert state.is_leader == false
|
||||
|
||||
# check_leadership also schedules :attempt_election for non-leaders.
|
||||
# Wait for re-election.
|
||||
Process.sleep(100)
|
||||
# With election_initial_delay_ms: 0, :attempt_election is already in the
|
||||
# mailbox. leader?/0 (a GenServer.call) processes it first, then answers.
|
||||
assert LeaderElection.leader?() == true
|
||||
end
|
||||
end
|
||||
|
|
@ -330,13 +324,13 @@ defmodule Aprsme.Cluster.LeaderElectionTest do
|
|||
|
||||
test "handles unknown messages without crashing", %{pid: pid} do
|
||||
send(pid, :unknown_message)
|
||||
Process.sleep(100)
|
||||
:sys.get_state(pid)
|
||||
assert Process.alive?(pid)
|
||||
end
|
||||
|
||||
test "handles check_leadership message", %{pid: pid} do
|
||||
send(pid, :check_leadership)
|
||||
Process.sleep(100)
|
||||
:sys.get_state(pid)
|
||||
assert Process.alive?(pid)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ defmodule Aprsme.Cluster.PacketDistributorTest do
|
|||
|
||||
# Start LeaderElection in non-clustered mode
|
||||
{:ok, _} = LeaderElection.start_link([])
|
||||
# Wait for election to complete (100ms timer + processing)
|
||||
Process.sleep(300)
|
||||
# Sync with the GenServer so election (0ms in test config) has run.
|
||||
LeaderElection.leader?()
|
||||
|
||||
on_exit(fn ->
|
||||
try do
|
||||
|
|
@ -47,19 +47,17 @@ defmodule Aprsme.Cluster.PacketDistributorTest do
|
|||
|
||||
PacketDistributor.distribute_packet(@test_packet)
|
||||
|
||||
refute_receive {:distributed_packet, _}, 100
|
||||
refute_receive {:distributed_packet, _}, 10
|
||||
end
|
||||
|
||||
test "distributes packet when cluster is enabled and node is leader" do
|
||||
Application.put_env(:aprsme, :cluster_enabled, true)
|
||||
# LeaderElection started in non-clustered mode becomes leader quickly
|
||||
Process.sleep(100)
|
||||
|
||||
PacketDistributor.subscribe()
|
||||
|
||||
PacketDistributor.distribute_packet(@test_packet)
|
||||
|
||||
assert_receive {:distributed_packet, packet}, 200
|
||||
assert_receive {:distributed_packet, packet}, 50
|
||||
assert packet.raw == "TEST>APRS:test packet"
|
||||
assert packet.sender == "TEST"
|
||||
end
|
||||
|
|
@ -75,7 +73,7 @@ defmodule Aprsme.Cluster.PacketDistributorTest do
|
|||
{:distributed_packet, @test_packet}
|
||||
)
|
||||
|
||||
assert_receive {:distributed_packet, _}, 500
|
||||
assert_receive {:distributed_packet, _}, 50
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -94,7 +92,7 @@ defmodule Aprsme.Cluster.PacketDistributorTest do
|
|||
assert {:ok, %{}} = PacketDistributor.init([])
|
||||
# Callback subscribes the caller to cluster:packets.
|
||||
Phoenix.PubSub.broadcast(Aprsme.PubSub, "cluster:packets", :ping)
|
||||
assert_receive :ping, 100
|
||||
assert_receive :ping, 50
|
||||
end
|
||||
|
||||
test "handle_info forwards distributed packets" do
|
||||
|
|
@ -112,7 +110,7 @@ defmodule Aprsme.Cluster.PacketDistributorTest do
|
|||
# After terminate, this process should no longer receive cluster:packets
|
||||
# broadcasts.
|
||||
Phoenix.PubSub.broadcast(Aprsme.PubSub, "cluster:packets", :should_not_arrive)
|
||||
refute_receive :should_not_arrive, 100
|
||||
refute_receive :should_not_arrive, 10
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ defmodule Aprsme.Cluster.PacketReceiverTest do
|
|||
GenServer.stop(LeaderElection)
|
||||
end
|
||||
|
||||
# Start LeaderElection and wait for election
|
||||
# Start LeaderElection and sync so election (0ms in test config) has run.
|
||||
{:ok, leader_pid} = LeaderElection.start_link([])
|
||||
Process.sleep(300)
|
||||
LeaderElection.leader?()
|
||||
|
||||
on_exit(fn ->
|
||||
try do
|
||||
|
|
@ -64,9 +64,7 @@ defmodule Aprsme.Cluster.PacketReceiverTest do
|
|||
|
||||
packet = %{raw: "TEST>APRS:test", sender: "TEST"}
|
||||
send(pid, {:distributed_packet, packet})
|
||||
|
||||
# Give it time to process
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Process should still be alive (no crash)
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -84,9 +82,7 @@ defmodule Aprsme.Cluster.PacketReceiverTest do
|
|||
|
||||
packet = %{raw: "TEST>APRS:test", sender: "TEST"}
|
||||
send(pid, {:distributed_packet, packet})
|
||||
|
||||
# Give it time to process
|
||||
Process.sleep(50)
|
||||
:sys.get_state(pid)
|
||||
|
||||
# Process should still be alive (no crash)
|
||||
assert Process.alive?(pid)
|
||||
|
|
@ -99,8 +95,7 @@ defmodule Aprsme.Cluster.PacketReceiverTest do
|
|||
|
||||
send(pid, :some_unknown_message)
|
||||
send(pid, {:unexpected, "data"})
|
||||
|
||||
Process.sleep(100)
|
||||
:sys.get_state(pid)
|
||||
|
||||
assert Process.alive?(pid)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ defmodule Aprsme.DeviceCacheTest do
|
|||
test "init/1 schedules an initial load and returns an empty state" do
|
||||
assert {:ok, state} = DeviceCache.init([])
|
||||
assert state == %{initial_load_done: false}
|
||||
assert_receive :initial_load, 1_500
|
||||
assert_receive :initial_load, 100
|
||||
end
|
||||
|
||||
test "handle_call(:refresh_cache, _, state) returns :ok" do
|
||||
|
|
|
|||
|
|
@ -163,9 +163,8 @@ defmodule Aprsme.DeviceIdentificationTest do
|
|||
|
||||
test "attempts to refresh when there are no devices at all" do
|
||||
Repo.delete_all(Devices)
|
||||
# fetch_and_upsert_devices goes through the circuit breaker. Without a
|
||||
# stub it either errors out (network failure) or returns :ok. Either
|
||||
# outcome exercises the refresh_if_stale(nil, _) branch.
|
||||
# fetch_and_upsert_devices goes through the circuit breaker. The short
|
||||
# Req timeout configured in test.exs makes the HTTP attempt fail fast.
|
||||
result = DeviceIdentification.maybe_refresh_devices()
|
||||
assert result == :ok or match?({:error, _}, result)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1285,7 +1285,7 @@ defmodule Aprsme.IsTest do
|
|||
receive do
|
||||
:stop -> :ok
|
||||
after
|
||||
5_000 -> :ok
|
||||
200 -> :ok
|
||||
end
|
||||
|
||||
send(parent, :done)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue