faster tests

This commit is contained in:
Graham McIntire 2026-01-27 09:30:18 -06:00
parent c694d452de
commit 421f2e05f3
No known key found for this signature in database
8 changed files with 77 additions and 64 deletions

View file

@ -532,10 +532,11 @@ defmodule Towerops.ApiTokensTest do
end
property "expired tokens always return error" do
check all(days_ago <- integer(1..365)) do
user = user_fixture()
organization = organization_fixture(user.id)
# Create fixtures once outside the property check
user = user_fixture()
organization = organization_fixture(user.id)
check all(days_ago <- integer(1..365), max_runs: 20) do
expires_at = DateTime.add(DateTime.utc_now(), -days_ago, :day)
{:ok, {_token, raw_token}} =

View file

@ -1005,23 +1005,24 @@ defmodule Towerops.EquipmentTest do
import Towerops.AccountsFixtures
property "creating devices with valid IPs always succeeds" do
# Create fixtures once outside the property check
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
})
check all(
name <- string(:alphanumeric, min_length: 2, max_length: 20),
octet1 <- integer(0..255),
octet2 <- integer(0..255),
octet3 <- integer(0..255),
octet4 <- integer(1..254)
octet4 <- integer(1..254),
max_runs: 20
) do
# Create fresh org and site for each property test run
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
})
ip_address = "#{octet1}.#{octet2}.#{octet3}.#{octet4}"
attrs = %{

View file

@ -87,11 +87,20 @@ defmodule Towerops.Devices.EventLoggerTest do
)
end
# Give the EventLogger time to process all events
Process.sleep(300)
# Poll for events with early exit (max 100ms)
events =
Enum.reduce_while(1..10, [], fn _, _acc ->
events = Towerops.Devices.list_devices_events(device.id, 10)
if length(events) >= 3 do
{:halt, events}
else
Process.sleep(10)
{:cont, []}
end
end)
# Verify all events were created
events = Towerops.Devices.list_devices_events(device.id, 10)
assert length(events) == 3
end

View file

@ -101,7 +101,7 @@ defmodule Towerops.Monitoring.PingTest do
# IPs with letters in octet position (use ?a..?z range)
map(string(?a..?z, length: 3), &"192.168.#{&1}.1")
]),
max_runs: 20
max_runs: 10
) do
# These fail at validation, before any system call
result = Ping.ping(invalid_ip)

View file

@ -22,8 +22,8 @@ defmodule Towerops.RedisHealthCheckTest do
assert {:error, :max_attempts_exceeded} =
RedisHealthCheck.wait_for_redis(redis_config,
max_attempts: 2,
backoff: 50,
timeout: 100
backoff: 10,
timeout: 10
)
end)
end
@ -69,7 +69,7 @@ defmodule Towerops.RedisHealthCheckTest do
# Suppress Redis connection warnings during test
_logs =
capture_log(fn ->
assert {:error, _reason} = RedisHealthCheck.check_health(redis_config, 100)
assert {:error, _reason} = RedisHealthCheck.check_health(redis_config, 10)
end)
end
@ -79,7 +79,7 @@ defmodule Towerops.RedisHealthCheckTest do
# Suppress Redis connection warnings during test
_logs =
capture_log(fn ->
assert {:error, _reason} = RedisHealthCheck.check_health(redis_config, 100)
assert {:error, _reason} = RedisHealthCheck.check_health(redis_config, 10)
end)
end
@ -89,7 +89,7 @@ defmodule Towerops.RedisHealthCheckTest do
# Suppress Redis connection warnings during test
_logs =
capture_log(fn ->
result = RedisHealthCheck.check_health(redis_config, 200)
result = RedisHealthCheck.check_health(redis_config, 10)
# Should return error (either immediate connection failure or timeout)
assert match?({:error, _}, result)
end)

View file

@ -137,10 +137,9 @@ defmodule Towerops.Snmp.MibTranslatorTest do
describe "error handling" do
test "handles malformed MIB names gracefully" do
# Test representative sample (reduced from 4 to 2 for performance)
malformed_names = [
"::noModule",
"MODULE::",
"::::",
"MODULE::object::extra"
]
@ -167,31 +166,16 @@ defmodule Towerops.Snmp.MibTranslatorTest do
describe "standard MIB translations" do
test "translates IF-MIB objects" do
# Test a few standard IF-MIB objects
mib_names = [
"IF-MIB::ifDescr",
"IF-MIB::ifType",
"IF-MIB::ifSpeed"
]
Enum.each(mib_names, fn name ->
result = MibTranslator.translate(name)
# These should successfully translate or error (if net-snmp not available)
assert match?({:ok, _}, result) or match?({:error, _}, result)
end)
# Test representative sample (reduced from 3 to 1 for performance)
result = MibTranslator.translate("IF-MIB::ifDescr")
# These should successfully translate or error (if net-snmp not available)
assert match?({:ok, _}, result) or match?({:error, _}, result)
end
test "translates SNMPv2-MIB objects" do
mib_names = [
"SNMPv2-MIB::sysName.0",
"SNMPv2-MIB::sysLocation.0",
"SNMPv2-MIB::sysContact.0"
]
Enum.each(mib_names, fn name ->
result = MibTranslator.translate(name)
assert match?({:ok, _}, result) or match?({:error, _}, result)
end)
# Test representative sample (reduced from 3 to 1 for performance)
result = MibTranslator.translate("SNMPv2-MIB::sysName.0")
assert match?({:ok, _}, result) or match?({:error, _}, result)
end
end
@ -300,10 +284,9 @@ defmodule Towerops.Snmp.MibTranslatorTest do
end
test "uses fallback for Ubiquiti AirMAX GPS OIDs" do
# Test representative sample (reduced from 4 to 2 for performance)
ubnt_gps_oids = [
{"UBNT-AirMAX-MIB::ubntGpsLat.0", "1.3.6.1.4.1.41112.1.4.9.3.0"},
{"UBNT-AirMAX-MIB::ubntGpsLon.0", "1.3.6.1.4.1.41112.1.4.9.4.0"},
{"UBNT-AirMAX-MIB::ubntGpsFix.0", "1.3.6.1.4.1.41112.1.4.9.2.0"},
{"UBNT-AirMAX-MIB::ubntGpsStatus.0", "1.3.6.1.4.1.41112.1.4.9.1.0"}
]
@ -329,13 +312,10 @@ defmodule Towerops.Snmp.MibTranslatorTest do
end
test "uses fallback for Cambium ePMP OIDs" do
# Test representative sample (reduced from 7 to 3 for performance)
cambium_oids = [
{"CAMBIUM-PMP80211-MIB::cambiumCurrentuImageVersion.0", "1.3.6.1.4.1.17713.21.1.1.17.0"},
{"CAMBIUM-PMP80211-MIB::cambiumEPMPMSN.0", "1.3.6.1.4.1.17713.21.1.1.31.0"},
{"CAMBIUM-PMP80211-MIB::cambiumDeviceLatitude.0", "1.3.6.1.4.1.17713.21.1.1.18.0"},
{"CAMBIUM-PMP80211-MIB::cambiumDeviceLongitude.0", "1.3.6.1.4.1.17713.21.1.1.19.0"},
{"CAMBIUM-PMP80211-MIB::cambiumEffectiveSyncSource", "1.3.6.1.4.1.17713.21.1.1.7"},
{"CAMBIUM-PMP80211-MIB::cambiumDFSStatus", "1.3.6.1.4.1.17713.21.1.1.6"},
{"CAMBIUM-PMP80211-MIB::sysCPUUsage", "1.3.6.1.4.1.17713.21.2.1.64"}
]
@ -361,11 +341,9 @@ defmodule Towerops.Snmp.MibTranslatorTest do
end
test "uses fallback for Ubiquiti AirMAX wireless stats OIDs" do
# Test representative sample (reduced from 5 to 2 for performance)
ubnt_wireless_oids = [
{"UBNT-AirMAX-MIB::ubntWlStatSignal", "1.3.6.1.4.1.41112.1.4.5.1.5"},
{"UBNT-AirMAX-MIB::ubntWlStatRssi", "1.3.6.1.4.1.41112.1.4.5.1.6"},
{"UBNT-AirMAX-MIB::ubntWlStatCcq", "1.3.6.1.4.1.41112.1.4.5.1.7"},
{"UBNT-AirMAX-MIB::ubntWlStatNoiseFloor", "1.3.6.1.4.1.41112.1.4.5.1.8"},
{"UBNT-AirMAX-MIB::ubntWlStatStaCount", "1.3.6.1.4.1.41112.1.4.5.1.15"}
]

View file

@ -98,8 +98,16 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do
# Send refresh message
send(view.pid, :refresh_data)
# Give it time to process
:timer.sleep(100)
# Poll for processing with early exit (max 50ms)
Enum.reduce_while(1..5, nil, fn _, _ ->
try do
{:halt, render(view)}
rescue
_ ->
Process.sleep(10)
{:cont, nil}
end
end)
# View should still be alive
assert render(view)
@ -123,8 +131,16 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do
# Simulate status change event
send(view.pid, {:device_status_changed, device.id, :up, 25})
# Give it time to process
:timer.sleep(100)
# Poll for processing with early exit (max 50ms)
Enum.reduce_while(1..5, nil, fn _, _ ->
try do
{:halt, render(view)}
rescue
_ ->
Process.sleep(10)
{:cont, nil}
end
end)
# View should still be alive and render
assert render(view)
@ -140,10 +156,18 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do
# Simulate discovery completed event
send(view.pid, {:discovery_completed, device.id})
# Give it time to process
:timer.sleep(100)
# Poll for processing with early exit (max 50ms)
html =
Enum.reduce_while(1..5, nil, fn _, _ ->
try do
{:halt, render(view)}
rescue
_ ->
Process.sleep(10)
{:cont, nil}
end
end) || render(view)
html = render(view)
assert html =~ "Discovery completed"
end

View file

@ -1321,7 +1321,7 @@ defmodule ToweropsWeb.UserAuthTest do
end
property "redirect paths are always valid for authenticated users", %{user: user} do
check all(has_org <- boolean()) do
check all(has_org <- boolean(), max_runs: 10) do
if has_org do
{:ok, _org} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
end