Skip to content

Commit 90e4bbe

Browse files
authored
refactor: assign auto-incremented GlobalObjectIdHash as a fallback in MultiInstanceHelpers.MakeNetworkObjectTestPrefab() + fix flaky tests exposed by this fix (#1094)
* refactor: assign auto-incremented GlobalObjectIdHash as a fallback in MultiInstanceHelpers.MakeNetworkObjectTestPrefab() * fix MultiClientConnectionApproval.ConnectionApproval() test * refactor Removing DefaultPayerGlobalObjectIdHashValue with new GlobalObjectIdHash goodness. * fix NetworkObjectMetricsTests * remove `DefaultPayerGlobalObjectIdHashValue` from OwnershipChangeMetricsTests
1 parent f733bec commit 90e4bbe

13 files changed

+110
-79
lines changed

com.unity.netcode.gameobjects/Tests/Runtime/BaseMultiInstanceTest.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ public abstract class BaseMultiInstanceTest
1414
protected NetworkManager m_ServerNetworkManager;
1515
protected NetworkManager[] m_ClientNetworkManagers;
1616

17-
internal static uint DefaultPayerGlobalObjectIdHashValue = 7777777;
18-
1917
protected abstract int NbClients { get; }
2018

2119
[UnitySetUp]
@@ -96,7 +94,7 @@ public IEnumerator StartSomeClientsAndServerWithPlayers(bool useHost, int nbClie
9694
* at runtime without it being treated as a SceneObject or causing other conflicts with the Netcode.
9795
*/
9896
// Make it a prefab
99-
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(networkObject, DefaultPayerGlobalObjectIdHashValue);
97+
MultiInstanceHelpers.MakeNetworkObjectTestPrefab(networkObject);
10098

10199
updatePlayerPrefab(m_PlayerPrefab); // update player prefab with whatever is needed before players are spawned
102100

com.unity.netcode.gameobjects/Tests/Runtime/Metrics/NetworkObjectMetricsTests.cs

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,40 @@ namespace Unity.Netcode.RuntimeTests.Metrics
1313
{
1414
public class NetworkObjectMetricsTests : SingleClientMetricTestBase
1515
{
16-
const string NewNetworkObjectName = "TestNetworkObjectToSpawn";
17-
18-
NetworkObject m_NewNetworkObject;
16+
private const string k_NewNetworkObjectName = "TestNetworkObjectToSpawn";
17+
private NetworkObject m_NewNetworkPrefab;
1918

2019
protected override Action<GameObject> UpdatePlayerPrefab => _ =>
2120
{
22-
var gameObject = new GameObject(NewNetworkObjectName);
23-
m_NewNetworkObject = gameObject.AddComponent<NetworkObject>();
24-
m_NewNetworkObject.NetworkManagerOwner = m_ServerNetworkManager;
25-
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(m_NewNetworkObject);
21+
var gameObject = new GameObject(k_NewNetworkObjectName);
22+
m_NewNetworkPrefab = gameObject.AddComponent<NetworkObject>();
23+
MultiInstanceHelpers.MakeNetworkObjectTestPrefab(m_NewNetworkPrefab);
24+
2625
var networkPrefab = new NetworkPrefab { Prefab = gameObject };
2726
m_ServerNetworkManager.NetworkConfig.NetworkPrefabs.Add(networkPrefab);
28-
2927
foreach (var client in m_ClientNetworkManagers)
3028
{
3129
client.NetworkConfig.NetworkPrefabs.Add(networkPrefab);
3230
}
3331
};
3432

33+
private NetworkObject SpawnNetworkObject()
34+
{
35+
// Spawn another network object so we can hide multiple.
36+
var gameObject = UnityEngine.Object.Instantiate(m_NewNetworkPrefab); // new GameObject(NewNetworkObjectName);
37+
var networkObject = gameObject.GetComponent<NetworkObject>();
38+
networkObject.NetworkManagerOwner = Server;
39+
networkObject.Spawn();
40+
41+
return networkObject;
42+
}
43+
3544
[UnityTest]
3645
public IEnumerator TrackNetworkObjectSpawnSentMetric()
3746
{
3847
var waitForMetricEvent = new WaitForMetricValues<ObjectSpawnedEvent>(ServerMetrics.Dispatcher, MetricNames.ObjectSpawnedSent);
3948

40-
m_NewNetworkObject.Spawn();
49+
SpawnNetworkObject();
4150

4251
yield return waitForMetricEvent.WaitForMetricsReceived();
4352

@@ -46,7 +55,7 @@ public IEnumerator TrackNetworkObjectSpawnSentMetric()
4655

4756
var objectSpawned = objectSpawnedSentMetricValues.First();
4857
Assert.AreEqual(Client.LocalClientId, objectSpawned.Connection.Id);
49-
Assert.AreEqual(NewNetworkObjectName, objectSpawned.NetworkId.Name);
58+
Assert.AreEqual($"{k_NewNetworkObjectName}(Clone)", objectSpawned.NetworkId.Name);
5059
Assert.AreNotEqual(0, objectSpawned.BytesCount);
5160
}
5261

@@ -55,7 +64,7 @@ public IEnumerator TrackNetworkObjectSpawnReceivedMetric()
5564
{
5665
var waitForMetricEvent = new WaitForMetricValues<ObjectSpawnedEvent>(ClientMetrics.Dispatcher, MetricNames.ObjectSpawnedReceived);
5766

58-
m_NewNetworkObject.Spawn();
67+
var networkObject = SpawnNetworkObject();
5968

6069
yield return waitForMetricEvent.WaitForMetricsReceived();
6170

@@ -64,21 +73,21 @@ public IEnumerator TrackNetworkObjectSpawnReceivedMetric()
6473

6574
var objectSpawned = objectSpawnedReceivedMetricValues.First();
6675
Assert.AreEqual(Server.LocalClientId, objectSpawned.Connection.Id);
67-
Assert.AreEqual(m_NewNetworkObject.NetworkObjectId, objectSpawned.NetworkId.NetworkId);
68-
Assert.AreEqual($"{NewNetworkObjectName}(Clone)", objectSpawned.NetworkId.Name);
76+
Assert.AreEqual(networkObject.NetworkObjectId, objectSpawned.NetworkId.NetworkId);
77+
Assert.AreEqual($"{k_NewNetworkObjectName}(Clone)", objectSpawned.NetworkId.Name);
6978
Assert.AreNotEqual(0, objectSpawned.BytesCount);
7079
}
7180

7281
[UnityTest]
7382
public IEnumerator TrackNetworkObjectDestroySentMetric()
7483
{
75-
m_NewNetworkObject.Spawn();
84+
var networkObject = SpawnNetworkObject();
7685

7786
yield return new WaitForSeconds(0.2f);
7887

7988
var waitForMetricEvent = new WaitForMetricValues<ObjectDestroyedEvent>(ServerMetrics.Dispatcher, MetricNames.ObjectDestroyedSent);
8089

81-
Server.SpawnManager.OnDespawnObject(m_NewNetworkObject, true);
90+
Server.SpawnManager.OnDespawnObject(networkObject, true);
8291

8392
yield return waitForMetricEvent.WaitForMetricsReceived();
8493

@@ -87,20 +96,20 @@ public IEnumerator TrackNetworkObjectDestroySentMetric()
8796

8897
var objectDestroyed = objectDestroyedSentMetricValues.Last();
8998
Assert.AreEqual(Client.LocalClientId, objectDestroyed.Connection.Id);
90-
Assert.AreEqual(NewNetworkObjectName, objectDestroyed.NetworkId.Name);
99+
Assert.AreEqual($"{k_NewNetworkObjectName}(Clone)", objectDestroyed.NetworkId.Name);
91100
Assert.AreNotEqual(0, objectDestroyed.BytesCount);
92101
}
93102

94103
[UnityTest]
95104
public IEnumerator TrackNetworkObjectDestroyReceivedMetric()
96105
{
97-
m_NewNetworkObject.Spawn();
106+
var networkObject = SpawnNetworkObject();
98107

99108
yield return new WaitForSeconds(0.2f);
100109

101110
var waitForMetricEvent = new WaitForMetricValues<ObjectDestroyedEvent>(ClientMetrics.Dispatcher, MetricNames.ObjectDestroyedReceived);
102111

103-
Server.SpawnManager.OnDespawnObject(m_NewNetworkObject, true);
112+
Server.SpawnManager.OnDespawnObject(networkObject, true);
104113

105114
yield return waitForMetricEvent.WaitForMetricsReceived();
106115

@@ -109,31 +118,26 @@ public IEnumerator TrackNetworkObjectDestroyReceivedMetric()
109118

110119
var objectDestroyed = objectDestroyedReceivedMetricValues.First();
111120
Assert.AreEqual(Server.LocalClientId, objectDestroyed.Connection.Id);
112-
Assert.AreEqual(m_NewNetworkObject.NetworkObjectId, objectDestroyed.NetworkId.NetworkId);
113-
Assert.AreEqual($"{NewNetworkObjectName}(Clone)", objectDestroyed.NetworkId.Name);
121+
Assert.AreEqual(networkObject.NetworkObjectId, objectDestroyed.NetworkId.NetworkId);
122+
Assert.AreEqual($"{k_NewNetworkObjectName}(Clone)", objectDestroyed.NetworkId.Name);
114123
Assert.AreNotEqual(0, objectDestroyed.BytesCount);
115124
}
116125

117126
[UnityTest]
118127
public IEnumerator TrackMultipleNetworkObjectSpawnSentMetric()
119128
{
120-
m_NewNetworkObject.Spawn();
121-
122-
// Spawn another network object so we can hide multiple.
123-
var gameObject = new GameObject(NewNetworkObjectName);
124-
var anotherNetworkObject = gameObject.AddComponent<NetworkObject>();
125-
anotherNetworkObject.NetworkManagerOwner = Server;
126-
anotherNetworkObject.Spawn();
129+
var networkObject1 = SpawnNetworkObject();
130+
var networkObject2 = SpawnNetworkObject();
127131

128132
yield return new WaitForSeconds(0.2f);
129133

130-
NetworkObject.NetworkHide(new List<NetworkObject>{m_NewNetworkObject, anotherNetworkObject}, Client.LocalClientId);
134+
NetworkObject.NetworkHide(new List<NetworkObject> { networkObject1, networkObject2 }, Client.LocalClientId);
131135

132136
yield return new WaitForSeconds(0.2f);
133137

134138
var waitForMetricEvent = new WaitForMetricValues<ObjectSpawnedEvent>(ServerMetrics.Dispatcher, MetricNames.ObjectSpawnedSent);
135139

136-
NetworkObject.NetworkShow(new List<NetworkObject>{m_NewNetworkObject, anotherNetworkObject}, Client.LocalClientId);
140+
NetworkObject.NetworkShow(new List<NetworkObject> { networkObject1, networkObject2 }, Client.LocalClientId);
137141

138142
yield return waitForMetricEvent.WaitForMetricsReceived();
139143

@@ -143,14 +147,14 @@ public IEnumerator TrackMultipleNetworkObjectSpawnSentMetric()
143147
objectSpawnedSentMetricValues,
144148
Has.Exactly(1).Matches<ObjectSpawnedEvent>(
145149
x => Client.LocalClientId == x.Connection.Id
146-
&& x.NetworkId.NetworkId == m_NewNetworkObject.NetworkObjectId
147-
&& x.NetworkId.Name == m_NewNetworkObject.name));
150+
&& x.NetworkId.NetworkId == networkObject1.NetworkObjectId
151+
&& x.NetworkId.Name == networkObject1.name));
148152
Assert.That(
149153
objectSpawnedSentMetricValues,
150154
Has.Exactly(1).Matches<ObjectSpawnedEvent>(
151155
x => Client.LocalClientId == x.Connection.Id
152-
&& x.NetworkId.NetworkId == anotherNetworkObject.NetworkObjectId
153-
&& x.NetworkId.Name == anotherNetworkObject.name));
156+
&& x.NetworkId.NetworkId == networkObject2.NetworkObjectId
157+
&& x.NetworkId.Name == networkObject2.name));
154158

155159
Assert.AreEqual(1, objectSpawnedSentMetricValues.Select(x => x.BytesCount).Distinct().Count());
156160
Assert.That(objectSpawnedSentMetricValues.Select(x => x.BytesCount), Has.All.Not.EqualTo(0));
@@ -159,19 +163,14 @@ public IEnumerator TrackMultipleNetworkObjectSpawnSentMetric()
159163
[UnityTest]
160164
public IEnumerator TrackMultipleNetworkObjectDestroySentMetric()
161165
{
162-
m_NewNetworkObject.Spawn();
163-
164-
// Spawn another network object so we can hide multiple.
165-
var gameObject = new GameObject(NewNetworkObjectName);
166-
var anotherNetworkObject = gameObject.AddComponent<NetworkObject>();
167-
anotherNetworkObject.NetworkManagerOwner = Server;
168-
anotherNetworkObject.Spawn();
166+
var networkObject1 = SpawnNetworkObject();
167+
var networkObject2 = SpawnNetworkObject();
169168

170169
yield return new WaitForSeconds(0.2f);
171170

172171
var waitForMetricEvent = new WaitForMetricValues<ObjectDestroyedEvent>(ServerMetrics.Dispatcher, MetricNames.ObjectDestroyedSent);
173172

174-
NetworkObject.NetworkHide(new List<NetworkObject>{m_NewNetworkObject, anotherNetworkObject}, Client.LocalClientId);
173+
NetworkObject.NetworkHide(new List<NetworkObject> { networkObject1, networkObject2 }, Client.LocalClientId);
175174

176175
yield return waitForMetricEvent.WaitForMetricsReceived();
177176

@@ -181,14 +180,14 @@ public IEnumerator TrackMultipleNetworkObjectDestroySentMetric()
181180
objectDestroyedSentMetricValues,
182181
Has.Exactly(1).Matches<ObjectDestroyedEvent>(
183182
x => Client.LocalClientId == x.Connection.Id
184-
&& x.NetworkId.NetworkId == m_NewNetworkObject.NetworkObjectId
185-
&& x.NetworkId.Name == m_NewNetworkObject.name));
183+
&& x.NetworkId.NetworkId == networkObject1.NetworkObjectId
184+
&& x.NetworkId.Name == networkObject1.name));
186185
Assert.That(
187186
objectDestroyedSentMetricValues,
188187
Has.Exactly(1).Matches<ObjectDestroyedEvent>(
189188
x => Client.LocalClientId == x.Connection.Id
190-
&& x.NetworkId.NetworkId == anotherNetworkObject.NetworkObjectId
191-
&& x.NetworkId.Name == anotherNetworkObject.name));
189+
&& x.NetworkId.NetworkId == networkObject2.NetworkObjectId
190+
&& x.NetworkId.Name == networkObject2.name));
192191

193192
Assert.AreEqual(1, objectDestroyedSentMetricValues.Select(x => x.BytesCount).Distinct().Count());
194193
Assert.That(objectDestroyedSentMetricValues.Select(x => x.BytesCount), Has.All.Not.EqualTo(0));

com.unity.netcode.gameobjects/Tests/Runtime/Metrics/OwnershipChangeMetricsTests.cs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,39 @@ namespace Unity.Netcode.RuntimeTests.Metrics
1212
{
1313
public class OwnershipChangeMetricsTests : SingleClientMetricTestBase
1414
{
15-
[UnityTest]
16-
public IEnumerator TrackOwnershipChangeSentMetric()
15+
private const string k_NewNetworkObjectName = "TestNetworkObjectToSpawn";
16+
private NetworkObject m_NewNetworkPrefab;
17+
18+
protected override Action<GameObject> UpdatePlayerPrefab => _ =>
1719
{
18-
var gameObject = new GameObject(Guid.NewGuid().ToString());
19-
var networkObject = gameObject.AddComponent<NetworkObject>();
20-
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(networkObject, DefaultPayerGlobalObjectIdHashValue);
20+
var gameObject = new GameObject(k_NewNetworkObjectName);
21+
m_NewNetworkPrefab = gameObject.AddComponent<NetworkObject>();
22+
MultiInstanceHelpers.MakeNetworkObjectTestPrefab(m_NewNetworkPrefab);
23+
24+
var networkPrefab = new NetworkPrefab { Prefab = gameObject };
25+
m_ServerNetworkManager.NetworkConfig.NetworkPrefabs.Add(networkPrefab);
26+
foreach (var client in m_ClientNetworkManagers)
27+
{
28+
client.NetworkConfig.NetworkPrefabs.Add(networkPrefab);
29+
}
30+
};
31+
32+
private NetworkObject SpawnNetworkObject()
33+
{
34+
// Spawn another network object so we can hide multiple.
35+
var gameObject = UnityEngine.Object.Instantiate(m_NewNetworkPrefab); // new GameObject(NewNetworkObjectName);
36+
var networkObject = gameObject.GetComponent<NetworkObject>();
2137
networkObject.NetworkManagerOwner = Server;
2238
networkObject.Spawn();
2339

40+
return networkObject;
41+
}
42+
43+
[UnityTest]
44+
public IEnumerator TrackOwnershipChangeSentMetric()
45+
{
46+
var networkObject = SpawnNetworkObject();
47+
2448
yield return new WaitForSeconds(0.2f);
2549

2650
var waitForMetricValues = new WaitForMetricValues<OwnershipChangeEvent>(ServerMetrics.Dispatcher, MetricNames.OwnershipChangeSent);
@@ -40,11 +64,7 @@ public IEnumerator TrackOwnershipChangeSentMetric()
4064
[UnityTest]
4165
public IEnumerator TrackOwnershipChangeReceivedMetric()
4266
{
43-
var gameObject = new GameObject(Guid.NewGuid().ToString());
44-
var networkObject = gameObject.AddComponent<NetworkObject>();
45-
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(networkObject, DefaultPayerGlobalObjectIdHashValue);
46-
networkObject.NetworkManagerOwner = Server;
47-
networkObject.Spawn();
67+
var networkObject = SpawnNetworkObject();
4868

4969
yield return new WaitForSeconds(0.2f);
5070

com.unity.netcode.gameobjects/Tests/Runtime/MultiInstanceHelpers.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ public class CoroutineResultWrapper<T>
204204
public T Result;
205205
}
206206

207+
private static uint s_AutoIncrementGlobalObjectIdHashCounter = 111111;
207208

208209
/// <summary>
209210
/// Normally we would only allow player prefabs to be set to a prefab. Not runtime created objects.
@@ -214,7 +215,7 @@ public class CoroutineResultWrapper<T>
214215
/// </summary>
215216
/// <param name="networkObject">The networkObject to be treated as Prefab</param>
216217
/// <param name="globalObjectIdHash">The GlobalObjectId to force</param>
217-
public static void MakeNetworkedObjectTestPrefab(NetworkObject networkObject, uint globalObjectIdHash = default)
218+
public static void MakeNetworkObjectTestPrefab(NetworkObject networkObject, uint globalObjectIdHash = default)
218219
{
219220
// Set a globalObjectId for prefab
220221
if (globalObjectIdHash != default)
@@ -225,6 +226,12 @@ public static void MakeNetworkedObjectTestPrefab(NetworkObject networkObject, ui
225226
// Force generation
226227
networkObject.GenerateGlobalObjectIdHash();
227228

229+
// Fallback to auto-increment if generation fails
230+
if (networkObject.GlobalObjectIdHash == default)
231+
{
232+
networkObject.GlobalObjectIdHash = ++s_AutoIncrementGlobalObjectIdHashCounter;
233+
}
234+
228235
// Prevent object from being snapped up as a scene object
229236
networkObject.IsSceneObject = false;
230237
}

com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourUpdaterTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void AddNetworkBehaviour(Type type, GameObject prefab)
6565
var networkObjectPrefab = prefabToSpawn.AddComponent<NetworkObject>();
6666
AddNetworkBehaviour(firstNetworkBehaviour, prefabToSpawn);
6767
AddNetworkBehaviour(secondNetworkBehaviour, prefabToSpawn);
68-
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(networkObjectPrefab);
68+
MultiInstanceHelpers.MakeNetworkObjectTestPrefab(networkObjectPrefab);
6969
m_ServerNetworkManager.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Prefab = prefabToSpawn });
7070
foreach (var clientNetworkManager in m_ClientNetworkManagers)
7171
{

com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public IEnumerator Setup()
6161
m_DummyPrefab = new GameObject("DummyPrefabPrototype");
6262
m_DummyPrefab.AddComponent<NetworkObject>();
6363
m_DummyPrefab.AddComponent<NetworkObjectOwnershipComponent>();
64-
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(m_DummyPrefab.GetComponent<NetworkObject>());
64+
MultiInstanceHelpers.MakeNetworkObjectTestPrefab(m_DummyPrefab.GetComponent<NetworkObject>());
6565
m_ServerNetworkManager.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab { Prefab = m_DummyPrefab });
6666
foreach (var clientNetworkManager in m_ClientNetworkManagers)
6767
{

com.unity.netcode.gameobjects/Tests/Runtime/NetworkPrefabHandlerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ private GameObject MakeValidNetworkPrefab()
2222
{
2323
Guid baseObjectID = NetworkManagerHelper.AddGameNetworkObject(k_TestPrefabObjectName + m_GlobalObjectIdHashBase.ToString());
2424
NetworkObject validPrefab = NetworkManagerHelper.InstantiatedNetworkObjects[baseObjectID];
25-
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(validPrefab, m_GlobalObjectIdHashBase);
25+
MultiInstanceHelpers.MakeNetworkObjectTestPrefab(validPrefab, m_GlobalObjectIdHashBase);
2626
m_GlobalObjectIdHashBase++;
2727
return validPrefab.gameObject;
2828
}

0 commit comments

Comments
 (0)