towerops/test/towerops/monitoring/monitoring_check_test.exs
Graham McIntire a61abd836c
fix: cloud poller automatic rebalancing
- create MonitoringCheck schema for the monitoring_checks table, fixing
  silent data loss where ping results were dropped by the wrong schema
- update agent channel and device monitor worker to use new schema
- fix Stats queries to use MonitoringCheck instead of Check schema
- add list_online_cloud_pollers and list_cloud_polled_devices queries
- add CloudLatencyProbeWorker to dispatch cross-agent latency probes
  every 8 hours via PubSub to all online cloud pollers
- scope AgentLatencyEvaluator to cloud pollers only with cloud_only
  filter, lower min_checks (5), wider time window (48h), and
  device-level assignments to avoid changing site/org defaults
- update cron schedule: probes at 0/8/16h, evaluation at 0:30/8:30/16:30
- refactor monitoring.ex and http_executor.ex to fix credo complexity
2026-02-12 15:32:33 -06:00

114 lines
3.3 KiB
Elixir

defmodule Towerops.Monitoring.MonitoringCheckTest do
use Towerops.DataCase
import Towerops.AccountsFixtures
import Towerops.OrganizationsFixtures
alias Towerops.Agents
alias Towerops.Monitoring
alias Towerops.Monitoring.MonitoringCheck
alias Towerops.Sites
describe "MonitoringCheck schema" do
test "valid changeset with required fields" do
{device, _agent} = create_device_with_agent()
changeset =
MonitoringCheck.changeset(%MonitoringCheck{}, %{
device_id: device.id,
status: "success",
checked_at: DateTime.utc_now()
})
assert changeset.valid?
end
test "invalid changeset missing required fields" do
changeset = MonitoringCheck.changeset(%MonitoringCheck{}, %{})
refute changeset.valid?
assert "can't be blank" in errors_on(changeset).device_id
assert "can't be blank" in errors_on(changeset).status
assert "can't be blank" in errors_on(changeset).checked_at
end
test "valid changeset with all fields" do
{device, agent} = create_device_with_agent()
changeset =
MonitoringCheck.changeset(%MonitoringCheck{}, %{
device_id: device.id,
agent_token_id: agent.id,
status: "success",
response_time_ms: 42.5,
checked_at: DateTime.utc_now()
})
assert changeset.valid?
end
end
describe "Monitoring.create_monitoring_check/1" do
test "inserts a monitoring check record" do
{device, agent} = create_device_with_agent()
now = DateTime.truncate(DateTime.utc_now(), :second)
assert {:ok, check} =
Monitoring.create_monitoring_check(%{
device_id: device.id,
agent_token_id: agent.id,
status: "success",
response_time_ms: 12.5,
checked_at: now
})
assert check.device_id == device.id
assert check.agent_token_id == agent.id
assert check.status == "success"
assert check.response_time_ms == 12.5
assert check.checked_at == now
end
test "inserts without agent_token_id" do
{device, _agent} = create_device_with_agent()
now = DateTime.truncate(DateTime.utc_now(), :second)
assert {:ok, check} =
Monitoring.create_monitoring_check(%{
device_id: device.id,
status: "failure",
checked_at: now
})
assert check.device_id == device.id
assert is_nil(check.agent_token_id)
assert check.status == "failure"
assert is_nil(check.response_time_ms)
end
test "rejects invalid attrs" do
assert {:error, changeset} = Monitoring.create_monitoring_check(%{})
refute changeset.valid?
end
end
defp create_device_with_agent do
user = user_fixture()
org = organization_fixture(user.id)
{:ok, agent, _token} = Agents.create_agent_token(org.id, "Test Agent")
{:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: org.id})
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Test Router",
ip_address: "192.168.1.1",
site_id: site.id,
organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
})
{device, agent}
end
end