Skip to content

Commit 617fa02

Browse files
test
Adjusting the NetworkObjectDestroyTests to be distributed authority compatible.
1 parent eaa9e1b commit 617fa02

File tree

1 file changed

+95
-67
lines changed

1 file changed

+95
-67
lines changed
Lines changed: 95 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using NUnit.Framework;
35
using Unity.Netcode.TestHelpers.Runtime;
46
using UnityEngine;
@@ -21,56 +23,91 @@ internal class NetworkObjectDestroyTests : NetcodeIntegrationTest
2123
{
2224
protected override int NumberOfClients => 2;
2325

24-
// TODO: [CmbServiceTests] Adapt to run with the service
25-
protected override bool UseCMBService()
26+
public class DestroyTestComponent : NetworkBehaviour
2627
{
27-
return false;
28+
public static List<string> ObjectsDestroyed = new List<string>();
29+
30+
public override void OnDestroy()
31+
{
32+
ObjectsDestroyed.Add(gameObject.name);
33+
base.OnDestroy();
34+
}
2835
}
2936

3037
public NetworkObjectDestroyTests(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { }
3138

39+
protected override IEnumerator OnSetup()
40+
{
41+
// Re-apply the default for each test
42+
LogAssert.ignoreFailingMessages = false;
43+
DestroyTestComponent.ObjectsDestroyed.Clear();
44+
return base.OnSetup();
45+
}
46+
3247
protected override void OnCreatePlayerPrefab()
3348
{
49+
m_PlayerPrefab.AddComponent<DestroyTestComponent>();
3450
var playerNetworkObject = m_PlayerPrefab.GetComponent<NetworkObject>();
3551
playerNetworkObject.SceneMigrationSynchronization = true;
3652
base.OnCreatePlayerPrefab();
3753
}
3854

55+
private NetworkManager GetAuthorityOfNetworkObject(ulong networkObjectId)
56+
{
57+
foreach (var networkManager in m_NetworkManagers)
58+
{
59+
if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId))
60+
{
61+
continue;
62+
}
63+
64+
if (networkManager.SpawnManager.SpawnedObjects[networkObjectId].HasAuthority)
65+
{
66+
return networkManager;
67+
}
68+
}
69+
return null;
70+
}
71+
72+
private bool NetworkObjectDoesNotExist(ulong networkObjectId)
73+
{
74+
foreach (var networkManager in m_NetworkManagers)
75+
{
76+
if (networkManager.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId))
77+
{
78+
return false;
79+
}
80+
}
81+
return true;
82+
}
83+
3984
/// <summary>
40-
/// Tests that a server can destroy a NetworkObject and that it gets despawned correctly.
85+
/// Tests that the authority NetworkManager instance of a NetworkObject is allowed to destroy it.
4186
/// </summary>
42-
/// <returns></returns>
87+
/// <returns>IEnumerator</returns>
4388
[UnityTest]
4489
public IEnumerator TestNetworkObjectAuthorityDestroy()
4590
{
46-
// This is the *SERVER VERSION* of the *CLIENT PLAYER*
47-
var serverClientPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper<NetworkObject>();
48-
yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation(x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId, m_ServerNetworkManager, serverClientPlayerResult);
4991

50-
// This is the *CLIENT VERSION* of the *CLIENT PLAYER*
51-
var clientClientPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper<NetworkObject>();
52-
yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation(x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId, m_ClientNetworkManagers[0], clientClientPlayerResult);
92+
var ownerNetworkManager = m_ClientNetworkManagers[1];
93+
var clientId = ownerNetworkManager.LocalClientId;
94+
var localClientPlayer = ownerNetworkManager.LocalClient.PlayerObject;
95+
var localNetworkObjectId = localClientPlayer.NetworkObjectId;
5396

54-
Assert.IsNotNull(serverClientPlayerResult.Result.gameObject);
55-
Assert.IsNotNull(clientClientPlayerResult.Result.gameObject);
97+
var authorityNetworkManager = GetAuthorityOfNetworkObject(localClientPlayer.NetworkObjectId);
98+
Assert.True(authorityNetworkManager != null, $"Could not find the authority of {localClientPlayer}!");
5699

57-
var targetNetworkManager = m_ClientNetworkManagers[0];
58-
if (m_DistributedAuthority)
59-
{
60-
targetNetworkManager = m_ClientNetworkManagers[1];
61-
// destroy the authoritative player (distributed authority)
62-
Object.Destroy(clientClientPlayerResult.Result.gameObject);
63-
}
64-
else
65-
{
66-
// destroy the authoritative player (client-server)
67-
Object.Destroy(serverClientPlayerResult.Result.gameObject);
68-
}
100+
var authorityPlayerClone = authorityNetworkManager.ConnectedClients[clientId].PlayerObject;
101+
102+
// Have the authority NetworkManager destroy the player instance
103+
Object.Destroy(authorityPlayerClone.gameObject);
104+
105+
var messageListener = m_DistributedAuthority ? m_ClientNetworkManagers[0] : m_ClientNetworkManagers[1];
69106

70-
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeHandled<DestroyObjectMessage>(targetNetworkManager);
107+
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeHandled<DestroyObjectMessage>(messageListener);
71108

72-
Assert.IsTrue(serverClientPlayerResult.Result == null); // Assert.IsNull doesn't work here
73-
Assert.IsTrue(clientClientPlayerResult.Result == null);
109+
yield return WaitForConditionOrTimeOut(() => NetworkObjectDoesNotExist(localNetworkObjectId));
110+
AssertOnTimeout($"Not all network managers despawned and destroyed player instance NetworkObjectId: {localNetworkObjectId}");
74111

75112
// validate that any unspawned networkobject can be destroyed
76113
var go = new GameObject();
@@ -97,62 +134,47 @@ public enum ClientDestroyObject
97134
public IEnumerator TestNetworkObjectClientDestroy([Values] ClientDestroyObject clientDestroyObject)
98135
{
99136
var isShuttingDown = clientDestroyObject == ClientDestroyObject.ShuttingDown;
100-
var clientPlayer = m_ClientNetworkManagers[0].LocalClient.PlayerObject;
101-
var clientId = clientPlayer.OwnerClientId;
102137

103-
//destroying a NetworkObject while shutting down is allowed
138+
var localNetworkManager = m_ClientNetworkManagers[1];
139+
var clientId = localNetworkManager.LocalClientId;
140+
var localClientPlayer = localNetworkManager.LocalClient.PlayerObject;
141+
142+
var nonAuthorityClient = m_ClientNetworkManagers[0];
143+
var clientPlayerClone = nonAuthorityClient.ConnectedClients[clientId].PlayerObject;
144+
104145
if (isShuttingDown)
105146
{
106-
if (m_DistributedAuthority)
107-
{
108-
// Shutdown the 2nd client
109-
m_ClientNetworkManagers[1].Shutdown();
110-
}
111-
else
112-
{
113-
// Shutdown the
114-
m_ClientNetworkManagers[0].Shutdown();
115-
}
147+
// The non-authority client is allowed to destroy any spawned object it does not
148+
// have authority over when it shuts down.
149+
nonAuthorityClient.Shutdown();
116150
}
117151
else
118152
{
153+
// The non-authority client is =NOT= allowed to destroy any spawned object it does not
154+
// have authority over during runtime.
119155
LogAssert.ignoreFailingMessages = true;
120-
NetworkLog.NetworkManagerOverride = m_ClientNetworkManagers[0];
156+
NetworkLog.NetworkManagerOverride = nonAuthorityClient;
157+
Object.Destroy(clientPlayerClone.gameObject);
121158
}
122159

123-
m_ClientPlayerName = clientPlayer.gameObject.name;
124-
m_ClientNetworkObjectId = clientPlayer.NetworkObjectId;
125-
if (m_DistributedAuthority)
126-
{
127-
m_ClientPlayerName = m_PlayerNetworkObjects[m_ClientNetworkManagers[1].LocalClientId][m_ClientNetworkManagers[0].LocalClientId].gameObject.name;
128-
m_ClientNetworkObjectId = m_PlayerNetworkObjects[m_ClientNetworkManagers[1].LocalClientId][m_ClientNetworkManagers[0].LocalClientId].NetworkObjectId;
129-
130-
if (!isShuttingDown)
131-
{
132-
NetworkLog.NetworkManagerOverride = m_ClientNetworkManagers[1];
133-
}
134-
// the 2nd client attempts to destroy the 1st client's player object (if shutting down then "ok" if not then not "ok")
135-
Object.DestroyImmediate(m_PlayerNetworkObjects[m_ClientNetworkManagers[1].LocalClientId][m_ClientNetworkManagers[0].LocalClientId].gameObject);
136-
}
137-
else
138-
{
139-
// the 1st client attempts to destroy its own player object (if shutting down then "ok" if not then not "ok")
140-
Object.DestroyImmediate(m_ClientNetworkManagers[0].LocalClient.PlayerObject.gameObject);
141-
}
160+
m_ClientPlayerName = clientPlayerClone.gameObject.name;
161+
m_ClientNetworkObjectId = clientPlayerClone.NetworkObjectId;
142162

143163
// destroying a NetworkObject while a session is active is not allowed
144164
if (!isShuttingDown)
145165
{
146166
yield return WaitForConditionOrTimeOut(HaveLogsBeenReceived);
147167
AssertOnTimeout($"Not all expected logs were received when destroying a {nameof(NetworkObject)} on the client side during an active session!");
148168
}
149-
if (m_DistributedAuthority)
150-
{
151-
Assert.IsFalse(m_ClientNetworkManagers[1].SpawnManager.NetworkObjectsToSynchronizeSceneChanges.ContainsKey(m_ClientNetworkObjectId), $"Player object {m_ClientNetworkObjectId} still exists within {nameof(NetworkSpawnManager.NetworkObjectsToSynchronizeSceneChanges)}!");
152-
}
153169
else
154170
{
155-
Assert.IsFalse(m_ClientNetworkManagers[0].SpawnManager.NetworkObjectsToSynchronizeSceneChanges.ContainsKey(m_ClientNetworkObjectId), $"Player object {m_ClientNetworkObjectId} still exists within {nameof(NetworkSpawnManager.NetworkObjectsToSynchronizeSceneChanges)}!");
171+
bool NonAuthorityClientDestroyed()
172+
{
173+
return DestroyTestComponent.ObjectsDestroyed.Contains(m_ClientPlayerName);
174+
}
175+
176+
yield return WaitForConditionOrTimeOut(NonAuthorityClientDestroyed);
177+
AssertOnTimeout($"Timed out waiting for player object {m_ClientNetworkObjectId} to no longer exist within {nameof(NetworkSpawnManager.NetworkObjectsToSynchronizeSceneChanges)}!");
156178
}
157179
}
158180

@@ -183,8 +205,14 @@ private bool HaveLogsBeenReceived()
183205
protected override IEnumerator OnTearDown()
184206
{
185207
NetworkLog.NetworkManagerOverride = null;
186-
LogAssert.ignoreFailingMessages = false;
187208
return base.OnTearDown();
188209
}
210+
211+
protected override void OnOneTimeTearDown()
212+
{
213+
// Re-apply the default as the last exiting action
214+
LogAssert.ignoreFailingMessages = false;
215+
base.OnOneTimeTearDown();
216+
}
189217
}
190218
}

0 commit comments

Comments
 (0)