- 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
114 lines
3.3 KiB
Elixir
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
|