feat: listener retry override, pool protocol filter, conn pool docs

- Per-listener `retries` overrides global default (0 = inherit)
- Pool-level `allowed_protos` filters proxies during merge
- Connection pooling documented in CHEATSHEET.md
- Both features exposed in /config and /status API responses
- 12 new tests (config parsing, API exposure, merge filtering)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-21 20:35:14 +01:00
parent c1c92ddc39
commit 3593481b30
13 changed files with 674 additions and 120 deletions

View File

@@ -307,6 +307,39 @@ class TestProxyPools:
assert c.listeners[1].pool_hops == 0
class TestAllowedProtos:
"""Test pool-level allowed_protos config."""
def test_allowed_protos_from_yaml(self, tmp_path):
cfg_file = tmp_path / "test.yaml"
cfg_file.write_text(
"proxy_pools:\n"
" socks_only:\n"
" sources: []\n"
" allowed_protos: [socks5]\n"
" any:\n"
" sources: []\n"
)
c = load_config(cfg_file)
assert c.proxy_pools["socks_only"].allowed_protos == ["socks5"]
assert c.proxy_pools["any"].allowed_protos == []
def test_allowed_protos_multiple(self, tmp_path):
cfg_file = tmp_path / "test.yaml"
cfg_file.write_text(
"proxy_pool:\n"
" sources: []\n"
" allowed_protos: [socks5, http]\n"
)
c = load_config(cfg_file)
assert c.proxy_pool.allowed_protos == ["socks5", "http"]
def test_allowed_protos_default_empty(self):
from s5p.config import ProxyPoolConfig
cfg = ProxyPoolConfig()
assert cfg.allowed_protos == []
class TestTorNodes:
"""Test tor_nodes config parsing."""
@@ -593,6 +626,40 @@ class TestListenerPoolCompat:
assert lc.pool_hops == 0
class TestListenerRetries:
"""Test per-listener retry override config."""
def test_retries_default(self):
lc = ListenerConfig()
assert lc.retries == 0
def test_retries_from_yaml(self, tmp_path):
cfg_file = tmp_path / "test.yaml"
cfg_file.write_text(
"listeners:\n"
" - listen: 1080\n"
" retries: 5\n"
" chain:\n"
" - socks5://127.0.0.1:9050\n"
" - pool\n"
" - listen: 1081\n"
" chain:\n"
" - socks5://127.0.0.1:9050\n"
)
c = load_config(cfg_file)
assert c.listeners[0].retries == 5
assert c.listeners[1].retries == 0
def test_retries_absent_from_yaml(self, tmp_path):
cfg_file = tmp_path / "test.yaml"
cfg_file.write_text(
"listeners:\n"
" - listen: 1080\n"
)
c = load_config(cfg_file)
assert c.listeners[0].retries == 0
class TestAuthConfig:
"""Test auth field in listener config."""