from __future__ import annotations import pytest import server_service from server_service import ServerConfig, ServerService from transport_server import TransportAwareFalloutTogetherServer class FakeCoreServer: def __init__(self, port: int = 7777): self.port = port class FakeTransport: instances = [] local_port_override = None def __init__(self, host, port, *, library_path=None): self.host = host self.requested_port = port self.library_path = library_path self.local_port = self.local_port_override or port self.closed = False self.__class__.instances.append(self) def close(self): self.closed = True class FakeAdapter: instances = [] def __init__(self, core, transport): self.core = core self.transport = transport self.started = False self.stopped = False self.__class__.instances.append(self) def start(self): self.started = True def stop(self): self.stopped = True self.transport.close() def reset_fakes(): FakeTransport.instances.clear() FakeTransport.local_port_override = None FakeAdapter.instances.clear() def test_server_service_uses_transport_aware_core_with_gns_disabled_by_default(tmp_path): config = ServerConfig(bans_path=str(tmp_path / "bans.json")) assert not config.enable_gns_transport service = ServerService(config) core = service._create_server() assert isinstance(core, TransportAwareFalloutTogetherServer) def test_gns_feature_flag_is_noop_when_disabled(monkeypatch): reset_fakes() monkeypatch.setattr(server_service, "GnsServerTransport", FakeTransport) monkeypatch.setattr(server_service, "GnsGameplayAdapter", FakeAdapter) service = ServerService(ServerConfig(enable_gns_transport=False)) service._server = FakeCoreServer() service._start_gns() assert service._gns_adapter is None assert FakeTransport.instances == [] assert FakeAdapter.instances == [] def test_gns_feature_flag_starts_udp_on_same_numeric_port_and_stops_cleanly(monkeypatch): reset_fakes() monkeypatch.setattr(server_service, "GnsServerTransport", FakeTransport) monkeypatch.setattr(server_service, "GnsGameplayAdapter", FakeAdapter) service = ServerService( ServerConfig( host="127.0.0.1", port=7777, enable_gns_transport=True, gns_bridge_path="/opt/commonwealth/libcommonwealth_online_gns_bridge.so", ) ) service._server = FakeCoreServer(7777) service._start_gns() assert len(FakeTransport.instances) == 1 transport = FakeTransport.instances[0] assert transport.host == "127.0.0.1" assert transport.requested_port == 7777 assert transport.library_path == "/opt/commonwealth/libcommonwealth_online_gns_bridge.so" assert len(FakeAdapter.instances) == 1 adapter = FakeAdapter.instances[0] assert adapter.started assert service._gns_adapter is adapter service._stop_gns() assert adapter.stopped assert transport.closed assert service._gns_adapter is None def test_gns_start_rejects_native_bridge_bound_to_wrong_udp_port(monkeypatch): reset_fakes() FakeTransport.local_port_override = 8888 monkeypatch.setattr(server_service, "GnsServerTransport", FakeTransport) monkeypatch.setattr(server_service, "GnsGameplayAdapter", FakeAdapter) service = ServerService(ServerConfig(port=7777, enable_gns_transport=True)) service._server = FakeCoreServer(7777) with pytest.raises(RuntimeError, match="expected UDP 7777"): service._start_gns() assert len(FakeTransport.instances) == 1 assert FakeTransport.instances[0].closed assert FakeAdapter.instances == [] assert service._gns_adapter is None