85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Regression tests for bounded DNS address fallback in the updater transport."""
|
|
|
|
import importlib.util
|
|
import pathlib
|
|
import socket
|
|
|
|
|
|
def load_module():
|
|
script_path = (
|
|
pathlib.Path(__file__).resolve().parents[1]
|
|
/ "resources"
|
|
/ "scripts"
|
|
/ "nap_install.py"
|
|
)
|
|
spec = importlib.util.spec_from_file_location(
|
|
"nap_install_address_fallback_test", script_path
|
|
)
|
|
module = importlib.util.module_from_spec(spec)
|
|
assert spec and spec.loader
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
class FakeSocket:
|
|
def __init__(self, family, attempts, failing_addresses):
|
|
self.family = family
|
|
self.attempts = attempts
|
|
self.failing_addresses = failing_addresses
|
|
self.timeouts = []
|
|
self.closed = False
|
|
|
|
def settimeout(self, value):
|
|
self.timeouts.append(value)
|
|
|
|
def bind(self, _address):
|
|
return None
|
|
|
|
def connect(self, address):
|
|
self.attempts.append((self.family, address[0]))
|
|
if address[0] in self.failing_addresses:
|
|
raise TimeoutError("unreachable test address")
|
|
|
|
def close(self):
|
|
self.closed = True
|
|
|
|
|
|
def test_updater_prefers_ipv4_and_bounds_failed_addresses():
|
|
mod = load_module()
|
|
attempts = []
|
|
sockets = []
|
|
|
|
def resolver(_host, port, _family, _socktype):
|
|
return [
|
|
(socket.AF_INET6, socket.SOCK_STREAM, 6, "", ("2001:db8::1", port, 0, 0)),
|
|
(socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.1", port)),
|
|
(socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.2", port)),
|
|
]
|
|
|
|
def factory(family, _socktype, _proto):
|
|
created = FakeSocket(family, attempts, {"192.0.2.1"})
|
|
sockets.append(created)
|
|
return created
|
|
|
|
connected = mod.connect_with_address_fallback(
|
|
("api.example.test", 443),
|
|
timeout=30,
|
|
resolver=resolver,
|
|
socket_factory=factory,
|
|
)
|
|
|
|
assert connected is sockets[1]
|
|
assert attempts == [
|
|
(socket.AF_INET, "192.0.2.1"),
|
|
(socket.AF_INET, "192.0.2.2"),
|
|
]
|
|
assert sockets[0].timeouts == [mod.API_CONNECT_ATTEMPT_TIMEOUT_SECONDS]
|
|
assert sockets[0].closed
|
|
assert sockets[1].timeouts == [mod.API_CONNECT_ATTEMPT_TIMEOUT_SECONDS, 30.0]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
test_updater_prefers_ipv4_and_bounds_failed_addresses()
|
|
print("ok: updater connection address fallback tests passed")
|