aprs.me/test/aprsme/broadcast_task_supervisor_test.exs
Graham McIntire a8e7b17ee1
Optimize test suite performance - 32.5% faster execution
Reduced test execution time from 21.2s to 14.3s through multiple optimizations:

1. Reduced test data size:
   - Memory efficiency test: 5000→1000 packets, smaller payloads (saved ~3.2s)
   - More focused test scenarios without sacrificing coverage

2. Reduced sleep times across test suite:
   - GPS movement tests: 100-500ms → 10-100ms
   - Broadcast supervisor tests: 50ms → 10ms
   - Packet consumer tests: 100-500ms → 20-50ms
   - Saved ~1-2 seconds total

3. Enabled parallel test execution:
   - Set max_cases to System.schedulers_online() * 2
   - Made DeviceIdentificationTest async
   - Made PasscodeTest and ConvertTest async
   - Better CPU utilization

4. Reduced assertion timeouts:
   - Changed from 1000ms to 200-500ms where appropriate
   - Faster failure detection

These optimizations maintain test reliability while significantly reducing
execution time. The occasional timing-sensitive LiveView test failures are
addressed with slightly more generous timeouts where needed.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 09:23:07 -05:00

165 lines
4.8 KiB
Elixir

defmodule Aprsme.BroadcastTaskSupervisorTest do
use ExUnit.Case, async: true
alias Aprsme.BroadcastTaskSupervisor
setup do
# Ensure the supervisor is started (it should be from application)
# Create a test topic for PubSub
test_topic = "test_topic_#{System.unique_integer()}"
Phoenix.PubSub.subscribe(Aprsme.PubSub, test_topic)
{:ok, test_topic: test_topic}
end
describe "broadcast_async/3" do
test "broadcasts messages to multiple topics asynchronously", %{test_topic: test_topic} do
# Create additional test topics
topic2 = "test_topic_2_#{System.unique_integer()}"
topic3 = "test_topic_3_#{System.unique_integer()}"
Phoenix.PubSub.subscribe(Aprsme.PubSub, topic2)
Phoenix.PubSub.subscribe(Aprsme.PubSub, topic3)
topics = [test_topic, topic2, topic3]
message = {:test_message, "Hello from broadcast"}
# Broadcast to all topics
{:ok, task} = BroadcastTaskSupervisor.broadcast_async(topics, message)
# Wait for the task to complete
Task.await(task)
# Should receive the message on all topics
assert_receive {:test_message, "Hello from broadcast"}
assert_receive {:test_message, "Hello from broadcast"}
assert_receive {:test_message, "Hello from broadcast"}
end
test "handles large topic lists efficiently", %{test_topic: test_topic} do
# Create 100 topics
topics =
for i <- 1..100 do
topic = "bulk_test_#{i}_#{System.unique_integer()}"
Phoenix.PubSub.subscribe(Aprsme.PubSub, topic)
topic
end
# Add our test topic
topics = [test_topic | topics]
message = {:bulk_test, "Bulk broadcast"}
# Measure time
start_time = System.monotonic_time(:millisecond)
{:ok, task} = BroadcastTaskSupervisor.broadcast_async(topics, message)
Task.await(task, 5000)
end_time = System.monotonic_time(:millisecond)
# Should complete quickly (under 100ms for 101 topics)
assert end_time - start_time < 100
# Verify we received the message
assert_receive {:bulk_test, "Bulk broadcast"}
end
end
describe "broadcast_one_async/3" do
test "broadcasts a single message asynchronously", %{test_topic: test_topic} do
message = {:single_test, "Single broadcast"}
{:ok, _pid} = BroadcastTaskSupervisor.broadcast_one_async(test_topic, message)
# Give it a moment to process
Process.sleep(10)
assert_receive {:single_test, "Single broadcast"}
end
end
describe "async_execute/1" do
test "executes arbitrary functions asynchronously" do
test_pid = self()
BroadcastTaskSupervisor.async_execute(fn ->
send(test_pid, :function_executed)
end)
assert_receive :function_executed, 1000
end
test "handles errors in async functions gracefully" do
# This should not crash the supervisor
{:ok, _pid} =
BroadcastTaskSupervisor.async_execute(fn ->
raise "Test error"
end)
# Give it time to fail - reduced from 50ms to 10ms
Process.sleep(10)
# Supervisor should still be running
stats = BroadcastTaskSupervisor.get_stats()
assert is_map(stats)
end
end
describe "get_stats/0" do
test "returns statistics about the broadcast pool" do
stats = BroadcastTaskSupervisor.get_stats()
assert is_map(stats)
assert Map.has_key?(stats, :active_tasks)
assert Map.has_key?(stats, :pool_size)
assert Map.has_key?(stats, :scheduler_usage)
assert is_integer(stats.active_tasks)
assert stats.active_tasks >= 0
assert is_integer(stats.pool_size)
assert stats.pool_size > 0
assert is_float(stats.scheduler_usage)
assert stats.scheduler_usage >= 0.0
end
end
describe "performance under load" do
test "handles concurrent broadcasts efficiently" do
# Create test topics
topics =
for i <- 1..10 do
"perf_test_#{i}"
end
# Subscribe to only the first topic
Phoenix.PubSub.subscribe(Aprsme.PubSub, List.first(topics))
# Launch 100 concurrent broadcasts
tasks =
for i <- 1..100 do
message = {:perf_test, i}
{:ok, task} = BroadcastTaskSupervisor.broadcast_async(topics, message)
task
end
# Wait for all tasks to complete
Enum.each(tasks, &Task.await(&1, 5000))
# Each topic should receive 100 messages
message_count = receive_all_messages()
# We subscribed to the first topic, so we should get 100 messages
assert message_count == 100
end
end
# Helper function to receive all messages
defp receive_all_messages(count \\ 0) do
receive do
{:perf_test, _} -> receive_all_messages(count + 1)
after
100 -> count
end
end
end