Skip to content

Commit a064258

Browse files
chore: update NetworkTransformOrderOfOperations test names and comments (#3727)
* update Adding modifications to names and additional comments on how the test works. * style removing white spaces
1 parent 47ae1ea commit a064258

File tree

1 file changed

+120
-78
lines changed

1 file changed

+120
-78
lines changed

com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOrderOfOperations.cs

Lines changed: 120 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,17 @@
1010

1111
namespace Unity.Netcode.RuntimeTests
1212
{
13-
13+
/// <summary>
14+
/// This test validates various spawn sequences to verify message
15+
/// ordering is preserved and each sequence action is invoked
16+
/// on non-authority instances in the order they were invoked on the
17+
/// authority instance (i.e. preserving order of operations).
18+
/// <see cref="OrderOfOperations"/>: Test entry point.<br />
19+
/// <see cref="RunTestSequences"/>: Runs a test based a series of sequences configured sequences.<br />
20+
/// <see cref="SpawnSequence"/>: Derived from to create a spawn sequence.
21+
/// <see cref="SpawnSequenceController"/>: Iterates through all defined/configured spawn sequences
22+
/// on both authoritative and non-authoritative instances for a test configuration.
23+
/// </summary>
1424
[TestFixture(HostOrServer.DAHost)]
1525
[TestFixture(HostOrServer.Host)]
1626
[TestFixture(HostOrServer.Server)]
@@ -25,7 +35,7 @@ internal class NetworkTransformOrderOfOperations : IntegrationTestWithApproximat
2535
private SpawnSequenceController m_AuthoritySeqControllerInstance;
2636

2737
private NetworkManager m_AuthorityNetworkManager;
28-
private List<NetworkObject> m_AuthorityGenericInstances = new List<NetworkObject>();
38+
private List<NetworkObject> m_AuthorityParentInstances = new List<NetworkObject>();
2939

3040
public NetworkTransformOrderOfOperations(HostOrServer host) : base(host)
3141
{
@@ -53,7 +63,7 @@ protected override void OnServerAndClientsCreated()
5363
private bool VerifyGenericsSpawned(StringBuilder errorLog)
5464
{
5565
var conditionMet = true;
56-
foreach (var networkObject in m_AuthorityGenericInstances)
66+
foreach (var networkObject in m_AuthorityParentInstances)
5767
{
5868
var networkObjectId = networkObject.NetworkObjectId;
5969
foreach (var networkManager in m_NetworkManagers)
@@ -75,7 +85,7 @@ private bool VerifyGenericsSpawned(StringBuilder errorLog)
7585

7686
private IEnumerator SpawnGenericParents()
7787
{
78-
m_AuthorityGenericInstances.Clear();
88+
m_AuthorityParentInstances.Clear();
7989
for (int i = 0; i < 3; i++)
8090
{
8191
var instance = Object.Instantiate(m_GenericObject);
@@ -85,7 +95,7 @@ private IEnumerator SpawnGenericParents()
8595
eulerAngles = GetRandomVector3(-180, 180),
8696
};
8797
SpawnObjectInstance(instance, m_AuthorityNetworkManager);
88-
m_AuthorityGenericInstances.Add(instance);
98+
m_AuthorityParentInstances.Add(instance);
8999
}
90100
yield return WaitForConditionOrTimeOut(VerifyGenericsSpawned);
91101
AssertOnTimeout("Failure to spawn generics on one or more clients!");
@@ -154,120 +164,125 @@ private bool TransformsMatch(StringBuilder errorLog)
154164

155165
#region OrderOfOperations Core Test Methods
156166
[UnityTest]
157-
158167
public IEnumerator OrderOfOperations()
159168
{
160169
m_EnableVerboseDebug = true;
161170
SpawnSequenceController.VerboseLog = m_EnableVerboseDebug;
162171
m_AuthorityNetworkManager = GetAuthorityNetworkManager();
163172
yield return SpawnGenericParents();
173+
var parent1 = m_AuthorityParentInstances[0];
174+
var parent2 = m_AuthorityParentInstances[1];
164175

165-
ConfigureSequencesTest1(m_AuthorityGenericInstances[0]);
176+
ConfigureSequencesTest1(parent1);
166177
yield return RunTestSequences();
167178

168-
ConfigureSequencesTest2(m_AuthorityGenericInstances[0]);
179+
ConfigureSequencesTest2(parent1);
169180
yield return RunTestSequences();
170181

171-
ConfigureSequencesTest3(m_AuthorityGenericInstances[0], m_AuthorityGenericInstances[1]);
182+
ConfigureSequencesTest3(parent1, parent2);
172183
yield return RunTestSequences();
173184

174-
ConfigureSequencesTest4(m_AuthorityGenericInstances[0], m_AuthorityGenericInstances[1]);
185+
ConfigureSequencesTest4(parent1, parent2);
175186
yield return RunTestSequences(false);
176187

177-
ConfigureSequencesTest5(m_AuthorityGenericInstances[0]);
188+
ConfigureSequencesTest5(parent1);
178189
yield return RunTestSequences();
179190

180-
ConfigureSequencesTest6(m_AuthorityGenericInstances[0]);
191+
ConfigureSequencesTest6_ClientServerOnly(parent1);
181192
yield return RunTestSequences();
182193

183-
ConfigureSequencesTest7(m_AuthorityGenericInstances[0]);
194+
ConfigureSequencesTest7_ClientServerOnly(parent1);
184195
yield return RunTestSequences(spawnWithOwnership: true);
185196

186-
ConfigureSequencesTest8(m_AuthorityGenericInstances[0]);
197+
ConfigureSequencesTest8(parent1);
187198
yield return RunTestSequences(spawnWithObservers: false);
188199

189-
ConfigureSequencesTest9(m_AuthorityGenericInstances[0]);
200+
ConfigureSequencesTest9(parent1);
190201
yield return RunTestSequences(spawnWithObservers: false);
191202

192-
ConfigureSequencesTest10(m_AuthorityGenericInstances[0], m_AuthorityGenericInstances[1]);
203+
ConfigureSequencesTest10_ClientServerOnly(parent1, parent2);
193204
yield return RunTestSequences(spawnWithOwnership: true);
194205

195-
ConfigureSequencesTest11(m_AuthorityGenericInstances[0], m_AuthorityGenericInstances[1]);
206+
ConfigureSequencesTest11_ClientServerOnly(parent1, parent2);
196207
yield return RunTestSequences(spawnWithOwnership: true);
197208
}
198209

210+
199211
private IEnumerator RunTestSequences(bool spawnWithObservers = true, bool spawnWithOwnership = false)
200212
{
201-
if (SpawnSequenceController.ShouldRun(m_AuthorityNetworkManager))
202-
{
203-
VerboseDebug($"Running {SpawnSequenceController.CurrentTest}");
204-
var instance = Object.Instantiate(m_ObjectToTest);
205-
instance.SpawnWithObservers = spawnWithObservers;
206-
SpawnObjectInstance(instance, spawnWithOwnership ? GetNonAuthorityNetworkManager() : m_AuthorityNetworkManager);
207-
m_AuthoritySeqControllerInstance = instance.GetComponent<SpawnSequenceController>();
208-
var authorityObjectId = m_AuthoritySeqControllerInstance.NetworkObjectId;
209-
m_AuthoritySeqControllerInstance.AfterSpawn();
210-
if (spawnWithObservers)
211-
{
212-
yield return WaitForSpawnedOnAllOrTimeOut(m_AuthoritySeqControllerInstance.NetworkObjectId);
213-
AssertOnTimeout($"All clients did not spawn {m_AuthoritySeqControllerInstance.name}!");
214-
foreach (var networkManager in m_NetworkManagers)
215-
{
216-
if (networkManager == m_AuthorityNetworkManager)
217-
{
218-
continue;
219-
}
220-
networkManager.SpawnManager.SpawnedObjects[authorityObjectId].GetComponent<SpawnSequenceController>().AfterSpawn();
221-
}
222-
}
213+
yield return __RunTestSequences(spawnWithObservers, spawnWithOwnership);
214+
215+
// Assure the generic parents are all at the root hierarchy.
216+
foreach (var parent in m_AuthorityParentInstances)
217+
{
218+
parent.transform.parent = null;
219+
}
220+
221+
// Reset the controller's global settings
222+
SpawnSequenceController.Clear();
223+
}
223224

224-
// Assure all sequenced actions have been invoked.
225-
yield return WaitForConditionOrTimeOut(SpawnSequenceController.AllActionsInvoked);
226-
if (s_GlobalTimeoutHelper.HasTimedOut())
225+
private IEnumerator __RunTestSequences(bool spawnWithObservers = true, bool spawnWithOwnership = false)
226+
{
227+
// Exit early if we shouldn't run
228+
if (!SpawnSequenceController.ShouldRun(m_AuthorityNetworkManager))
229+
{
230+
VerboseDebug($"Skipping {SpawnSequenceController.CurrentTest}");
231+
yield break;
232+
}
233+
234+
VerboseDebug($"Running {SpawnSequenceController.CurrentTest}");
235+
var instance = Object.Instantiate(m_ObjectToTest);
236+
instance.SpawnWithObservers = spawnWithObservers;
237+
SpawnObjectInstance(instance, spawnWithOwnership ? GetNonAuthorityNetworkManager() : m_AuthorityNetworkManager);
238+
m_AuthoritySeqControllerInstance = instance.GetComponent<SpawnSequenceController>();
239+
var authorityObjectId = m_AuthoritySeqControllerInstance.NetworkObjectId;
240+
m_AuthoritySeqControllerInstance.AfterSpawn();
241+
if (spawnWithObservers)
242+
{
243+
yield return WaitForSpawnedOnAllOrTimeOut(m_AuthoritySeqControllerInstance.NetworkObjectId);
244+
AssertOnTimeout($"All clients did not spawn {m_AuthoritySeqControllerInstance.name}!");
245+
foreach (var networkManager in m_NetworkManagers)
227246
{
228-
// If we timed out, then check for pending and if found wait for the condition
229-
// once more.
230-
if (SpawnSequenceController.ActionIsPending())
247+
if (networkManager == m_AuthorityNetworkManager)
231248
{
232-
yield return WaitForConditionOrTimeOut(SpawnSequenceController.AllActionsInvoked);
249+
continue;
233250
}
251+
networkManager.SpawnManager.SpawnedObjects[authorityObjectId].GetComponent<SpawnSequenceController>().AfterSpawn();
234252
}
235-
AssertOnTimeout($"[{SpawnSequenceController.CurrentTest}] Not all actions were invoked for the current test sequence!\n {SpawnSequenceController.ErrorLog}");
236-
yield return WaitForConditionOrTimeOut(TransformsMatch);
237-
AssertOnTimeout($"Not all {m_AuthoritySeqControllerInstance.name} instances' transforms match!");
253+
}
238254

239-
// De-spawn the test object
240-
if (m_AuthoritySeqControllerInstance.HasAuthority)
241-
{
242-
m_AuthoritySeqControllerInstance.NetworkObject.Despawn();
243-
}
244-
else
255+
// Assure all sequenced actions have been invoked.
256+
yield return WaitForConditionOrTimeOut(SpawnSequenceController.AllActionsInvoked);
257+
if (s_GlobalTimeoutHelper.HasTimedOut())
258+
{
259+
// If we timed out, then check for pending and if found wait for the condition
260+
// once more.
261+
if (SpawnSequenceController.ActionIsPending())
245262
{
246-
foreach (var networkManager in m_NetworkManagers)
247-
{
248-
if (networkManager.SpawnManager.SpawnedObjects[m_AuthoritySeqControllerInstance.NetworkObjectId].HasAuthority)
249-
{
250-
networkManager.SpawnManager.SpawnedObjects[m_AuthoritySeqControllerInstance.NetworkObjectId].Despawn();
251-
break;
252-
}
253-
}
263+
yield return WaitForConditionOrTimeOut(SpawnSequenceController.AllActionsInvoked);
254264
}
265+
}
266+
AssertOnTimeout($"[{SpawnSequenceController.CurrentTest}] Not all actions were invoked for the current test sequence!\n {SpawnSequenceController.ErrorLog}");
267+
yield return WaitForConditionOrTimeOut(TransformsMatch);
268+
AssertOnTimeout($"Not all {m_AuthoritySeqControllerInstance.name} instances' transforms match!");
255269

256-
// Assure the generic parents are all at the root hierarchy.
257-
foreach (var parent in m_AuthorityGenericInstances)
270+
// De-spawn the test object
271+
if (m_AuthoritySeqControllerInstance.HasAuthority)
272+
{
273+
m_AuthoritySeqControllerInstance.NetworkObject.Despawn();
274+
}
275+
else
276+
{
277+
foreach (var networkManager in m_NetworkManagers)
258278
{
259-
if (parent.transform.parent != null)
279+
if (networkManager.SpawnManager.SpawnedObjects[m_AuthoritySeqControllerInstance.NetworkObjectId].HasAuthority)
260280
{
261-
parent.transform.parent = null;
281+
networkManager.SpawnManager.SpawnedObjects[m_AuthoritySeqControllerInstance.NetworkObjectId].Despawn();
282+
break;
262283
}
263284
}
264285
}
265-
else
266-
{
267-
VerboseDebug($"Skipping {SpawnSequenceController.CurrentTest}");
268-
}
269-
// Reset the controller's global settings
270-
SpawnSequenceController.Clear();
271286
}
272287
#endregion
273288

@@ -451,7 +466,7 @@ private void ConfigureSequencesTest5(NetworkObject parent1)
451466
/// Authority-> Spawn, change ownership, change parent (1), Teleport RPC with NetworkBehaviourReference
452467
/// ClientOwner-> Teleport RPC using NetworkBehaviourReference
453468
/// </summary>
454-
private void ConfigureSequencesTest6(NetworkObject parent1)
469+
private void ConfigureSequencesTest6_ClientServerOnly(NetworkObject parent1)
455470
{
456471
SpawnSequenceController.CurrentTest = "Test6 (Client-Server Only)";
457472
if (m_AuthorityNetworkManager.DistributedAuthorityMode)
@@ -496,7 +511,7 @@ private void ConfigureSequencesTest6(NetworkObject parent1)
496511
/// Authority-> Spawn with ownership,change parent (1), Teleport RPC with NetworkBehaviourReference
497512
/// ClientOwner-> Teleport RPC using NetworkBehaviourReference
498513
/// </summary>
499-
private void ConfigureSequencesTest7(NetworkObject parent1)
514+
private void ConfigureSequencesTest7_ClientServerOnly(NetworkObject parent1)
500515
{
501516
SpawnSequenceController.CurrentTest = "Test7 (Client-Server Only)";
502517
if (m_AuthorityNetworkManager.DistributedAuthorityMode)
@@ -606,7 +621,7 @@ private void ConfigureSequencesTest9(NetworkObject parent1)
606621
/// Authority-> Spawn with ownership, change parent (1), Wait (1), Parent RPC with NetworkObjectReference
607622
/// ClientOwner-> Re-parent (2) RPC using NetworkObjectReference
608623
/// </summary>
609-
private void ConfigureSequencesTest10(NetworkObject parent1, NetworkObject parent2)
624+
private void ConfigureSequencesTest10_ClientServerOnly(NetworkObject parent1, NetworkObject parent2)
610625
{
611626
SpawnSequenceController.CurrentTest = "Test10 (Client-Server Only)";
612627
if (m_AuthorityNetworkManager.DistributedAuthorityMode)
@@ -641,7 +656,7 @@ private void ConfigureSequencesTest10(NetworkObject parent1, NetworkObject paren
641656
/// ClientOwner-> Parent (1) RPC using NetworkObjectReference
642657
/// Server-> On the parent changing --> re-parent (2)
643658
/// </summary>
644-
private void ConfigureSequencesTest11(NetworkObject parent1, NetworkObject parent2)
659+
private void ConfigureSequencesTest11_ClientServerOnly(NetworkObject parent1, NetworkObject parent2)
645660
{
646661
SpawnSequenceController.CurrentTest = "Test11 (Client-Server Only)";
647662
if (m_AuthorityNetworkManager.DistributedAuthorityMode)
@@ -650,7 +665,6 @@ private void ConfigureSequencesTest11(NetworkObject parent1, NetworkObject paren
650665
return;
651666
}
652667

653-
654668
var parentRpc = new ReferenceRpcSequence()
655669
{
656670
IsParentRPC = true,
@@ -867,6 +881,11 @@ protected override void OnAction()
867881
}
868882
}
869883

884+
/// <summary>
885+
/// Derive from this to create a new type of spawn sequence
886+
/// or derive from an existing one to modify or extend the
887+
/// sequence's behavior.
888+
/// </summary>
870889
internal class SpawnSequence
871890
{
872891
public enum SpawnStage
@@ -947,12 +966,18 @@ private IEnumerator TimeDelayCoroutine(SpawnStage stage, SpawnSequenceController
947966
}
948967
}
949968

969+
/// <summary>
970+
/// Process the current giveen set of configured spawn sequences. <br />
971+
/// <see cref="s_SpawnSequencedActions"/> contains the spawn sequences for a test configuraiton. <br />
972+
/// Some spawn sequences might only run under certain conditions determined within <see cref="ShouldRun(NetworkManager)"/>.
973+
/// </summary>
950974
public class SpawnSequenceController : NetworkTransform
951975
{
952976
public static bool VerboseLog;
953977
public static string CurrentTest;
954978

955979
public static bool ClientServerOnly;
980+
public static bool DistributedAuthorityOnly;
956981

957982
public static bool ShouldRun(NetworkManager authorityNetworkManager)
958983
{
@@ -1059,6 +1084,23 @@ public void TeleportRpc(Vector3 position, Quaternion rotation, RpcParams rpcPara
10591084
}
10601085
}
10611086

1087+
/// <summary>
1088+
/// This is added to the generic spawned objects (parents) to validate that
1089+
/// after having spawned a NetworkObject, as the authority, and then invoking
1090+
/// an RPC, that accepts an <see cref="NetworkBehaviourReference"/> or <see cref="NetworkObjectReference"/>
1091+
/// which references the newly spawned <see cref="NetworkObject"/> or an associated <see cref="NetworkBehaviour"/>
1092+
/// component on an already known spawned object, that the object will have been spawned prior to the
1093+
/// RPC being invoked on the non-authority side.
1094+
/// </summary>
1095+
/// <remarks>
1096+
/// Currently, NGO does not support this usage pattern if you:
1097+
/// - spawn with no observers
1098+
/// - invoke the RPC with a reference to the spawned object within the same frame/call-stack
1099+
/// This limitation is due to the network show defers the queuing of the <see cref="CreateObjectMessage"/>
1100+
/// until the end of the frame as opposed to generating it when spawned. This could be supported if
1101+
/// we convert to more of a command based system that is applied locally on the spawn authority side
1102+
/// but queued and then messages are generated from the queued commands at the end of the frame.
1103+
/// </remarks>
10621104
public class ReferenceRpcHelper : NetworkBehaviour
10631105
{
10641106
[Rpc(SendTo.NotMe)]

0 commit comments

Comments
 (0)