重构:模块化 RRPP Lite 并更新入口
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""拆分后 rrpp_core 的独立回归测试(不依赖 Qt 或真实代理连接)。"""
|
||||
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
LITE_DIR = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(LITE_DIR))
|
||||
|
||||
from rrpp_core.forwarder_primitives import (
|
||||
force_http_close,
|
||||
inject_proxy_auth,
|
||||
parse_connect_authority,
|
||||
parse_http_absolute,
|
||||
)
|
||||
from rrpp_core.node_api import NodeAuthError, b64url
|
||||
from rrpp_core.node_secrets import NodeSecretsStore
|
||||
from rrpp_core.network_primitives import is_private_host, is_private_ipv4_int, ttl_cache
|
||||
from rrpp_core.pac_data import atomic_write, read_version, validate_document
|
||||
from rrpp_core.routing_primitives import (
|
||||
build_suffix_trie,
|
||||
merge_ip_ranges,
|
||||
parse_domain_rules,
|
||||
suffix_trie_matches,
|
||||
)
|
||||
from rrpp_core.settings_store import JsonSettingsStore
|
||||
from rrpp_core.traffic import TrafficStats, format_bytes
|
||||
|
||||
|
||||
class CoreModuleTests(unittest.TestCase):
|
||||
def test_domain_rules_and_trie(self):
|
||||
suffixes, exact, regexes, invalid = parse_domain_rules(
|
||||
["example.com", "full:only.example", "regexp:^edge-[0-9]+\\.example$", "regexp:["]
|
||||
)
|
||||
self.assertEqual(invalid, 1)
|
||||
self.assertIn("example.com", suffixes)
|
||||
self.assertIn("only.example", exact)
|
||||
self.assertTrue(regexes[0].search("edge-42.example"))
|
||||
trie = build_suffix_trie(suffixes)
|
||||
self.assertTrue(suffix_trie_matches("cdn.example.com", trie))
|
||||
self.assertFalse(suffix_trie_matches("example.net", trie))
|
||||
self.assertEqual(
|
||||
merge_ip_ranges(["10.0.0.0/25", "10.0.0.128/25"], 4),
|
||||
[(167772160, 167772415)],
|
||||
)
|
||||
|
||||
def test_forwarder_primitives(self):
|
||||
self.assertEqual(
|
||||
parse_connect_authority("CONNECT [::1]:443 HTTP/1.1"), ("::1", 443)
|
||||
)
|
||||
self.assertEqual(
|
||||
parse_http_absolute("GET https://example.com/path HTTP/1.1"),
|
||||
("example.com", 443),
|
||||
)
|
||||
request = b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
|
||||
injected = inject_proxy_auth(request, "token")
|
||||
self.assertIn(b"Authorization: Basic token\r\n", injected)
|
||||
self.assertEqual(inject_proxy_auth(injected, "different"), injected)
|
||||
self.assertIn(b"Connection: close\r\n", force_http_close(request))
|
||||
|
||||
def test_settings_pac_and_node_secrets_storage(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
directory = Path(temporary)
|
||||
settings = JsonSettingsStore(lambda: directory / "settings.json")
|
||||
self.assertEqual(settings.load(), {})
|
||||
settings.save({"local_port": 1080})
|
||||
self.assertEqual(settings.load(), {"local_port": 1080})
|
||||
|
||||
payload = {"version": "1", "domains": ["example.com"]}
|
||||
atomic_write(directory, "pac_domains", payload)
|
||||
self.assertEqual(read_version(directory / "pac_domains.json"), ("1", ""))
|
||||
self.assertTrue(validate_document("pac_domains", payload))
|
||||
|
||||
secrets = NodeSecretsStore(lambda: directory)
|
||||
self.assertEqual(secrets.decrypt_bytes(secrets.encrypt_text("round-trip")), "round-trip")
|
||||
secrets.save_auth("test-user", "test-password")
|
||||
self.assertEqual(
|
||||
secrets.load_auth(), {"username": "test-user", "password": "test-password"}
|
||||
)
|
||||
|
||||
def test_traffic_and_node_protocol_helpers(self):
|
||||
times = iter((10.0, 12.0))
|
||||
stats = TrafficStats(clock=lambda: next(times))
|
||||
stats.reset()
|
||||
stats.add(up=20, down=10)
|
||||
self.assertEqual(stats.rate(), (10, 5, 20, 10))
|
||||
self.assertEqual(format_bytes(1536), "1.5 KB")
|
||||
self.assertEqual(b64url("a/b="), "YS9iPQ")
|
||||
error = NodeAuthError("denied", 403)
|
||||
self.assertEqual((str(error), error.code), ("denied", 403))
|
||||
|
||||
def test_network_primitives_and_ttl_cache(self):
|
||||
self.assertTrue(is_private_ipv4_int(0x0A010203))
|
||||
self.assertTrue(is_private_host("::1"))
|
||||
self.assertFalse(is_private_host("8.8.8.8"))
|
||||
calls = []
|
||||
|
||||
@ttl_cache(300)
|
||||
def probe(value):
|
||||
calls.append(value)
|
||||
return value
|
||||
|
||||
self.assertEqual((probe("x"), probe("x")), ("x", "x"))
|
||||
self.assertEqual(calls, ["x"])
|
||||
probe.cache_clear()
|
||||
probe("x")
|
||||
self.assertEqual(calls, ["x", "x"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
Reference in New Issue
Block a user