Skip to content

Commit 0d4a8b1

Browse files
test
adding a test to validate this specific issue where the authority changes the ownership.
1 parent a1bdccd commit 0d4a8b1

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

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

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using NUnit.Framework;
5+
using Unity.Netcode.Components;
56
using Unity.Netcode.TestHelpers.Runtime;
67
using UnityEngine;
78
using UnityEngine.TestTools;
@@ -25,6 +26,12 @@ public override void OnGainedOwnership()
2526
OnGainedOwnershipFired = true;
2627
}
2728

29+
protected override void OnOwnershipChanged(ulong previous, ulong current)
30+
{
31+
Assert.True(previous != current, $"[{nameof(OnOwnershipChanged)}][Invalid Parameters] Invoked and the previous ({previous}) equals the current ({current})!");
32+
base.OnOwnershipChanged(previous, current);
33+
}
34+
2835
public override void OnNetworkSpawn()
2936
{
3037
if (!SpawnedInstances.ContainsKey(NetworkManager.LocalClientId))
@@ -39,6 +46,12 @@ public void ResetFlags()
3946
OnLostOwnershipFired = false;
4047
OnGainedOwnershipFired = false;
4148
}
49+
50+
[Rpc(SendTo.Authority)]
51+
public void ChangeOwnershipRpc(RpcParams rpcParams = default)
52+
{
53+
NetworkObject.ChangeOwnership(rpcParams.Receive.SenderClientId);
54+
}
4255
}
4356

4457

@@ -71,6 +84,7 @@ protected override void OnServerAndClientsCreated()
7184
{
7285
m_OwnershipPrefab = CreateNetworkObjectPrefab("OnwershipPrefab");
7386
m_OwnershipPrefab.AddComponent<NetworkObjectOwnershipComponent>();
87+
m_OwnershipPrefab.AddComponent<NetworkTransform>();
7488
if (m_DistributedAuthority)
7589
{
7690
m_OwnershipPrefab.GetComponent<NetworkObject>().SetOwnershipStatus(NetworkObject.OwnershipStatus.Transferable);
@@ -465,7 +479,87 @@ public IEnumerator TestOwnedObjectCounts()
465479

466480
yield return WaitForConditionOrTimeOut(ServerHasCorrectClientOwnedObjectCount);
467481
AssertOnTimeout($"Server does not have the correct count for all clients spawned {k_NumberOfSpawnedObjects} {nameof(NetworkObject)}s!");
482+
}
468483

484+
/// <summary>
485+
/// Validates that when changing ownership NetworkTransform does not enter into a bad state
486+
/// because the previous and current owner identifiers are the same. For client-server this
487+
/// ends up always being the server, but for distributed authority the authority changes when
488+
/// ownership changes.
489+
/// </summary>
490+
[UnityTest]
491+
public IEnumerator TestAuthorityChangingOwnership()
492+
{
493+
var authorityManager = (NetworkManager)null;
494+
var allNetworkManagers = m_ClientNetworkManagers.ToList();
495+
allNetworkManagers.Add(m_ServerNetworkManager);
496+
497+
if (m_DistributedAuthority)
498+
{
499+
var authorityId = Random.Range(1, NumberOfClients) - 1;
500+
authorityManager = m_ClientNetworkManagers[authorityId];
501+
m_OwnershipObject = SpawnObject(m_OwnershipPrefab, authorityManager);
502+
m_OwnershipNetworkObject = m_OwnershipObject.GetComponent<NetworkObject>();
503+
}
504+
else
505+
{
506+
authorityManager = m_ServerNetworkManager;
507+
m_OwnershipObject = SpawnObject(m_OwnershipPrefab, m_ServerNetworkManager);
508+
m_OwnershipNetworkObject = m_OwnershipObject.GetComponent<NetworkObject>();
509+
}
510+
var ownershipNetworkObjectId = m_OwnershipNetworkObject.NetworkObjectId;
511+
bool WaitForClientsToSpawnNetworkObject()
512+
{
513+
foreach (var clientNetworkManager in m_ClientNetworkManagers)
514+
{
515+
if (!clientNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId))
516+
{
517+
return false;
518+
}
519+
}
520+
return true;
521+
}
522+
523+
yield return WaitForConditionOrTimeOut(WaitForClientsToSpawnNetworkObject);
524+
AssertOnTimeout($"Timed out waiting for all clients to spawn the {m_OwnershipNetworkObject.name} {nameof(NetworkObject)} instance!");
525+
526+
var currentTargetOwner = (ulong)0;
527+
bool WaitForAllInstancesToChangeOwnership()
528+
{
529+
foreach (var clientNetworkManager in m_ClientNetworkManagers)
530+
{
531+
if (!clientNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId))
532+
{
533+
return false;
534+
}
535+
if (clientNetworkManager.SpawnManager.SpawnedObjects[ownershipNetworkObjectId].OwnerClientId != currentTargetOwner)
536+
{
537+
return false;
538+
}
539+
}
540+
return true;
541+
}
542+
543+
// Change ownership a few times and as long as the previous and current owners are not the same when
544+
// OnOwnershipChanged is invoked then the test passed.
545+
foreach (var networkManager in allNetworkManagers)
546+
{
547+
if (networkManager == authorityManager)
548+
{
549+
continue;
550+
}
551+
var clonedObject = networkManager.SpawnManager.SpawnedObjects[ownershipNetworkObjectId];
552+
553+
if (clonedObject.OwnerClientId == networkManager.LocalClientId)
554+
{
555+
continue;
556+
}
557+
558+
var testComponent = clonedObject.GetComponent<NetworkObjectOwnershipComponent>();
559+
testComponent.ChangeOwnershipRpc();
560+
yield return WaitForAllInstancesToChangeOwnership();
561+
AssertOnTimeout($"Timed out waiting for all instances to change ownership to Client-{networkManager.LocalClientId}!");
562+
}
469563
}
470564
}
471565
}

0 commit comments

Comments
 (0)