release: prepare 0.2.0 for sing-box 1.14

This commit is contained in:
2026-09-08 19:26:00 +05:00
parent 81ea89f7fa
commit 76dce5b47a
42 changed files with 1634 additions and 549 deletions
+31 -2
View File
@@ -5,18 +5,30 @@ import tempfile
import unittest
from pathlib import Path
from vpn_egressctl.renderer_1_13_19 import render_bytes, render_config
from vpn_egressctl.renderer_1_14_0 import render_bytes, render_config
from vpn_egressctl.uri import parse_hysteria2_uri
from tests.helpers import make_policy
class RendererTests(unittest.TestCase):
def test_gecko_golden_fixture(self) -> None:
with tempfile.TemporaryDirectory() as directory:
actual = render_bytes(
make_policy(Path(directory)),
parse_hysteria2_uri(
"hysteria2://AUTH@fi.api.withen.pro:443/"
"?insecure=0&obfs=gecko&obfs-password=OBFS"
),
)
expected = Path("tests/fixtures/sing-box-1.14.0-gecko.json").read_bytes()
self.assertEqual(actual, expected)
def test_complete_production_shape(self) -> None:
with tempfile.TemporaryDirectory() as directory:
policy = make_policy(Path(directory))
endpoint = parse_hysteria2_uri(
"hysteria2://AUTH@fi.api.withen.pro:443/?insecure=0&obfs=salamander&obfs-password=OBFS"
"hysteria2://AUTH@fi.api.withen.pro:443/?insecure=0&obfs=gecko&obfs-password=OBFS"
)
config = render_config(policy, endpoint)
self.assertEqual(list(config), ["log", "dns", "inbounds", "outbounds", "route"])
@@ -26,16 +38,33 @@ class RendererTests(unittest.TestCase):
self.assertEqual(tun["auto_redirect_input_mark"], "0x2023")
self.assertEqual(tun["auto_redirect_output_mark"], "0x2024")
self.assertEqual(tun["auto_redirect_reset_mark"], "0x2025")
self.assertEqual(tun["dns_mode"], "disabled")
outbound = config["outbounds"][0]
self.assertEqual(outbound["server"], "fi.api.withen.pro")
self.assertEqual(outbound["password"], "AUTH")
self.assertEqual(outbound["obfs"]["password"], "OBFS")
self.assertEqual(outbound["obfs"]["type"], "gecko")
self.assertEqual(outbound["obfs"]["min_packet_size"], 512)
self.assertEqual(outbound["obfs"]["max_packet_size"], 1200)
self.assertFalse(outbound["disable_chrome_parrot"])
self.assertNotIn("bbr_profile", outbound)
self.assertEqual(outbound["bind_interface"], "eth0")
self.assertEqual([item["tag"] for item in config["outbounds"]], ["hy2-out"])
self.assertEqual(config["dns"]["servers"][1]["detour"], "hy2-out")
self.assertEqual(config["route"]["final"], "hy2-out")
self.assertNotIn("185.156.108.141", render_bytes(policy, endpoint).decode())
def test_salamander_fallback_does_not_render_gecko_fields(self) -> None:
with tempfile.TemporaryDirectory() as directory:
config = render_config(
make_policy(Path(directory)),
parse_hysteria2_uri(
"hy2://auth@example.com?obfs=salamander&obfs-password=legacy"
),
)
obfs = config["outbounds"][0]["obfs"]
self.assertEqual(obfs, {"type": "salamander", "password": "legacy"})
def test_multi_port_mapping(self) -> None:
with tempfile.TemporaryDirectory() as directory:
config = render_config(