#!/usr/bin/env python3 """Список исключений прокси лежит в нескольких профилях (Bash, PowerShell, Codex, VS Code). Раньше копии расходились, и один и тот же хост то шёл мимо прокси, то нет. Тест сверяет каждую копию с эталоном из proxy-client.""" import re import runpy import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] CLI = REPO_ROOT / "proxy-client/.local/bin/proxy-client" # Где список продублирован: файл -> (регулярное выражение, начало строки, # которое в файле подставляется переменной и потому не попадает в захват). COPIES = ( ("chezmoi/dot_codex/dot_env", re.compile(r"^NO_PROXY=(.+)$", re.M), ""), ("chezmoi/dot_codex/dot_env", re.compile(r"^no_proxy=(.+)$", re.M), ""), ( "chezmoi/dot_config/powershell/profile.ps1", re.compile(r"^\s*NoProxy\s*=\s*'(.+)'\s*$", re.M), "", ), ( "chezmoi/dot_local/bin/start-claude-proxy.ps1", re.compile(r'^\$NoProxy = "\$\{ProxyHostName\},(.+)"\s*$', re.M), "hproxy.local,", ), ( "vscode/.vscode-server/server-env-setup", re.compile(r'^\s*export NO_PROXY="(.+)"\s*$', re.M), "", ), ) # Списки обхода для Windows: тот же смысл, другой синтаксис (точка с запятой, # поддомены звёздочкой), поэтому сверяем их только между собой. BYPASS_FILES = ( "chezmoi/dot_local/bin/start-claude-proxy.ps1", "chezmoi/dot_local/bin/start-codex-proxy.ps1", ) BYPASS_RE = re.compile(r'^\$ProxyBypassList = "\$\{ProxyHostName\};(.+)"\s*$', re.M) def expected_no_proxy(): """Эталон — то, что proxy-client выдаёт в режиме по умолчанию.""" module = runpy.run_path(str(CLI)) items = [module["DEFAULT_ADDRESS"], "localhost", "127.0.0.1", "::1", "[::1]"] items.extend(module["DEFAULT_NO_PROXY_EXTRA"]) return ",".join(dict.fromkeys(items)) class NoProxySyncTest(unittest.TestCase): def test_copies_match_proxy_client(self): expected = expected_no_proxy() for relative_path, pattern, prefix in COPIES: text = (REPO_ROOT / relative_path).read_text(encoding="utf-8") match = pattern.search(text) self.assertIsNotNone( match, "{}: не найден список исключений".format(relative_path) ) self.assertEqual( expected, prefix + match.group(1), "{}: список разошёлся".format(relative_path), ) def test_windows_bypass_lists_match_each_other(self): values = [] for relative_path in BYPASS_FILES: text = (REPO_ROOT / relative_path).read_text(encoding="utf-8") match = BYPASS_RE.search(text) self.assertIsNotNone( match, "{}: не найден ProxyBypassList".format(relative_path) ) values.append(match.group(1)) self.assertEqual(values[0], values[1], "ProxyBypassList разошёлся") if __name__ == "__main__": unittest.main()