login: sync def so the 0.5s brute-force sleep runs on the threadpool, not the event loop (+latency regression test)

This commit is contained in:
jozamudi committed 2026-09-16 00:49:22 +00:00
1 parent 9a4b8fb299
commit 673aca827f
2 files changed
+29 -1

No files matched your search

+24
View File
@@ -71,6 +71,30 @@ def test_wrong_password(base=BASE):
assert req("POST", "/login", {"username": "admin", "password": "nope"}, base=base) == 401
def test_wrong_password_does_not_stall_event_loop(base=BASE):
# regression: login was async def, so the 0.5s anti-brute-force sleep ran
# ON the event loop and stalled every in-flight request. With the sync
# handler the sleep runs on the threadpool and /api/cdn answers instantly
# while a wrong-password login is still sleeping.
import threading
import time as _time
done = threading.Event()
def slow_fail():
req("POST", "/login", {"username": "loop-probe", "password": "wrong12345"}, base=base)
done.set()
t = threading.Thread(target=slow_fail, daemon=True)
t.start()
_time.sleep(0.05) # let the login reach its sleep
t0 = _time.time()
assert req("GET", "/api/cdn", base=base) == 200
dt = _time.time() - t0
done.wait(timeout=5)
t.join(timeout=5)
assert dt < 0.3, f"/api/cdn took {dt:.2f}s — login's sleep blocked the loop"
def test_login_and_access(base=BASE):
jar = login("admin", "adminpw12345", base)
assert req("GET", "/api/search?q=x", jar=jar, base=base) == 200