From 4838f979942be882ab3cebcaf1ccbadbc7806d50 Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Thu, 30 Oct 2025 17:33:37 -0500 Subject: [PATCH 1/2] test - fix Resolving the PeerDisconnectCallbackTests instability where sometimes the disconnect notification is processed prior to the targeted client's NetworkManager having completely disconnected and shutdown (this would only have a chance of happening if server disconnects the client). Hoping to resolve the instability with the ParentingInSceneObjectsTests resulting in a false failure. --- .../Runtime/PeerDisconnectCallbackTests.cs | 20 +++++++++++++++++-- .../ParentingInSceneObjectsTests.cs | 8 ++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/PeerDisconnectCallbackTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/PeerDisconnectCallbackTests.cs index 896aa90bf5..b7512753a4 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/PeerDisconnectCallbackTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/PeerDisconnectCallbackTests.cs @@ -83,9 +83,21 @@ private void OnConnectionEventCallback(NetworkManager networkManager, Connection } } + private bool m_TargetClientShutdown; + private NetworkManager m_TargetClient; + + private void ClientToDisconnect_OnClientStopped(bool wasHost) + { + m_TargetClient.OnClientStopped -= ClientToDisconnect_OnClientStopped; + m_TargetClientShutdown = true; + } + [UnityTest] public IEnumerator TestPeerDisconnectCallback([Values] ClientDisconnectType clientDisconnectType, [Values(1ul, 2ul, 3ul)] ulong disconnectedClient) { + m_TargetClientShutdown = false; + m_TargetClient = m_ClientNetworkManagers[disconnectedClient - 1]; + m_TargetClient.OnClientStopped += ClientToDisconnect_OnClientStopped; foreach (var client in m_ClientNetworkManagers) { client.OnConnectionEvent += OnConnectionEventCallback; @@ -129,12 +141,15 @@ public IEnumerator TestPeerDisconnectCallback([Values] ClientDisconnectType clie } else { - yield return StopOneClient(m_ClientNetworkManagers[disconnectedClient - 1]); + yield return StopOneClient(m_TargetClient); } yield return WaitForConditionOrTimeOut(hooks); + AssertOnTimeout($"Timed out waiting for all clients to receive the {nameof(ClientDisconnectedMessage)}!"); - Assert.False(s_GlobalTimeoutHelper.TimedOut); + // Make sure the target client is shutdown before performing validation + yield return WaitForConditionOrTimeOut(() => m_TargetClientShutdown); + AssertOnTimeout($"Timed out waiting for {m_TargetClient.name} to shutdown!"); foreach (var client in m_ClientNetworkManagers) { @@ -182,5 +197,6 @@ public IEnumerator TestPeerDisconnectCallback([Values] ClientDisconnectType clie // Host receives peer disconnect, dedicated server does not Assert.AreEqual(m_UseHost ? 3 : 2, m_PeerDisconnectCount); } + } } diff --git a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs index b227eb2fb8..ac5a7b47d8 100644 --- a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs +++ b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs @@ -332,21 +332,21 @@ public IEnumerator InSceneParentingTest([Values] ParentingSpace parentingSpace) { InSceneParentChildHandler.AuthorityRootParent.DeparentSetValuesAndReparent(); - yield return WaitForConditionOrTimeOut(ValidateClientsAgainstAuthorityTransformValues); + yield return WaitForConditionOrTimeOut(() => ValidateAllChildrenParentingStatus(true)); if (s_GlobalTimeoutHelper.TimedOut) { InSceneParentChildHandler.AuthorityRootParent.CheckChildren(); yield return debugWait; } - AssertOnTimeout($"[Final Pass][Deparent-Reparent-{i}] Timed out waiting for all clients transform values to match the server transform values!\n {m_ErrorValidationLog}"); + AssertOnTimeout($"[Final Pass][Deparent-Reparent-{i}] Timed out waiting for all children to be removed from their parent!\n {m_ErrorValidationLog}"); - yield return WaitForConditionOrTimeOut(() => ValidateAllChildrenParentingStatus(true)); + yield return WaitForConditionOrTimeOut(ValidateClientsAgainstAuthorityTransformValues); if (s_GlobalTimeoutHelper.TimedOut) { InSceneParentChildHandler.AuthorityRootParent.CheckChildren(); yield return debugWait; } - AssertOnTimeout($"[Final Pass][Deparent-Reparent-{i}] Timed out waiting for all children to be removed from their parent!\n {m_ErrorValidationLog}"); + AssertOnTimeout($"[Final Pass][Deparent-Reparent-{i}] Timed out waiting for all clients transform values to match the server transform values!\n {m_ErrorValidationLog}"); } // In the final pass, we remove the second generation nested child From f2ee3357b763e444eba02bd9ccc290f39e03d450 Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Thu, 30 Oct 2025 19:20:43 -0500 Subject: [PATCH 2/2] test fix Fixing potential cause for instabilities on this set of tests due to the initial network prefab transform settings not being applied to the prefab but applied to the spawned instances which could be causing issues since they were being applied to the non-authority instances. This fix moves the applied test NetworkTrransform settings to the player prefab prior to spawning any instances. --- .../NetworkTransform/NetworkTransformBase.cs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformBase.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformBase.cs index cc7491eeec..ba03c78fb4 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformBase.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformBase.cs @@ -230,6 +230,11 @@ protected override void OnCreatePlayerPrefab() { var networkTransformTestComponent = m_PlayerPrefab.AddComponent(); networkTransformTestComponent.ServerAuthority = m_Authority == Authority.ServerAuthority; + // Handle setting up additional transform settings for the current test here. + networkTransformTestComponent.UseUnreliableDeltas = UseUnreliableDeltas(); + networkTransformTestComponent.UseHalfFloatPrecision = m_Precision == Precision.Half; + networkTransformTestComponent.UseQuaternionSynchronization = m_Rotation == Rotation.Quaternion; + networkTransformTestComponent.UseQuaternionCompression = m_RotationCompression == RotationCompression.QuaternionCompress; } protected override void OnServerAndClientsCreated() @@ -291,19 +296,6 @@ protected virtual void OnClientsAndServerConnectedSetup() // Get the NetworkTransformTestComponent to make sure the client side is ready before starting test m_AuthoritativeTransform = m_AuthoritativePlayer.GetComponent(); m_NonAuthoritativeTransform = m_NonAuthoritativePlayer.GetComponent(); - - // Setup whether we are or are not using unreliable deltas - m_AuthoritativeTransform.UseUnreliableDeltas = UseUnreliableDeltas(); - m_NonAuthoritativeTransform.UseUnreliableDeltas = UseUnreliableDeltas(); - - m_AuthoritativeTransform.UseHalfFloatPrecision = m_Precision == Precision.Half; - m_AuthoritativeTransform.UseQuaternionSynchronization = m_Rotation == Rotation.Quaternion; - m_AuthoritativeTransform.UseQuaternionCompression = m_RotationCompression == RotationCompression.QuaternionCompress; - m_NonAuthoritativeTransform.UseHalfFloatPrecision = m_Precision == Precision.Half; - m_NonAuthoritativeTransform.UseQuaternionSynchronization = m_Rotation == Rotation.Quaternion; - m_NonAuthoritativeTransform.UseQuaternionCompression = m_RotationCompression == RotationCompression.QuaternionCompress; - - m_OwnerTransform = m_AuthoritativeTransform.IsOwner ? m_AuthoritativeTransform : m_NonAuthoritativeTransform; }