perf: optimize slow tests with bulk inserts and fewer iterations
Optimized the slowest tests to improve test suite performance:
1. Property-based IP validation test (6s → ~2.4s)
- Reduced max_runs from 50 to 20 iterations
- Still provides good coverage while being much faster
2. Database-heavy tests (~1s each)
- Replaced individual create_check calls with bulk Repo.insert_all
- Reduced check counts from 15 to 10 where adequate for testing
- Fixed timestamp handling (truncate to :second for Ecto)
- Fixed response_time_ms to use floats (schema requirement)
- Removed updated_at (disabled in Check schema)
- Tests affected:
* get_device_latency_by_agent/2
* get_uptime_percentage/1
* get_latency_data/2 respects limit
* AgentLatencyEvaluator tests
Expected speedup: ~40% reduction in top 10 slowest tests (12.8s → ~7.7s)
These optimizations maintain test coverage while significantly reducing
database transaction overhead.
This commit is contained in:
parent
64ad63d3e3
commit
fc37680931
4 changed files with 108 additions and 74 deletions
|
|
@ -8,6 +8,7 @@ defmodule Towerops.Agents.StatsTest do
|
|||
alias Towerops.Agents.Stats
|
||||
alias Towerops.Devices.Device
|
||||
alias Towerops.Monitoring
|
||||
alias Towerops.Monitoring.Check
|
||||
alias Towerops.Repo
|
||||
alias Towerops.Sites
|
||||
alias Towerops.Snmp.Device
|
||||
|
|
@ -492,27 +493,39 @@ defmodule Towerops.Agents.StatsTest do
|
|||
snmp_version: "2c"
|
||||
})
|
||||
|
||||
# Create checks from agent1 with avg 50ms
|
||||
for _ <- 1..15 do
|
||||
Monitoring.create_check(%{
|
||||
device_id: device.id,
|
||||
agent_token_id: agent1.id,
|
||||
status: :success,
|
||||
response_time_ms: 50,
|
||||
checked_at: DateTime.utc_now()
|
||||
})
|
||||
end
|
||||
# Create checks from agent1 with avg 50ms (bulk insert for speed)
|
||||
now = DateTime.truncate(DateTime.utc_now(), :second)
|
||||
|
||||
# Create checks from agent2 with avg 100ms
|
||||
for _ <- 1..15 do
|
||||
Monitoring.create_check(%{
|
||||
device_id: device.id,
|
||||
agent_token_id: agent2.id,
|
||||
status: :success,
|
||||
response_time_ms: 100,
|
||||
checked_at: DateTime.utc_now()
|
||||
})
|
||||
end
|
||||
checks_agent1 =
|
||||
for _ <- 1..10 do
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
agent_token_id: agent1.id,
|
||||
status: :success,
|
||||
response_time_ms: 50.0,
|
||||
checked_at: now,
|
||||
inserted_at: now
|
||||
}
|
||||
end
|
||||
|
||||
Repo.insert_all(Check, checks_agent1)
|
||||
|
||||
# Create checks from agent2 with avg 100ms (bulk insert for speed)
|
||||
checks_agent2 =
|
||||
for _ <- 1..10 do
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
agent_token_id: agent2.id,
|
||||
status: :success,
|
||||
response_time_ms: 100.0,
|
||||
checked_at: now,
|
||||
inserted_at: now
|
||||
}
|
||||
end
|
||||
|
||||
Repo.insert_all(Check, checks_agent2)
|
||||
|
||||
latency_by_agent = Stats.get_device_latency_by_agent(device.id)
|
||||
|
||||
|
|
@ -522,9 +535,9 @@ defmodule Towerops.Agents.StatsTest do
|
|||
agent2_latency = Enum.find(latency_by_agent, &(&1.agent_token_id == agent2.id))
|
||||
|
||||
assert agent1_latency.avg_latency_ms == 50.0
|
||||
assert agent1_latency.check_count == 15
|
||||
assert agent1_latency.check_count == 10
|
||||
assert agent2_latency.avg_latency_ms == 100.0
|
||||
assert agent2_latency.check_count == 15
|
||||
assert agent2_latency.check_count == 10
|
||||
end
|
||||
|
||||
test "filters by successful checks only" do
|
||||
|
|
|
|||
|
|
@ -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: 50
|
||||
max_runs: 20
|
||||
) do
|
||||
# These fail at validation, before any system call
|
||||
result = Ping.ping(invalid_ip)
|
||||
|
|
@ -115,7 +115,7 @@ defmodule Towerops.Monitoring.PingTest do
|
|||
octet2 <- integer(0..255),
|
||||
octet3 <- integer(0..255),
|
||||
octet4 <- integer(0..255),
|
||||
max_runs: 50
|
||||
max_runs: 20
|
||||
) do
|
||||
ip = "#{octet1}.#{octet2}.#{octet3}.#{octet4}"
|
||||
# Just verify IP validation passes (don't actually ping)
|
||||
|
|
|
|||
|
|
@ -208,40 +208,45 @@ defmodule Towerops.MonitoringTest do
|
|||
end
|
||||
|
||||
test "get_uptime_percentage/1 returns uptime percentage", %{device: device} do
|
||||
base_time = DateTime.utc_now()
|
||||
base_time = DateTime.truncate(DateTime.utc_now(), :second)
|
||||
|
||||
# Create 3 successful and 1 failed check
|
||||
{:ok, _} =
|
||||
Monitoring.create_check(%{
|
||||
# Create 3 successful and 1 failed check (bulk insert for speed)
|
||||
checks = [
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
status: :success,
|
||||
response_time_ms: 50,
|
||||
checked_at: DateTime.add(base_time, -60, :second)
|
||||
})
|
||||
|
||||
{:ok, _} =
|
||||
Monitoring.create_check(%{
|
||||
response_time_ms: 50.0,
|
||||
checked_at: DateTime.add(base_time, -60, :second),
|
||||
inserted_at: base_time
|
||||
},
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
status: :success,
|
||||
response_time_ms: 60,
|
||||
checked_at: DateTime.add(base_time, -120, :second)
|
||||
})
|
||||
|
||||
{:ok, _} =
|
||||
Monitoring.create_check(%{
|
||||
response_time_ms: 60.0,
|
||||
checked_at: DateTime.add(base_time, -120, :second),
|
||||
inserted_at: base_time
|
||||
},
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
status: :failure,
|
||||
response_time_ms: nil,
|
||||
checked_at: DateTime.add(base_time, -180, :second)
|
||||
})
|
||||
|
||||
{:ok, _} =
|
||||
Monitoring.create_check(%{
|
||||
checked_at: DateTime.add(base_time, -180, :second),
|
||||
inserted_at: base_time
|
||||
},
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
status: :success,
|
||||
response_time_ms: 70,
|
||||
checked_at: DateTime.add(base_time, -240, :second)
|
||||
})
|
||||
response_time_ms: 70.0,
|
||||
checked_at: DateTime.add(base_time, -240, :second),
|
||||
inserted_at: base_time
|
||||
}
|
||||
]
|
||||
|
||||
Repo.insert_all(Check, checks)
|
||||
|
||||
result = Monitoring.get_uptime_percentage(device.id)
|
||||
assert result == 75.0
|
||||
|
|
@ -333,18 +338,22 @@ defmodule Towerops.MonitoringTest do
|
|||
end
|
||||
|
||||
test "get_latency_data/2 respects limit option", %{device: device} do
|
||||
base_time = ~U[2025-12-21 12:00:00Z]
|
||||
base_time = DateTime.truncate(~U[2025-12-21 12:00:00Z], :second)
|
||||
|
||||
# Create 5 checks
|
||||
for i <- 1..5 do
|
||||
{:ok, _} =
|
||||
Monitoring.create_check(%{
|
||||
# Create 5 checks (bulk insert for speed)
|
||||
checks =
|
||||
for i <- 1..5 do
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
status: :success,
|
||||
response_time_ms: 50 + i,
|
||||
checked_at: DateTime.add(base_time, i * 60, :second)
|
||||
})
|
||||
end
|
||||
response_time_ms: (50 + i) * 1.0,
|
||||
checked_at: DateTime.add(base_time, i * 60, :second),
|
||||
inserted_at: base_time
|
||||
}
|
||||
end
|
||||
|
||||
Repo.insert_all(Check, checks)
|
||||
|
||||
since = DateTime.add(base_time, -3600, :second)
|
||||
result = Monitoring.get_latency_data(device.id, since: since, limit: 3)
|
||||
|
|
|
|||
|
|
@ -249,24 +249,36 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
|
|||
snmp_version: "2c"
|
||||
})
|
||||
|
||||
# Create checks from both cloud agents
|
||||
for _ <- 1..15 do
|
||||
Monitoring.create_check(%{
|
||||
device_id: device.id,
|
||||
agent_token_id: slow_cloud.id,
|
||||
status: :success,
|
||||
response_time_ms: 100,
|
||||
checked_at: DateTime.utc_now()
|
||||
})
|
||||
# Create checks from both cloud agents (bulk insert for speed)
|
||||
now = DateTime.truncate(DateTime.utc_now(), :second)
|
||||
|
||||
Monitoring.create_check(%{
|
||||
device_id: device.id,
|
||||
agent_token_id: fast_cloud.id,
|
||||
status: :success,
|
||||
response_time_ms: 50,
|
||||
checked_at: DateTime.utc_now()
|
||||
})
|
||||
end
|
||||
for_result =
|
||||
for _ <- 1..10 do
|
||||
[
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
agent_token_id: slow_cloud.id,
|
||||
status: :success,
|
||||
response_time_ms: 100.0,
|
||||
checked_at: now,
|
||||
inserted_at: now
|
||||
},
|
||||
%{
|
||||
id: Ecto.UUID.generate(),
|
||||
device_id: device.id,
|
||||
agent_token_id: fast_cloud.id,
|
||||
status: :success,
|
||||
response_time_ms: 50.0,
|
||||
checked_at: now,
|
||||
inserted_at: now
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
checks = List.flatten(for_result)
|
||||
|
||||
Repo.insert_all(Towerops.Monitoring.Check, checks)
|
||||
|
||||
# Trigger evaluation
|
||||
AgentLatencyEvaluator.trigger_evaluation()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue