|
| 1 | +"""Run the production route application against a synchronous MTContext fixture.""" |
| 2 | +import pathlib |
| 3 | +import subprocess |
| 4 | +import tempfile |
| 5 | + |
| 6 | +root = pathlib.Path(__file__).resolve().parents[2] |
| 7 | +source = (root / 'submodules/TelegramCore/Sources/Settings/ProxySettings.swift').read_text(encoding='utf-8') |
| 8 | +start = source.index('func applySharedProxySettingsToNetwork(') |
| 9 | +apply = source[start:source.index('\n}\n', start) + 2] |
| 10 | +fixtures = r''' |
| 11 | +import Foundation |
| 12 | +final class MTSocksProxySettings: NSObject { |
| 13 | + let id: String |
| 14 | + init(_ id: String) { self.id = id } |
| 15 | + override func isEqual(_ object: Any?) -> Bool { |
| 16 | + return (object as? MTSocksProxySettings)?.id == self.id |
| 17 | + } |
| 18 | +} |
| 19 | +struct Connection { |
| 20 | + var isWebProxy = false |
| 21 | + var isVlessProxy = false |
| 22 | +} |
| 23 | +struct ProxyServerSettings { |
| 24 | + static let managedBootstrapProxySettings = MTSocksProxySettings("blocked") |
| 25 | + var connection: Connection |
| 26 | + var webProxyConfiguration: String? = nil |
| 27 | + var vlessProxyURL: String? = nil |
| 28 | + var mtProxySettings: MTSocksProxySettings? = nil |
| 29 | +} |
| 30 | +struct ProxySettings { |
| 31 | + var useLocalDNSForProxyHosts = false |
| 32 | + var effectiveActiveServer: ProxyServerSettings? |
| 33 | +} |
| 34 | +final class WebProxyManager { |
| 35 | + static let shared = WebProxyManager() |
| 36 | + func configure(activeWebProxy: String?) {} |
| 37 | + func isReady(for configuration: String) -> Bool { true } |
| 38 | +} |
| 39 | +final class VlessManager { |
| 40 | + static let shared = VlessManager() |
| 41 | + func configure(activeProfileURL: String?) {} |
| 42 | +} |
| 43 | +final class Environment { |
| 44 | + let socksProxySettings: MTSocksProxySettings? |
| 45 | + init(_ route: MTSocksProxySettings?) { self.socksProxySettings = route } |
| 46 | + func withUpdatedSocksProxySettings(_ route: MTSocksProxySettings?) -> Environment { |
| 47 | + return Environment(route) |
| 48 | + } |
| 49 | +} |
| 50 | +final class Context { |
| 51 | + var forceLocalDNS = false |
| 52 | + var environment = Environment(nil) |
| 53 | + var updates = 0 |
| 54 | + func updateApiEnvironment(_ f: (Environment?) -> Environment?) { |
| 55 | + if let updated = f(environment) { environment = updated; updates += 1 } |
| 56 | + } |
| 57 | +} |
| 58 | +final class Network { |
| 59 | + let context = Context() |
| 60 | + var paused = false |
| 61 | + var resumedRoutes: [String] = [] |
| 62 | + var drops = 0 |
| 63 | + func pauseForWebProxyBootstrap() { paused = true } |
| 64 | + func resumeIfWebProxyBootstrapPaused() { |
| 65 | + if paused { resumedRoutes.append(context.environment.socksProxySettings?.id ?? "direct") } |
| 66 | + paused = false |
| 67 | + } |
| 68 | + func dropConnectionStatus() { drops += 1 } |
| 69 | + func rebuildTransport() {} |
| 70 | +} |
| 71 | +''' |
| 72 | +tests = r''' |
| 73 | +for web in [false, true] { |
| 74 | + for previous in [nil, "old-remote-proxy", "old-loopback-profile", "blocked"] as [String?] { |
| 75 | + let network = Network() |
| 76 | + network.context.environment = Environment(previous.map { MTSocksProxySettings($0) }) |
| 77 | + var server = ProxyServerSettings(connection: Connection(isWebProxy: web, isVlessProxy: !web)) |
| 78 | + var settings = ProxySettings(effectiveActiveServer: server) |
| 79 | + applySharedProxySettingsToNetwork(settings: settings, network: network) |
| 80 | + precondition(network.paused) |
| 81 | + precondition(network.context.environment.socksProxySettings?.id == "blocked") |
| 82 | + precondition(network.resumedRoutes.isEmpty) |
| 83 | + let updates = network.context.updates |
| 84 | + for _ in 0..<100 { applySharedProxySettingsToNetwork(settings: settings, network: network) } |
| 85 | + precondition(network.context.updates == updates, "Repeated bootstrap rebuilt the route") |
| 86 | +
|
| 87 | + server.mtProxySettings = MTSocksProxySettings("new-loopback-profile") |
| 88 | + settings.effectiveActiveServer = server |
| 89 | + applySharedProxySettingsToNetwork(settings: settings, network: network) |
| 90 | + precondition(!network.paused) |
| 91 | + precondition(network.resumedRoutes == ["new-loopback-profile"], "Resumed before route update") |
| 92 | + settings.effectiveActiveServer = nil |
| 93 | + applySharedProxySettingsToNetwork(settings: settings, network: network) |
| 94 | + precondition(network.context.environment.socksProxySettings == nil) |
| 95 | + } |
| 96 | +} |
| 97 | +print("Managed bootstrap: previous routes blocked, repeated events coalesced, ready route installed before resume") |
| 98 | +''' |
| 99 | +with tempfile.TemporaryDirectory(prefix='managed-bootstrap-') as tmp: |
| 100 | + file = pathlib.Path(tmp) / 'main.swift' |
| 101 | + file.write_text(fixtures + apply + tests, encoding='utf-8') |
| 102 | + subprocess.run(['swift', str(file)], check=True) |
0 commit comments