SPB Git forge

spb/hfmarketdata

Public

Open high-frequency market data platform — FirstRate full-history downloader, DuckDB/Parquet lake, open REST API and React docs platform (www.hfmarketdata.io)

127commits 1branches 0releases
24.7 MBsize
maindefault branch
11 days agolast push
JavaScript 53.7% Python 38.3% CSS 4.6% TypeScript 3.1%
4.9 KB · 113 lines python
Raw Blame History
1"""Lua sliding-window counters (fakeredis + lupa): remaining, reset, window rollover, force, peek, fail-open."""2from __future__ import annotations34import pytest567@pytest.fixture8def rl(app):9    from ratelimit import redis_limiter10    redis_limiter.reset_for_tests()11    return redis_limiter121314@pytest.fixture15def tiers(app):16    from ratelimit import tiers17    return tiers181920T0 = 1_800_000_000_000  # ms212223def test_requests_counter_and_reset(rl, tiers):24    keyless = tiers.TIERS["keyless"]25    d = rl.apply_tier("ip:test", keyless, req_cost=1, at_ms=T0)26    assert d.allowed and d.applied27    assert d.remaining_requests == 29 and d.limit_requests == 3028    assert d.remaining_rows == 100_00029    assert d.reset_requests == T0 // 1000 + 3600           # oldest bucket + window30    for _ in range(29):31        d = rl.apply_tier("ip:test", keyless, req_cost=1, at_ms=T0 + 5_000)32    assert d.allowed and d.remaining_requests == 033    d = rl.apply_tier("ip:test", keyless, req_cost=1, at_ms=T0 + 6_000)34    assert not d.allowed and not d.allowed_requests and d.allowed_rows and not d.applied35    assert d.remaining_requests == 036    assert d.reset_requests == T0 // 1000 + 3600373839def test_window_rollover_frees_oldest_bucket(rl, tiers):40    free = tiers.TIERS["free"]   # 60 s window, 120 requests41    for i in range(120):42        d = rl.apply_tier("key:1", free, req_cost=1, at_ms=T0 + i * 100)   # all within 12 s43    assert d.remaining_requests == 044    assert not rl.apply_tier("key:1", free, req_cost=1, at_ms=T0 + 30_000).allowed45    # 60 s after the first bucket the first second (10 requests) has rolled out of the window46    d = rl.apply_tier("key:1", free, req_cost=0, at_ms=T0 + 60_000)47    assert d.remaining_requests == 1048    d = rl.apply_tier("key:1", free, req_cost=1, at_ms=T0 + 60_000)49    assert d.allowed and d.remaining_requests == 950    # far in the future: everything expired, hash pruned51    d = rl.apply_tier("key:1", free, req_cost=0, at_ms=T0 + 200_000)52    assert d.remaining_requests == 12053    assert rl.client().hlen("rl:key:1:req") == 0545556def test_rows_counter_precheck_and_force(rl, tiers):57    keyless = tiers.TIERS["keyless"]58    # charge rows after the fact, even when it overshoots59    d = rl.apply_tier("ip:r", keyless, req_cost=0, rows_cost=99_990, force=True, at_ms=T0)60    assert d.applied and d.remaining_rows == 1061    d = rl.apply_tier("ip:r", keyless, req_cost=0, rows_cost=50, force=True, at_ms=T0 + 1000)62    assert d.applied and not d.allowed_rows and d.remaining_rows == 063    # now the pre-check refuses on rows while requests are still available64    d = rl.apply_tier("ip:r", keyless, req_cost=1, at_ms=T0 + 2000)65    assert d.allowed_requests and not d.allowed_rows and not d.applied66    assert d.reset_rows == T0 // 1000 + 3600676869def test_peek_does_not_write(rl, tiers):70    free = tiers.TIERS["free"]71    d = rl.peek_tier("key:9", free, at_ms=T0)72    assert d.remaining_requests == 120 and d.remaining_rows == 1_000_00073    assert rl.client().exists("rl:key:9:req") == 0747576def test_two_principals_are_independent(rl, tiers):77    keyless = tiers.TIERS["keyless"]78    rl.apply_tier("ip:a", keyless, at_ms=T0)79    assert rl.peek_tier("ip:b", keyless, at_ms=T0).remaining_requests == 3080    assert rl.peek_tier("ip:a", keyless, at_ms=T0).remaining_requests == 29818283def test_fail_open_when_redis_raises(rl, tiers, monkeypatch, caplog):84    import redis as redis_lib8586    class Broken:87        def evalsha(self, *a, **k):88            raise redis_lib.exceptions.ConnectionError("down")8990        def script_load(self, *a):91            raise redis_lib.exceptions.ConnectionError("down")9293    monkeypatch.setattr(rl, "_client", Broken())94    monkeypatch.setattr(rl, "_sha", None)95    monkeypatch.setattr(rl, "_down_until", 0.0)96    monkeypatch.setattr(rl, "_last_warn", 0.0)97    with caplog.at_level("WARNING"):98        assert rl.apply_tier("ip:x", tiers.TIERS["keyless"], at_ms=T0) is None99    assert "fails open" in caplog.text100    assert not rl.available()          # circuit open for a few seconds101102103def test_tier_table_is_exact(tiers):104    t = tiers.TIERS105    assert (t["keyless"].window_s, t["keyless"].requests, t["keyless"].rows, t["keyless"].max_rows_per_request) == (3600, 30, 100_000, 5_000)106    assert (t["free"].window_s, t["free"].requests, t["free"].rows, t["free"].max_rows_per_request) == (60, 120, 1_000_000, 50_000)107    assert (t["high_usage"].window_s, t["high_usage"].requests, t["high_usage"].rows, t["high_usage"].max_rows_per_request) == (60, 600, 10_000_000, 200_000)108    assert t["keyless"].requests_type == "requests_per_hour" and t["free"].rows_type == "rows_per_minute"109    assert tiers.row_cost(101, status=200, media_type="application/vnd.apache.parquet", quota_exempt=False) == 51110    assert tiers.row_cost(500, status=304, media_type="application/json", quota_exempt=False) == 0111    assert tiers.row_cost(500, status=200, media_type="application/json", quota_exempt=True) == 0112    assert tiers.row_cost(500, status=404, media_type="application/json", quota_exempt=False) == 0113