using System; using System.Collections; using UnityEngine; using UnityEngine.TestTools; using NUnit.Framework; namespace Unity.Netcode.RuntimeTests { public class NetworkManagerTransportTests { [Test] public void ClientDoesNotStartWhenTransportFails() { bool callbackInvoked = false; Action onTransportFailure = () => { callbackInvoked = true; }; var manager = new GameObject().AddComponent(); manager.OnTransportFailure += onTransportFailure; var transport = manager.gameObject.AddComponent(); transport.FailOnStart = true; manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport }; LogAssert.Expect(LogType.Error, $"Client is shutting down due to network transport start failure of {transport.GetType().Name}!"); Assert.False(manager.StartClient()); Assert.False(manager.IsListening); Assert.False(manager.IsConnectedClient); Assert.True(callbackInvoked); } [Test] public void HostDoesNotStartWhenTransportFails() { bool callbackInvoked = false; Action onTransportFailure = () => { callbackInvoked = true; }; var manager = new GameObject().AddComponent(); manager.OnTransportFailure += onTransportFailure; var transport = manager.gameObject.AddComponent(); transport.FailOnStart = true; manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport }; LogAssert.Expect(LogType.Error, $"Server is shutting down due to network transport start failure of {transport.GetType().Name}!"); Assert.False(manager.StartHost()); Assert.False(manager.IsListening); Assert.True(callbackInvoked); } [Test] public void ServerDoesNotStartWhenTransportFails() { bool callbackInvoked = false; Action onTransportFailure = () => { callbackInvoked = true; }; var manager = new GameObject().AddComponent(); manager.OnTransportFailure += onTransportFailure; var transport = manager.gameObject.AddComponent(); transport.FailOnStart = true; manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport }; LogAssert.Expect(LogType.Error, $"Server is shutting down due to network transport start failure of {transport.GetType().Name}!"); Assert.False(manager.StartServer()); Assert.False(manager.IsListening); Assert.True(callbackInvoked); } [UnityTest] public IEnumerator ShutsDownWhenTransportFails() { bool callbackInvoked = false; Action onTransportFailure = () => { callbackInvoked = true; }; var manager = new GameObject().AddComponent(); manager.OnTransportFailure += onTransportFailure; var transport = manager.gameObject.AddComponent(); transport.FailOnNextPoll = true; manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport }; Assert.True(manager.StartServer()); Assert.True(manager.IsListening); LogAssert.Expect(LogType.Error, $"Shutting down due to network transport failure of {transport.GetType().Name}!"); // Need two updates to actually shut down. First one to see the transport failing, which // marks the NetworkManager as shutting down. Second one where actual shutdown occurs. yield return null; yield return null; Assert.False(manager.IsListening); Assert.True(callbackInvoked); } /// /// Does nothing but simulate a transport that can fail at startup and/or when polling events. /// public class FailedTransport : TestingNetworkTransport { public bool FailOnStart = false; public bool FailOnNextPoll = false; public override bool StartClient() => !FailOnStart; public override bool StartServer() => !FailOnStart; public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment payload, out float receiveTime) { clientId = 0; payload = new ArraySegment(); receiveTime = 0; if (FailOnNextPoll) { FailOnNextPoll = false; return NetworkEvent.TransportFailure; } else { return NetworkEvent.Nothing; } } public override ulong ServerClientId => 0; public override void Send(ulong clientId, ArraySegment payload, NetworkDelivery networkDelivery) { } public override void Initialize(NetworkManager networkManager = null) { } public override void Shutdown() { } public override ulong GetCurrentRtt(ulong clientId) => 0; public override void DisconnectRemoteClient(ulong clientId) { } public override void DisconnectLocalClient() { } } } }