From 747711d991ba069de736d1fc6cdcdd37a0e46477 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 2 May 2025 19:48:28 -0500 Subject: [PATCH 01/24] fix This fixes some compatibility issues with the initial total number of clients count being always +1 as opposed to just checking for the scenario where an integration test is connecting to a CMB server and has the `NetcodeIntegrationTest.NumberOfClients` set to zero (which in this case we have to create at least 1 client). This also updates the `m_NumberOfClients` when this scenario is detected. This also fixes some issues with allowing the `NetcodeIntegrationTest `to still create and assign `m_ServerNetworkManager`. The fix replaces all pertinent areas within `NetcodeIntegrationTest` that was directly using `m_ServerNetworkManager` with the returned value of `NetcodeIntegrationTest.GetAuthorityNetworkManager`. --- .../Runtime/NetcodeIntegrationTest.cs | 84 ++++++++++++------- .../Runtime/NetcodeIntegrationTestHelpers.cs | 36 ++++++-- pvpExceptions.json | 1 - 3 files changed, 82 insertions(+), 39 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index e6261ae88b..a0689cd00a 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -97,7 +97,7 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj } /// - /// Total number of clients that should be connected at any point during a test + /// Total number of clients that should be connected at any point during a test. /// protected int TotalClients => m_UseHost ? m_NumberOfClients + 1 : m_NumberOfClients; @@ -107,15 +107,21 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj /// Specifies the number of client instances to be created for the integration test. /// /// - /// When running with a hosted CMB Service, NumberOfClients + 1 clients are created. - /// This holds assumptions throughout the test suite that when running with a host, there is an extra client. - /// For example, see the calculation for . + /// Client-Server network topology:
+ /// When running as a host the total number of clients will be NumberOfClients + 1.
+ /// See the calculation for . + /// Distributed Authority network topology:
+ /// When connecting to a CMB server, if the == 0 then a session owner client will + /// be automatically added in order to start the session and the private internal m_NumberOfClients value, which + /// is initialized as , will be incremented by 1 making yield the + /// same results as if we were running a Host where it will effectively be + /// + 1. ///
protected abstract int NumberOfClients { get; } private int m_NumberOfClients; /// - /// Set this to false to create the clients first. + /// Set this to false to create the clients first.
/// Note: If you are using scene placed NetworkObjects or doing any form of scene testing and /// get prefab hash id "soft synchronization" errors, then set this to false and run your test /// again. This is a work-around until we can resolve some issues with NetworkManagerOwner and @@ -513,7 +519,13 @@ protected virtual void OnServerAndClientsCreated() ///
protected void CreateServerAndClients() { - CreateServerAndClients(NumberOfClients); + // If we are connecting to a CMB server and we have a zero client count, + // then we must make m_NumberOfClients = 1 for the session owner. + if (UseCMBService() && NumberOfClients == 0 && m_NumberOfClients == 0) + { + m_NumberOfClients = 1; + } + CreateServerAndClients(m_NumberOfClients); } private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetworkManager) @@ -546,7 +558,7 @@ private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetw protected virtual void OnNewClientCreated(NetworkManager networkManager) { // Ensure any late joining client has all NetworkPrefabs required to connect. - foreach (var networkPrefab in m_ServerNetworkManager.NetworkConfig.Prefabs.Prefabs) + foreach (var networkPrefab in GetAuthorityNetworkManager().NetworkConfig.Prefabs.Prefabs) { if (!networkManager.NetworkConfig.Prefabs.Contains(networkPrefab.Prefab)) { @@ -761,7 +773,7 @@ protected void StopOneClientWithTimeTravel(NetworkManager networkManager, bool d protected void SetTimeTravelSimulatedLatency(float latencySeconds) { - ((MockTransport)m_ServerNetworkManager.NetworkConfig.NetworkTransport).SimulatedLatencySeconds = latencySeconds; + ((MockTransport)GetAuthorityNetworkManager().NetworkConfig.NetworkTransport).SimulatedLatencySeconds = latencySeconds; foreach (var client in m_ClientNetworkManagers) { ((MockTransport)client.NetworkConfig.NetworkTransport).SimulatedLatencySeconds = latencySeconds; @@ -770,7 +782,7 @@ protected void SetTimeTravelSimulatedLatency(float latencySeconds) protected void SetTimeTravelSimulatedDropRate(float dropRatePercent) { - ((MockTransport)m_ServerNetworkManager.NetworkConfig.NetworkTransport).PacketDropRate = dropRatePercent; + ((MockTransport)GetAuthorityNetworkManager().NetworkConfig.NetworkTransport).PacketDropRate = dropRatePercent; foreach (var client in m_ClientNetworkManagers) { ((MockTransport)client.NetworkConfig.NetworkTransport).PacketDropRate = dropRatePercent; @@ -779,7 +791,7 @@ protected void SetTimeTravelSimulatedDropRate(float dropRatePercent) protected void SetTimeTravelSimulatedLatencyJitter(float jitterSeconds) { - ((MockTransport)m_ServerNetworkManager.NetworkConfig.NetworkTransport).LatencyJitter = jitterSeconds; + ((MockTransport)GetAuthorityNetworkManager().NetworkConfig.NetworkTransport).LatencyJitter = jitterSeconds; foreach (var client in m_ClientNetworkManagers) { ((MockTransport)client.NetworkConfig.NetworkTransport).LatencyJitter = jitterSeconds; @@ -801,10 +813,23 @@ protected void CreateServerAndClients(int numberOfClients) m_TargetFrameRate = -1; } - // Add an extra session owner client when using the cmb service - if (m_UseCmbService) + // In the event this is invoked within a derived integration test and + // the number of clients is 0, then we need to have at least 1 client + // to be the session owner. + if (UseCMBService() && numberOfClients == 0) { - numberOfClients += 1; + numberOfClients = 1; + // If m_NumberOfCleints == 0, then we should increment it. + if (m_NumberOfClients == 0) + { + m_NumberOfClients = 1; + } + else + { + // Otherwise, log a warning to the developer that they may be doing something bad. + Debug.LogWarning($"[{nameof(CreateServerAndClients)}] Invoked with number of clients set to zero but m_NumberOfClients was {m_NumberOfClients}. " + + $"Unless this was intended, this could cause issues with the {nameof(NetcodeIntegrationTest)}!"); + } } // Create multiple NetworkManager instances @@ -824,7 +849,7 @@ protected void CreateServerAndClients(int numberOfClients) } m_NetworkManagers = managers.ToArray(); - s_DefaultWaitForTick = new WaitForSecondsRealtime(1.0f / m_ServerNetworkManager.NetworkConfig.TickRate); + s_DefaultWaitForTick = new WaitForSecondsRealtime(1.0f / GetAuthorityNetworkManager().NetworkConfig.TickRate); // Set the player prefab for the server and clients foreach (var manager in m_NetworkManagers) @@ -943,7 +968,7 @@ protected void ClientNetworkManagerPostStartInit() if (m_UseHost) { #if UNITY_2023_1_OR_NEWER - var clientSideServerPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); + var clientSideServerPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == NetworkManager.ServerClientId); #else var clientSideServerPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); #endif @@ -955,9 +980,9 @@ protected void ClientNetworkManagerPostStartInit() m_PlayerNetworkObjects.Add(playerNetworkObject.NetworkManager.LocalClientId, new Dictionary()); } - if (!m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].ContainsKey(m_ServerNetworkManager.LocalClientId)) + if (!m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].ContainsKey(NetworkManager.ServerClientId)) { - m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); + m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(NetworkManager.ServerClientId, playerNetworkObject); } } } @@ -1021,7 +1046,7 @@ protected IEnumerator StartServerAndClients() AssertOnTimeout($"{nameof(StartServerAndClients)} timed out waiting for all clients to be connected!\n {m_InternalErrorLog}"); - if (m_UseHost || m_ServerNetworkManager.IsHost) + if (m_UseHost || authorityManager.IsHost) { #if UNITY_2023_1_OR_NEWER // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries @@ -1039,7 +1064,7 @@ protected IEnumerator StartServerAndClients() if (!m_UseCmbService) { - m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); + m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(authorityManager.LocalClientId, playerNetworkObject); } } } @@ -1111,7 +1136,7 @@ protected void StartServerAndClientsWithTimeTravel() AssertOnTimeout($"{nameof(StartServerAndClients)} timed out waiting for all clients to be connected!"); - if (m_UseHost || m_ServerNetworkManager.IsHost) + if (m_UseHost || authorityManager.IsHost) { #if UNITY_2023_1_OR_NEWER // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries @@ -1129,7 +1154,7 @@ protected void StartServerAndClientsWithTimeTravel() if (!m_UseCmbService) { - m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); + m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(authorityManager.LocalClientId, playerNetworkObject); } } } @@ -1449,10 +1474,9 @@ protected void DestroySceneNetworkObjects() /// protected void EnableMessageLogging() { - m_ServerNetworkManager.ConnectionManager.MessageManager.Hook(new DebugNetworkHooks()); - foreach (var client in m_ClientNetworkManagers) + foreach (var networkManager in m_NetworkManagers) { - client.ConnectionManager.MessageManager.Hook(new DebugNetworkHooks()); + networkManager.ConnectionManager.MessageManager.Hook(new DebugNetworkHooks()); } } @@ -1632,10 +1656,11 @@ private bool CheckClientsConnected(NetworkManager[] clientsToCheck) protected bool WaitForClientsConnectedOrTimeOutWithTimeTravel(NetworkManager[] clientsToCheck) { var remoteClientCount = clientsToCheck.Length; - var serverClientCount = m_ServerNetworkManager.IsHost ? remoteClientCount + 1 : remoteClientCount; + var authorityNetworkManager = GetAuthorityNetworkManager(); + var serverClientCount = authorityNetworkManager.IsHost ? remoteClientCount + 1 : remoteClientCount; return WaitForConditionOrTimeOutWithTimeTravel(() => clientsToCheck.Where((c) => c.IsConnectedClient).Count() == remoteClientCount && - m_ServerNetworkManager.ConnectedClients.Count == serverClientCount); + authorityNetworkManager.ConnectedClients.Count == serverClientCount); } /// @@ -1746,9 +1771,10 @@ protected GameObject CreateNetworkObjectPrefab(string baseName) { var prefabCreateAssertError = $"You can only invoke this method during {nameof(OnServerAndClientsCreated)} " + $"but before {nameof(OnStartedServerAndClients)}!"; - Assert.IsNotNull(m_ServerNetworkManager, prefabCreateAssertError); - Assert.IsFalse(m_ServerNetworkManager.IsListening, prefabCreateAssertError); - var prefabObject = NetcodeIntegrationTestHelpers.CreateNetworkObjectPrefab(baseName, m_ServerNetworkManager, m_ClientNetworkManagers); + var authorityNetworkManager = GetAuthorityNetworkManager(); + Assert.IsNotNull(authorityNetworkManager, prefabCreateAssertError); + Assert.IsFalse(authorityNetworkManager.IsListening, prefabCreateAssertError); + var prefabObject = NetcodeIntegrationTestHelpers.CreateNetworkObjectPrefab(baseName, authorityNetworkManager, m_ClientNetworkManagers); // DANGO-TODO: Ownership flags could require us to change this // For testing purposes, we default to true for the distribute ownership property when in a distirbuted authority network topology. prefabObject.GetComponent().Ownership |= NetworkObject.OwnershipStatus.Distributable; diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 579e62b1c4..68552207f5 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -265,16 +265,18 @@ public static bool Create(int clientCount, out NetworkManager server, out Networ { s_NetworkManagerInstances = new List(); server = null; - if (serverFirst) + // Only if we are not connecting to a CMB server + if (serverFirst && !useCmbService) { - server = CreateServer(useMockTransport || useCmbService); + server = CreateServer(useMockTransport); } CreateNewClients(clientCount, out clients, useMockTransport, useCmbService); - if (!serverFirst) + // Only if we are not connecting to a CMB server + if (!serverFirst && !useCmbService) { - server = CreateServer(useMockTransport || useCmbService); + server = CreateServer(useMockTransport); } s_OriginalTargetFrameRate = Application.targetFrameRate; @@ -627,7 +629,19 @@ internal static GameObject CreateNetworkObject(string baseName, NetworkManager o return gameObject; } - public static GameObject CreateNetworkObjectPrefab(string baseName, NetworkManager server, params NetworkManager[] clients) + /// + /// This will create and register a instance for all instances.
+ /// *** Invoke this method before starting any of the instances ***. + ///
+ /// + /// When using a network topology, the authority + /// can be within the clients array of instances. + /// + /// The base name of the network prefab. Keep it short as additional information will be added to this name. + /// The authority (i.e. server, host, or session owner) + /// The clients that should also have this instance added to their network prefab list. + /// The prefab's root + public static GameObject CreateNetworkObjectPrefab(string baseName, NetworkManager authorityNetworkManager, params NetworkManager[] clients) { void AddNetworkPrefab(NetworkConfig config, NetworkPrefab prefab) { @@ -635,17 +649,21 @@ void AddNetworkPrefab(NetworkConfig config, NetworkPrefab prefab) } var prefabCreateAssertError = $"You can only invoke this method before starting the network manager(s)!"; - Assert.IsNotNull(server, prefabCreateAssertError); - Assert.IsFalse(server.IsListening, prefabCreateAssertError); + Assert.IsNotNull(authorityNetworkManager, prefabCreateAssertError); + Assert.IsFalse(authorityNetworkManager.IsListening, prefabCreateAssertError); - var gameObject = CreateNetworkObject(baseName, server); + var gameObject = CreateNetworkObject(baseName, authorityNetworkManager); var networkPrefab = new NetworkPrefab() { Prefab = gameObject }; // We could refactor this test framework to share a NetworkPrefabList instance, but at this point it's // probably more trouble than it's worth to verify these lists stay in sync across all tests... - AddNetworkPrefab(server.NetworkConfig, networkPrefab); + AddNetworkPrefab(authorityNetworkManager.NetworkConfig, networkPrefab); foreach (var clientNetworkManager in clients) { + if (clientNetworkManager == authorityNetworkManager) + { + continue; + } AddNetworkPrefab(clientNetworkManager.NetworkConfig, networkPrefab); } return gameObject; diff --git a/pvpExceptions.json b/pvpExceptions.json index 7f54933590..4e721b02e8 100644 --- a/pvpExceptions.json +++ b/pvpExceptions.json @@ -173,7 +173,6 @@ "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: uint GetNextGlobalIdHashValue(): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IsNetcodeIntegrationTestRunning: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: void RegisterNetcodeIntegrationTest(bool): undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: GameObject CreateNetworkObjectPrefab(string, NetworkManager, params NetworkManager[]): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: void MarkAsSceneObjectRoot(GameObject, NetworkManager, NetworkManager[]): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator WaitForClientConnected(NetworkManager, ResultWrapper, float): missing ", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IEnumerator WaitForClientsConnected(NetworkManager[], ResultWrapper, float): missing ", From 145aada92fdf88dbf09040bdcfbecbba2fe54301 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 2 May 2025 23:23:41 -0500 Subject: [PATCH 02/24] fix and update Fixing some issues with getting the session owner prior to actually starting and connecting to a service. Added a better log message that includes the actual name of the NetworkManager when a prefab cannot be found. --- .../Runtime/Spawning/NetworkSpawnManager.cs | 2 +- .../Runtime/NetcodeIntegrationTest.cs | 38 +++++++++++++------ .../Runtime/NetcodeIntegrationTestHelpers.cs | 10 ++--- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs index 50c1e008d0..ba9db8329d 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs @@ -831,7 +831,7 @@ internal NetworkObject GetNetworkObjectToSpawn(uint globalObjectIdHash, ulong ow { if (NetworkLog.CurrentLogLevel <= LogLevel.Error) { - NetworkLog.LogError($"Failed to create object locally. [{nameof(globalObjectIdHash)}={globalObjectIdHash}]. {nameof(NetworkPrefab)} could not be found. Is the prefab registered with {nameof(NetworkManager)}?"); + NetworkLog.LogError($"Failed to create object locally. [{nameof(globalObjectIdHash)}={globalObjectIdHash}]. {nameof(NetworkPrefab)} could not be found. Is the prefab registered with {NetworkManager.name}?"); } } else diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index a0689cd00a..5bdc20bfe9 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -162,10 +162,23 @@ protected NetworkManager GetAuthorityNetworkManager() { if (m_UseCmbService) { + // TODO: Because we start the NetworkManagers back-to-back, the service can make a NetworkManager + // (other than the very first one) the session owner. This could lead to test instabilities and + // we need to add additional code during the start process that will start the very 1st instance + // and wait for it to be approved and assigned the session owner before we assume anything. + // Otherwise, any pick from the m_NetworkManagers could result in that specific instance not being + // the first session owner. + // If we haven't even started any NetworkManager, then just return the first + // instance until we resolve the above issue. + if (!NetcodeIntegrationTestHelpers.IsStarted) + { + return m_NetworkManagers[0]; + } + foreach (var client in m_NetworkManagers) { - // If client isn't approved we are still in setup and want to return the first client - // otherwise look for the session owner + // See above notes. + // TODO: Once the above is resolved, just check for client.LocalClient.IsSessionOwner if (!client.LocalClient.IsApproved || client.LocalClient.IsSessionOwner) { return client; @@ -203,7 +216,7 @@ protected NetworkManager GetNonAuthorityNetworkManager() /// Indicates whether the currently running tests are targeting the hosted CMB Service ///
/// Can only be true if returns true. - protected bool m_UseCmbService; + protected bool m_UseCmbService { get; private set; } /// /// Indicates whether a hosted CMB service is available. @@ -419,6 +432,9 @@ protected virtual void OnInlineSetup() [UnitySetUp] public IEnumerator SetUp() { + // In addition to setting the number of clients in the OneTimeSetup, we need to re-apply the number of clients for each unique test + // in the event that a previous test stopped a client. + m_NumberOfClients = NumberOfClients; VerboseDebugLog.Clear(); VerboseDebug($"Entering {nameof(SetUp)}"); NetcodeLogAssert = new NetcodeLogAssert(); @@ -521,7 +537,7 @@ protected void CreateServerAndClients() { // If we are connecting to a CMB server and we have a zero client count, // then we must make m_NumberOfClients = 1 for the session owner. - if (UseCMBService() && NumberOfClients == 0 && m_NumberOfClients == 0) + if (m_UseCmbService && NumberOfClients == 0 && m_NumberOfClients == 0) { m_NumberOfClients = 1; } @@ -816,7 +832,7 @@ protected void CreateServerAndClients(int numberOfClients) // In the event this is invoked within a derived integration test and // the number of clients is 0, then we need to have at least 1 client // to be the session owner. - if (UseCMBService() && numberOfClients == 0) + if (m_UseCmbService && numberOfClients == 0) { numberOfClients = 1; // If m_NumberOfCleints == 0, then we should increment it. @@ -995,7 +1011,6 @@ protected virtual bool ShouldCheckForSpawnedPlayers() return true; } - /// /// This starts the server and clients as long as /// returns true. @@ -1009,9 +1024,6 @@ protected IEnumerator StartServerAndClients() // Start the instances and pass in our SceneManagerInitialization action that is invoked immediately after host-server // is started and after each client is started. - // When using the CMBService, we don't have a server, so get the appropriate authority network manager - var authorityManager = GetAuthorityNetworkManager(); - VerboseDebug($"Starting with useCmbService: {m_UseCmbService}"); if (!NetcodeIntegrationTestHelpers.Start(m_UseHost, !m_UseCmbService, m_ServerNetworkManager, m_ClientNetworkManagers)) { @@ -1019,6 +1031,9 @@ protected IEnumerator StartServerAndClients() Assert.Fail("Failed to start instances"); } + // When using the CMBService, we don't have a server, so get the appropriate authority network manager + var authorityManager = GetAuthorityNetworkManager(); + // When scene management is enabled, we need to re-apply the scenes populated list since we have overriden the ISceneManagerHandler // imeplementation at this point. This assures any pre-loaded scenes will be automatically assigned to the server and force clients // to load their own scenes. @@ -1382,9 +1397,11 @@ private void DestroyNetworkManagers() var networkManagers = Object.FindObjectsByType(FindObjectsSortMode.None); foreach (var networkManager in networkManagers) { - Object.DestroyImmediate(networkManager.gameObject); } + m_NetworkManagers = null; + m_ClientNetworkManagers = null; + m_ServerNetworkManager = null; } /// @@ -1949,7 +1966,6 @@ private void InitializeTestConfiguration(NetworkTopologyTypes networkTopologyTyp if (UseCMBService()) { m_UseCmbService = m_DistributedAuthority && hostOrServer == HostOrServer.DAHost; - } } diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 68552207f5..36645a5794 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -21,6 +21,7 @@ public static class NetcodeIntegrationTestHelpers private static List s_NetworkManagerInstances = new List(); private static Dictionary s_Hooks = new Dictionary(); private static bool s_IsStarted; + internal static bool IsStarted => s_IsStarted; private static int s_ClientCount; private static int s_OriginalTargetFrameRate = -1; @@ -643,11 +644,6 @@ internal static GameObject CreateNetworkObject(string baseName, NetworkManager o /// The prefab's root public static GameObject CreateNetworkObjectPrefab(string baseName, NetworkManager authorityNetworkManager, params NetworkManager[] clients) { - void AddNetworkPrefab(NetworkConfig config, NetworkPrefab prefab) - { - config.Prefabs.Add(prefab); - } - var prefabCreateAssertError = $"You can only invoke this method before starting the network manager(s)!"; Assert.IsNotNull(authorityNetworkManager, prefabCreateAssertError); Assert.IsFalse(authorityNetworkManager.IsListening, prefabCreateAssertError); @@ -657,14 +653,14 @@ void AddNetworkPrefab(NetworkConfig config, NetworkPrefab prefab) // We could refactor this test framework to share a NetworkPrefabList instance, but at this point it's // probably more trouble than it's worth to verify these lists stay in sync across all tests... - AddNetworkPrefab(authorityNetworkManager.NetworkConfig, networkPrefab); + authorityNetworkManager.NetworkConfig.Prefabs.Add(networkPrefab); foreach (var clientNetworkManager in clients) { if (clientNetworkManager == authorityNetworkManager) { continue; } - AddNetworkPrefab(clientNetworkManager.NetworkConfig, networkPrefab); + clientNetworkManager.NetworkConfig.Prefabs.Add(new NetworkPrefab() { Prefab = gameObject }); } return gameObject; } From 683d15f642062c69fd763201ffd09ee30db0f6b6 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sat, 3 May 2025 13:01:41 -0500 Subject: [PATCH 03/24] fix Fixing some issues with DistributedAuthorityCodecTests creating prefabs after having started the NetworkManager and issues with NetworkBehaviourTests having some bad/legacy technical debt in the initial design for those tests (particularly how it was checking if clients spawned objects). --- .../Runtime/NetcodeIntegrationTest.cs | 22 ++++- .../DistributedAuthorityCodecTests.cs | 10 +- .../Runtime/NetworkBehaviourUpdaterTests.cs | 97 +++++++++++-------- 3 files changed, 83 insertions(+), 46 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 5bdc20bfe9..7b18acebfe 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -218,6 +218,23 @@ protected NetworkManager GetNonAuthorityNetworkManager() /// Can only be true if returns true. protected bool m_UseCmbService { get; private set; } + private string m_UseCmbServiceEnvString = null; + private bool m_UseCmbServiceEnv; + + /// + /// Will set itself once and if already set then return true + /// + /// true/false + internal bool UseCMBServiceEnviromentVariableSet() + { + if (!m_UseCmbServiceEnv && m_UseCmbServiceEnvString == null) + { + var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "unset"; + m_UseCmbServiceEnv = useCmbService.ToLower() == "true"; + } + return m_UseCmbServiceEnv; + } + /// /// Indicates whether a hosted CMB service is available. /// @@ -228,8 +245,7 @@ protected virtual bool UseCMBService() #if USE_CMB_SERVICE return true; #else - var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "unset"; - return useCmbService.ToLower() == "true"; + return UseCMBServiceEnviromentVariableSet(); #endif } @@ -1438,6 +1454,8 @@ public void OneTimeTearDown() #endif IsRunning = false; + m_UseCmbServiceEnvString = null; + m_UseCmbServiceEnv = false; } /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs index af69df9aa8..d05a0bc533 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs @@ -45,6 +45,8 @@ internal class DistributedAuthorityCodecTests : NetcodeIntegrationTest private static readonly ushort k_TransportPort = GetPortToBind(); private const int k_ClientId = 0; + private GameObject m_TestPrefab; + /// /// Configures the port to look for the rust echo-server. /// @@ -247,9 +249,7 @@ public IEnumerator NetworkVariableDelta() [UnityTest] public IEnumerator NetworkVariableDelta_WithValueUpdate() { - var networkObj = CreateNetworkObjectPrefab("TestObject"); - networkObj.AddComponent(); - var instance = SpawnObject(networkObj, Client); + var instance = SpawnObject(m_SpawnObject, Client); yield return m_ClientCodecHook.WaitForMessageReceived(); var component = instance.GetComponent(); @@ -262,9 +262,7 @@ public IEnumerator NetworkVariableDelta_WithValueUpdate() [UnityTest] public IEnumerator NetworkListDelta_WithValueUpdate() { - var networkObj = CreateNetworkObjectPrefab("TestObject"); - networkObj.AddComponent(); - var instance = SpawnObject(networkObj, Client); + var instance = SpawnObject(m_SpawnObject, Client); yield return m_ClientCodecHook.WaitForMessageReceived(); var component = instance.GetComponent(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs index a7b0fc9244..164c8a7f21 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs @@ -1,11 +1,11 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Text; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; using UnityEngine.TestTools; -using Object = UnityEngine.Object; namespace Unity.Netcode.RuntimeTests { @@ -85,15 +85,6 @@ public void SetOwnerWrite() m_SeconValue = new NetworkVariable(default, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); } - public override void OnNetworkSpawn() - { - // Non-Authority will register each NetworkObject when it is spawned - if ((NetworkManager.DistributedAuthorityMode && !IsOwner) || (!NetworkManager.DistributedAuthorityMode && !IsServer)) - { - NetworkBehaviourUpdaterTests.ClientSideNotifyObjectSpawned(gameObject); - } - } - /// /// Server side only, sets the NetworkVariables being used to the ValueToSetNetVarTo /// that is pre-configured when the Network Prefab is created. @@ -160,12 +151,14 @@ internal struct NetVarCombinationTypes internal class NetworkBehaviourUpdaterTests : NetcodeIntegrationTest { // Go ahead and create maximum number of clients (not all tests will use them) - protected override int NumberOfClients => m_NumberOfClients; + protected override int NumberOfClients => m_ClientCount; public const int NetVarValueToSet = 1; - private static List s_ClientSpawnedNetworkObjects = new List(); + private List m_SpawnedObjects = new List(); private GameObject m_PrefabToSpawn; private NetVarCombinationTypes m_NetVarCombinationTypes; - private int m_NumberOfClients = 0; + private int m_ClientCount = 0; + + private StringBuilder m_ErrorLog = new StringBuilder(); public NetworkBehaviourUpdaterTests(HostOrServer hostOrServer, int numberOfClients, NetVarContainer.NetVarsToCheck first, NetVarContainer.NetVarsToCheck second) : base(hostOrServer) { @@ -174,25 +167,24 @@ public NetworkBehaviourUpdaterTests(HostOrServer hostOrServer, int numberOfClien FirstType = first, SecondType = second }; - m_NumberOfClients = numberOfClients; + // Adjust the client count if connecting to the service. + m_ClientCount = UseCMBServiceEnviromentVariableSet() ? numberOfClients + 1 : numberOfClients; } - protected override IEnumerator OnSetup() + protected override bool UseCMBService() { - s_ClientSpawnedNetworkObjects.Clear(); - return base.OnSetup(); + return true; } - /// - /// Clients will call this when NetworkObjects are spawned on their end - /// - /// the GameObject of the NetworkObject spawned - public static void ClientSideNotifyObjectSpawned(GameObject objectSpaned) + protected override void OnOneTimeTearDown() { - if (!s_ClientSpawnedNetworkObjects.Contains(objectSpaned)) - { - s_ClientSpawnedNetworkObjects.Add(objectSpaned); - } + base.OnOneTimeTearDown(); + } + + protected override IEnumerator OnSetup() + { + m_SpawnedObjects.Clear(); + return base.OnSetup(); } protected override void OnServerAndClientsCreated() @@ -221,6 +213,31 @@ protected override void OnServerAndClientsCreated() base.OnServerAndClientsCreated(); } + /// + /// Determines if all clients have spawned clone instances. + /// + /// + /// will contain log entries of the + /// instances and NetworkObjects + /// that did not get spawned. + /// + /// true(success) or false (failure) + private bool AllClientsSpawnedObjects() + { + m_ErrorLog.Clear(); + foreach (var networkManager in m_NetworkManagers) + { + foreach (var networkObjectId in m_SpawnedObjects) + { + if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId)) + { + m_ErrorLog.AppendLine($"[{networkManager.name}] Has not spawned {nameof(NetworkObject)}-{networkObjectId}."); + } + } + } + return m_ErrorLog.Length == 0; + } + /// /// The updated BehaviourUpdaterAllTests was re-designed to replicate the same functionality being tested in the /// original version of this test with additional time out handling and a re-organization in the order of operations. @@ -243,22 +260,19 @@ public IEnumerator BehaviourUpdaterAllTests([Values(1, 2)] int numToSpawn) // the appropriate number of NetworkObjects with the NetVarContainer behaviour var numberOfObjectsToSpawn = numToSpawn * NumberOfClients; - var authority = m_NetworkTopologyType == NetworkTopologyTypes.DistributedAuthority ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; + var authority = GetAuthorityNetworkManager(); // spawn the objects for (int i = 0; i < numToSpawn; i++) { - var spawnedObject = Object.Instantiate(m_PrefabToSpawn); + var spawnedObject = SpawnObject(m_PrefabToSpawn, authority); spawnedPrefabs.Add(spawnedObject); - var networkSpawnedObject = spawnedObject.GetComponent(); - networkSpawnedObject.NetworkManagerOwner = authority; - networkSpawnedObject.Spawn(); + m_SpawnedObjects.Add(spawnedObject.GetComponent().NetworkObjectId); } // Waits for all clients to spawn the NetworkObjects - yield return WaitForConditionOrTimeOut(() => numberOfObjectsToSpawn == s_ClientSpawnedNetworkObjects.Count); - Assert.IsFalse(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for clients to report spawning objects! " + - $"Total reported client-side spawned objects {s_ClientSpawnedNetworkObjects.Count}"); + yield return WaitForConditionOrTimeOut(AllClientsSpawnedObjects); + AssertOnTimeout($"Timed out waiting for clients to report spawning objects!\n {m_ErrorLog}"); // Once all clients have spawned the NetworkObjects, set the network variables for @@ -287,12 +301,19 @@ public IEnumerator BehaviourUpdaterAllTests([Values(1, 2)] int numToSpawn) // Get a list of all NetVarContainer components on the client-side spawned NetworkObjects var clientSideNetVarContainers = new List(); - foreach (var clientSpawnedObjects in s_ClientSpawnedNetworkObjects) + foreach (var networkManager in m_NetworkManagers) { - var netVarContainers = clientSpawnedObjects.GetComponents(); - foreach (var netvarContiner in netVarContainers) + if (networkManager == authority) { - clientSideNetVarContainers.Add(netvarContiner); + continue; + } + foreach (var networkObjectId in m_SpawnedObjects) + { + var netVarContainers = networkManager.SpawnManager.SpawnedObjects[networkObjectId].GetComponents(); + foreach (var netvarContiner in netVarContainers) + { + clientSideNetVarContainers.Add(netvarContiner); + } } } From f3f4be7eae8c93dc695e1c616b6a7c7d380bbca3 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sat, 3 May 2025 14:22:05 -0500 Subject: [PATCH 04/24] test fixes and updates This "should" constitute the remaining fixes for this PR's adjustments. --- .../Runtime/NetcodeIntegrationTest.cs | 16 ++++++--- .../Runtime/NetworkBehaviourUpdaterTests.cs | 7 +--- .../NetworkVarBufferCopyTest.cs | 13 ++++++-- .../Tests/Runtime/NetworkVisibilityTests.cs | 26 ++++----------- .../Runtime/Physics/NetworkRigidbodyTest.cs | 7 ++-- .../Prefabs/NetworkPrefabOverrideTests.cs | 33 ++++++++++++------- 6 files changed, 55 insertions(+), 47 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 7b18acebfe..a3b79ce136 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -99,7 +99,10 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj /// /// Total number of clients that should be connected at any point during a test. /// - protected int TotalClients => m_UseHost ? m_NumberOfClients + 1 : m_NumberOfClients; + /// + /// When using the CMB Service, we ignore if is true. + /// + protected int TotalClients => m_UseHost && !UseCMBService() ? m_NumberOfClients + 1 : m_NumberOfClients; protected const uint k_DefaultTickRate = 30; @@ -222,15 +225,20 @@ protected NetworkManager GetNonAuthorityNetworkManager() private bool m_UseCmbServiceEnv; /// - /// Will set itself once and if already set then return true + /// Will check the environment variable once and then always return the results + /// of the first check. /// + /// + /// This resets its properties during , so it will + /// check the environment variable once per test set. + /// /// true/false - internal bool UseCMBServiceEnviromentVariableSet() + private bool UseCMBServiceEnviromentVariableSet() { if (!m_UseCmbServiceEnv && m_UseCmbServiceEnvString == null) { var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "unset"; - m_UseCmbServiceEnv = useCmbService.ToLower() == "true"; + m_UseCmbServiceEnv = bool.Parse(useCmbService.ToLower()); } return m_UseCmbServiceEnv; } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs index 164c8a7f21..19ddedb105 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs @@ -168,12 +168,7 @@ public NetworkBehaviourUpdaterTests(HostOrServer hostOrServer, int numberOfClien SecondType = second }; // Adjust the client count if connecting to the service. - m_ClientCount = UseCMBServiceEnviromentVariableSet() ? numberOfClients + 1 : numberOfClients; - } - - protected override bool UseCMBService() - { - return true; + m_ClientCount = UseCMBService() ? numberOfClients + 1 : numberOfClients; } protected override void OnOneTimeTearDown() diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs index 1de2aa1c36..dcc6f8fe01 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs @@ -101,9 +101,16 @@ public override void OnNetworkSpawn() base.OnNetworkSpawn(); } } - protected override int NumberOfClients => 1; + protected override int NumberOfClients => m_ClientCount; - public NetworkVarBufferCopyTest(HostOrServer hostOrServer) : base(hostOrServer) { } + private const int k_ClientCount = 1; + private int m_ClientCount = k_ClientCount; + + public NetworkVarBufferCopyTest(HostOrServer hostOrServer) : base(hostOrServer) + { + // Adjust the client count if connecting to the CMB service. + m_ClientCount = UseCMBService() ? k_ClientCount + 1 : k_ClientCount; + } private static List s_ClientDummyNetBehavioursSpawned = new List(); public static void ClientDummyNetBehaviourSpawned(DummyNetBehaviour dummyNetBehaviour) @@ -126,7 +133,7 @@ protected override void OnCreatePlayerPrefab() [UnityTest] public IEnumerator TestEntireBufferIsCopiedOnNetworkVariableDelta() { - // This is the *SERVER VERSION* of the *CLIENT PLAYER* + // This is the *SERVER/SESSION OWNER VERSION* of the *CLIENT PLAYER* var authority = GetAuthorityNetworkManager(); var nonAuthority = GetNonAuthorityNetworkManager(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs index 0cbef0f4dc..faee1f721f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs @@ -49,35 +49,21 @@ protected override IEnumerator OnServerAndClientsConnected() [UnityTest] public IEnumerator HiddenObjectsTest() { - var expectedCount = NumberOfClients + (m_UseHost ? 1 : 0); -#if UNITY_2023_1_OR_NEWER - yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == expectedCount); -#else - yield return WaitForConditionOrTimeOut(() => Object.FindObjectsOfType().Where((c) => c.IsSpawned).Count() == expectedCount); -#endif - - Assert.IsFalse(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for the visible object count to equal 2!"); + yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == TotalClients); + AssertOnTimeout($"Timed out waiting for the visible object count to equal {TotalClients}!Actual count {Object.FindObjectsByType(FindObjectsSortMode.None).Count(c => c.IsSpawned)}"); } [UnityTest] public IEnumerator HideShowAndDeleteTest() { - var expectedCount = NumberOfClients + (m_UseHost ? 1 : 0); -#if UNITY_2023_1_OR_NEWER - yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Count(c => c.IsSpawned) == expectedCount); -#else - yield return WaitForConditionOrTimeOut(() => Object.FindObjectsOfType().Where((c) => c.IsSpawned).Count() == expectedCount); -#endif - AssertOnTimeout($"Timed out waiting for the visible object count to equal 2! Actual count {Object.FindObjectsByType(FindObjectsSortMode.None).Count(c => c.IsSpawned)}"); + yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Count(c => c.IsSpawned) == TotalClients); + + AssertOnTimeout($"Timed out waiting for the visible object count to equal {TotalClients}! Actual count {Object.FindObjectsByType(FindObjectsSortMode.None).Count(c => c.IsSpawned)}"); var sessionOwnerNetworkObject = m_SpawnedObject.GetComponent(); var nonAuthority = GetNonAuthorityNetworkManager(); sessionOwnerNetworkObject.NetworkHide(nonAuthority.LocalClientId); -#if UNITY_2023_1_OR_NEWER - yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == expectedCount - 1); -#else - yield return WaitForConditionOrTimeOut(() => Object.FindObjectsOfType().Where((c) => c.IsSpawned).Count() == expectedCount - 1); -#endif + yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == TotalClients - 1); AssertOnTimeout($"Timed out waiting for {m_SpawnedObject.name} to be hidden from client!"); var networkObjectId = sessionOwnerNetworkObject.NetworkObjectId; sessionOwnerNetworkObject.NetworkShow(nonAuthority.LocalClientId); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs index af92c49e9b..357e36ebf0 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs @@ -339,9 +339,10 @@ protected void Log(string msg) [TestFixture(HostOrServer.DAHost, ContactEventTypes.WithInfo)] internal class RigidbodyContactEventManagerTests : IntegrationTestWithApproximation { - protected override int NumberOfClients => 1; - + protected override int NumberOfClients => m_ClientCount; + private const int k_ClientCount = 1; + private int m_ClientCount = k_ClientCount; private GameObject m_RigidbodyContactEventManager; public enum ContactEventTypes @@ -355,6 +356,8 @@ public enum ContactEventTypes public RigidbodyContactEventManagerTests(HostOrServer hostOrServer, ContactEventTypes contactEventType) : base(hostOrServer) { + // Adjust the client count if connecting to the CMB service. + m_ClientCount = UseCMBService() ? k_ClientCount + 1 : k_ClientCount; m_ContactEventType = contactEventType; } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs index db50428f7f..9880762bd1 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs @@ -133,10 +133,11 @@ protected override void OnCreatePlayerPrefab() /// protected override void OnServerAndClientsCreated() { + var authorityNetworkManager = GetAuthorityNetworkManager(); // Create a NetworkPrefab with an override - var basePrefab = NetcodeIntegrationTestHelpers.CreateNetworkObject($"{k_PrefabRootName}-base", m_ServerNetworkManager, true); + var basePrefab = NetcodeIntegrationTestHelpers.CreateNetworkObject($"{k_PrefabRootName}-base", authorityNetworkManager, true); basePrefab.AddComponent(); - var targetPrefab = NetcodeIntegrationTestHelpers.CreateNetworkObject($"{k_PrefabRootName}-over", m_ServerNetworkManager, true); + var targetPrefab = NetcodeIntegrationTestHelpers.CreateNetworkObject($"{k_PrefabRootName}-over", authorityNetworkManager, true); targetPrefab.AddComponent(); m_PrefabOverride = new NetworkPrefab() { @@ -147,17 +148,21 @@ protected override void OnServerAndClientsCreated() }; // Add the prefab override handler for instance specific player prefabs to the server side - var playerPrefabOverrideHandler = m_ServerNetworkManager.gameObject.AddComponent(); + var playerPrefabOverrideHandler = authorityNetworkManager.gameObject.AddComponent(); playerPrefabOverrideHandler.ServerSideInstance = m_PlayerPrefab; playerPrefabOverrideHandler.ClientSideInstance = m_ClientSidePlayerPrefab.Prefab; // Add the NetworkPrefab with override - m_ServerNetworkManager.NetworkConfig.Prefabs.Add(m_PrefabOverride); + authorityNetworkManager.NetworkConfig.Prefabs.Add(m_PrefabOverride); // Add the client player prefab that will be used on clients (and the host) - m_ServerNetworkManager.NetworkConfig.Prefabs.Add(m_ClientSidePlayerPrefab); + authorityNetworkManager.NetworkConfig.Prefabs.Add(m_ClientSidePlayerPrefab); foreach (var networkManager in m_ClientNetworkManagers) { + if (authorityNetworkManager == networkManager) + { + continue; + } // Add the prefab override handler for instance specific player prefabs to the client side playerPrefabOverrideHandler = networkManager.gameObject.AddComponent(); playerPrefabOverrideHandler.ServerSideInstance = m_PlayerPrefab; @@ -208,7 +213,7 @@ protected override IEnumerator OnTearDown() private GameObject GetPlayerNetworkPrefabObject(NetworkManager networkManager) { - return networkManager.IsClient ? m_ClientSidePlayerPrefab.Prefab : m_PlayerPrefab; + return networkManager != GetAuthorityNetworkManager() ? m_ClientSidePlayerPrefab.Prefab : m_PlayerPrefab; } [UnityTest] @@ -217,11 +222,13 @@ public IEnumerator PrefabOverrideTests() var prefabNetworkObject = (NetworkObject)null; var spawnedGlobalObjectId = (uint)0; + var authorityNetworkManager = GetAuthorityNetworkManager(); + if (!m_UseHost) { // If running as just a server, validate that all player prefab clone instances are the server side version - prefabNetworkObject = GetPlayerNetworkPrefabObject(m_ServerNetworkManager).GetComponent(); - foreach (var playerEntry in m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId]) + prefabNetworkObject = GetPlayerNetworkPrefabObject(authorityNetworkManager).GetComponent(); + foreach (var playerEntry in m_PlayerNetworkObjects[authorityNetworkManager.LocalClientId]) { spawnedGlobalObjectId = playerEntry.Value.GlobalObjectIdHash; Assert.IsTrue(prefabNetworkObject.GlobalObjectIdHash == spawnedGlobalObjectId, $"Server-Side {playerEntry.Value.name} was spawned as prefab ({spawnedGlobalObjectId}) but we expected ({prefabNetworkObject.GlobalObjectIdHash})!"); @@ -254,7 +261,7 @@ public IEnumerator PrefabOverrideTests() // Validates prefab overrides via NetworkPrefab configuration. var spawnedInstance = (NetworkObject)null; - var networkManagerOwner = m_ServerNetworkManager; + var networkManagerOwner = authorityNetworkManager; if (m_DistributedAuthority) { @@ -291,15 +298,17 @@ bool ObjectSpawnedOnAllNetworkMangers() yield return WaitForConditionOrTimeOut(ObjectSpawnedOnAllNetworkMangers); AssertOnTimeout($"The spawned prefab override validation failed!\n {builder}"); + var nonAuthorityInstance = GetNonAuthorityNetworkManager(); + // Verify that the despawn and destroy order of operations is correct for client owned NetworkObjects and the nunmber of times each is invoked is correct - spawnedInstance = NetworkObject.InstantiateAndSpawn(m_PrefabOverride.SourcePrefabToOverride, networkManagerOwner, m_ClientNetworkManagers[0].LocalClientId); + spawnedInstance = NetworkObject.InstantiateAndSpawn(m_PrefabOverride.SourcePrefabToOverride, networkManagerOwner, nonAuthorityInstance.LocalClientId); yield return WaitForConditionOrTimeOut(ObjectSpawnedOnAllNetworkMangers); AssertOnTimeout($"The spawned prefab override validation failed!\n {builder}"); - var clientId = m_ClientNetworkManagers[0].LocalClientId; - m_ClientNetworkManagers[0].Shutdown(); + var clientId = nonAuthorityInstance.LocalClientId; + nonAuthorityInstance.Shutdown(); // Wait until all of the client's owned objects are destroyed // If no asserts occur, then the despawn & destroy order of operations and invocation count is correct From 7fb399194417fc30b36d34e709e0647e213fb3de Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sat, 3 May 2025 14:29:07 -0500 Subject: [PATCH 05/24] style removing unused property. renaming a local variable for consistency in naming. --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 4 ++-- .../DistributedAuthority/DistributedAuthorityCodecTests.cs | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index a3b79ce136..9dd656c484 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -1700,10 +1700,10 @@ protected bool WaitForClientsConnectedOrTimeOutWithTimeTravel(NetworkManager[] c { var remoteClientCount = clientsToCheck.Length; var authorityNetworkManager = GetAuthorityNetworkManager(); - var serverClientCount = authorityNetworkManager.IsHost ? remoteClientCount + 1 : remoteClientCount; + var authorityClientCount = authorityNetworkManager.IsHost ? remoteClientCount + 1 : remoteClientCount; return WaitForConditionOrTimeOutWithTimeTravel(() => clientsToCheck.Where((c) => c.IsConnectedClient).Count() == remoteClientCount && - authorityNetworkManager.ConnectedClients.Count == serverClientCount); + authorityNetworkManager.ConnectedClients.Count == authorityClientCount); } /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs index d05a0bc533..71b87abe81 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs @@ -45,8 +45,6 @@ internal class DistributedAuthorityCodecTests : NetcodeIntegrationTest private static readonly ushort k_TransportPort = GetPortToBind(); private const int k_ClientId = 0; - private GameObject m_TestPrefab; - /// /// Configures the port to look for the rust echo-server. /// From 8c05e0333973d59b43d599b10a10bd01382d4ad3 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sat, 3 May 2025 14:32:54 -0500 Subject: [PATCH 06/24] style removing unused overridden virtual method. --- .../Tests/Runtime/NetworkBehaviourUpdaterTests.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs index 19ddedb105..ed86bcc641 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs @@ -171,11 +171,6 @@ public NetworkBehaviourUpdaterTests(HostOrServer hostOrServer, int numberOfClien m_ClientCount = UseCMBService() ? numberOfClients + 1 : numberOfClients; } - protected override void OnOneTimeTearDown() - { - base.OnOneTimeTearDown(); - } - protected override IEnumerator OnSetup() { m_SpawnedObjects.Clear(); From f2aeef93ead5c37de4f7bef0d26c1b1c9d2cbea8 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sat, 3 May 2025 15:25:29 -0500 Subject: [PATCH 07/24] fix Fixing an issue where trying to parse for a bool I did not verify the alternative of no environment variable being set and the string value being "unset" as opposed to "false". This fixes that issue and if it is not a valid bool string the it logs a warning and disables CMB service testing. --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 9dd656c484..12a4c4dc43 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -237,8 +237,16 @@ private bool UseCMBServiceEnviromentVariableSet() { if (!m_UseCmbServiceEnv && m_UseCmbServiceEnvString == null) { - var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "unset"; - m_UseCmbServiceEnv = bool.Parse(useCmbService.ToLower()); + var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false"; + if (bool.TryParse(useCmbService.ToLower(), out bool isTrue)) + { + m_UseCmbService = isTrue; + } + else + { + Debug.LogWarning($"USE_CMB_SERVICE value ({useCmbService}) is not a valid bool value. {m_UseCmbService} is being set to false."); + m_UseCmbServiceEnv = false; + } } return m_UseCmbServiceEnv; } From 1a4db66dc978dac23122a5284da9ba544ddf526f Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sat, 3 May 2025 15:28:44 -0500 Subject: [PATCH 08/24] style Fixing the wording on the USE_CMB_SERVICE warning log if it is an invalid bool string. --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 12a4c4dc43..668900ab1a 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -244,7 +244,7 @@ private bool UseCMBServiceEnviromentVariableSet() } else { - Debug.LogWarning($"USE_CMB_SERVICE value ({useCmbService}) is not a valid bool value. {m_UseCmbService} is being set to false."); + Debug.LogWarning($"The USE_CMB_SERVICE ({useCmbService}) value is an invalid bool string. {m_UseCmbService} is being set to false."); m_UseCmbServiceEnv = false; } } From 2cb2d845e509038c6e764b944b12ccde18e46e2b Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sun, 4 May 2025 12:48:31 -0500 Subject: [PATCH 09/24] test update Added some additional script to ignore anything that is not converted to run against the CMB server or any test that is configured to use a client-server network topology. Added OneTimeSetup to all non-NetcodeIntegrationTest derived tests that will also ignore the test until it is reviewed and determined it should be converted over or we do not need to run the test again since it will have already run multiple times on multiple platforms. --- .../Runtime/NetcodeIntegrationTest.cs | 81 +++++++++++++++---- .../Runtime/NetcodeIntegrationTestHelpers.cs | 12 +++ .../Runtime/ClientOnlyConnectionTests.cs | 7 ++ .../Runtime/NestedNetworkManagerTests.cs | 8 ++ .../Runtime/NetworkManagerEventsTests.cs | 7 ++ .../Prefabs/NetworkPrefabHandlerTests.cs | 8 ++ .../Profiling/NetworkVariableNameTests.cs | 7 ++ .../Tests/Runtime/RpcQueueTests.cs | 7 ++ .../NetworkBehaviourReferenceTests.cs | 7 ++ .../NetworkObjectReferenceTests.cs | 7 ++ .../Runtime/Timing/NetworkTimeSystemTests.cs | 7 ++ .../Runtime/Timing/TimeInitializationTest.cs | 7 ++ .../UnityTransportConnectionTests.cs | 8 ++ .../Runtime/Transports/UnityTransportTests.cs | 8 ++ .../Tests/Runtime/UniversalRpcTests.cs | 10 --- .../Assets/Tests/Runtime/AddressablesTests.cs | 6 ++ .../Tests/Runtime/DontDestroyOnLoadTests.cs | 6 +- .../Assets/Tests/Runtime/MessageOrdering.cs | 6 ++ .../Runtime/MultiClientConnectionApproval.cs | 7 ++ .../ClientSynchronizationModeTests.cs | 6 ++ .../InScenePlacedNetworkObjectTests.cs | 7 ++ .../NetworkObjectTestComponent.cs | 2 +- .../NetworkSceneManagerDDOLTests.cs | 7 ++ .../SceneEventDataTests.cs | 9 +++ ...pawnNetworkObjectsDuringSceneEventsTest.cs | 6 ++ .../NestedNetworkTransformTests.cs | 6 ++ ...ariableInitializationOnNetworkSpawnTest.cs | 7 ++ ...oMemoryLeakOnNetworkManagerShutdownTest.cs | 7 ++ .../NetworkObjectParentingTests.cs | 7 ++ .../Runtime/OnNetworkSpawnExceptionTests.cs | 7 ++ .../Tests/Runtime/PrefabExtendedTests.cs | 6 ++ .../Assets/Tests/Runtime/RpcObserverTests.cs | 9 ++- .../Assets/Tests/Runtime/RpcTestsAutomated.cs | 6 ++ .../Runtime/RpcUserSerializableTypesTest.cs | 45 +++-------- .../SceneObjectsNotDestroyedOnShutdownTest.cs | 32 ++------ 35 files changed, 297 insertions(+), 88 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 668900ab1a..5cded99385 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -96,13 +96,27 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj } } + private int GetTotalClients() + { + if (m_DistributedAuthority) + { + // If not connecting to a CMB service then we are using a DAHost and we add 1 to this count. + return !UseCMBService() && m_UseHost ? m_NumberOfClients + 1 : m_NumberOfClients; + } + else + { + // If using a host then we add one to this count. + return m_UseHost ? m_NumberOfClients + 1 : m_NumberOfClients; + } + } + /// /// Total number of clients that should be connected at any point during a test. /// /// /// When using the CMB Service, we ignore if is true. /// - protected int TotalClients => m_UseHost && !UseCMBService() ? m_NumberOfClients + 1 : m_NumberOfClients; + protected int TotalClients => GetTotalClients(); protected const uint k_DefaultTickRate = 30; @@ -212,7 +226,7 @@ protected NetworkManager GetNonAuthorityNetworkManager() protected Dictionary> m_PlayerNetworkObjects = new Dictionary>(); protected bool m_UseHost = true; - protected bool m_DistributedAuthority; + protected bool m_DistributedAuthority => m_NetworkTopologyType == NetworkTopologyTypes.DistributedAuthority; protected NetworkTopologyTypes m_NetworkTopologyType = NetworkTopologyTypes.ClientServer; /// @@ -233,14 +247,14 @@ protected NetworkManager GetNonAuthorityNetworkManager() /// check the environment variable once per test set. /// /// true/false - private bool UseCMBServiceEnviromentVariableSet() + private bool GetServiceEnviromentVariable() { if (!m_UseCmbServiceEnv && m_UseCmbServiceEnvString == null) { var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false"; if (bool.TryParse(useCmbService.ToLower(), out bool isTrue)) { - m_UseCmbService = isTrue; + m_UseCmbServiceEnv = isTrue; } else { @@ -261,7 +275,7 @@ protected virtual bool UseCMBService() #if USE_CMB_SERVICE return true; #else - return UseCMBServiceEnviromentVariableSet(); + return m_UseCmbService; #endif } @@ -408,6 +422,24 @@ protected virtual void OnOneTimeSetup() [OneTimeSetUp] public void OneTimeSetup() + { + // Only For CMB Server Tests: + // If the environment variable is set (i.e. doing a CMB server run) but UseCMBservice returns false, then ignore the test. + // Note: This will prevent us from re-running all of the non-DA integration tests that have already run multiple times on + // multiple platforms + if (GetServiceEnviromentVariable() && !UseCMBService()) + { + Assert.Ignore("[CMB-Server Test Run] Skipping non-distributed authority test."); + return; + } + else + { + // Otherwise, continue with the test + InternalOnOneTimeSetup(); + } + } + + private void InternalOnOneTimeSetup() { Application.runInBackground = true; m_NumberOfClients = NumberOfClients; @@ -515,7 +547,6 @@ public IEnumerator SetUp() } } - VerboseDebug($"Exiting {nameof(SetUp)}"); } @@ -1983,23 +2014,45 @@ public NetcodeIntegrationTest(HostOrServer hostOrServer) InitializeTestConfiguration(m_NetworkTopologyType, hostOrServer); } + /// + /// Override this virtual method to execute script that runs before the base class constructor has finished executing.
+ ///
+ /// + /// ***NOTE*** + /// When this method is invoked there will have been no properties set (i.e. nothing is configured).
+ /// Primarily this is to set things like environemnt variables or other more external configurations that could + /// determine how the is configured. + ///
+ protected virtual void OnPreInitializeConfiguration() + { + } + private void InitializeTestConfiguration(NetworkTopologyTypes networkTopologyType, HostOrServer? hostOrServer) { - if (!hostOrServer.HasValue) - { - // Always default to hosting, set the type of host based on the topology type - hostOrServer = networkTopologyType == NetworkTopologyTypes.DistributedAuthority ? HostOrServer.DAHost : HostOrServer.Host; - } + OnPreInitializeConfiguration(); NetworkMessageManager.EnableMessageOrderConsoleLog = false; + // Set m_NetworkTopologyType first because m_DistributedAuthority is calculated from it. m_NetworkTopologyType = networkTopologyType; - m_DistributedAuthority = m_NetworkTopologyType == NetworkTopologyTypes.DistributedAuthority; + + if (!hostOrServer.HasValue) + { + // Always default to hosting, set the type of host based on the topology type. + // Note: For m_DistributedAuthority to be true, the m_NetworkTopologyType must be set to NetworkTopologyTypes.DistributedAuthority + hostOrServer = m_DistributedAuthority ? HostOrServer.DAHost : HostOrServer.Host; + } m_UseHost = hostOrServer == HostOrServer.Host || hostOrServer == HostOrServer.DAHost; - if (UseCMBService()) + // If we are using a distributed authority network topology and the environment variable + // to use the CMBService is set, then perform the m_UseCmbService check. + if (m_DistributedAuthority && GetServiceEnviromentVariable()) { - m_UseCmbService = m_DistributedAuthority && hostOrServer == HostOrServer.DAHost; + m_UseCmbService = hostOrServer == HostOrServer.DAHost; + // In the event UseCMBService is overridden, we apply the value returned. + // If it is, then whatever UseCMBService returns is the setting for m_UseCmbService. + // If it is not, then it will return whatever m_UseCmbService's setting is from the above check. + m_UseCmbService = UseCMBService(); } } diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 36645a5794..58cfe82ae0 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -172,6 +172,18 @@ public static void RegisterHandlers(NetworkManager networkManager, bool serverSi } } + /// + /// Use for non derived integration tests to automatically ignore the + /// test is the USE_CMB_SERVICE is set. + /// + internal static void IgnoreIfServiceEnviromentVariableSet() + { + if (bool.TryParse(Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false", out bool isTrue) ? isTrue : false) + { + Assert.Ignore("[CMB-Server Test Run] Skipping non-distributed authority test."); + } + } + private static readonly string k_TransportHost = GetAddressToBind(); private static readonly ushort k_TransportPort = GetPortToBind(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/ClientOnlyConnectionTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/ClientOnlyConnectionTests.cs index dbd97fae53..c8677bed40 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/ClientOnlyConnectionTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/ClientOnlyConnectionTests.cs @@ -15,6 +15,13 @@ internal class ClientOnlyConnectionTests private bool m_WasDisconnected; private TimeoutHelper m_TimeoutHelper; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [SetUp] public void Setup() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NestedNetworkManagerTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NestedNetworkManagerTests.cs index c31f8a83f5..95b23182c9 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NestedNetworkManagerTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NestedNetworkManagerTests.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; using Unity.Netcode.Transports.UTP; using UnityEngine; using UnityEngine.TestTools; @@ -8,6 +9,13 @@ namespace Unity.Netcode.RuntimeTests { internal class NestedNetworkManagerTests { + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [Test] public void CheckNestedNetworkManager() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerEventsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerEventsTests.cs index c2d482da67..93d13c9e18 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerEventsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerEventsTests.cs @@ -17,6 +17,13 @@ internal class NetworkManagerEventsTests private bool m_Instantiated; private bool m_Destroyed; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + /// /// Validates the and event notifications /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabHandlerTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabHandlerTests.cs index c66c843abf..7460ea65fc 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabHandlerTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabHandlerTests.cs @@ -16,6 +16,12 @@ namespace Unity.Netcode.RuntimeTests ///
internal class NetworkPrefabHandlerTests { + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } private const string k_TestPrefabObjectName = "NetworkPrefabTestObject"; private uint m_ObjectId = 1; @@ -28,6 +34,8 @@ private GameObject MakeValidNetworkPrefab() return validPrefab.gameObject; } + + /// /// Tests the NetwokConfig NetworkPrefabsList initialization during NetworkManager's Init method to make sure that /// it will still initialize but remove the invalid prefabs diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs index 1ec833369c..c0b870193a 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs @@ -8,6 +8,13 @@ internal sealed class NetworkVariableNameTests { private NetworkVariableNameComponent m_NetworkVariableNameComponent; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [SetUp] public void SetUp() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/RpcQueueTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/RpcQueueTests.cs index 5d7775fa95..1489fb61b9 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/RpcQueueTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/RpcQueueTests.cs @@ -15,6 +15,13 @@ namespace Unity.Netcode.RuntimeTests /// internal class RpcQueueTests { + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [SetUp] public void Setup() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs index 6b7d497738..51d2ae8e71 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs @@ -15,6 +15,13 @@ namespace Unity.Netcode.RuntimeTests ///
internal class NetworkBehaviourReferenceTests : IDisposable { + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + private class TestNetworkBehaviour : NetworkBehaviour { public static bool ReceivedRPC; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs index ab347f435f..1fbce803fc 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -17,6 +17,13 @@ namespace Unity.Netcode.RuntimeTests ///
internal class NetworkObjectReferenceTests : IDisposable { + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + private class TestNetworkBehaviour : NetworkBehaviour { public static bool ReceivedRPC; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs index 7172feb302..64cfcf030e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs @@ -17,6 +17,13 @@ internal class NetworkTimeSystemTests private float m_OriginalTimeScale = 1.0f; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [SetUp] public void Setup() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeInitializationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeInitializationTest.cs index dc06c2877d..28053fe167 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeInitializationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeInitializationTest.cs @@ -15,6 +15,13 @@ internal class TimeInitializationTest private int m_ConnectedTick; private NetworkManager m_Client; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [UnityTest] public IEnumerator TestClientTimeInitializationOnConnect([Values(0, 1f)] float serverStartDelay, [Values(0, 1f)] float clientStartDelay, [Values(true, false)] bool isHost) { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs index 3e2c746082..c0a13e2f0d 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; using Unity.Netcode.Transports.UTP; using UnityEngine; using UnityEngine.TestTools; @@ -19,6 +20,13 @@ internal class UnityTransportConnectionTests private List m_ServerEvents; private List[] m_ClientsEvents = new List[k_NumClients]; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [UnityTearDown] public IEnumerator Cleanup() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs index 03bd6c2c4c..4963e5ea05 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; using Unity.Netcode.Transports.UTP; using Unity.Networking.Transport; using UnityEngine; @@ -34,6 +35,13 @@ internal class UnityTransportTests private UnityTransport m_Server, m_Client1, m_Client2; private List m_ServerEvents, m_Client1Events, m_Client2Events; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [UnityTearDown] public IEnumerator Cleanup() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs index 72b71ccbf5..91a61fd4a8 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs @@ -1542,16 +1542,6 @@ [Values] AllocationType allocationType } - [TestFixture(HostOrServer.Host)] - [TestFixture(HostOrServer.Server)] - internal class UniversalRpcTestDefaultSendToSpecifiedInParamsSendingToServerAndOwner : UniversalRpcTestsBase - { - public UniversalRpcTestDefaultSendToSpecifiedInParamsSendingToServerAndOwner(HostOrServer hostOrServer) : base(hostOrServer) - { - - } - } - [TestFixture(HostOrServer.DAHost)] [TestFixture(HostOrServer.Host)] [TestFixture(HostOrServer.Server)] diff --git a/testproject/Assets/Tests/Runtime/AddressablesTests.cs b/testproject/Assets/Tests/Runtime/AddressablesTests.cs index 8af531b0b2..0cab9cff2b 100644 --- a/testproject/Assets/Tests/Runtime/AddressablesTests.cs +++ b/testproject/Assets/Tests/Runtime/AddressablesTests.cs @@ -39,6 +39,12 @@ protected override void OnInlineTearDown() ShutdownAndCleanUp(); } + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + private IEnumerator LoadAsset(AssetReferenceGameObject asset, NetcodeIntegrationTestHelpers.ResultWrapper prefab) { var handle = asset.LoadAssetAsync(); diff --git a/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs b/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs index dcea70efdd..105265b08f 100644 --- a/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs +++ b/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs @@ -9,12 +9,16 @@ namespace TestProject.RuntimeTests { + [TestFixture(HostOrServer.Host)] + [TestFixture(HostOrServer.DAHost)] public class DontDestroyOnLoadTests : NetcodeIntegrationTest { private const int k_ClientsToConnect = 4; protected override int NumberOfClients => 0; private GameObject m_DontDestroyOnLoadObject; + public DontDestroyOnLoadTests(HostOrServer hostOrServer) : base(hostOrServer) { } + protected override void OnServerAndClientsCreated() { m_DontDestroyOnLoadObject = CreateNetworkObjectPrefab("DDOLObject"); @@ -52,7 +56,7 @@ private bool AllClientsSpawnedObjectIntoDDOL() [UnityTest] public IEnumerator ValidateNetworkObjectSynchronization() { - var objectInstance = SpawnObject(m_DontDestroyOnLoadObject, m_ServerNetworkManager); + var objectInstance = SpawnObject(m_DontDestroyOnLoadObject, GetAuthorityNetworkManager()); m_SpawnedNetworkObjectId = objectInstance.GetComponent().NetworkObjectId; // Wait a tick for the object to be automatically migrated into the DDOL yield return s_DefaultWaitForTick; diff --git a/testproject/Assets/Tests/Runtime/MessageOrdering.cs b/testproject/Assets/Tests/Runtime/MessageOrdering.cs index d4fe59193c..8295b20940 100644 --- a/testproject/Assets/Tests/Runtime/MessageOrdering.cs +++ b/testproject/Assets/Tests/Runtime/MessageOrdering.cs @@ -16,6 +16,12 @@ public class MessageOrderingTests private NetworkManager m_ServerNetworkManager; private NetworkManager[] m_ClientNetworkManagers; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } [UnitySetUp] public IEnumerator SetUp() diff --git a/testproject/Assets/Tests/Runtime/MultiClientConnectionApproval.cs b/testproject/Assets/Tests/Runtime/MultiClientConnectionApproval.cs index fa3858c61d..cb85f0baa9 100644 --- a/testproject/Assets/Tests/Runtime/MultiClientConnectionApproval.cs +++ b/testproject/Assets/Tests/Runtime/MultiClientConnectionApproval.cs @@ -22,6 +22,13 @@ public class MultiClientConnectionApproval private bool m_DelayedApproval; private List m_ResponseToSet = new List(); + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + /// /// Tests connection approval and connection approval failure /// diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationModeTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationModeTests.cs index 5f776b2883..f69bec2d12 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationModeTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationModeTests.cs @@ -56,6 +56,12 @@ public ClientSynchronizationModeTests(ServerPreloadStates serverPreloadStates) m_ServerPreloadState = serverPreloadStates; } + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + protected override IEnumerator OnSetup() { m_TempClientPreLoadedScenes.Clear(); diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs index bff15bcdc0..2904a510a4 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs @@ -581,6 +581,13 @@ internal class InScenePlacedNetworkObjectClientTests : NetcodeIntegrationTest private Scene m_Scene; + + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + protected override IEnumerator OnSetup() { SceneManager.sceneLoaded += SceneManager_sceneLoaded; diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkObjectTestComponent.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkObjectTestComponent.cs index f2ea87833d..6a8594b2d7 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkObjectTestComponent.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkObjectTestComponent.cs @@ -56,7 +56,7 @@ public override void OnNetworkSpawn() } } - if (IsServer) + if (IsServer || IsSessionOwner) { ServerNetworkObjectInstance = NetworkObject; if (DisableOnSpawn && !ObjectWasDisabledUponSpawn) diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerDDOLTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerDDOLTests.cs index 4862c676aa..f38a311ea8 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerDDOLTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerDDOLTests.cs @@ -19,6 +19,13 @@ public class NetworkSceneManagerDDOLTests protected float m_ConditionMetFrequency = 0.1f; + [OneTimeSetUp] + public void OneTimeSetup() + { + // This does not need to be tested against a CMB Server + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [UnitySetUp] protected IEnumerator SetUp() { diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs index 457cdde9b7..3731d7a5ab 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs @@ -1,7 +1,9 @@ using System; using System.Collections; using System.Collections.Generic; +using NUnit.Framework; using Unity.Netcode; +using Unity.Netcode.TestHelpers.Runtime; using Unity.Netcode.Transports.UTP; using UnityEngine; using UnityEngine.SceneManagement; @@ -15,6 +17,13 @@ namespace TestProject.RuntimeTests ///
public class SceneEventDataTests { + [OneTimeSetUp] + public void OneTimeSetup() + { + // This test does not need to run against a CMB server + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + /// /// This verifies that change from Allocator.TmpJob to Allocator.Persistent /// will not cause memory leak warning notifications if the scene event takes diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SpawnNetworkObjectsDuringSceneEventsTest.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SpawnNetworkObjectsDuringSceneEventsTest.cs index 4450cf2b78..e91570fd9c 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SpawnNetworkObjectsDuringSceneEventsTest.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SpawnNetworkObjectsDuringSceneEventsTest.cs @@ -32,6 +32,12 @@ public override void OnNetworkSpawn() } } + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + protected override void OnServerAndClientsCreated() { SpawnObjectTrackingComponent.SpawnedObjects = 0; diff --git a/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs b/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs index b99e044727..46ff5b7d58 100644 --- a/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs @@ -129,6 +129,12 @@ public NestedNetworkTransformTests() } + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + protected override void OnOneTimeSetup() { m_OriginalVarianceThreshold = base.GetDeltaVarianceThreshold(); diff --git a/testproject/Assets/Tests/Runtime/NetworkVariableInitializationOnNetworkSpawnTest.cs b/testproject/Assets/Tests/Runtime/NetworkVariableInitializationOnNetworkSpawnTest.cs index 802519f4fe..e71979dfd7 100644 --- a/testproject/Assets/Tests/Runtime/NetworkVariableInitializationOnNetworkSpawnTest.cs +++ b/testproject/Assets/Tests/Runtime/NetworkVariableInitializationOnNetworkSpawnTest.cs @@ -12,6 +12,13 @@ public class NetworkVariableInitializationOnNetworkSpawnTest { private GameObject m_Prefab; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [UnitySetUp] public IEnumerator SetUp() { diff --git a/testproject/Assets/Tests/Runtime/NoMemoryLeakOnNetworkManagerShutdownTest.cs b/testproject/Assets/Tests/Runtime/NoMemoryLeakOnNetworkManagerShutdownTest.cs index c1024325f6..9204454cd5 100644 --- a/testproject/Assets/Tests/Runtime/NoMemoryLeakOnNetworkManagerShutdownTest.cs +++ b/testproject/Assets/Tests/Runtime/NoMemoryLeakOnNetworkManagerShutdownTest.cs @@ -12,6 +12,13 @@ public class NoMemoryLeakOnNetworkManagerShutdownTest { private GameObject m_Prefab; + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [SetUp] public void Setup() { diff --git a/testproject/Assets/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs b/testproject/Assets/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs index c148a05d2c..a8eda1a829 100644 --- a/testproject/Assets/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs +++ b/testproject/Assets/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs @@ -38,6 +38,13 @@ public NetworkObjectParentingTests(NetworkTopologyTypes networkTopologyType) m_NetworkTopologyType = networkTopologyType; } + [OneTimeSetUp] + public void OneTimeSetup() + { + // TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (scene.name == nameof(NetworkObjectParentingTests)) diff --git a/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs b/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs index db2886ac0d..ea81ac8409 100644 --- a/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs +++ b/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs @@ -94,6 +94,13 @@ public class OnNetworkSpawnExceptionTests : NetcodeIntegrationTest private GameObject m_DespawnWithAndWithoutExceptionPrefab; private const int k_NumObjects = 10; + + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + [UnityTest] public IEnumerator WhenOnNetworkSpawnThrowsException_FutureOnNetworkSpawnsAreNotPrevented() { diff --git a/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs b/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs index 7bfe12083f..665590d342 100644 --- a/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs +++ b/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs @@ -36,6 +36,12 @@ public enum SceneManagementTypes private StringBuilder m_ErrorLog = new StringBuilder(); + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public PrefabExtendedTests(SceneManagementTypes sceneManagementType) { m_SceneManagementEnabled = sceneManagementType == SceneManagementTypes.SceneManagementEnabled; diff --git a/testproject/Assets/Tests/Runtime/RpcObserverTests.cs b/testproject/Assets/Tests/Runtime/RpcObserverTests.cs index d5a7e17542..0db86ccb1a 100644 --- a/testproject/Assets/Tests/Runtime/RpcObserverTests.cs +++ b/testproject/Assets/Tests/Runtime/RpcObserverTests.cs @@ -14,9 +14,8 @@ namespace TestProject.RuntimeTests /// Integration test to validate ClientRpcs will only /// send to observers of the NetworkObject /// -#if NGO_DAMODE + [TestFixture(HostOrServer.DAHost)] -#endif [TestFixture(HostOrServer.Host)] [TestFixture(HostOrServer.Server)] public class RpcObserverTests : NetcodeIntegrationTest @@ -31,6 +30,12 @@ public class RpcObserverTests : NetcodeIntegrationTest private NativeArray m_NonObserverArrayError; private bool m_ArrayAllocated; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public RpcObserverTests(HostOrServer hostOrServer) : base(hostOrServer) { } protected override void OnServerAndClientsCreated() diff --git a/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs b/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs index f99da71d52..228bfbfdd5 100644 --- a/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs +++ b/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs @@ -17,6 +17,12 @@ public class RpcTestsAutomated : NetcodeIntegrationTest protected override int NumberOfClients => 4; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + protected override NetworkManagerInstatiationMode OnSetIntegrationTestMode() { return NetworkManagerInstatiationMode.DoNotCreate; diff --git a/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs b/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs index 83e327e5a7..e9cc45211f 100644 --- a/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs +++ b/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs @@ -48,10 +48,9 @@ public void NetworkSerialize(BufferSerializer } } -#if NGO_DAMODE + [TestFixture(NetworkTopologyTypes.DistributedAuthority)] [TestFixture(NetworkTopologyTypes.ClientServer)] -#endif public class RpcUserSerializableTypesTest : NetcodeIntegrationTest { private UserSerializableClass m_UserSerializableClass; @@ -83,9 +82,13 @@ public class RpcUserSerializableTypesTest : NetcodeIntegrationTest protected override int NumberOfClients => 1; -#if NGO_DAMODE + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public RpcUserSerializableTypesTest(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } -#endif protected override NetworkManagerInstatiationMode OnSetIntegrationTestMode() { @@ -114,7 +117,7 @@ public IEnumerator NetworkSerializableTest() // [Client-Side] We only need to get the client side Player's NetworkObject so we can grab that instance of the TestSerializationComponent // Use the client's instance of the var targetContext = m_ClientNetworkManagers[0]; -#if NGO_DAMODE + // When in distributed authority mode: // Owner Instances // - Can send ClientRpcs @@ -127,7 +130,7 @@ public IEnumerator NetworkSerializableTest() // Use the server instance of the client's player targetContext = m_ServerNetworkManager; } -#endif + var clientContextPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper(); yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation((x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId), targetContext, clientContextPlayerResult); @@ -339,7 +342,6 @@ public IEnumerator ExtensionMethodRpcTest() serverIntListCalled && serverStrListCalled; }; -#if NGO_DAMODE // When in distributed authority mode: // Owner Instances // - Can send ClientRpcs @@ -356,7 +358,6 @@ public IEnumerator ExtensionMethodRpcTest() serverSideNetworkBehaviourClass.SendStringListOwnerRpc(strList); } else -#endif { clientSideNetworkBehaviourClass.SendMyObjectServerRpc(obj); clientSideNetworkBehaviourClass.SendMySharedObjectReferencedByIdServerRpc(obj2); @@ -533,7 +534,6 @@ public IEnumerator ExtensionMethodArrayRpcTest() serverIntListCalled && serverStrListCalled; }; -#if NGO_DAMODE // When in distributed authority mode: // Owner Instances // - Can send ClientRpcs @@ -550,7 +550,6 @@ public IEnumerator ExtensionMethodArrayRpcTest() serverSideNetworkBehaviourClass.SendStringListOwnerRpc(strList); } else -#endif { clientSideNetworkBehaviourClass.SendMyObjectServerRpc(objs); clientSideNetworkBehaviourClass.SendMySharedObjectReferencedByIdServerRpc(objs2); @@ -703,7 +702,6 @@ public IEnumerator NetworkSerializableArrayTestHandler(int arraySize, bool sendN yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation((x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId), m_ClientNetworkManagers[0], clientClientPlayerResult); var clientSideNetworkBehaviourClass = clientClientPlayerResult.Result.gameObject.GetComponent(); -#if NGO_DAMODE // When in distributed authority mode: // Owner Instances // - Can send ClientRpcs @@ -719,7 +717,6 @@ public IEnumerator NetworkSerializableArrayTestHandler(int arraySize, bool sendN serverSideNetworkBehaviourClass.OnSerializableStructsUpdatedClientRpc = OnClientReceivedUserSerializableStructsUpdated; } else -#endif { serverSideNetworkBehaviourClass.OnSerializableClassesUpdatedServerRpc = OnServerReceivedUserSerializableClassesUpdated; serverSideNetworkBehaviourClass.OnSerializableStructsUpdatedServerRpc = OnServerReceivedUserSerializableStructsUpdated; @@ -749,7 +746,6 @@ public IEnumerator NetworkSerializableArrayTestHandler(int arraySize, bool sendN }; m_UserSerializableStructArray.Add(userSerializableStruct); } -#if NGO_DAMODE // When in distributed authority mode: // Owner Instances // - Can send ClientRpcs @@ -763,7 +759,6 @@ public IEnumerator NetworkSerializableArrayTestHandler(int arraySize, bool sendN serverSideNetworkBehaviourClass.ClientStartStructTest(m_UserSerializableStructArray.ToArray()); } else -#endif { clientSideNetworkBehaviourClass.ClientStartTest(m_UserSerializableClassArray.ToArray()); clientSideNetworkBehaviourClass.ClientStartStructTest(m_UserSerializableStructArray.ToArray()); @@ -771,7 +766,6 @@ public IEnumerator NetworkSerializableArrayTestHandler(int arraySize, bool sendN } else { -#if NGO_DAMODE // When in distributed authority mode: // Owner Instances // - Can send ClientRpcs @@ -785,7 +779,6 @@ public IEnumerator NetworkSerializableArrayTestHandler(int arraySize, bool sendN serverSideNetworkBehaviourClass.ClientStartStructTest(null); } else -#endif { clientSideNetworkBehaviourClass.ClientStartTest(null); clientSideNetworkBehaviourClass.ClientStartStructTest(null); @@ -958,13 +951,11 @@ public class TestSerializationComponent : NetworkBehaviour /// public void ClientStartTest(UserSerializableClass userSerializableClass) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendOwnerSerializedDataClassRpc(userSerializableClass); } else -#endif { SendServerSerializedDataClassServerRpc(userSerializableClass); } @@ -1024,13 +1015,11 @@ private void SendClientSerializedDataClassClientRpc(UserSerializableClass userSe #region ClientStartTest(TemplatedType t1val, TemplatedType.NestedTemplatedType t2val, TemplatedType.Enum enumVal) public void ClientStartTest(TemplatedType t1val, TemplatedType.NestedTemplatedType t2val, TemplatedType.Enum enumVal) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendTemplateStructOwnerRpc(t1val, t2val, enumVal); } else -#endif { SendTemplateStructServerRpc(t1val, t2val, enumVal); } @@ -1076,13 +1065,11 @@ private void SendTemplateStructClientRpc(TemplatedType t1val, TemplatedType #region ClientStartTest(NetworkSerializableTemplatedType t1val, NetworkSerializableTemplatedType.NestedTemplatedType t2val) public void ClientStartTest(NetworkSerializableTemplatedType t1val, NetworkSerializableTemplatedType.NestedTemplatedType t2val) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendNetworkSerializableTemplateStructOwnerRpc(t1val, t2val); } else -#endif { SendNetworkSerializableTemplateStructServerRpc(t1val, t2val); } @@ -1128,13 +1115,11 @@ private void SendNetworkSerializableTemplateStructClientRpc(NetworkSerializableT #region ClientStartTest(TemplatedType[] t1val, TemplatedType.NestedTemplatedType[] t2val, TemplatedType.Enum[] enumVal) public void ClientStartTest(TemplatedType[] t1val, TemplatedType.NestedTemplatedType[] t2val, TemplatedType.Enum[] enumVal) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendTemplateStructOwnerRpc(t1val, t2val, enumVal); } else -#endif { SendTemplateStructServerRpc(t1val, t2val, enumVal); } @@ -1181,13 +1166,11 @@ private void SendTemplateStructClientRpc(TemplatedType[] t1val, TemplatedTy #region ClientStartTest(NetworkSerializableTemplatedType[] t1val, NetworkSerializableTemplatedType.NestedTemplatedType[] t2val) public void ClientStartTest(NetworkSerializableTemplatedType[] t1val, NetworkSerializableTemplatedType.NestedTemplatedType[] t2val) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendNetworkSerializableTemplateStructOwnerRpc(t1val, t2val); } else -#endif { SendNetworkSerializableTemplateStructServerRpc(t1val, t2val); } @@ -1237,13 +1220,11 @@ private void SendNetworkSerializableTemplateStructClientRpc(NetworkSerializableT /// public void ClientStartTest(UserSerializableStruct userSerializableStruct) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendServerSerializedDataStructOwnerRpc(userSerializableStruct); } else -#endif { SendServerSerializedDataStructServerRpc(userSerializableStruct); } @@ -1288,10 +1269,6 @@ private void SendClientSerializedDataStructClientRpc(UserSerializableStruct user #endregion - - - - #region SendMyObject [Rpc(SendTo.NotOwner)] public void SendMyObjectNotOwnerRpc(MyObject obj) @@ -1469,13 +1446,11 @@ public class TestCustomTypesArrayComponent : NetworkBehaviour /// public void ClientStartTest(UserSerializableClass[] userSerializableClasses) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendServerSerializedDataClassArryOwnerRpc(userSerializableClasses); } else -#endif { SendServerSerializedDataClassArryServerRpc(userSerializableClasses); } @@ -1536,13 +1511,11 @@ private void SendClientSerializedDataClassArrayClientRpc(UserSerializableClass[] /// public void ClientStartStructTest(UserSerializableStruct[] userSerializableStructs) { -#if NGO_DAMODE if (NetworkManager.DistributedAuthorityMode) { SendServerSerializedDataStructArrayOwnerRpc(userSerializableStructs); } else -#endif { SendServerSerializedDataStructArrayServerRpc(userSerializableStructs); } diff --git a/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs b/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs index c0d5e87b04..ae2442ece8 100644 --- a/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs +++ b/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs @@ -19,6 +19,12 @@ public class SceneObjectsNotDestroyedOnShutdownTest : NetcodeIntegrationTest private Scene m_TestScene; private WaitForSeconds m_DefaultWaitForTick = new WaitForSeconds(1.0f / 30); + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + [UnityTest] public IEnumerator SceneObjectsNotDestroyedOnShutdown() { @@ -27,30 +33,19 @@ public IEnumerator SceneObjectsNotDestroyedOnShutdown() yield return WaitForConditionOrTimeOut(() => m_TestScene.IsValid() && m_TestScene.isLoaded); AssertOnTimeout($"Timed out waiting for scene {k_TestScene} to load!"); -#if UNITY_2023_1_OR_NEWER var loadedInSceneObject = Object.FindObjectsByType(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName)).FirstOrDefault(); -#else - var loadedInSceneObject = Object.FindObjectsOfType().Where((c) => c.name.Contains(k_SceneObjectName)).FirstOrDefault(); -#endif Assert.IsNotNull(loadedInSceneObject, $"Failed to find {k_SceneObjectName} before starting client!"); AssertOnTimeout($"Timed out waiting to find {k_SceneObjectName} after scene load and before starting client!\""); yield return CreateAndStartNewClient(); -#if UNITY_2023_1_OR_NEWER var loadedInSceneObjects = Object.FindObjectsByType(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName)); -#else - var loadedInSceneObjects = Object.FindObjectsOfType().Where((c) => c.name.Contains(k_SceneObjectName)); -#endif Assert.IsTrue(loadedInSceneObjects.Count() > 1, $"Only found one instance of {k_SceneObjectName} after client connected!"); m_ClientNetworkManagers[0].Shutdown(); yield return m_DefaultWaitForTick; -#if UNITY_2023_1_OR_NEWER loadedInSceneObjects = Object.FindObjectsByType(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName)); -#else - loadedInSceneObjects = Object.FindObjectsOfType().Where((c) => c.name.Contains(k_SceneObjectName)); -#endif + Assert.IsTrue(loadedInSceneObjects.Count() > 1, $"Only found one instance of {k_SceneObjectName} after client shutdown!"); } @@ -63,11 +58,7 @@ public IEnumerator ChildSceneObjectsDoNotDestroyOnShutdown() yield return WaitForConditionOrTimeOut(() => m_TestScene.IsValid() && m_TestScene.isLoaded); AssertOnTimeout($"Timed out waiting for scene {k_TestScene} to load!"); -#if UNITY_2023_1_OR_NEWER var loadedInSceneObject = Object.FindObjectsByType(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName)).FirstOrDefault(); -#else - var loadedInSceneObject = Object.FindObjectsOfType().Where((c) => c.name.Contains(k_SceneObjectName)).FirstOrDefault(); -#endif Assert.IsNotNull(loadedInSceneObject, $"Failed to find {k_SceneObjectName} before starting client!"); yield return CreateAndStartNewClient(); @@ -77,11 +68,7 @@ public IEnumerator ChildSceneObjectsDoNotDestroyOnShutdown() yield return WaitForConditionOrTimeOut(() => PlayerHasChildren(clientId)); AssertOnTimeout($"Client-{clientId} player never parented {k_SceneObjectName}!"); -#if UNITY_2023_1_OR_NEWER var loadedInSceneObjects = Object.FindObjectsByType(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName)); -#else - var loadedInSceneObjects = Object.FindObjectsOfType().Where((c) => c.name.Contains(k_SceneObjectName)); -#endif Assert.IsTrue(loadedInSceneObjects.Count() > 1, $"Only found one instance of {k_SceneObjectName} after client connected!"); m_ClientNetworkManagers[0].Shutdown(); yield return m_DefaultWaitForTick; @@ -89,11 +76,8 @@ public IEnumerator ChildSceneObjectsDoNotDestroyOnShutdown() // Sanity check to make sure the client's player no longer has any children yield return WaitForConditionOrTimeOut(() => PlayerNoLongerExistsWithChildren(clientId)); AssertOnTimeout($"Client-{clientId} player still exits with children after client shutdown!"); -#if UNITY_2023_1_OR_NEWER + loadedInSceneObjects = Object.FindObjectsByType(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName)); -#else - loadedInSceneObjects = Object.FindObjectsOfType().Where((c) => c.name.Contains(k_SceneObjectName)); -#endif // Make sure any in-scene placed NetworkObject instantiated has no parent foreach (var insceneObject in loadedInSceneObjects) { From 3e72d79b8ce2df9da6cfdd30efc8cd4b63fad0ca Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sun, 4 May 2025 13:39:46 -0500 Subject: [PATCH 10/24] Test - Stability Adjusted 3 tests that showed potential for instabilities. --- .../Runtime/DistributedAuthority/DistributeObjectsTests.cs | 5 +++++ .../Runtime/NetworkObject/NetworkObjectOwnershipTests.cs | 5 +++-- .../NetworkObject/NetworkObjectSpawnManyObjectsTests.cs | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs index 087156dfed..345f4ba86f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs @@ -161,6 +161,11 @@ private bool ValidateOwnershipTablesMatch() { foreach (var client in clients) { + if (!DistributeObjectsTestHelper.DistributedObjects.ContainsKey(client)) + { + m_ErrorLog.AppendLine($"[Client-{client}] Does not have an entry in the root of the {nameof(DistributeObjectsTestHelper.DistributedObjects)} table!"); + return false; + } var clientOwnerTable = DistributeObjectsTestHelper.DistributedObjects[client]; if (!clientOwnerTable.ContainsKey(hostClientEntry.Key)) { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs index e7fc968de1..91f3636477 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs @@ -92,8 +92,8 @@ protected override void OnServerAndClientsCreated() base.OnServerAndClientsCreated(); } - [Test] - public void TestPlayerIsOwned() + [UnityTest] + public IEnumerator TestPlayerIsOwned() { var clientOwnedObjects = m_ClientNetworkManagers[0].SpawnManager.GetClientOwnedObjects(m_ClientNetworkManagers[0].LocalClientId); @@ -102,6 +102,7 @@ public void TestPlayerIsOwned() clientPlayerObject = m_ClientNetworkManagers[0].LocalClient.OwnedObjects.Where((c) => c.IsLocalPlayer).FirstOrDefault(); Assert.NotNull(clientPlayerObject, $"Client Id {m_ClientNetworkManagers[0].LocalClientId} does not have its local player marked as an owned object using local client!"); + yield return null; } private bool AllObjectsSpawnedOnClients() diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs index 5db4c0a3b8..573c233314 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs @@ -67,6 +67,8 @@ public IEnumerator WhenManyObjectsAreSpawnedAtOnce_AllAreReceived() yield return WaitForConditionOrTimeOut(() => SpawnObjecTrackingComponent.SpawnedObjects == k_SpawnedObjects, timeoutHelper); AssertOnTimeout($"Timed out waiting for the client to spawn {k_SpawnedObjects} objects! Time to spawn: {timeSpawned} | Time to timeout: {timeStarted - Time.realtimeSinceStartup}", timeoutHelper); + + yield return s_DefaultWaitForTick; } } } From ea28b6959fb599074814a916c53d6f23c4525522 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sun, 4 May 2025 20:03:01 -0500 Subject: [PATCH 11/24] style Fixing misspelled GetServiceEnvironmentVariable. Fixing comment for grammar and clarity. --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 4 ++-- .../TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 5cded99385..ee2524dbbc 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -247,7 +247,7 @@ protected NetworkManager GetNonAuthorityNetworkManager() /// check the environment variable once per test set. /// /// true/false - private bool GetServiceEnviromentVariable() + private bool GetServiceEnvironmentVariable() { if (!m_UseCmbServiceEnv && m_UseCmbServiceEnvString == null) { @@ -427,7 +427,7 @@ public void OneTimeSetup() // If the environment variable is set (i.e. doing a CMB server run) but UseCMBservice returns false, then ignore the test. // Note: This will prevent us from re-running all of the non-DA integration tests that have already run multiple times on // multiple platforms - if (GetServiceEnviromentVariable() && !UseCMBService()) + if (GetServiceEnvironmentVariable() && !UseCMBService()) { Assert.Ignore("[CMB-Server Test Run] Skipping non-distributed authority test."); return; diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 58cfe82ae0..5fe010e6bc 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -174,7 +174,7 @@ public static void RegisterHandlers(NetworkManager networkManager, bool serverSi /// /// Use for non derived integration tests to automatically ignore the - /// test is the USE_CMB_SERVICE is set. + /// test if running against a CMB server. /// internal static void IgnoreIfServiceEnviromentVariableSet() { From 54a2e99ca4ccc2938d8b69a36071abbe2ae5ab92 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sun, 4 May 2025 20:29:44 -0500 Subject: [PATCH 12/24] style Missed one reference to GetServiceEnviromentVariable --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index ee2524dbbc..efe6649a76 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -2046,7 +2046,7 @@ private void InitializeTestConfiguration(NetworkTopologyTypes networkTopologyTyp // If we are using a distributed authority network topology and the environment variable // to use the CMBService is set, then perform the m_UseCmbService check. - if (m_DistributedAuthority && GetServiceEnviromentVariable()) + if (m_DistributedAuthority && GetServiceEnvironmentVariable()) { m_UseCmbService = hostOrServer == HostOrServer.DAHost; // In the event UseCMBService is overridden, we apply the value returned. From 8265347e4f80758fdc2b4ebb7fd461e10ff51792 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 5 May 2025 16:43:28 -0500 Subject: [PATCH 13/24] test-update Reverting back to always incrementing clients when running against a CMB server. Excluding a few more tests I missed previously. Fixing RpcProxyMessageTesting to actually run and test against the correct expected counts. --- .../Runtime/NetcodeIntegrationTest.cs | 52 ++++++----------- .../RpcProxyMessageTesting.cs | 57 +++++++++++++++---- ...NetworkManagerCustomMessageManagerTests.cs | 8 +++ .../NetworkManagerSceneManagerTests.cs | 8 +++ .../Runtime/NetworkManagerTransportTests.cs | 7 +++ .../NetworkTransformStateTests.cs | 8 +++ .../Tests/Runtime/NetworkUpdateLoopTests.cs | 9 +++ 7 files changed, 102 insertions(+), 47 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index efe6649a76..b7ff0ec32d 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -164,6 +164,7 @@ public enum HostOrServer /// The Server instance instantiated and tracked within the current test protected NetworkManager m_ServerNetworkManager; + /// All the client instances instantiated and tracked within the current test protected NetworkManager[] m_ClientNetworkManagers; /// All the instances instantiated and tracked within the current test @@ -251,14 +252,14 @@ private bool GetServiceEnvironmentVariable() { if (!m_UseCmbServiceEnv && m_UseCmbServiceEnvString == null) { - var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false"; - if (bool.TryParse(useCmbService.ToLower(), out bool isTrue)) + m_UseCmbServiceEnvString = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false"; + if (bool.TryParse(m_UseCmbServiceEnvString.ToLower(), out bool isTrue)) { m_UseCmbServiceEnv = isTrue; } else { - Debug.LogWarning($"The USE_CMB_SERVICE ({useCmbService}) value is an invalid bool string. {m_UseCmbService} is being set to false."); + Debug.LogWarning($"The USE_CMB_SERVICE ({m_UseCmbServiceEnvString}) value is an invalid bool string. {m_UseCmbService} is being set to false."); m_UseCmbServiceEnv = false; } } @@ -592,21 +593,6 @@ protected virtual void OnServerAndClientsCreated() { } - /// - /// Will create number of clients. - /// To create a specific number of clients - /// - protected void CreateServerAndClients() - { - // If we are connecting to a CMB server and we have a zero client count, - // then we must make m_NumberOfClients = 1 for the session owner. - if (m_UseCmbService && NumberOfClients == 0 && m_NumberOfClients == 0) - { - m_NumberOfClients = 1; - } - CreateServerAndClients(m_NumberOfClients); - } - private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetworkManager) { var clientNetworkManagersList = new List(m_ClientNetworkManagers); @@ -877,6 +863,15 @@ protected void SetTimeTravelSimulatedLatencyJitter(float jitterSeconds) } } + /// + /// Will create number of clients. + /// To create a specific number of clients + /// + protected void CreateServerAndClients() + { + CreateServerAndClients(NumberOfClients); + } + /// /// Creates the server and clients /// @@ -892,23 +887,10 @@ protected void CreateServerAndClients(int numberOfClients) m_TargetFrameRate = -1; } - // In the event this is invoked within a derived integration test and - // the number of clients is 0, then we need to have at least 1 client - // to be the session owner. - if (m_UseCmbService && numberOfClients == 0) + // If we are connecting to a CMB server we add +1 for the session owner + if (m_UseCmbService) { - numberOfClients = 1; - // If m_NumberOfCleints == 0, then we should increment it. - if (m_NumberOfClients == 0) - { - m_NumberOfClients = 1; - } - else - { - // Otherwise, log a warning to the developer that they may be doing something bad. - Debug.LogWarning($"[{nameof(CreateServerAndClients)}] Invoked with number of clients set to zero but m_NumberOfClients was {m_NumberOfClients}. " + - $"Unless this was intended, this could cause issues with the {nameof(NetcodeIntegrationTest)}!"); - } + numberOfClients++; } // Create multiple NetworkManager instances @@ -917,7 +899,7 @@ protected void CreateServerAndClients(int numberOfClients) Debug.LogError("Failed to create instances"); Assert.Fail("Failed to create instances"); } - + m_NumberOfClients = numberOfClients; m_ClientNetworkManagers = clients; m_ServerNetworkManager = server; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs index 9a7a9f8557..d534ec418e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs @@ -3,6 +3,7 @@ using System.Text; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; +using UnityEngine.TestTools; namespace Unity.Netcode.RuntimeTests { @@ -20,10 +21,17 @@ public class RpcProxyMessageTesting : NetcodeIntegrationTest { protected override int NumberOfClients => 2; - private List m_ProxyTestInstances = new List(); + private List m_ProxyTestInstances = new List(); private StringBuilder m_ValidationLogger = new StringBuilder(); + protected override void OnPreInitializeConfiguration() + { + System.Environment.SetEnvironmentVariable("USE_CMB_SERVICE", "true"); + System.Environment.SetEnvironmentVariable("CMB_SERVICE_PORT", null); + base.OnPreInitializeConfiguration(); + } + public RpcProxyMessageTesting(HostOrServer hostOrServer) : base(hostOrServer) { } protected override IEnumerator OnSetup() @@ -34,7 +42,7 @@ protected override IEnumerator OnSetup() protected override void OnCreatePlayerPrefab() { - m_PlayerPrefab.AddComponent(); + m_PlayerPrefab.AddComponent(); base.OnCreatePlayerPrefab(); } @@ -44,28 +52,53 @@ private bool ValidateRpcProxyRpcs() m_ValidationLogger.Clear(); foreach (var proxy in m_ProxyTestInstances) { - if (proxy.ReceivedRpc.Count < NumberOfClients) + + // Since we are sending to everyone but the authority, the local instance of each client's player should have zero + // entries. + if (proxy.ReceivedRpc.Count != 0) { - m_ValidationLogger.AppendLine($"Not all clients received RPC from Client-{proxy.OwnerClientId}!"); + m_ValidationLogger.AppendLine($"Client-{proxy.OwnerClientId} sent itself an Rpc!"); } - foreach (var clientId in proxy.ReceivedRpc) + foreach (var networkManager in m_NetworkManagers) { - if (clientId == proxy.OwnerClientId) + // Skip the local player instance + if (networkManager.LocalClientId == proxy.OwnerClientId) + { + continue; + } + + // Get the cloned player instance of the player based on the player's NetworkObjectId + if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(proxy.NetworkObjectId)) { - m_ValidationLogger.AppendLine($"Client-{proxy.OwnerClientId} sent itself an Rpc!"); + m_ValidationLogger.AppendLine($"Client-{networkManager.LocalClientId} does not have a cloned instance for Player-{proxy.OwnerClientId}!"); + } + var clonedPlayer = networkManager.SpawnManager.SpawnedObjects[proxy.NetworkObjectId].GetComponent(); + // For each cloned player, each client should receive 1 RPC call per cloned player instance. + // Example (With 3 clients including session owner): + // Client-1 (SO): Sends to NotAuthority + // Client-2: Should receive 1 RPC on its clone of Player-1 + // Client-3: Should receive 1 RPC on its clone of Player-1 + // Client-2: Sends to NotAuthority + // Client-1: Should receive 1 RPC on its clone of Player-2 + // Client-3: Should receive 1 RPC on its clone of Player-2 + // Client-3: Sends to NotAuthority + // Client-1: Should receive 1 RPC on its clone of Player-3 + // Client-2: Should receive 1 RPC on its clone of Player-3 + if (clonedPlayer.ReceivedRpc.Count != 1) + { + m_ValidationLogger.AppendLine($"[{clonedPlayer.name}] Received ({clonedPlayer.ReceivedRpc.Count}) RPCs when we were expected only 1!"); } } } return m_ValidationLogger.Length == 0; } - + [UnityTest] public IEnumerator ProxyDoesNotInvokeOnSender() { - m_ProxyTestInstances.Add(m_ServerNetworkManager.LocalClient.PlayerObject.GetComponent()); - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { - m_ProxyTestInstances.Add(client.LocalClient.PlayerObject.GetComponent()); + m_ProxyTestInstances.Add(client.LocalClient.PlayerObject.GetComponent()); } foreach (var clientProxyTest in m_ProxyTestInstances) @@ -77,7 +110,7 @@ public IEnumerator ProxyDoesNotInvokeOnSender() AssertOnTimeout(m_ValidationLogger.ToString()); } - public class RpcProxyText : NetworkBehaviour + public class RpcProxyTest : NetworkBehaviour { public List ReceivedRpc = new List(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerCustomMessageManagerTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerCustomMessageManagerTests.cs index a43bd24746..da5e0b17ce 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerCustomMessageManagerTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerCustomMessageManagerTests.cs @@ -1,10 +1,18 @@ using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; namespace Unity.Netcode.RuntimeTests { internal class NetworkManagerCustomMessageManagerTests { + [OneTimeSetUp] + public void OneTimeSetup() + { + // This test does not need to run against the Rust server. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [Test] public void CustomMessageManagerAssigned() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerSceneManagerTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerSceneManagerTests.cs index d7544b71f3..39b1bc9e14 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerSceneManagerTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerSceneManagerTests.cs @@ -1,10 +1,18 @@ using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; namespace Unity.Netcode.RuntimeTests { internal class NetworkManagerSceneManagerTests { + [OneTimeSetUp] + public void OneTimeSetup() + { + // This test does not need to run against the Rust server. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [Test] public void SceneManagerAssigned() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs index 484f6301fd..1c4d346a61 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs @@ -11,6 +11,13 @@ namespace Unity.Netcode.RuntimeTests { internal class NetworkManagerTransportTests { + [OneTimeSetUp] + public void OneTimeSetup() + { + // This test does not need to run against the Rust server. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [Test] public void ClientDoesNotStartWhenTransportFails() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformStateTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformStateTests.cs index 0b47dff72a..6ab913866b 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformStateTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformStateTests.cs @@ -1,6 +1,7 @@ #if !MULTIPLAYER_TOOLS using NUnit.Framework; using Unity.Netcode.Components; +using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; @@ -77,6 +78,13 @@ public enum Precision private Precision m_Precision; private Rotation m_Rotation; + [OneTimeSetUp] + public void OneTimeSetup() + { + // This test does not need to run against the Rust server. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + public NetworkTransformStateTests(TransformSpace transformSpace, Precision precision, Rotation rotation) { m_TransformSpace = transformSpace; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkUpdateLoopTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkUpdateLoopTests.cs index 06d10d414f..e8d773f68c 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkUpdateLoopTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkUpdateLoopTests.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Linq; using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; using UnityEngine.LowLevel; using UnityEngine.PlayerLoop; @@ -11,6 +12,14 @@ namespace Unity.Netcode.RuntimeTests { internal class NetworkUpdateLoopTests { + + [OneTimeSetUp] + public void OneTimeSetup() + { + // This test does not need to run against the Rust server. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [Test] public void RegisterCustomLoopInTheMiddle() { From e83c1f5bcd87477410bd448ef32b96dbc12bde20 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 5 May 2025 16:47:39 -0500 Subject: [PATCH 14/24] style - pvp Un-fixing the improperly named test class to avoid more PVP errors. --- .../DistributedAuthority/RpcProxyMessageTesting.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs index d534ec418e..e5dcaddd01 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs @@ -21,7 +21,7 @@ public class RpcProxyMessageTesting : NetcodeIntegrationTest { protected override int NumberOfClients => 2; - private List m_ProxyTestInstances = new List(); + private List m_ProxyTestInstances = new List(); private StringBuilder m_ValidationLogger = new StringBuilder(); @@ -42,7 +42,7 @@ protected override IEnumerator OnSetup() protected override void OnCreatePlayerPrefab() { - m_PlayerPrefab.AddComponent(); + m_PlayerPrefab.AddComponent(); base.OnCreatePlayerPrefab(); } @@ -72,7 +72,7 @@ private bool ValidateRpcProxyRpcs() { m_ValidationLogger.AppendLine($"Client-{networkManager.LocalClientId} does not have a cloned instance for Player-{proxy.OwnerClientId}!"); } - var clonedPlayer = networkManager.SpawnManager.SpawnedObjects[proxy.NetworkObjectId].GetComponent(); + var clonedPlayer = networkManager.SpawnManager.SpawnedObjects[proxy.NetworkObjectId].GetComponent(); // For each cloned player, each client should receive 1 RPC call per cloned player instance. // Example (With 3 clients including session owner): // Client-1 (SO): Sends to NotAuthority @@ -98,7 +98,7 @@ public IEnumerator ProxyDoesNotInvokeOnSender() { foreach (var client in m_NetworkManagers) { - m_ProxyTestInstances.Add(client.LocalClient.PlayerObject.GetComponent()); + m_ProxyTestInstances.Add(client.LocalClient.PlayerObject.GetComponent()); } foreach (var clientProxyTest in m_ProxyTestInstances) @@ -110,7 +110,7 @@ public IEnumerator ProxyDoesNotInvokeOnSender() AssertOnTimeout(m_ValidationLogger.ToString()); } - public class RpcProxyTest : NetworkBehaviour + public class RpcProxyText : NetworkBehaviour { public List ReceivedRpc = new List(); From 891ccde47af16efd48083137b05cbcae6fd0edd1 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 5 May 2025 16:52:49 -0500 Subject: [PATCH 15/24] update removing the OnPreInitializeConfiguration() --- .../Runtime/DistributedAuthority/RpcProxyMessageTesting.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs index e5dcaddd01..279a01b94d 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/RpcProxyMessageTesting.cs @@ -25,13 +25,6 @@ public class RpcProxyMessageTesting : NetcodeIntegrationTest private StringBuilder m_ValidationLogger = new StringBuilder(); - protected override void OnPreInitializeConfiguration() - { - System.Environment.SetEnvironmentVariable("USE_CMB_SERVICE", "true"); - System.Environment.SetEnvironmentVariable("CMB_SERVICE_PORT", null); - base.OnPreInitializeConfiguration(); - } - public RpcProxyMessageTesting(HostOrServer hostOrServer) : base(hostOrServer) { } protected override IEnumerator OnSetup() From 4ee486592da5258b2a4ea019c57bb8c07deb1ad0 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Tue, 6 May 2025 14:39:58 -0500 Subject: [PATCH 16/24] fix Session owner now starts and connects ahead of the other clients. This exposed an issue with the connection sequence and the NetworkClient not getting the approved set to true when the client finished synchronizing. FIxed an issue where NetworkManager names were skewed by 1 during the initial start up sequence (which can make things confusing if logging its name). Fixed an issue with invoking the ClientNetworkManagerPostStartInit a 2nd time when connected to a CMB server. Added some additional logging within the NetworkObjectOwnershipTests.TestOwnedObjectCounts. Added a better logical check within the ConnectionApprovedMessage. --- .../Messages/ConnectionApprovedMessage.cs | 5 +- .../SceneManagement/NetworkSceneManager.cs | 17 +- .../Runtime/NetcodeIntegrationTest.cs | 201 +++++++++--------- .../Runtime/NetcodeIntegrationTestHelpers.cs | 17 +- .../NetworkObjectOwnershipTests.cs | 20 +- 5 files changed, 149 insertions(+), 111 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs index ab46a4465f..c5a6efdfc9 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics; using Unity.Collections; namespace Unity.Netcode @@ -273,10 +274,10 @@ public void Handle(ref NetworkContext context) // Stop the client-side approval timeout coroutine since we are approved. networkManager.ConnectionManager.StopClientApprovalCoroutine(); - networkManager.ConnectionManager.ConnectedClientIds.Clear(); foreach (var clientId in ConnectedClientIds) { - if (!networkManager.ConnectionManager.ConnectedClientIds.Contains(clientId)) + // If there is any disconnect between the connection sequence of Ids vs ConnectedClients, then add the client. + if (!networkManager.ConnectionManager.ConnectedClientIds.Contains(clientId) || !networkManager.ConnectionManager.ConnectedClients.ContainsKey(clientId)) { networkManager.ConnectionManager.AddClient(clientId); } diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index 9a85c510b7..4823116d1b 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -2604,8 +2604,15 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId) SceneName = string.Empty, ClientId = clientId }); - if (NetworkManager.ConnectedClients.ContainsKey(clientId)) + + if (NetworkManager.DistributedAuthorityMode) { + // Make sure we have a NetworkClient for this synchronized client + if (!NetworkManager.ConnectedClients.ContainsKey(clientId)) + { + NetworkManager.ConnectionManager.AddClient(clientId); + } + // Mark this client as being connected NetworkManager.ConnectedClients[clientId].IsConnected = true; } } @@ -2619,6 +2626,14 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId) ClientId = clientId }); + // Make sure we have a NetworkClient for this synchronized client + if (!NetworkManager.ConnectedClients.ContainsKey(clientId)) + { + NetworkManager.ConnectionManager.AddClient(clientId); + } + // Mark this client as being connected + NetworkManager.ConnectedClients[clientId].IsConnected = true; + // Show any NetworkObjects that are: // - Hidden from the session owner // - Owned by this client diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index b7ff0ec32d..f46b5010f7 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -180,14 +180,8 @@ protected NetworkManager GetAuthorityNetworkManager() { if (m_UseCmbService) { - // TODO: Because we start the NetworkManagers back-to-back, the service can make a NetworkManager - // (other than the very first one) the session owner. This could lead to test instabilities and - // we need to add additional code during the start process that will start the very 1st instance - // and wait for it to be approved and assigned the session owner before we assume anything. - // Otherwise, any pick from the m_NetworkManagers could result in that specific instance not being - // the first session owner. - // If we haven't even started any NetworkManager, then just return the first - // instance until we resolve the above issue. + // If we haven't even started any NetworkManager, then return the first instance + // since it will be the session owner. if (!NetcodeIntegrationTestHelpers.IsStarted) { return m_NetworkManagers[0]; @@ -195,9 +189,7 @@ protected NetworkManager GetAuthorityNetworkManager() foreach (var client in m_NetworkManagers) { - // See above notes. - // TODO: Once the above is resolved, just check for client.LocalClient.IsSessionOwner - if (!client.LocalClient.IsApproved || client.LocalClient.IsSessionOwner) + if (client.LocalClient.IsSessionOwner) { return client; } @@ -584,15 +576,6 @@ private void CreatePlayerPrefab() VerboseDebug($"Exiting {nameof(CreatePlayerPrefab)}"); } - /// - /// This is invoked before the server and client(s) are started. - /// Override this method if you want to make any adjustments to their - /// NetworkManager instances. - /// - protected virtual void OnServerAndClientsCreated() - { - } - private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetworkManager) { var clientNetworkManagersList = new List(m_ClientNetworkManagers); @@ -615,6 +598,78 @@ private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetw m_NetworkManagers = clientNetworkManagersList.ToArray(); } + /// + /// This is invoked before the server and client(s) are started. + /// Override this method if you want to make any adjustments to their + /// NetworkManager instances. + /// + protected virtual void OnServerAndClientsCreated() + { + } + + /// + /// Will create number of clients. + /// To create a specific number of clients + /// + protected void CreateServerAndClients() + { + CreateServerAndClients(NumberOfClients); + } + + /// + /// Creates the server and clients + /// + /// The number of client instances to create + protected void CreateServerAndClients(int numberOfClients) + { + VerboseDebug($"Entering {nameof(CreateServerAndClients)}"); + + CreatePlayerPrefab(); + + if (m_EnableTimeTravel) + { + m_TargetFrameRate = -1; + } + + // If we are connecting to a CMB server we add +1 for the session owner + if (m_UseCmbService) + { + numberOfClients++; + } + + // Create multiple NetworkManager instances + if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_CreateServerFirst, m_EnableTimeTravel, m_UseCmbService)) + { + Debug.LogError("Failed to create instances"); + Assert.Fail("Failed to create instances"); + } + m_NumberOfClients = numberOfClients; + m_ClientNetworkManagers = clients; + m_ServerNetworkManager = server; + + var managers = clients.ToList(); + if (!m_UseCmbService) + { + managers.Insert(0, m_ServerNetworkManager); + } + m_NetworkManagers = managers.ToArray(); + + s_DefaultWaitForTick = new WaitForSecondsRealtime(1.0f / GetAuthorityNetworkManager().NetworkConfig.TickRate); + + // Set the player prefab for the server and clients + foreach (var manager in m_NetworkManagers) + { + manager.NetworkConfig.PlayerPrefab = m_PlayerPrefab; + SetDistributedAuthorityProperties(manager); + } + + // Provides opportunity to allow child derived classes to + // modify the NetworkManager's configuration before starting. + OnServerAndClientsCreated(); + + VerboseDebug($"Exiting {nameof(CreateServerAndClients)}"); + } + /// /// CreateAndStartNewClient Only /// Invoked when the newly created client has been created @@ -863,69 +918,6 @@ protected void SetTimeTravelSimulatedLatencyJitter(float jitterSeconds) } } - /// - /// Will create number of clients. - /// To create a specific number of clients - /// - protected void CreateServerAndClients() - { - CreateServerAndClients(NumberOfClients); - } - - /// - /// Creates the server and clients - /// - /// The number of client instances to create - protected void CreateServerAndClients(int numberOfClients) - { - VerboseDebug($"Entering {nameof(CreateServerAndClients)}"); - - CreatePlayerPrefab(); - - if (m_EnableTimeTravel) - { - m_TargetFrameRate = -1; - } - - // If we are connecting to a CMB server we add +1 for the session owner - if (m_UseCmbService) - { - numberOfClients++; - } - - // Create multiple NetworkManager instances - if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_CreateServerFirst, m_EnableTimeTravel, m_UseCmbService)) - { - Debug.LogError("Failed to create instances"); - Assert.Fail("Failed to create instances"); - } - m_NumberOfClients = numberOfClients; - m_ClientNetworkManagers = clients; - m_ServerNetworkManager = server; - - var managers = clients.ToList(); - if (!m_UseCmbService) - { - managers.Insert(0, m_ServerNetworkManager); - } - m_NetworkManagers = managers.ToArray(); - - s_DefaultWaitForTick = new WaitForSecondsRealtime(1.0f / GetAuthorityNetworkManager().NetworkConfig.TickRate); - - // Set the player prefab for the server and clients - foreach (var manager in m_NetworkManagers) - { - manager.NetworkConfig.PlayerPrefab = m_PlayerPrefab; - SetDistributedAuthorityProperties(manager); - } - - // Provides opportunity to allow child derived classes to - // modify the NetworkManager's configuration before starting. - OnServerAndClientsCreated(); - - VerboseDebug($"Exiting {nameof(CreateServerAndClients)}"); - } - /// /// Override this method and return false in order to be able /// to manually control when the server and clients are started. @@ -1028,11 +1020,7 @@ protected void ClientNetworkManagerPostStartInit() if (m_UseHost) { -#if UNITY_2023_1_OR_NEWER var clientSideServerPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == NetworkManager.ServerClientId); -#else - var clientSideServerPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); -#endif foreach (var playerNetworkObject in clientSideServerPlayerClones) { // When the server is not the host this needs to be done @@ -1056,6 +1044,19 @@ protected virtual bool ShouldCheckForSpawnedPlayers() return true; } + /// + /// Starts the session owner and awaits for it to connect before starting the remaining clients. + /// + private IEnumerator StartSessionOwner() + { + VerboseDebug("Starting session owner..."); + NetcodeIntegrationTestHelpers.StartOneClient(m_ClientNetworkManagers[0]); + yield return WaitForConditionOrTimeOut(() => m_ClientNetworkManagers[0].IsConnectedClient); + AssertOnTimeout($"Timed out waiting for the session owner to connect to CMB Server!"); + Assert.True(m_ClientNetworkManagers[0].LocalClient.IsSessionOwner, $"Client-{m_ClientNetworkManagers[0].LocalClientId} started session but was not set to be the session owner!"); + VerboseDebug("Session owner connected and approved."); + } + /// /// This starts the server and clients as long as /// returns true. @@ -1066,17 +1067,21 @@ protected IEnumerator StartServerAndClients() { VerboseDebug($"Entering {nameof(StartServerAndClients)}"); + if (m_UseCmbService) + { + VerboseDebug("Using a distributed authority CMB Server for connection."); + yield return StartSessionOwner(); + } + // Start the instances and pass in our SceneManagerInitialization action that is invoked immediately after host-server // is started and after each client is started. - - VerboseDebug($"Starting with useCmbService: {m_UseCmbService}"); if (!NetcodeIntegrationTestHelpers.Start(m_UseHost, !m_UseCmbService, m_ServerNetworkManager, m_ClientNetworkManagers)) { Debug.LogError("Failed to start instances"); Assert.Fail("Failed to start instances"); } - // When using the CMBService, we don't have a server, so get the appropriate authority network manager + // Get the authority NetworkMananger (Server, Host, or Session Owner) var authorityManager = GetAuthorityNetworkManager(); // When scene management is enabled, we need to re-apply the scenes populated list since we have overriden the ISceneManagerHandler @@ -1108,13 +1113,8 @@ protected IEnumerator StartServerAndClients() if (m_UseHost || authorityManager.IsHost) { -#if UNITY_2023_1_OR_NEWER // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries var serverPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == authorityManager.LocalClientId); -#else - // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries - var serverPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == authorityManager.LocalClientId); -#endif foreach (var playerNetworkObject in serverPlayerClones) { if (!m_PlayerNetworkObjects.ContainsKey(playerNetworkObject.NetworkManager.LocalClientId)) @@ -1128,6 +1128,8 @@ protected IEnumerator StartServerAndClients() } } } + + // With distributed authority, we check that all players have spawned on all NetworkManager instances if (m_DistributedAuthority) { foreach (var networkManager in m_NetworkManagers) @@ -1137,8 +1139,10 @@ protected IEnumerator StartServerAndClients() } } - if (ShouldCheckForSpawnedPlayers()) + // Client-Server or DAHost + if (ShouldCheckForSpawnedPlayers() && !m_UseCmbService) { + // Check for players being spawned on server instance ClientNetworkManagerPostStartInit(); } @@ -1698,13 +1702,12 @@ private bool CheckClientsConnected(NetworkManager[] clientsToCheck) } var manager = GetAuthorityNetworkManager(); - var expectedCount = manager.IsHost ? clientsToCheck.Length + 1 : clientsToCheck.Length; var currentCount = manager.ConnectedClients.Count; - if (currentCount != expectedCount) + if (currentCount != TotalClients) { allClientsConnected = false; - m_InternalErrorLog.AppendLine($"[Server-Side] Expected {expectedCount} clients to connect but only {currentCount} connected!"); + m_InternalErrorLog.AppendLine($"[Server-Side] Expected {TotalClients} clients to connect but only {currentCount} connected!"); } return allClientsConnected; diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 5fe010e6bc..0cb8b3725b 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -327,10 +327,13 @@ internal static NetworkManager CreateNewClient(int identifier, bool mockTranspor public static bool CreateNewClients(int clientCount, out NetworkManager[] clients, bool useMockTransport = false, bool useCmbService = false) { clients = new NetworkManager[clientCount]; + // Pre-identify NetworkManager identifiers based on network topology type + var startCount = useCmbService ? 1 : 0; for (int i = 0; i < clientCount; i++) { // Create networkManager component - clients[i] = CreateNewClient(i, useMockTransport, useCmbService); + clients[i] = CreateNewClient(startCount, useMockTransport, useCmbService); + startCount++; } NetworkManagerInstances.AddRange(clients); @@ -546,6 +549,18 @@ public static bool Start(bool host, NetworkManager server, NetworkManager[] clie foreach (var client in clients) { + if (client.IsConnectedClient) + { + // Skip starting the session owner + if (client.DistributedAuthorityMode && client.CMBServiceConnection && client.LocalClient.IsSessionOwner) + { + continue; + } + else + { + throw new Exception("Client NetworkManager is already connected when starting clients!"); + } + } client.StartClient(); hooks = new MultiInstanceHooks(); client.ConnectionManager.MessageManager.Hook(hooks); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs index 91f3636477..0f5fa1a972 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Text; using NUnit.Framework; using Unity.Netcode.Components; using Unity.Netcode.TestHelpers.Runtime; @@ -443,15 +444,18 @@ private bool AllClientsHaveCorrectObjectCount() return true; } + private StringBuilder m_ErrorLog = new StringBuilder(); + private bool ServerHasCorrectClientOwnedObjectCount() { + m_ErrorLog.Clear(); var authority = GetAuthorityNetworkManager(); - // Only check when we are the host - if (authority.IsHost) + // Only check when we are the host or session owner + if (authority.IsHost || (!authority.IsServer && authority.LocalClient.IsSessionOwner)) { if (authority.LocalClient.OwnedObjects.Length < k_NumberOfSpawnedObjects) { - return false; + m_ErrorLog.AppendLine($"[{authority.name}] Has only {authority.LocalClient.OwnedObjects.Length} spawned objects and expected is {k_NumberOfSpawnedObjects}"); } } @@ -459,10 +463,10 @@ private bool ServerHasCorrectClientOwnedObjectCount() { if (connectedClient.Value.OwnedObjects.Length < k_NumberOfSpawnedObjects) { - return false; + m_ErrorLog.AppendLine($"[Client-{connectedClient.Key}] Has only {connectedClient.Value.OwnedObjects.Length} spawned objects and expected is {k_NumberOfSpawnedObjects}"); } } - return true; + return m_ErrorLog.Length == 0; } [UnityTest] @@ -470,7 +474,7 @@ public IEnumerator TestOwnedObjectCounts() { foreach (var manager in m_NetworkManagers) { - for (int i = 0; i < 5; i++) + for (int i = 0; i < k_NumberOfSpawnedObjects; i++) { SpawnObject(m_OwnershipPrefab, manager); } @@ -480,7 +484,7 @@ public IEnumerator TestOwnedObjectCounts() AssertOnTimeout($"Not all clients spawned {k_NumberOfSpawnedObjects} {nameof(NetworkObject)}s!"); yield return WaitForConditionOrTimeOut(ServerHasCorrectClientOwnedObjectCount); - AssertOnTimeout($"Server does not have the correct count for all clients spawned {k_NumberOfSpawnedObjects} {nameof(NetworkObject)}s!"); + AssertOnTimeout($"Server does not have the correct count for all clients spawned {k_NumberOfSpawnedObjects} {nameof(NetworkObject)}s!\n {m_ErrorLog}"); } /// @@ -496,7 +500,7 @@ public IEnumerator TestAuthorityChangingOwnership() if (m_DistributedAuthority) { - var authorityId = Random.Range(1, NumberOfClients) - 1; + var authorityId = Random.Range(1, TotalClients) - 1; authorityManager = m_ClientNetworkManagers[authorityId]; m_OwnershipObject = SpawnObject(m_OwnershipPrefab, authorityManager); m_OwnershipNetworkObject = m_OwnershipObject.GetComponent(); From 48edae26032b390575ccb05238c033dfeac2473f Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Tue, 6 May 2025 14:52:33 -0500 Subject: [PATCH 17/24] style removing VS IDE injected namespace... >.< --- .../Runtime/Messaging/Messages/ConnectionApprovedMessage.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs index c5a6efdfc9..68a157e35e 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Diagnostics; using Unity.Collections; namespace Unity.Netcode From a0ec8fa3cfa19b9c2c6aae1434637926ca47efb8 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Tue, 6 May 2025 15:35:06 -0500 Subject: [PATCH 18/24] fix Removing the distributed authority check when receiving a client's synchronization as this is needed for client-server as well. --- .../Runtime/SceneManagement/NetworkSceneManager.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index 4823116d1b..bd18a1110e 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -2605,16 +2605,13 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId) ClientId = clientId }); - if (NetworkManager.DistributedAuthorityMode) + // Make sure we have a NetworkClient for this synchronized client + if (!NetworkManager.ConnectedClients.ContainsKey(clientId)) { - // Make sure we have a NetworkClient for this synchronized client - if (!NetworkManager.ConnectedClients.ContainsKey(clientId)) - { - NetworkManager.ConnectionManager.AddClient(clientId); - } - // Mark this client as being connected - NetworkManager.ConnectedClients[clientId].IsConnected = true; + NetworkManager.ConnectionManager.AddClient(clientId); } + // Mark this client as being connected + NetworkManager.ConnectedClients[clientId].IsConnected = true; } else { From 2e79aae91b38819dab3ca508113422f20b89da04 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Tue, 6 May 2025 15:38:59 -0500 Subject: [PATCH 19/24] style condensing the logic and pulling out commonly executed script from the previous logical checks. --- .../SceneManagement/NetworkSceneManager.cs | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index bd18a1110e..b904056c8a 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -2595,42 +2595,26 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId) case SceneEventType.SynchronizeComplete: { // At this point the client is considered fully "connected" - if ((NetworkManager.DistributedAuthorityMode && NetworkManager.LocalClient.IsSessionOwner) || !NetworkManager.DistributedAuthorityMode) + // Make sure we have a NetworkClient for this synchronized client + if (!NetworkManager.ConnectedClients.ContainsKey(clientId)) { - // Notify the local server that a client has finished synchronizing - OnSceneEvent?.Invoke(new SceneEvent() - { - SceneEventType = sceneEventData.SceneEventType, - SceneName = string.Empty, - ClientId = clientId - }); - - // Make sure we have a NetworkClient for this synchronized client - if (!NetworkManager.ConnectedClients.ContainsKey(clientId)) - { - NetworkManager.ConnectionManager.AddClient(clientId); - } - // Mark this client as being connected - NetworkManager.ConnectedClients[clientId].IsConnected = true; + NetworkManager.ConnectionManager.AddClient(clientId); } - else - { - // Notify the local server that a client has finished synchronizing - OnSceneEvent?.Invoke(new SceneEvent() - { - SceneEventType = sceneEventData.SceneEventType, - SceneName = string.Empty, - ClientId = clientId - }); + // Mark this client as being connected + NetworkManager.ConnectedClients[clientId].IsConnected = true; - // Make sure we have a NetworkClient for this synchronized client - if (!NetworkManager.ConnectedClients.ContainsKey(clientId)) - { - NetworkManager.ConnectionManager.AddClient(clientId); - } - // Mark this client as being connected - NetworkManager.ConnectedClients[clientId].IsConnected = true; + // Notify the local server that a client has finished synchronizing + OnSceneEvent?.Invoke(new SceneEvent() + { + SceneEventType = sceneEventData.SceneEventType, + SceneName = string.Empty, + ClientId = clientId + }); + // For non-authority clients in a distributed authority session, we show hidden objects, + // we distribute NetworkObjects, and then we end the scene event. + if (NetworkManager.DistributedAuthorityMode && !NetworkManager.LocalClient.IsSessionOwner) + { // Show any NetworkObjects that are: // - Hidden from the session owner // - Owned by this client From bf33c893198cc9bef4b531d47a7118dfc9c4d366 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Tue, 6 May 2025 16:04:30 -0500 Subject: [PATCH 20/24] update one more test to be excluded --- .../Tests/Runtime/StartStopTests.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/StartStopTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/StartStopTests.cs index bb928e1746..eaa4ebe91e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/StartStopTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/StartStopTests.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; namespace Unity.Netcode.RuntimeTests @@ -7,6 +8,13 @@ internal class StartStopTests { private NetworkManager m_NetworkManager; + [OneTimeSetUp] + public void OneTimeSetup() + { + // This test does not need to run against the Rust server. + NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet(); + } + [SetUp] public void Setup() { From 8f50f1460f83c826f5de7edef2017d9375c39de3 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Tue, 6 May 2025 17:56:21 -0500 Subject: [PATCH 21/24] update Don't auto-start the session owner when running codec tests. --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 10 +++++++++- .../DistributedAuthorityCodecTests.cs | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index f46b5010f7..3441ec1b5d 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -1057,6 +1057,14 @@ private IEnumerator StartSessionOwner() VerboseDebug("Session owner connected and approved."); } + /// + /// Determines whether the session owner will be auto-started prior to any other client + /// + internal virtual bool ShouldAutoStartSessionOwner() + { + return true; + } + /// /// This starts the server and clients as long as /// returns true. @@ -1067,7 +1075,7 @@ protected IEnumerator StartServerAndClients() { VerboseDebug($"Entering {nameof(StartServerAndClients)}"); - if (m_UseCmbService) + if (m_UseCmbService && ShouldAutoStartSessionOwner()) { VerboseDebug("Using a distributed authority CMB Server for connection."); yield return StartSessionOwner(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs index 71b87abe81..07c2e0067f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs @@ -68,6 +68,14 @@ public void TestAuthorityRpc(byte[] _) } } + /// + /// Don't auto start the session owner for codec tests + /// + internal override bool ShouldAutoStartSessionOwner() + { + return false; + } + protected override void OnOneTimeSetup() { // Prevents the tests from running if no CMB Service is detected From 528d1203e518a61ae024f9ceaabee7a127917c5a Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Tue, 6 May 2025 21:54:43 -0500 Subject: [PATCH 22/24] update Return 1st client NetworkManager if not auto-starting the session owner and there are no defined session owners in the existing client NetworkManagers. --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 3441ec1b5d..aa7408060b 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -194,7 +194,18 @@ protected NetworkManager GetAuthorityNetworkManager() return client; } } - Assert.Fail("No DA session owner found!"); + + // If we have not found a session owner and we are not + // auto-starting the session owner, then return the first + // client NetworkManager. + if (!ShouldAutoStartSessionOwner()) + { + return m_NetworkManagers[0]; + } + else + { + Assert.Fail("No DA session owner found!"); + } } return m_ServerNetworkManager; From a89bfbbcae9f49890f36a97826bf564bf8b8e40b Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 12 May 2025 17:25:37 -0500 Subject: [PATCH 23/24] update - 1:1 Review changes Modifications after doing 1:1 with Emma. --- .../Messages/ConnectionApprovedMessage.cs | 2 + .../Runtime/NetcodeIntegrationTest.cs | 60 +++---------------- .../Runtime/NetcodeIntegrationTestHelpers.cs | 19 +++++- .../DistributedAuthorityCodecTests.cs | 10 +--- .../Runtime/NetworkBehaviourUpdaterTests.cs | 2 +- .../NetworkObjectSpawnManyObjectsTests.cs | 2 + .../NetworkVarBufferCopyTest.cs | 7 +-- .../Runtime/Physics/NetworkRigidbodyTest.cs | 6 +- 8 files changed, 34 insertions(+), 74 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs index 68a157e35e..807429fdb8 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs @@ -275,6 +275,8 @@ public void Handle(ref NetworkContext context) foreach (var clientId in ConnectedClientIds) { + // DANGO-TODO: Revisit the entire connection sequence and determine why we would need to check both cases as we shouldn't have to =or= we could + // try removing this after the Rust server connection sequence stuff is resolved. (Might be only needed if scene management is disabled) // If there is any disconnect between the connection sequence of Ids vs ConnectedClients, then add the client. if (!networkManager.ConnectionManager.ConnectedClientIds.Contains(clientId) || !networkManager.ConnectionManager.ConnectedClients.ContainsKey(clientId)) { diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index aa7408060b..ea365b3fc0 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -194,18 +194,7 @@ protected NetworkManager GetAuthorityNetworkManager() return client; } } - - // If we have not found a session owner and we are not - // auto-starting the session owner, then return the first - // client NetworkManager. - if (!ShouldAutoStartSessionOwner()) - { - return m_NetworkManagers[0]; - } - else - { - Assert.Fail("No DA session owner found!"); - } + Assert.Fail("No DA session owner found!"); } return m_ServerNetworkManager; @@ -255,7 +244,7 @@ private bool GetServiceEnvironmentVariable() { if (!m_UseCmbServiceEnv && m_UseCmbServiceEnvString == null) { - m_UseCmbServiceEnvString = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false"; + m_UseCmbServiceEnvString = NetcodeIntegrationTestHelpers.GetCMBServiceEnvironentVariable(); if (bool.TryParse(m_UseCmbServiceEnvString.ToLower(), out bool isTrue)) { m_UseCmbServiceEnv = isTrue; @@ -276,11 +265,7 @@ private bool GetServiceEnvironmentVariable() /// true if a DAHost test should run against a hosted CMB service instance; otherwise false protected virtual bool UseCMBService() { -#if USE_CMB_SERVICE - return true; -#else return m_UseCmbService; -#endif } protected virtual NetworkTopologyTypes OnGetNetworkTopologyType() @@ -983,13 +968,8 @@ private void ClientNetworkManagerPostStart(NetworkManager networkManager) m_PlayerNetworkObjects.Add(networkManager.LocalClientId, new Dictionary()); } -#if UNITY_2023_1_OR_NEWER // Get all player instances for the current client NetworkManager instance var clientPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == networkManager.LocalClientId).ToList(); -#else - // Get all player instances for the current client NetworkManager instance - var clientPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == networkManager.LocalClientId).ToList(); -#endif // Add this player instance to each client player entry foreach (var playerNetworkObject in clientPlayerClones) { @@ -1004,13 +984,8 @@ private void ClientNetworkManagerPostStart(NetworkManager networkManager) m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(networkManager.LocalClientId, playerNetworkObject); } } -#if UNITY_2023_1_OR_NEWER // For late joining clients, add the remaining (if any) cloned versions of each client's player clientPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.NetworkManager == networkManager).ToList(); -#else - // For late joining clients, add the remaining (if any) cloned versions of each client's player - clientPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.NetworkManager == networkManager).ToList(); -#endif foreach (var playerNetworkObject in clientPlayerClones) { if (!m_PlayerNetworkObjects[networkManager.LocalClientId].ContainsKey(playerNetworkObject.OwnerClientId)) @@ -1058,6 +1033,10 @@ protected virtual bool ShouldCheckForSpawnedPlayers() /// /// Starts the session owner and awaits for it to connect before starting the remaining clients. /// + /// + /// DANGO-TODO: Renove this when the Rust server connection sequence is fixed and we don't have to pre-start + /// the session owner. + /// private IEnumerator StartSessionOwner() { VerboseDebug("Starting session owner..."); @@ -1068,14 +1047,6 @@ private IEnumerator StartSessionOwner() VerboseDebug("Session owner connected and approved."); } - /// - /// Determines whether the session owner will be auto-started prior to any other client - /// - internal virtual bool ShouldAutoStartSessionOwner() - { - return true; - } - /// /// This starts the server and clients as long as /// returns true. @@ -1086,7 +1057,9 @@ protected IEnumerator StartServerAndClients() { VerboseDebug($"Entering {nameof(StartServerAndClients)}"); - if (m_UseCmbService && ShouldAutoStartSessionOwner()) + // DANGO-TODO: Renove this when the Rust server connection sequence is fixed and we don't have to pre-start + // the session owner. + if (m_UseCmbService) { VerboseDebug("Using a distributed authority CMB Server for connection."); yield return StartSessionOwner(); @@ -2018,23 +1991,8 @@ public NetcodeIntegrationTest(HostOrServer hostOrServer) InitializeTestConfiguration(m_NetworkTopologyType, hostOrServer); } - /// - /// Override this virtual method to execute script that runs before the base class constructor has finished executing.
- ///
- /// - /// ***NOTE*** - /// When this method is invoked there will have been no properties set (i.e. nothing is configured).
- /// Primarily this is to set things like environemnt variables or other more external configurations that could - /// determine how the is configured. - ///
- protected virtual void OnPreInitializeConfiguration() - { - } - private void InitializeTestConfiguration(NetworkTopologyTypes networkTopologyType, HostOrServer? hostOrServer) { - OnPreInitializeConfiguration(); - NetworkMessageManager.EnableMessageOrderConsoleLog = false; // Set m_NetworkTopologyType first because m_DistributedAuthority is calculated from it. diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 0cb8b3725b..331a345d22 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -172,13 +172,26 @@ public static void RegisterHandlers(NetworkManager networkManager, bool serverSi } } + /// + /// Gets the CMB_SERVICE environemnt variable or returns "false" if it does not exist + /// + /// string + internal static string GetCMBServiceEnvironentVariable() + { +#if USE_CMB_SERVICE + return "true"; +#else + return Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false"; +#endif + } + /// /// Use for non derived integration tests to automatically ignore the /// test if running against a CMB server. /// internal static void IgnoreIfServiceEnviromentVariableSet() { - if (bool.TryParse(Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "false", out bool isTrue) ? isTrue : false) + if (bool.TryParse(GetCMBServiceEnvironentVariable(), out bool isTrue) ? isTrue : false) { Assert.Ignore("[CMB-Server Test Run] Skipping non-distributed authority test."); } @@ -327,7 +340,7 @@ internal static NetworkManager CreateNewClient(int identifier, bool mockTranspor public static bool CreateNewClients(int clientCount, out NetworkManager[] clients, bool useMockTransport = false, bool useCmbService = false) { clients = new NetworkManager[clientCount]; - // Pre-identify NetworkManager identifiers based on network topology type + // Pre-identify NetworkManager identifiers based on network topology type (Rust server starts at client identifier 1 and considers itself 0) var startCount = useCmbService ? 1 : 0; for (int i = 0; i < clientCount; i++) { @@ -549,6 +562,8 @@ public static bool Start(bool host, NetworkManager server, NetworkManager[] clie foreach (var client in clients) { + // DANGO-TODO: Renove this entire check when the Rust server connection sequence is fixed and we don't have to pre-start + // the session owner. if (client.IsConnectedClient) { // Skip starting the session owner diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs index 07c2e0067f..9c28fcf94e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs @@ -30,7 +30,7 @@ namespace Unity.Netcode.RuntimeTests /// internal class DistributedAuthorityCodecTests : NetcodeIntegrationTest { - protected override int NumberOfClients => 1; + protected override int NumberOfClients => 0; // Use the CMB Service for all tests protected override bool UseCMBService() => true; @@ -68,14 +68,6 @@ public void TestAuthorityRpc(byte[] _) } } - /// - /// Don't auto start the session owner for codec tests - /// - internal override bool ShouldAutoStartSessionOwner() - { - return false; - } - protected override void OnOneTimeSetup() { // Prevents the tests from running if no CMB Service is detected diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs index ed86bcc641..10eb4ee742 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs @@ -168,7 +168,7 @@ public NetworkBehaviourUpdaterTests(HostOrServer hostOrServer, int numberOfClien SecondType = second }; // Adjust the client count if connecting to the service. - m_ClientCount = UseCMBService() ? numberOfClients + 1 : numberOfClients; + m_ClientCount = numberOfClients; } protected override IEnumerator OnSetup() diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs index 573c233314..879319b10f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs @@ -68,6 +68,8 @@ public IEnumerator WhenManyObjectsAreSpawnedAtOnce_AllAreReceived() AssertOnTimeout($"Timed out waiting for the client to spawn {k_SpawnedObjects} objects! Time to spawn: {timeSpawned} | Time to timeout: {timeStarted - Time.realtimeSinceStartup}", timeoutHelper); + // Provide one full tick for all messages to finish being processed. + // DANGO-TODO: Determine if this is only when testing against Rust server (i.e. messages still pending and clients shutting down before they are dequeued) yield return s_DefaultWaitForTick; } } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs index dcc6f8fe01..ab894f0ce6 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs @@ -101,15 +101,10 @@ public override void OnNetworkSpawn() base.OnNetworkSpawn(); } } - protected override int NumberOfClients => m_ClientCount; - - private const int k_ClientCount = 1; - private int m_ClientCount = k_ClientCount; + protected override int NumberOfClients => 1; public NetworkVarBufferCopyTest(HostOrServer hostOrServer) : base(hostOrServer) { - // Adjust the client count if connecting to the CMB service. - m_ClientCount = UseCMBService() ? k_ClientCount + 1 : k_ClientCount; } private static List s_ClientDummyNetBehavioursSpawned = new List(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs index 357e36ebf0..fc813316da 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs @@ -339,10 +339,8 @@ protected void Log(string msg) [TestFixture(HostOrServer.DAHost, ContactEventTypes.WithInfo)] internal class RigidbodyContactEventManagerTests : IntegrationTestWithApproximation { - protected override int NumberOfClients => m_ClientCount; + protected override int NumberOfClients => 1; - private const int k_ClientCount = 1; - private int m_ClientCount = k_ClientCount; private GameObject m_RigidbodyContactEventManager; public enum ContactEventTypes @@ -356,8 +354,6 @@ public enum ContactEventTypes public RigidbodyContactEventManagerTests(HostOrServer hostOrServer, ContactEventTypes contactEventType) : base(hostOrServer) { - // Adjust the client count if connecting to the CMB service. - m_ClientCount = UseCMBService() ? k_ClientCount + 1 : k_ClientCount; m_ContactEventType = contactEventType; } From 317e6b8330905d9e8df8c2bf4830923e98a5087e Mon Sep 17 00:00:00 2001 From: Emma Date: Tue, 13 May 2025 12:05:59 -0400 Subject: [PATCH 24/24] Fix DistributedAuthorityCodecTests.cs --- .../DistributedAuthorityCodecTests.cs | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs index 9c28fcf94e..3714f4a6d0 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityCodecTests.cs @@ -39,7 +39,7 @@ internal class DistributedAuthorityCodecTests : NetcodeIntegrationTest protected override NetworkTopologyTypes OnGetNetworkTopologyType() => NetworkTopologyTypes.DistributedAuthority; private CodecTestHooks m_ClientCodecHook; - private NetworkManager Client => m_ClientNetworkManagers[0]; + private NetworkManager m_Client; private string m_TransportHost = Environment.GetEnvironmentVariable("NGO_HOST") ?? "127.0.0.1"; private static readonly ushort k_TransportPort = GetPortToBind(); @@ -100,48 +100,48 @@ protected override void OnCreatePlayerPrefab() ///
protected override void OnServerAndClientsCreated() { - var utpTransport = Client.gameObject.AddComponent(); - Client.NetworkConfig.NetworkTransport = utpTransport; - Client.NetworkConfig.EnableSceneManagement = false; - Client.NetworkConfig.AutoSpawnPlayerPrefabClientSide = true; + m_Client = GetAuthorityNetworkManager(); + + var utpTransport = m_Client.gameObject.AddComponent(); + m_Client.NetworkConfig.NetworkTransport = utpTransport; + m_Client.NetworkConfig.EnableSceneManagement = false; + m_Client.NetworkConfig.AutoSpawnPlayerPrefabClientSide = true; utpTransport.ConnectionData.Address = Dns.GetHostAddresses(m_TransportHost).First().ToString(); utpTransport.ConnectionData.Port = k_TransportPort; - Client.LogLevel = LogLevel.Developer; + m_Client.LogLevel = LogLevel.Developer; // Validate we are in distributed authority mode with client side spawning and using CMB Service - Assert.True(Client.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); - Assert.True(Client.AutoSpawnPlayerPrefabClientSide, "Client side spawning is not set!"); - Assert.True(Client.CMBServiceConnection, "CMBServiceConnection is not set!"); + Assert.True(m_Client.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); + Assert.True(m_Client.AutoSpawnPlayerPrefabClientSide, "Client side spawning is not set!"); + Assert.True(m_Client.CMBServiceConnection, "CMBServiceConnection is not set!"); // Create a prefab for creating and destroying tests (auto-registers with NetworkManagers) m_SpawnObject = CreateNetworkObjectPrefab("TestObject"); m_SpawnObject.AddComponent(); - - // Ignore the client connection timeout after starting the client - m_BypassConnectionTimeout = true; } protected override IEnumerator OnStartedServerAndClients() { // Validate the NetworkManager are in distributed authority mode - Assert.True(Client.DistributedAuthorityMode, "Distributed authority is not set!"); + Assert.True(m_Client.DistributedAuthorityMode, "Distributed authority is not set!"); - // Register hooks after starting clients and server (in this case just the one client) - // We do this at this point in time because the MessageManager exists (happens within the same call stack when starting NetworkManagers) - m_ClientCodecHook = new CodecTestHooks(); - Client.MessageManager.Hook(m_ClientCodecHook); yield return base.OnStartedServerAndClients(); // wait for client to connect since m_BypassConnectionTimeout - yield return WaitForConditionOrTimeOut(() => Client.LocalClient.PlayerObject != null); + yield return WaitForConditionOrTimeOut(() => m_Client.LocalClient.PlayerObject != null); AssertOnTimeout($"Timed out waiting for the client's player to be spanwed!"); + + // Register hooks after starting clients and server (in this case just the one client) + // We do this at this after all the setup has finished in order to ensure our hooks are only catching messages from the tests + m_ClientCodecHook = new CodecTestHooks(); + m_Client.MessageManager.Hook(m_ClientCodecHook); } [UnityTest] public IEnumerator AuthorityRpc() { - var player = Client.LocalClient.PlayerObject; - player.OwnerClientId = Client.LocalClientId + 1; + var player = m_Client.LocalClient.PlayerObject; + player.OwnerClientId = m_Client.LocalClientId + 1; var networkComponent = player.GetComponent(); networkComponent.UpdateNetworkProperties(); @@ -189,14 +189,14 @@ public IEnumerator ClientDisconnected() [UnityTest] public IEnumerator CreateObject() { - SpawnObject(m_SpawnObject, Client); + SpawnObject(m_SpawnObject, m_Client); yield return m_ClientCodecHook.WaitForMessageReceived(); } [UnityTest] public IEnumerator DestroyObject() { - var spawnedObject = SpawnObject(m_SpawnObject, Client); + var spawnedObject = SpawnObject(m_SpawnObject, m_Client); yield return m_ClientCodecHook.WaitForMessageReceived(); spawnedObject.GetComponent().Despawn(); yield return m_ClientCodecHook.WaitForMessageReceived(); @@ -231,10 +231,10 @@ public IEnumerator NamedMessage() [UnityTest] public IEnumerator NetworkVariableDelta() { - var component = Client.LocalClient.PlayerObject.GetComponent(); + var component = m_Client.LocalClient.PlayerObject.GetComponent(); var message = new NetworkVariableDeltaMessage { - NetworkObjectId = Client.LocalClient.PlayerObject.NetworkObjectId, + NetworkObjectId = m_Client.LocalClient.PlayerObject.NetworkObjectId, NetworkBehaviourIndex = component.NetworkBehaviourId, DeliveryMappedNetworkVariableIndex = new HashSet { 0, 1 }, TargetClientId = 5, @@ -247,7 +247,7 @@ public IEnumerator NetworkVariableDelta() [UnityTest] public IEnumerator NetworkVariableDelta_WithValueUpdate() { - var instance = SpawnObject(m_SpawnObject, Client); + var instance = SpawnObject(m_SpawnObject, m_Client); yield return m_ClientCodecHook.WaitForMessageReceived(); var component = instance.GetComponent(); @@ -260,7 +260,7 @@ public IEnumerator NetworkVariableDelta_WithValueUpdate() [UnityTest] public IEnumerator NetworkListDelta_WithValueUpdate() { - var instance = SpawnObject(m_SpawnObject, Client); + var instance = SpawnObject(m_SpawnObject, m_Client); yield return m_ClientCodecHook.WaitForMessageReceived(); var component = instance.GetComponent(); @@ -337,8 +337,8 @@ public IEnumerator UnnamedMessage() [UnityTest] public IEnumerator SceneEventMessageLoad() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.Load, LoadSceneMode = LoadSceneMode.Single, @@ -357,14 +357,14 @@ public IEnumerator SceneEventMessageLoad() [UnityTest] public IEnumerator SceneEventMessageLoadWithObjects() { - Client.SceneManager.SkipSceneHandling = true; + m_Client.SceneManager.SkipSceneHandling = true; var prefabNetworkObject = m_SpawnObject.GetComponent(); - Client.SceneManager.ScenePlacedObjects.Add(0, new Dictionary() + m_Client.SceneManager.ScenePlacedObjects.Add(0, new Dictionary() { { 1, prefabNetworkObject } }); - var eventData = new SceneEventData(Client) + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.Load, LoadSceneMode = LoadSceneMode.Single, @@ -383,8 +383,8 @@ public IEnumerator SceneEventMessageLoadWithObjects() [UnityTest] public IEnumerator SceneEventMessageUnload() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.Unload, LoadSceneMode = LoadSceneMode.Single, @@ -403,8 +403,8 @@ public IEnumerator SceneEventMessageUnload() [UnityTest] public IEnumerator SceneEventMessageLoadComplete() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.LoadComplete, LoadSceneMode = LoadSceneMode.Single, @@ -423,8 +423,8 @@ public IEnumerator SceneEventMessageLoadComplete() [UnityTest] public IEnumerator SceneEventMessageUnloadComplete() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.UnloadComplete, LoadSceneMode = LoadSceneMode.Single, @@ -443,8 +443,8 @@ public IEnumerator SceneEventMessageUnloadComplete() [UnityTest] public IEnumerator SceneEventMessageLoadCompleted() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.LoadEventCompleted, LoadSceneMode = LoadSceneMode.Single, @@ -465,8 +465,8 @@ public IEnumerator SceneEventMessageLoadCompleted() [UnityTest] public IEnumerator SceneEventMessageUnloadLoadCompleted() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.UnloadEventCompleted, LoadSceneMode = LoadSceneMode.Single, @@ -487,8 +487,8 @@ public IEnumerator SceneEventMessageUnloadLoadCompleted() [UnityTest] public IEnumerator SceneEventMessageSynchronize() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.Synchronize, LoadSceneMode = LoadSceneMode.Single, @@ -512,8 +512,8 @@ public IEnumerator SceneEventMessageSynchronize() [UnityTest] public IEnumerator SceneEventMessageReSynchronize() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.ReSynchronize, LoadSceneMode = LoadSceneMode.Single, @@ -532,8 +532,8 @@ public IEnumerator SceneEventMessageReSynchronize() [UnityTest] public IEnumerator SceneEventMessageSynchronizeComplete() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.ReSynchronize, LoadSceneMode = LoadSceneMode.Single, @@ -552,8 +552,8 @@ public IEnumerator SceneEventMessageSynchronizeComplete() [UnityTest] public IEnumerator SceneEventMessageActiveSceneChanged() { - Client.SceneManager.SkipSceneHandling = true; - var eventData = new SceneEventData(Client) + m_Client.SceneManager.SkipSceneHandling = true; + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.ActiveSceneChanged, ActiveSceneHash = XXHash.Hash32("ActiveScene") @@ -569,15 +569,15 @@ public IEnumerator SceneEventMessageActiveSceneChanged() [UnityTest, Ignore("Serializing twice causes data to disappear in the SceneManager for this event")] public IEnumerator SceneEventMessageObjectSceneChanged() { - Client.SceneManager.SkipSceneHandling = true; + m_Client.SceneManager.SkipSceneHandling = true; var prefabNetworkObject = m_SpawnObject.GetComponent(); - Client.SceneManager.ObjectsMigratedIntoNewScene = new Dictionary>> + m_Client.SceneManager.ObjectsMigratedIntoNewScene = new Dictionary>> { { 0, new Dictionary>()} }; - Client.SceneManager.ObjectsMigratedIntoNewScene[0].Add(Client.LocalClientId, new List() { prefabNetworkObject }); - var eventData = new SceneEventData(Client) + m_Client.SceneManager.ObjectsMigratedIntoNewScene[0].Add(m_Client.LocalClientId, new List() { prefabNetworkObject }); + var eventData = new SceneEventData(m_Client) { SceneEventType = SceneEventType.ObjectSceneChanged, }; @@ -592,12 +592,12 @@ public IEnumerator SceneEventMessageObjectSceneChanged() private IEnumerator SendMessage(ref T message) where T : INetworkMessage { - Client.MessageManager.SetVersion(k_ClientId, XXHash.Hash32(typeof(T).FullName), message.Version); + m_Client.MessageManager.SetVersion(k_ClientId, XXHash.Hash32(typeof(T).FullName), message.Version); var clientIds = new NativeArray(1, Allocator.Temp); clientIds[0] = k_ClientId; - Client.MessageManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, clientIds); - Client.MessageManager.ProcessSendQueues(); + m_Client.MessageManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, clientIds); + m_Client.MessageManager.ProcessSendQueues(); return m_ClientCodecHook.WaitForMessageReceived(message); }