1.7 KiB · text 5af55d9
defmodule GitGud.Federation.RateLimiterTest do
use GitGud.DataCase, async: false
alias GitGud.Federation
alias GitGud.Federation.RateLimiter
setup do
RateLimiter.reset()
original = Application.get_env(:git_gud, RateLimiter, [])
on_exit(fn ->
Application.put_env(:git_gud, RateLimiter, original)
RateLimiter.reset()
end)
%{original: original}
end
test "allows up to the threshold, then rate limits", %{original: orig} do
Application.put_env(
:git_gud,
RateLimiter,
Keyword.merge(orig, inbox_per_minute: 3, allowlist_multiplier: nil)
)
assert :ok = RateLimiter.check("x.example")
assert :ok = RateLimiter.check("x.example")
assert :ok = RateLimiter.check("x.example")
assert {:error, :rate_limited, retry} = RateLimiter.check("x.example")
assert retry > 0
end
test "buckets are per-host" do
assert :ok = RateLimiter.check("a.example")
assert :ok = RateLimiter.check("b.example")
snap = RateLimiter.snapshot()
assert {"a.example", 1} in snap
assert {"b.example", 1} in snap
end
test "allowlisted hosts get the multiplied threshold", %{original: orig} do
Application.put_env(
:git_gud,
RateLimiter,
Keyword.merge(orig, inbox_per_minute: 2, allowlist_multiplier: 5)
)
{:ok, _} = Federation.allowlist_instance("trusted.example")
# Base would cap at 2, but with mult=5 we expect 10 to fit.
for _ <- 1..10, do: assert(:ok = RateLimiter.check("trusted.example"))
assert {:error, :rate_limited, _} = RateLimiter.check("trusted.example")
end
test "nil host is always allowed" do
assert :ok = RateLimiter.check(nil)
end
end