diff --git a/test/towerops/api_tokens_test.exs b/test/towerops/api_tokens_test.exs index a5f60cd2..4fe62476 100644 --- a/test/towerops/api_tokens_test.exs +++ b/test/towerops/api_tokens_test.exs @@ -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}} = diff --git a/test/towerops/devices_test.exs b/test/towerops/devices_test.exs index cafdd773..7eb8f7a2 100644 --- a/test/towerops/devices_test.exs +++ b/test/towerops/devices_test.exs @@ -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 = %{ diff --git a/test/towerops/equipment/event_logger_test.exs b/test/towerops/equipment/event_logger_test.exs index b1e9ab14..9632cd5f 100644 --- a/test/towerops/equipment/event_logger_test.exs +++ b/test/towerops/equipment/event_logger_test.exs @@ -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 diff --git a/test/towerops/monitoring/ping_test.exs b/test/towerops/monitoring/ping_test.exs index 686f7c2a..bd369e1b 100644 --- a/test/towerops/monitoring/ping_test.exs +++ b/test/towerops/monitoring/ping_test.exs @@ -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) diff --git a/test/towerops/redis_health_check_test.exs b/test/towerops/redis_health_check_test.exs index 172ea196..f09cc56e 100644 --- a/test/towerops/redis_health_check_test.exs +++ b/test/towerops/redis_health_check_test.exs @@ -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) diff --git a/test/towerops/snmp/mib_translator_test.exs b/test/towerops/snmp/mib_translator_test.exs index 50226747..17e60efa 100644 --- a/test/towerops/snmp/mib_translator_test.exs +++ b/test/towerops/snmp/mib_translator_test.exs @@ -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"} ] diff --git a/test/towerops_web/live/device_live_nested/show_test.exs b/test/towerops_web/live/device_live_nested/show_test.exs index 693a680b..90c47421 100644 --- a/test/towerops_web/live/device_live_nested/show_test.exs +++ b/test/towerops_web/live/device_live_nested/show_test.exs @@ -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 diff --git a/test/towerops_web/user_auth_test.exs b/test/towerops_web/user_auth_test.exs index 6161520e..440f5997 100644 --- a/test/towerops_web/user_auth_test.exs +++ b/test/towerops_web/user_auth_test.exs @@ -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