using System.Collections; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; using UnityEngine.TestTools; namespace Unity.Netcode.RuntimeTests { internal class SessionVersionConnectionRequest : NetcodeIntegrationTest { protected override int NumberOfClients => 0; public SessionVersionConnectionRequest() : base(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost) { } private bool m_UseValidSessionVersion; private bool m_ClientWasDisconnected; private NetworkManager m_ClientNetworkManager; /// /// Callback used to mock the scenario where a client has an invalid session version /// /// private SessionConfig GetInavlidSessionConfig() { return new SessionConfig(m_ServerNetworkManager.SessionConfig.SessionVersion - 1); } /// /// Overriding this method allows us to configure the newly instantiated client's /// NetworkManager prior to it being started. /// /// the newly instantiated NetworkManager protected override void OnNewClientCreated(NetworkManager networkManager) { m_ClientWasDisconnected = false; m_ClientNetworkManager = networkManager; m_ClientNetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback; if (!m_UseValidSessionVersion) { networkManager.OnGetSessionConfig = GetInavlidSessionConfig; } base.OnNewClientCreated(networkManager); } /// /// Tracks if the client was disconnected or not /// private void OnClientDisconnectCallback(ulong clientId) { m_ClientWasDisconnected = true; m_ClientNetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback; } /// /// This handles disabling the internal integration test logic that waits for /// clients to be connected. When we know the client will be disconnected, /// we want to have the NetcodeIntegrationTest not wait for the client to /// connect (otherwise it will timeout there and fail the test). /// /// /// true = wait | false = don't wait protected override bool ShouldWaitForNewClientToConnect(NetworkManager networkManager) { return m_UseValidSessionVersion; } /// /// Validates that when the client's session config version is valid a client will be /// allowed to connect and when it is not valid the client will be disconnected. /// /// /// This is just a mock of the service logic to validate everything on the NGO side is /// working correctly. /// /// true = use valid session version | false = use invalid session version [UnityTest] public IEnumerator ValidateSessionVersion([Values] bool useValidSessionVersion) { // Test client being disconnected due to invalid session version m_UseValidSessionVersion = useValidSessionVersion; yield return CreateAndStartNewClient(); yield return s_DefaultWaitForTick; if (!m_UseValidSessionVersion) { yield return WaitForConditionOrTimeOut(() => m_ClientWasDisconnected); AssertOnTimeout("Client was not disconnected when it should have been!"); Assert.True(m_ClientNetworkManager.DisconnectReason == ConnectionRequestMessage.InvalidSessionVersionMessage, "Client did not receive the correct invalid session version message!"); } else { Assert.False(m_ClientWasDisconnected, "Client was disconnected when it was expected to connect!"); Assert.True(m_ClientNetworkManager.IsConnectedClient, "Client did not connect properly using the correct session version!"); } } /// /// Invoked at the end of each integration test pass. /// Primarily used to clean up for the next pass. /// protected override IEnumerator OnTearDown() { m_ClientNetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback; m_ClientNetworkManager = null; yield return base.OnTearDown(); } } }