from __future__ import annotations from pyxray.libs.nodes import parse_node_link from pyxray.libs.xray_config import XrayConfigSettings, generate_tinytun_config, write_tinytun_config_file def test_generate_tinytun_config_matches_v2raya_defaults() -> None: settings = XrayConfigSettings() node = parse_node_link(_ss_link("198.51.100.10")) config = generate_tinytun_config(node, settings, geosite_file="/data/geosite.dat") assert config["tun"] == { "name": "tun0", "ip": "198.18.0.1", "netmask": "255.255.255.255", "ipv6_mode": "auto", "ipv6": "fd00::1", "ipv6_prefix": 128, "auto_route": True, "mtu": 1500, } assert config["socks5"] == {"name": "proxy", "address": "127.0.0.1:52345"} assert "198.51.100.10" in config["filtering"]["skip_ips"] assert config["filtering"]["skip_networks"][:5] == ["127.0.0.0/8", "169.254.0.0/16", "::1/128", "fc00::/7", "fe80::/10"] assert config["filtering"]["block_ports"] == [22, 23, 25, 110, 143] assert config["filtering"]["allow_ports"] == [80, 443, 53] assert config["route"] == {"auto_detect_interface": True} def test_generate_tinytun_dns_groups_and_routing_from_dns_rules() -> None: settings = XrayConfigSettings() node = parse_node_link(_ss_link("ss.example.net")) config = generate_tinytun_config(node, settings, geosite_file="/data/geosite.dat") dns = config["dns"] assert dns["groups"][0] == {"name": "direct", "servers": ["223.5.5.5:53"], "strategy": "concurrent", "upstream": "direct", "protocol": "udp"} assert dns["groups"][1] == {"name": "proxy", "servers": ["8.8.8.8:53"], "strategy": "concurrent", "upstream": "proxy", "protocol": "udp"} assert "match(geosite:private),direct" in dns["routing"]["rules"] assert "match(geosite:cn),direct" in dns["routing"]["rules"] assert dns["routing"]["fallback_group"] == "proxy" assert dns["routing"]["geosite_file"] == "/data/geosite.dat" assert dns["routing"]["enable_cache"] is True assert dns["routing"]["cache_capacity"] == 4096 assert dns["hijack"] == {"enabled": False, "mark": 1, "table_id": 100, "capture_tcp": True} def test_write_tinytun_config_file_only_for_tun_mode(tmp_path) -> None: settings = XrayConfigSettings() node = parse_node_link(_ss_link("198.51.100.10")) assert write_tinytun_config_file(node, settings, tmp_path) is None settings.transparent.mode = "proxy" settings.transparent.type = "tun" settings.transparent.tun_auto_route = False settings.transparent.tun_bypass_interfaces = "172.17.0.0/16" settings.transparent.tun_exclude_processes = "/usr/bin/xray, pyxray" path = write_tinytun_config_file(node, settings, tmp_path, geosite_file="/data/geosite.dat") content = path.read_text(encoding="utf-8") assert path.name == "tinytun.yaml" assert "auto_route: false" in content assert "- 172.17.0.0/16" in content assert "- xray" in content assert "- pyxray" in content def _ss_link(host: str) -> str: return f"ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpzZWNyZXQ@{host}:8388#ss-node"