fix(proxy-client): замечания слепого ревью
- state.json снова хранит адрес и порт: при смене конфига у работающего Xray status/env/run отказывают и советуют перезапустить start. - Ошибки разбора ссылки называют файл профиля. - Тесты: отказ start при чужой версии Xray, ключи REALITY не попадают в вывод, Xray узнаётся после замены файла; машинный конфиг проверяется через CLI; тест пути по умолчанию не зависит от доступности Hiddify. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
5ccc75419d
commit
09f57aa1e7
3 files changed
+168
-56
No files matched your search
+40
-34
@@ -152,8 +152,12 @@ class ExternalProxyCliTest(unittest.TestCase):
|
||||
self.assertIn("только для type=xray", result.stderr)
|
||||
|
||||
def test_missing_config_uses_hiddify_default(self):
|
||||
# Доступен ли Hiddify на этой машине, неважно: и отчёт о доступности,
|
||||
# и ошибка называют адрес по умолчанию.
|
||||
result = self.run_cli("status", PROXY_PREFLIGHT_TIMEOUT="0.05")
|
||||
self.assertIn("Hiddify (hproxy.local:12334)", result.stderr)
|
||||
output = result.stdout + result.stderr
|
||||
self.assertIn("Hiddify", output)
|
||||
self.assertIn("hproxy.local:12334", output)
|
||||
|
||||
def test_broken_config_symlink_is_an_error(self):
|
||||
self.config_dir.mkdir()
|
||||
@@ -178,24 +182,37 @@ class ExternalProxyCliTest(unittest.TestCase):
|
||||
self.assertIn("положительным числом", result.stderr)
|
||||
|
||||
|
||||
class MachineConfigTest(unittest.TestCase):
|
||||
class MachineConfigCliTest(unittest.TestCase):
|
||||
"""Машинный конфиг проверяем через команду: код выхода и путь в ошибке."""
|
||||
|
||||
VALID = (
|
||||
"[proxy]\ntype = external\nname = Test\naddress = 127.0.0.1\n"
|
||||
"port = 12334\nno_proxy_extra =\n"
|
||||
)
|
||||
|
||||
def parse(self, text):
|
||||
return MODULE["parse_config"](text)
|
||||
def setUp(self):
|
||||
temporary = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(temporary.cleanup)
|
||||
self.root = Path(temporary.name)
|
||||
self.path = self.root / "proxy-client/config"
|
||||
self.path.parent.mkdir()
|
||||
|
||||
def test_valid_config(self):
|
||||
config = self.parse(self.VALID.replace("no_proxy_extra =", "no_proxy_extra = a, b"))
|
||||
self.assertEqual(
|
||||
("external", "Test", "127.0.0.1", 12334, ("a", "b")),
|
||||
(config.proxy_type, config.name, config.address, config.port, config.no_proxy_extra),
|
||||
def start_with(self, text):
|
||||
# start с type=external отказывает сразу после чтения конфига:
|
||||
# сеть и Xray не нужны.
|
||||
self.path.write_text(text, encoding="utf-8")
|
||||
return subprocess.run(
|
||||
[str(CLI), "start"],
|
||||
env=dict(os.environ, XDG_CONFIG_HOME=str(self.root), PYTHONDONTWRITEBYTECODE="1"),
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=15,
|
||||
check=False,
|
||||
)
|
||||
|
||||
def test_invalid_structure_and_values(self):
|
||||
def test_invalid_configs_are_rejected_with_path(self):
|
||||
cases = {
|
||||
"not ini": "not an ini\n",
|
||||
"unknown section": self.VALID + "[other]\nkey = value\n",
|
||||
"unknown key": self.VALID + "extra = value\n",
|
||||
"duplicate key": self.VALID + "port = 12335\n",
|
||||
@@ -210,33 +227,20 @@ class MachineConfigTest(unittest.TestCase):
|
||||
"no_proxy_extra =", "no_proxy_extra = one.example,,two.example"
|
||||
),
|
||||
}
|
||||
for label, text in cases.items():
|
||||
with self.subTest(label):
|
||||
# Ошибки синтаксиса INI приходят от configparser; load_config
|
||||
# добавляет к ним путь к файлу.
|
||||
with self.assertRaises((ProxyError, MODULE["configparser"].Error)):
|
||||
self.parse(text)
|
||||
|
||||
def test_addresses(self):
|
||||
for address in ("127.0.0.1", "2001:db8::1", "proxy-1.example", "trailing.example."):
|
||||
with self.subTest(address):
|
||||
self.assertEqual(
|
||||
address, self.parse(self.VALID.replace("127.0.0.1", address)).address
|
||||
)
|
||||
for address in ("http://proxy", "[::1]", "has space", "proxy/path", "user@proxy",
|
||||
"прокси.example", "fe80::1%eth0"):
|
||||
with self.subTest(address):
|
||||
with self.assertRaisesRegex(ProxyError, "address"):
|
||||
self.parse(self.VALID.replace("127.0.0.1", address))
|
||||
cases["address " + address] = self.VALID.replace("127.0.0.1", address)
|
||||
for label, text in cases.items():
|
||||
with self.subTest(label):
|
||||
result = self.start_with(text)
|
||||
self.assertEqual(1, result.returncode)
|
||||
self.assertIn("Ошибка: машинный конфиг {}:".format(self.path), result.stderr)
|
||||
|
||||
def test_load_error_names_config_file(self):
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
path = Path(root) / "proxy-client/config"
|
||||
path.parent.mkdir()
|
||||
path.write_text("not an ini\n", encoding="utf-8")
|
||||
with mock.patch.dict(os.environ, {"XDG_CONFIG_HOME": root}):
|
||||
with self.assertRaisesRegex(ProxyError, str(path)):
|
||||
MODULE["load_config"]()
|
||||
def test_valid_addresses_are_accepted(self):
|
||||
for address in ("127.0.0.1", "2001:db8::1", "proxy-1.example", "trailing.example."):
|
||||
with self.subTest(address):
|
||||
result = self.start_with(self.VALID.replace("127.0.0.1", address))
|
||||
self.assertIn("только для type=xray", result.stderr)
|
||||
|
||||
|
||||
UUID = "11111111-2222-4333-8444-555555555555"
|
||||
@@ -538,6 +542,8 @@ class XrayInstallTest(unittest.TestCase):
|
||||
"supervisor_pid": os.getpid(),
|
||||
"xray_pid": os.getpid(),
|
||||
"xray_path": os.path.realpath("/proc/self/exe"),
|
||||
"address": "127.0.0.1",
|
||||
"port": 1,
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
|
||||
Reference in new issue
Block a user