- Bump version 0.1.0 -> 0.3.0 - Add systemd service unit (config/s5p.service) and install-service Makefile target - Add CLI argument parsing tests (tests/test_cli.py, 27 tests) - Expand protocol tests with SOCKS5/4/HTTP handshake, error, and auth coverage (tests/test_proto.py, 30 tests) - Add full API reference to docs/USAGE.md with response schemas for all GET/POST endpoints - Update INSTALL.md, CHEATSHEET.md with systemd section - Update ROADMAP.md, TASKS.md for v0.3.0
154 lines
4.5 KiB
Python
154 lines
4.5 KiB
Python
"""Tests for CLI argument parsing."""
|
|
|
|
import pytest
|
|
|
|
from s5p import __version__
|
|
from s5p.cli import _parse_args
|
|
|
|
|
|
class TestDefaults:
|
|
"""Default argument values."""
|
|
|
|
def test_no_args(self):
|
|
args = _parse_args([])
|
|
assert args.config is None
|
|
assert args.listen is None
|
|
assert args.chain is None
|
|
assert args.timeout is None
|
|
assert args.retries is None
|
|
assert args.max_connections is None
|
|
assert args.verbose is False
|
|
assert args.quiet is False
|
|
assert args.proxy_source is None
|
|
assert args.api is None
|
|
assert args.cprofile is None
|
|
assert args.tracemalloc is None
|
|
|
|
|
|
class TestFlags:
|
|
"""Flag parsing."""
|
|
|
|
def test_verbose(self):
|
|
args = _parse_args(["-v"])
|
|
assert args.verbose is True
|
|
|
|
def test_quiet(self):
|
|
args = _parse_args(["-q"])
|
|
assert args.quiet is True
|
|
|
|
def test_config(self):
|
|
args = _parse_args(["-c", "s5p.yaml"])
|
|
assert args.config == "s5p.yaml"
|
|
|
|
def test_config_long(self):
|
|
args = _parse_args(["--config", "s5p.yaml"])
|
|
assert args.config == "s5p.yaml"
|
|
|
|
def test_listen(self):
|
|
args = _parse_args(["-l", "0.0.0.0:9999"])
|
|
assert args.listen == "0.0.0.0:9999"
|
|
|
|
def test_chain(self):
|
|
args = _parse_args(["-C", "socks5://127.0.0.1:9050"])
|
|
assert args.chain == "socks5://127.0.0.1:9050"
|
|
|
|
def test_chain_multi(self):
|
|
args = _parse_args(["-C", "socks5://a:1080,http://b:8080"])
|
|
assert args.chain == "socks5://a:1080,http://b:8080"
|
|
|
|
def test_timeout(self):
|
|
args = _parse_args(["-t", "30"])
|
|
assert args.timeout == 30.0
|
|
|
|
def test_retries(self):
|
|
args = _parse_args(["-r", "5"])
|
|
assert args.retries == 5
|
|
|
|
def test_max_connections(self):
|
|
args = _parse_args(["-m", "512"])
|
|
assert args.max_connections == 512
|
|
|
|
def test_proxy_source(self):
|
|
args = _parse_args(["-S", "http://api:8081/proxies"])
|
|
assert args.proxy_source == "http://api:8081/proxies"
|
|
|
|
def test_api(self):
|
|
args = _parse_args(["--api", "127.0.0.1:1081"])
|
|
assert args.api == "127.0.0.1:1081"
|
|
|
|
def test_cprofile_default(self):
|
|
args = _parse_args(["--cprofile"])
|
|
assert args.cprofile == "s5p.prof"
|
|
|
|
def test_cprofile_custom(self):
|
|
args = _parse_args(["--cprofile", "out.prof"])
|
|
assert args.cprofile == "out.prof"
|
|
|
|
def test_tracemalloc_default(self):
|
|
args = _parse_args(["--tracemalloc"])
|
|
assert args.tracemalloc == 10
|
|
|
|
def test_tracemalloc_custom(self):
|
|
args = _parse_args(["--tracemalloc", "20"])
|
|
assert args.tracemalloc == 20
|
|
|
|
|
|
class TestVersion:
|
|
"""--version flag."""
|
|
|
|
def test_version_output(self, capsys):
|
|
with pytest.raises(SystemExit, match="0"):
|
|
_parse_args(["--version"])
|
|
captured = capsys.readouterr()
|
|
assert captured.out.strip() == f"s5p {__version__}"
|
|
|
|
def test_version_short(self, capsys):
|
|
with pytest.raises(SystemExit, match="0"):
|
|
_parse_args(["-V"])
|
|
captured = capsys.readouterr()
|
|
assert "0.3.0" in captured.out
|
|
|
|
|
|
class TestCombinations:
|
|
"""Multiple flags together."""
|
|
|
|
def test_verbose_with_chain(self):
|
|
args = _parse_args(["-v", "-C", "socks5://tor:9050"])
|
|
assert args.verbose is True
|
|
assert args.chain == "socks5://tor:9050"
|
|
|
|
def test_config_with_api(self):
|
|
args = _parse_args(["-c", "s5p.yaml", "--api", "0.0.0.0:1090"])
|
|
assert args.config == "s5p.yaml"
|
|
assert args.api == "0.0.0.0:1090"
|
|
|
|
def test_listen_with_timeout_and_retries(self):
|
|
args = _parse_args(["-l", ":8080", "-t", "15", "-r", "3"])
|
|
assert args.listen == ":8080"
|
|
assert args.timeout == 15.0
|
|
assert args.retries == 3
|
|
|
|
|
|
class TestInvalid:
|
|
"""Invalid argument handling."""
|
|
|
|
def test_unknown_flag(self):
|
|
with pytest.raises(SystemExit, match="2"):
|
|
_parse_args(["--nonexistent"])
|
|
|
|
def test_timeout_non_numeric(self):
|
|
with pytest.raises(SystemExit, match="2"):
|
|
_parse_args(["-t", "abc"])
|
|
|
|
def test_retries_non_numeric(self):
|
|
with pytest.raises(SystemExit, match="2"):
|
|
_parse_args(["-r", "abc"])
|
|
|
|
def test_max_connections_non_numeric(self):
|
|
with pytest.raises(SystemExit, match="2"):
|
|
_parse_args(["-m", "abc"])
|
|
|
|
def test_tracemalloc_non_numeric(self):
|
|
with pytest.raises(SystemExit, match="2"):
|
|
_parse_args(["--tracemalloc", "abc"])
|