Files
s5p/tests/test_cli.py
user a741c0a017
All checks were successful
ci / secrets (push) Successful in 9s
ci / test (push) Successful in 20s
ci / build (push) Successful in 15s
feat: v0.3.0 stabilization -- systemd, tests, API docs
- 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
2026-02-21 18:35:51 +01:00

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"])