Add Monitoring.Supervisor tests

- Test start_monitor/1 and stop_monitor/1
- Test start_snmp_poller/1 and stop_snmp_poller/1
- Test start_all_monitors/0 and start_all_snmp_pollers/0
- Verify process lifecycle management
- Coverage: 67.05% -> 67.09%
This commit is contained in:
Graham McIntire 2026-01-13 08:21:50 -06:00
parent 3068f944fb
commit df315a897a
No known key found for this signature in database

View file

@ -4,6 +4,7 @@ defmodule Towerops.Monitoring.SupervisorTest do
import Towerops.AccountsFixtures
alias Towerops.Monitoring.Supervisor, as: MonitoringSupervisor
alias Towerops.Snmp.PollerRegistry
setup do
user = user_fixture()
@ -17,67 +18,30 @@ defmodule Towerops.Monitoring.SupervisorTest do
{:ok, equipment} =
Towerops.Equipment.create_equipment(%{
name: "Test Router",
name: "Router 1",
ip_address: "192.168.1.1",
site_id: site.id,
monitoring_enabled: true
})
{:ok, snmp_equipment} =
Towerops.Equipment.create_equipment(%{
name: "SNMP Router",
ip_address: "192.168.1.2",
site_id: site.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161
})
%{equipment: equipment, snmp_equipment: snmp_equipment}
%{equipment: equipment, site: site}
end
describe "start_monitor/1" do
test "starts a monitor for equipment", %{equipment: equipment} do
# Start the monitor
result = MonitoringSupervisor.start_monitor(equipment.id)
assert {:ok, pid} = MonitoringSupervisor.start_monitor(equipment.id)
assert is_pid(pid)
assert Process.alive?(pid)
# Should return {:ok, pid} or {:error, {:already_started, pid}}
case result do
{:ok, pid} ->
assert is_pid(pid)
assert Process.alive?(pid)
# Cleanup
MonitoringSupervisor.stop_monitor(equipment.id)
{:error, {:already_started, pid}} ->
assert is_pid(pid)
# Already started is acceptable
MonitoringSupervisor.stop_monitor(equipment.id)
other ->
flunk("Unexpected result: #{inspect(other)}")
end
# Cleanup
MonitoringSupervisor.stop_monitor(equipment.id)
end
test "returns error when starting duplicate monitor", %{equipment: equipment} do
# Start the first monitor
test "returns error when monitor already running", %{equipment: equipment} do
{:ok, _pid} = MonitoringSupervisor.start_monitor(equipment.id)
# Try to start another for the same equipment
result = MonitoringSupervisor.start_monitor(equipment.id)
case result do
{:error, {:already_started, pid}} ->
assert is_pid(pid)
{:error, reason} ->
# Other errors are acceptable (e.g., already registered)
assert reason
other ->
flunk("Expected error, got: #{inspect(other)}")
end
assert {:error, {:already_started, _pid}} =
MonitoringSupervisor.start_monitor(equipment.id)
# Cleanup
MonitoringSupervisor.stop_monitor(equipment.id)
@ -86,69 +50,49 @@ defmodule Towerops.Monitoring.SupervisorTest do
describe "stop_monitor/1" do
test "stops a running monitor", %{equipment: equipment} do
# Start the monitor first
{:ok, pid} = MonitoringSupervisor.start_monitor(equipment.id)
assert Process.alive?(pid)
# Stop it
result = MonitoringSupervisor.stop_monitor(equipment.id)
assert result == :ok
assert :ok = MonitoringSupervisor.stop_monitor(equipment.id)
# Give it a moment to shut down
Process.sleep(50)
# Verify it's stopped
# Give it a moment to terminate
Process.sleep(10)
refute Process.alive?(pid)
end
test "returns :ok when stopping non-existent monitor" do
fake_id = Ecto.UUID.generate()
result = MonitoringSupervisor.stop_monitor(fake_id)
assert result == :ok
test "returns :ok when monitor not running", %{equipment: equipment} do
assert :ok = MonitoringSupervisor.stop_monitor(equipment.id)
end
end
describe "start_snmp_poller/1" do
test "starts an SNMP poller for equipment", %{snmp_equipment: equipment} do
# Start the SNMP poller
result = MonitoringSupervisor.start_snmp_poller(equipment.id)
test "starts an SNMP poller for equipment", %{equipment: equipment} do
# Enable SNMP for the equipment
{:ok, equipment} =
Towerops.Equipment.update_equipment(equipment, %{
snmp_enabled: true,
snmp_community: "public"
})
# Should return {:ok, pid} or {:error, {:already_started, pid}}
case result do
{:ok, pid} ->
assert is_pid(pid)
assert Process.alive?(pid)
# Cleanup
MonitoringSupervisor.stop_snmp_poller(equipment.id)
assert {:ok, pid} = MonitoringSupervisor.start_snmp_poller(equipment.id)
assert is_pid(pid)
assert Process.alive?(pid)
{:error, {:already_started, pid}} ->
assert is_pid(pid)
# Already started is acceptable
MonitoringSupervisor.stop_snmp_poller(equipment.id)
other ->
flunk("Unexpected result: #{inspect(other)}")
end
# Cleanup
MonitoringSupervisor.stop_snmp_poller(equipment.id)
end
test "returns error when starting duplicate poller", %{snmp_equipment: equipment} do
# Start the first poller
test "returns error when poller already running", %{equipment: equipment} do
{:ok, equipment} =
Towerops.Equipment.update_equipment(equipment, %{
snmp_enabled: true,
snmp_community: "public"
})
{:ok, _pid} = MonitoringSupervisor.start_snmp_poller(equipment.id)
# Try to start another for the same equipment
result = MonitoringSupervisor.start_snmp_poller(equipment.id)
case result do
{:error, {:already_started, pid}} ->
assert is_pid(pid)
{:error, reason} ->
# Other errors are acceptable
assert reason
other ->
flunk("Expected error, got: #{inspect(other)}")
end
assert {:error, {:already_started, _pid}} =
MonitoringSupervisor.start_snmp_poller(equipment.id)
# Cleanup
MonitoringSupervisor.stop_snmp_poller(equipment.id)
@ -156,84 +100,85 @@ defmodule Towerops.Monitoring.SupervisorTest do
end
describe "stop_snmp_poller/1" do
test "stops a running SNMP poller", %{snmp_equipment: equipment} do
# Start the poller first
test "stops a running SNMP poller", %{equipment: equipment} do
{:ok, equipment} =
Towerops.Equipment.update_equipment(equipment, %{
snmp_enabled: true,
snmp_community: "public"
})
{:ok, pid} = MonitoringSupervisor.start_snmp_poller(equipment.id)
assert Process.alive?(pid)
# Stop it
result = MonitoringSupervisor.stop_snmp_poller(equipment.id)
assert result == :ok
assert :ok = MonitoringSupervisor.stop_snmp_poller(equipment.id)
# Give it a moment to shut down
Process.sleep(50)
# Verify it's stopped
# Give it a moment to terminate
Process.sleep(10)
refute Process.alive?(pid)
end
test "returns :ok when stopping non-existent poller" do
fake_id = Ecto.UUID.generate()
result = MonitoringSupervisor.stop_snmp_poller(fake_id)
assert result == :ok
test "returns :ok when poller not running", %{equipment: equipment} do
assert :ok = MonitoringSupervisor.stop_snmp_poller(equipment.id)
end
end
describe "start_all_monitors/0" do
test "starts monitors for all monitored equipment", %{equipment: equipment} do
# Make sure equipment has monitoring enabled
{:ok, _} = Towerops.Equipment.update_equipment(equipment, %{monitoring_enabled: true})
test "starts monitors for all monitored equipment", %{equipment: equipment, site: site} do
# Create another monitored equipment
{:ok, equipment2} =
Towerops.Equipment.create_equipment(%{
name: "Router 2",
ip_address: "192.168.1.2",
site_id: site.id,
monitoring_enabled: true
})
# Start all monitors
result = MonitoringSupervisor.start_all_monitors()
assert result == :ok
MonitoringSupervisor.start_all_monitors()
# Give monitors time to start
Process.sleep(100)
# Check that both are running
assert [{pid1, _}] = Registry.lookup(Towerops.Monitoring.Registry, equipment.id)
assert [{pid2, _}] = Registry.lookup(Towerops.Monitoring.Registry, equipment2.id)
assert Process.alive?(pid1)
assert Process.alive?(pid2)
# Verify monitor was started
case Registry.lookup(Towerops.Monitoring.Registry, equipment.id) do
[{pid, _}] ->
assert is_pid(pid)
assert Process.alive?(pid)
# Cleanup
MonitoringSupervisor.stop_monitor(equipment.id)
[] ->
# It's ok if it didn't start (maybe monitoring is disabled in test)
assert true
end
# Cleanup
MonitoringSupervisor.stop_monitor(equipment.id)
MonitoringSupervisor.stop_monitor(equipment2.id)
end
end
describe "start_all_snmp_pollers/0" do
test "starts pollers for all SNMP-enabled equipment", %{snmp_equipment: equipment} do
# Make sure equipment has SNMP enabled
test "starts pollers for all SNMP-enabled equipment", %{equipment: equipment, site: site} do
# Enable SNMP on equipment
{:ok, _} =
Towerops.Equipment.update_equipment(equipment, %{
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
})
# Create another SNMP-enabled equipment
{:ok, equipment2} =
Towerops.Equipment.create_equipment(%{
name: "Router 2",
ip_address: "192.168.1.2",
site_id: site.id,
snmp_enabled: true,
snmp_community: "public"
})
# Start all pollers
result = MonitoringSupervisor.start_all_snmp_pollers()
assert result == :ok
MonitoringSupervisor.start_all_snmp_pollers()
# Give pollers time to start
Process.sleep(100)
# Check that both are running
assert [{pid1, _}] = Registry.lookup(PollerRegistry, equipment.id)
assert [{pid2, _}] = Registry.lookup(PollerRegistry, equipment2.id)
assert Process.alive?(pid1)
assert Process.alive?(pid2)
# Verify poller was started (may or may not be running depending on equipment state)
case Registry.lookup(Towerops.Snmp.PollerRegistry, equipment.id) do
[{pid, _}] ->
assert is_pid(pid)
# Cleanup
MonitoringSupervisor.stop_snmp_poller(equipment.id)
[] ->
# It's ok if it didn't start
assert true
end
# Cleanup
MonitoringSupervisor.stop_snmp_poller(equipment.id)
MonitoringSupervisor.stop_snmp_poller(equipment2.id)
end
end
end