"""Tests for config advisor — TDD: tests before implementation.""" import pytest from i2p_apps.setup.local_probe import LocalProbeResult from i2p_apps.setup.stun_probe import NatProbeResult from i2p_apps.setup.network_probe import ( BandwidthEstimate, DnsProbeResult, LatencyProbeResult, NetworkProbeResult, ) from i2p_apps.setup.config_advisor import ConfigRecommendation, advise def _local(crypto=15000, ram=8_000_000_000, total_ram=16_000_000_000, cpus=8, disk=200.0, disk_free=100_000_000_000): return LocalProbeResult( crypto_ops_per_sec=crypto, available_ram_bytes=ram, total_ram_bytes=total_ram, cpu_count=cpus, disk_write_mbps=disk, disk_free_bytes=disk_free, ) def _nat(present=True, nat_type="cone", ip="203.0.113.42", port=54321): return NatProbeResult( nat_present=present, nat_type=nat_type, external_ip=ip, external_port=port, servers_reached=2, ) def _network(bw_mbps=12.0): return NetworkProbeResult( dns=DnsProbeResult(True, True, True, 10.0), latency=LatencyProbeResult(45.0, 8.0, 3, 3), bandwidth=BandwidthEstimate(bw_mbps, "cdn_download") if bw_mbps else None, reseed_reachable=True, ) class TestAdvise: def test_returns_config_recommendation(self): result = advise(_local()) assert isinstance(result, ConfigRecommendation) def test_high_cpu_gets_more_tunnels(self): low = advise(_local(crypto=1000)) high = advise(_local(crypto=60000)) assert high.inbound_tunnel_count > low.inbound_tunnel_count def test_symmetric_nat_disables_upnp(self): result = advise(_local(), nat=_nat(nat_type="symmetric")) assert result.upnp_enabled is False assert any("ymmetric" in w for w in result.warnings) def test_cone_nat_enables_upnp(self): result = advise(_local(), nat=_nat(nat_type="cone")) assert result.upnp_enabled is True def test_open_internet_no_upnp(self): result = advise(_local(), nat=_nat(present=False, nat_type="open")) assert result.upnp_enabled is False def test_high_bandwidth_high_share(self): result = advise(_local(), network=_network(bw_mbps=100.0)) assert result.share_percentage >= 60 assert result.bandwidth_limit_kbps > 0 def test_low_bandwidth_low_share(self): result = advise(_local(), network=_network(bw_mbps=0.5)) assert result.share_percentage <= 40 def test_no_network_uses_defaults(self): result = advise(_local()) assert result.share_percentage == 50 assert result.bandwidth_limit_kbps == 0 def test_floodfill_requires_good_cpu_and_bandwidth(self): # High CPU + high bandwidth + cone NAT = floodfill result = advise( _local(crypto=60000), nat=_nat(nat_type="cone"), network=_network(bw_mbps=100.0), ) assert result.floodfill is True def test_symmetric_nat_blocks_floodfill(self): result = advise( _local(crypto=60000), nat=_nat(nat_type="symmetric"), network=_network(bw_mbps=100.0), ) assert result.floodfill is False def test_low_cpu_blocks_floodfill(self): result = advise( _local(crypto=1000), nat=_nat(nat_type="cone"), network=_network(bw_mbps=100.0), ) assert result.floodfill is False def test_listen_port_default(self): result = advise(_local()) assert isinstance(result.listen_port, int) assert result.listen_port > 0 def test_to_router_config_overrides(self): result = advise(_local(), nat=_nat(), network=_network()) overrides = result.to_router_config_overrides() assert isinstance(overrides, dict) assert "bandwidth_limit_kbps" in overrides assert "share_percentage" in overrides