towerops/test/towerops/snmp/entity_physical_reading_test.exs

244 lines
6.6 KiB
Elixir

defmodule Towerops.Snmp.EntityPhysicalReadingTest do
use Towerops.DataCase, async: true
import Towerops.SnmpFixtures
alias Towerops.Repo
alias Towerops.Snmp.EntityPhysical
alias Towerops.Snmp.EntityPhysicalReading
describe "changeset/2" do
test "validates required fields" do
changeset = EntityPhysicalReading.changeset(%EntityPhysicalReading{}, %{})
refute changeset.valid?
assert "can't be blank" in errors_on(changeset).entity_physical_id
assert "can't be blank" in errors_on(changeset).measured_at
end
test "accepts valid attributes" do
snmp_device = snmp_device_fixture()
{:ok, entity} =
%EntityPhysical{}
|> EntityPhysical.changeset(%{
snmp_device_id: snmp_device.id,
entity_index: "1",
entity_class: "powerSupply",
name: "PS1"
})
|> Repo.insert()
attrs = %{
entity_physical_id: entity.id,
operational_status: "up",
admin_status: "unlocked",
measured_at: DateTime.utc_now()
}
changeset = EntityPhysicalReading.changeset(%EntityPhysicalReading{}, attrs)
assert changeset.valid?
end
test "validates operational_status is a known value" do
snmp_device = snmp_device_fixture()
{:ok, entity} =
%EntityPhysical{}
|> EntityPhysical.changeset(%{
snmp_device_id: snmp_device.id,
entity_index: "1",
entity_class: "fan",
name: "Fan1"
})
|> Repo.insert()
# Valid statuses: up, down, testing, unknown, dormant, notPresent, lowerLayerDown
valid_statuses = [
"up",
"down",
"testing",
"unknown",
"dormant",
"notPresent",
"lowerLayerDown"
]
for status <- valid_statuses do
changeset =
EntityPhysicalReading.changeset(%EntityPhysicalReading{}, %{
entity_physical_id: entity.id,
operational_status: status,
measured_at: DateTime.utc_now()
})
assert changeset.valid?, "Status #{status} should be valid"
end
end
test "validates admin_status is a known value" do
snmp_device = snmp_device_fixture()
{:ok, entity} =
%EntityPhysical{}
|> EntityPhysical.changeset(%{
snmp_device_id: snmp_device.id,
entity_index: "1",
entity_class: "module",
name: "Module1"
})
|> Repo.insert()
# Valid statuses: locked, unlocked, shuttingDown, unknown
valid_statuses = ["locked", "unlocked", "shuttingDown", "unknown"]
for status <- valid_statuses do
changeset =
EntityPhysicalReading.changeset(%EntityPhysicalReading{}, %{
entity_physical_id: entity.id,
admin_status: status,
measured_at: DateTime.utc_now()
})
assert changeset.valid?, "Status #{status} should be valid"
end
end
test "allows nil for optional status fields" do
snmp_device = snmp_device_fixture()
{:ok, entity} =
%EntityPhysical{}
|> EntityPhysical.changeset(%{
snmp_device_id: snmp_device.id,
entity_index: "1",
entity_class: "chassis",
name: "Chassis1"
})
|> Repo.insert()
attrs = %{
entity_physical_id: entity.id,
measured_at: DateTime.utc_now()
}
changeset = EntityPhysicalReading.changeset(%EntityPhysicalReading{}, attrs)
assert changeset.valid?
end
test "casts measured_at to DateTime" do
snmp_device = snmp_device_fixture()
{:ok, entity} =
%EntityPhysical{}
|> EntityPhysical.changeset(%{
snmp_device_id: snmp_device.id,
entity_index: "1",
entity_class: "sensor",
name: "Temp1"
})
|> Repo.insert()
now = Towerops.Time.now()
attrs = %{
entity_physical_id: entity.id,
operational_status: "up",
measured_at: now
}
changeset = EntityPhysicalReading.changeset(%EntityPhysicalReading{}, attrs)
assert changeset.valid?
assert Ecto.Changeset.get_field(changeset, :measured_at) == now
end
end
describe "database constraints" do
test "requires entity_physical_id foreign key to exist" do
attrs = %{
entity_physical_id: Ecto.UUID.generate(),
operational_status: "up",
measured_at: DateTime.utc_now()
}
assert {:error, changeset} =
%EntityPhysicalReading{}
|> EntityPhysicalReading.changeset(attrs)
|> Repo.insert()
assert "does not exist" in errors_on(changeset).entity_physical_id
end
test "cascades delete when entity_physical is deleted" do
snmp_device = snmp_device_fixture()
{:ok, entity} =
%EntityPhysical{}
|> EntityPhysical.changeset(%{
snmp_device_id: snmp_device.id,
entity_index: "1",
entity_class: "powerSupply",
name: "PS1"
})
|> Repo.insert()
{:ok, reading} =
%EntityPhysicalReading{}
|> EntityPhysicalReading.changeset(%{
entity_physical_id: entity.id,
operational_status: "up",
measured_at: DateTime.utc_now()
})
|> Repo.insert()
# Delete entity
Repo.delete!(entity)
# Reading should be deleted
assert is_nil(Repo.get(EntityPhysicalReading, reading.id))
end
end
describe "querying" do
test "can query readings by entity_physical_id" do
snmp_device = snmp_device_fixture()
{:ok, entity} =
%EntityPhysical{}
|> EntityPhysical.changeset(%{
snmp_device_id: snmp_device.id,
entity_index: "1",
entity_class: "fan",
name: "Fan1"
})
|> Repo.insert()
{:ok, _reading1} =
%EntityPhysicalReading{}
|> EntityPhysicalReading.changeset(%{
entity_physical_id: entity.id,
operational_status: "up",
measured_at: DateTime.add(DateTime.utc_now(), -3600, :second)
})
|> Repo.insert()
{:ok, reading2} =
%EntityPhysicalReading{}
|> EntityPhysicalReading.changeset(%{
entity_physical_id: entity.id,
operational_status: "down",
measured_at: DateTime.utc_now()
})
|> Repo.insert()
readings =
EntityPhysicalReading
|> where([r], r.entity_physical_id == ^entity.id)
|> order_by([r], desc: r.measured_at)
|> Repo.all()
assert length(readings) == 2
assert hd(readings).id == reading2.id
end
end
end