- 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
213 lines
6.3 KiB
Elixir
213 lines
6.3 KiB
Elixir
defmodule Towerops.Agents.CloudPollerTest do
|
|
use Towerops.DataCase
|
|
|
|
import Towerops.AccountsFixtures
|
|
import Towerops.OrganizationsFixtures
|
|
|
|
alias Towerops.Agents
|
|
alias Towerops.Repo
|
|
alias Towerops.Sites
|
|
|
|
describe "list_online_cloud_pollers/0" do
|
|
test "returns cloud pollers seen within 5 minutes" do
|
|
{:ok, cloud_poller, _token} = Agents.create_cloud_poller("Cloud 1")
|
|
|
|
cloud_poller
|
|
|> Ecto.Changeset.change(%{last_seen_at: DateTime.truncate(DateTime.utc_now(), :second)})
|
|
|> Repo.update!()
|
|
|
|
pollers = Agents.list_online_cloud_pollers()
|
|
|
|
assert length(pollers) == 1
|
|
assert hd(pollers).id == cloud_poller.id
|
|
end
|
|
|
|
test "excludes cloud pollers not seen recently" do
|
|
{:ok, cloud_poller, _token} = Agents.create_cloud_poller("Stale Cloud")
|
|
|
|
ten_min_ago = DateTime.utc_now() |> DateTime.add(-10, :minute) |> DateTime.truncate(:second)
|
|
|
|
cloud_poller
|
|
|> Ecto.Changeset.change(%{last_seen_at: ten_min_ago})
|
|
|> Repo.update!()
|
|
|
|
assert Agents.list_online_cloud_pollers() == []
|
|
end
|
|
|
|
test "excludes disabled cloud pollers" do
|
|
{:ok, cloud_poller, _token} = Agents.create_cloud_poller("Disabled Cloud")
|
|
|
|
cloud_poller
|
|
|> Ecto.Changeset.change(%{
|
|
last_seen_at: DateTime.truncate(DateTime.utc_now(), :second),
|
|
enabled: false
|
|
})
|
|
|> Repo.update!()
|
|
|
|
assert Agents.list_online_cloud_pollers() == []
|
|
end
|
|
|
|
test "excludes regular (non-cloud) agents" do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
{:ok, agent, _token} = Agents.create_agent_token(org.id, "Regular Agent")
|
|
|
|
agent
|
|
|> Ecto.Changeset.change(%{last_seen_at: DateTime.truncate(DateTime.utc_now(), :second)})
|
|
|> Repo.update!()
|
|
|
|
assert Agents.list_online_cloud_pollers() == []
|
|
end
|
|
end
|
|
|
|
describe "list_cloud_polled_devices/0" do
|
|
test "returns devices with no agent assignment" do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
{:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: org.id})
|
|
|
|
{:ok, device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "Unassigned Router",
|
|
ip_address: "192.168.1.1",
|
|
site_id: site.id,
|
|
organization_id: org.id,
|
|
snmp_enabled: true,
|
|
snmp_community: "public",
|
|
snmp_version: "2c",
|
|
monitoring_enabled: true
|
|
})
|
|
|
|
devices = Agents.list_cloud_polled_devices()
|
|
|
|
assert length(devices) == 1
|
|
assert hd(devices).id == device.id
|
|
end
|
|
|
|
test "returns devices assigned to a cloud poller" do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
{:ok, cloud_poller, _token} = Agents.create_cloud_poller("Cloud 1")
|
|
{:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: org.id})
|
|
|
|
{:ok, device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "Cloud Polled Router",
|
|
ip_address: "192.168.1.1",
|
|
site_id: site.id,
|
|
organization_id: org.id,
|
|
snmp_enabled: true,
|
|
snmp_community: "public",
|
|
snmp_version: "2c",
|
|
monitoring_enabled: true
|
|
})
|
|
|
|
{:ok, _} = Agents.assign_device_to_agent(cloud_poller.id, device.id)
|
|
|
|
devices = Agents.list_cloud_polled_devices()
|
|
|
|
assert length(devices) == 1
|
|
assert hd(devices).id == device.id
|
|
end
|
|
|
|
test "excludes devices assigned to a local agent" do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
{:ok, local_agent, _token} = Agents.create_agent_token(org.id, "Local Agent")
|
|
{:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: org.id})
|
|
|
|
{:ok, device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "Local Router",
|
|
ip_address: "192.168.1.1",
|
|
site_id: site.id,
|
|
organization_id: org.id,
|
|
snmp_enabled: true,
|
|
snmp_community: "public",
|
|
snmp_version: "2c",
|
|
monitoring_enabled: true
|
|
})
|
|
|
|
{:ok, _} = Agents.assign_device_to_agent(local_agent.id, device.id)
|
|
|
|
assert Agents.list_cloud_polled_devices() == []
|
|
end
|
|
|
|
test "excludes devices with monitoring disabled" do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
{:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: org.id})
|
|
|
|
{:ok, _device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "No Monitoring Router",
|
|
ip_address: "192.168.1.1",
|
|
site_id: site.id,
|
|
organization_id: org.id,
|
|
snmp_enabled: true,
|
|
snmp_community: "public",
|
|
snmp_version: "2c",
|
|
monitoring_enabled: false
|
|
})
|
|
|
|
assert Agents.list_cloud_polled_devices() == []
|
|
end
|
|
|
|
test "includes devices whose site default is a cloud poller" do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
{:ok, cloud_poller, _token} = Agents.create_cloud_poller("Cloud 1")
|
|
|
|
{:ok, site} =
|
|
Sites.create_site(%{
|
|
name: "Cloud Site",
|
|
organization_id: org.id,
|
|
agent_token_id: cloud_poller.id
|
|
})
|
|
|
|
{:ok, device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "Site Cloud Router",
|
|
ip_address: "192.168.1.1",
|
|
site_id: site.id,
|
|
organization_id: org.id,
|
|
snmp_enabled: true,
|
|
snmp_community: "public",
|
|
snmp_version: "2c",
|
|
monitoring_enabled: true
|
|
})
|
|
|
|
devices = Agents.list_cloud_polled_devices()
|
|
|
|
assert length(devices) == 1
|
|
assert hd(devices).id == device.id
|
|
end
|
|
|
|
test "excludes devices whose site default is a local agent" do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
{:ok, local_agent, _token} = Agents.create_agent_token(org.id, "Local Agent")
|
|
|
|
{:ok, site} =
|
|
Sites.create_site(%{
|
|
name: "Local Site",
|
|
organization_id: org.id,
|
|
agent_token_id: local_agent.id
|
|
})
|
|
|
|
{:ok, _device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "Site Local Router",
|
|
ip_address: "192.168.1.1",
|
|
site_id: site.id,
|
|
organization_id: org.id,
|
|
snmp_enabled: true,
|
|
snmp_community: "public",
|
|
snmp_version: "2c",
|
|
monitoring_enabled: true
|
|
})
|
|
|
|
assert Agents.list_cloud_polled_devices() == []
|
|
end
|
|
end
|
|
end
|