towerops/test/towerops/snmp/batch_insert_test.exs

459 lines
13 KiB
Elixir

defmodule Towerops.Snmp.BatchInsertTest do
use Towerops.DataCase, async: false
import Towerops.AccountsFixtures
alias Towerops.Repo
alias Towerops.Snmp
alias Towerops.Snmp.Device
alias Towerops.Snmp.Interface
alias Towerops.Snmp.InterfaceStat
alias Towerops.Snmp.Processor
alias Towerops.Snmp.ProcessorReading
alias Towerops.Snmp.Sensor
alias Towerops.Snmp.SensorReading
alias Towerops.Snmp.Storage
alias Towerops.Snmp.StorageReading
setup do
user = user_fixture()
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
{:ok, site} =
Towerops.Sites.create_site(%{
name: "Test Site",
organization_id: organization.id
})
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Test Router",
ip_address: "192.168.1.1",
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
site_id: site.id,
organization_id: organization.id
})
snmp_device =
%Device{}
|> Device.changeset(%{
device_id: device.id,
sys_name: "test-router",
sys_descr: "Test Device"
})
|> Repo.insert!()
sensor =
%Sensor{}
|> Sensor.changeset(%{
snmp_device_id: snmp_device.id,
sensor_type: "temperature",
sensor_index: "temp_1",
sensor_oid: "1.3.6.1.4.1.9.9.91.1.1.1.1.4.1"
})
|> Repo.insert!()
sensor2 =
%Sensor{}
|> Sensor.changeset(%{
snmp_device_id: snmp_device.id,
sensor_type: "voltage",
sensor_index: "volt_1",
sensor_oid: "1.3.6.1.4.1.9.9.91.1.1.1.1.4.2"
})
|> Repo.insert!()
interface =
%Interface{}
|> Interface.changeset(%{
snmp_device_id: snmp_device.id,
if_index: 1,
if_name: "eth0"
})
|> Repo.insert!()
interface2 =
%Interface{}
|> Interface.changeset(%{
snmp_device_id: snmp_device.id,
if_index: 2,
if_name: "eth1"
})
|> Repo.insert!()
processor =
%Processor{}
|> Processor.changeset(%{
snmp_device_id: snmp_device.id,
processor_index: "1",
processor_type: "hr_processor",
description: "CPU 1"
})
|> Repo.insert!()
processor2 =
%Processor{}
|> Processor.changeset(%{
snmp_device_id: snmp_device.id,
processor_index: "2",
processor_type: "hr_processor",
description: "CPU 2"
})
|> Repo.insert!()
storage =
%Storage{}
|> Storage.changeset(%{
snmp_device_id: snmp_device.id,
storage_index: 1,
storage_type: "fixed_disk",
description: "/dev/sda1"
})
|> Repo.insert!()
storage2 =
%Storage{}
|> Storage.changeset(%{
snmp_device_id: snmp_device.id,
storage_index: 2,
storage_type: "ram",
description: "Physical Memory"
})
|> Repo.insert!()
%{
snmp_device: snmp_device,
sensor: sensor,
sensor2: sensor2,
interface: interface,
interface2: interface2,
processor: processor,
processor2: processor2,
storage: storage,
storage2: storage2
}
end
describe "create_sensor_readings_batch/1" do
test "inserts multiple sensor readings", %{sensor: sensor, sensor2: sensor2} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{sensor_id: sensor.id, value: 25.5, status: "ok", checked_at: now},
%{sensor_id: sensor2.id, value: 3.3, status: "warning", checked_at: now}
]
assert {2, nil} = Snmp.create_sensor_readings_batch(entries)
readings = Repo.all(SensorReading)
assert length(readings) == 2
reading1 = Enum.find(readings, &(&1.sensor_id == sensor.id))
assert reading1.value == 25.5
assert reading1.status == "ok"
assert reading1.checked_at == now
assert reading1.id
assert reading1.inserted_at
reading2 = Enum.find(readings, &(&1.sensor_id == sensor2.id))
assert reading2.value == 3.3
assert reading2.status == "warning"
end
test "returns {0, nil} for empty list" do
assert {0, nil} = Snmp.create_sensor_readings_batch([])
assert Repo.all(SensorReading) == []
end
test "generates unique UUIDs for each entry", %{sensor: sensor} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{sensor_id: sensor.id, value: 10.0, status: "ok", checked_at: now},
%{sensor_id: sensor.id, value: 11.0, status: "ok", checked_at: now}
]
{2, nil} = Snmp.create_sensor_readings_batch(entries)
readings = Repo.all(SensorReading)
ids = Enum.map(readings, & &1.id)
assert length(Enum.uniq(ids)) == 2
end
test "handles optional state_descr field", %{sensor: sensor} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{
sensor_id: sensor.id,
value: 25.5,
status: "ok",
state_descr: "Normal operating temperature",
checked_at: now
}
]
assert {1, nil} = Snmp.create_sensor_readings_batch(entries)
[reading] = Repo.all(SensorReading)
assert reading.state_descr == "Normal operating temperature"
end
test "handles entries with nil value", %{sensor: sensor} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{sensor_id: sensor.id, value: nil, status: "error", checked_at: now}
]
assert {1, nil} = Snmp.create_sensor_readings_batch(entries)
[reading] = Repo.all(SensorReading)
assert reading.value == nil
assert reading.status == "error"
end
end
describe "create_interface_stats_batch/1" do
test "inserts multiple interface stats", %{interface: interface, interface2: interface2} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{
interface_id: interface.id,
if_in_octets: 1000,
if_out_octets: 2000,
if_in_errors: 0,
if_out_errors: 0,
if_in_discards: 0,
if_out_discards: 0,
checked_at: now
},
%{
interface_id: interface2.id,
if_in_octets: 5000,
if_out_octets: 6000,
if_in_errors: 1,
if_out_errors: 2,
if_in_discards: 3,
if_out_discards: 4,
checked_at: now
}
]
assert {2, nil} = Snmp.create_interface_stats_batch(entries)
stats = Repo.all(InterfaceStat)
assert length(stats) == 2
stat1 = Enum.find(stats, &(&1.interface_id == interface.id))
assert stat1.if_in_octets == 1000
assert stat1.if_out_octets == 2000
assert stat1.if_in_errors == 0
assert stat1.if_out_errors == 0
assert stat1.if_in_discards == 0
assert stat1.if_out_discards == 0
assert stat1.checked_at == now
assert stat1.id
assert stat1.inserted_at
stat2 = Enum.find(stats, &(&1.interface_id == interface2.id))
assert stat2.if_in_octets == 5000
assert stat2.if_out_octets == 6000
assert stat2.if_in_errors == 1
assert stat2.if_out_errors == 2
end
test "returns {0, nil} for empty list" do
assert {0, nil} = Snmp.create_interface_stats_batch([])
assert Repo.all(InterfaceStat) == []
end
test "generates unique UUIDs for each entry", %{interface: interface} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{interface_id: interface.id, if_in_octets: 100, if_out_octets: 200, checked_at: now},
%{interface_id: interface.id, if_in_octets: 300, if_out_octets: 400, checked_at: now}
]
{2, nil} = Snmp.create_interface_stats_batch(entries)
stats = Repo.all(InterfaceStat)
ids = Enum.map(stats, & &1.id)
assert length(Enum.uniq(ids)) == 2
end
test "handles entries with nil counter values", %{interface: interface} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{interface_id: interface.id, if_in_octets: nil, if_out_octets: nil, checked_at: now}
]
assert {1, nil} = Snmp.create_interface_stats_batch(entries)
[stat] = Repo.all(InterfaceStat)
assert stat.if_in_octets == nil
assert stat.if_out_octets == nil
end
end
describe "create_processor_readings_batch/1" do
test "inserts multiple processor readings", %{processor: processor, processor2: processor2} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{processor_id: processor.id, load_percent: 45.0, status: "ok", checked_at: now},
%{processor_id: processor2.id, load_percent: 92.0, status: "critical", checked_at: now}
]
assert {2, nil} = Snmp.create_processor_readings_batch(entries)
readings = Repo.all(ProcessorReading)
assert length(readings) == 2
reading1 = Enum.find(readings, &(&1.processor_id == processor.id))
assert reading1.load_percent == 45.0
assert reading1.status == "ok"
assert reading1.checked_at == now
assert reading1.id
assert reading1.inserted_at
reading2 = Enum.find(readings, &(&1.processor_id == processor2.id))
assert reading2.load_percent == 92.0
assert reading2.status == "critical"
end
test "returns {0, nil} for empty list" do
assert {0, nil} = Snmp.create_processor_readings_batch([])
assert Repo.all(ProcessorReading) == []
end
test "generates unique UUIDs for each entry", %{processor: processor} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{processor_id: processor.id, load_percent: 10.0, status: "ok", checked_at: now},
%{processor_id: processor.id, load_percent: 20.0, status: "ok", checked_at: now}
]
{2, nil} = Snmp.create_processor_readings_batch(entries)
readings = Repo.all(ProcessorReading)
ids = Enum.map(readings, & &1.id)
assert length(Enum.uniq(ids)) == 2
end
test "handles entries with nil load_percent", %{processor: processor} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{processor_id: processor.id, load_percent: nil, status: "error", checked_at: now}
]
assert {1, nil} = Snmp.create_processor_readings_batch(entries)
[reading] = Repo.all(ProcessorReading)
assert reading.load_percent == nil
assert reading.status == "error"
end
end
describe "create_storage_readings_batch/1" do
test "inserts multiple storage readings", %{storage: storage, storage2: storage2} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{
storage_id: storage.id,
used_bytes: 5_000_000,
total_bytes: 10_000_000,
usage_percent: 50.0,
checked_at: now
},
%{
storage_id: storage2.id,
used_bytes: 2_000_000,
total_bytes: 8_000_000,
usage_percent: 25.0,
checked_at: now
}
]
assert {2, nil} = Snmp.create_storage_readings_batch(entries)
readings = Repo.all(StorageReading)
assert length(readings) == 2
reading1 = Enum.find(readings, &(&1.storage_id == storage.id))
assert reading1.used_bytes == 5_000_000
assert reading1.total_bytes == 10_000_000
assert reading1.usage_percent == 50.0
assert reading1.checked_at == now
assert reading1.id
assert reading1.inserted_at
reading2 = Enum.find(readings, &(&1.storage_id == storage2.id))
assert reading2.used_bytes == 2_000_000
assert reading2.total_bytes == 8_000_000
assert reading2.usage_percent == 25.0
end
test "returns {0, nil} for empty list" do
assert {0, nil} = Snmp.create_storage_readings_batch([])
assert Repo.all(StorageReading) == []
end
test "generates unique UUIDs for each entry", %{storage: storage} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{
storage_id: storage.id,
used_bytes: 1000,
total_bytes: 2000,
usage_percent: 50.0,
checked_at: now
},
%{
storage_id: storage.id,
used_bytes: 1500,
total_bytes: 2000,
usage_percent: 75.0,
checked_at: now
}
]
{2, nil} = Snmp.create_storage_readings_batch(entries)
readings = Repo.all(StorageReading)
ids = Enum.map(readings, & &1.id)
assert length(Enum.uniq(ids)) == 2
end
test "handles entries with nil optional fields", %{storage: storage} do
now = DateTime.truncate(DateTime.utc_now(), :second)
entries = [
%{
storage_id: storage.id,
used_bytes: nil,
total_bytes: nil,
usage_percent: nil,
checked_at: now
}
]
assert {1, nil} = Snmp.create_storage_readings_batch(entries)
[reading] = Repo.all(StorageReading)
assert reading.used_bytes == nil
assert reading.total_bytes == nil
assert reading.usage_percent == nil
end
end
end