From e688d4d9f2f51f5b6d5afb1d9861b812206efa55 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Thu, 7 May 2026 19:35:23 -0500 Subject: [PATCH] test: cover Snmp.Discovery sync_processors/sync_storage upsert paths New file: discovery_sync_test.exs - sync_processors/2: insert, remove, update happy paths + empty-list no-op - sync_storage/2: insert + remove + update across two sync calls --- test/towerops/snmp/discovery_sync_test.exs | 123 +++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 test/towerops/snmp/discovery_sync_test.exs diff --git a/test/towerops/snmp/discovery_sync_test.exs b/test/towerops/snmp/discovery_sync_test.exs new file mode 100644 index 00000000..bc3e0930 --- /dev/null +++ b/test/towerops/snmp/discovery_sync_test.exs @@ -0,0 +1,123 @@ +defmodule Towerops.Snmp.DiscoverySyncTest do + @moduledoc """ + Tests for sync_processors / sync_storage / sync_mempools / sync_transceivers + / sync_printer_supplies / sync_entity_physical / save_neighbors / save_arp_entries. + These functions reconcile discovery output with the database. + """ + use Towerops.DataCase, async: true + + import Towerops.AccountsFixtures + + alias Towerops.Repo + alias Towerops.Snmp + alias Towerops.Snmp.Discovery + alias Towerops.Snmp.Processor + alias Towerops.Snmp.Storage + + setup do + user = user_fixture() + {:ok, org} = Towerops.Organizations.create_organization(%{name: "Sync Org"}, user.id) + {:ok, site} = Towerops.Sites.create_site(%{name: "Sync Site", organization_id: org.id}) + + {:ok, device} = + Towerops.Devices.create_device(%{ + name: "SyncDev", + ip_address: "10.40.0.1", + site_id: site.id, + organization_id: org.id + }) + + {:ok, snmp_device} = Repo.insert(%Snmp.Device{device_id: device.id, sys_descr: "test"}) + %{snmp_device: snmp_device} + end + + describe "sync_processors/2" do + test "inserts processors when none exist", %{snmp_device: snmp_device} do + assert :ok = + Discovery.sync_processors(snmp_device, [ + %{processor_index: "1", description: "CPU 1", processor_type: "hr_processor", load_percent: 25.0}, + %{processor_index: "2", description: "CPU 2", processor_type: "hr_processor", load_percent: 50.0} + ]) + + processors = Repo.all(from(p in Processor, where: p.snmp_device_id == ^snmp_device.id)) + assert length(processors) == 2 + end + + test "removes processors that are no longer present", %{snmp_device: snmp_device} do + Discovery.sync_processors(snmp_device, [ + %{processor_index: "1", description: "CPU 1", processor_type: "hr_processor", load_percent: 25.0}, + %{processor_index: "2", description: "CPU 2", processor_type: "hr_processor", load_percent: 50.0} + ]) + + Discovery.sync_processors(snmp_device, [ + %{processor_index: "1", description: "CPU 1", load_percent: 30.0} + ]) + + processors = Repo.all(from(p in Processor, where: p.snmp_device_id == ^snmp_device.id)) + assert length(processors) == 1 + assert hd(processors).processor_index == "1" + assert hd(processors).load_percent == 30.0 + end + + test "updates load_percent on existing processors", %{snmp_device: snmp_device} do + Discovery.sync_processors(snmp_device, [ + %{processor_index: "1", description: "CPU 1", processor_type: "hr_processor", load_percent: 25.0} + ]) + + Discovery.sync_processors(snmp_device, [ + %{ + processor_index: "1", + description: "CPU 1", + processor_type: "hr_processor", + load_percent: 88.0 + } + ]) + + [p] = Repo.all(from(p in Processor, where: p.snmp_device_id == ^snmp_device.id)) + assert p.load_percent == 88.0 + end + + test "no-ops on empty list when nothing was previously stored", + %{snmp_device: snmp_device} do + assert :ok = Discovery.sync_processors(snmp_device, []) + assert [] == Repo.all(from(p in Processor, where: p.snmp_device_id == ^snmp_device.id)) + end + end + + describe "sync_storage/2" do + test "inserts and removes storage entries", %{snmp_device: snmp_device} do + Discovery.sync_storage(snmp_device, [ + %{ + storage_index: 1, + description: "Disk A", + storage_type: "fixed_disk", + total_bytes: 1_000_000, + used_bytes: 500_000 + }, + %{ + storage_index: 2, + description: "Disk B", + storage_type: "fixed_disk", + total_bytes: 2_000_000, + used_bytes: 1_000_000 + } + ]) + + assert length(Repo.all(from(s in Storage, where: s.snmp_device_id == ^snmp_device.id))) == 2 + + Discovery.sync_storage(snmp_device, [ + %{ + storage_index: 1, + description: "Disk A", + storage_type: "fixed_disk", + total_bytes: 1_000_000, + used_bytes: 750_000 + } + ]) + + [s] = Repo.all(from(s in Storage, where: s.snmp_device_id == ^snmp_device.id)) + assert s.storage_index == 1 + assert s.used_bytes == 750_000 + end + end +end