|
1 | 1 | using System.Collections;
|
| 2 | +using System.Text; |
2 | 3 | using NUnit.Framework;
|
3 | 4 | using TestProject.ManualTests;
|
4 | 5 | using Unity.Netcode;
|
|
8 | 9 |
|
9 | 10 | namespace TestProject.RuntimeTests
|
10 | 11 | {
|
11 |
| - public class DontDestroyOnLoadTests |
| 12 | + public class DontDestroyOnLoadTests : NetcodeIntegrationTest |
12 | 13 | {
|
13 |
| - private NetworkManager m_ServerNetworkManager; |
14 |
| - private NetworkManager[] m_ClientNetworkManagers; |
15 |
| - private GameObject m_PlayerPrefab; |
| 14 | + private const int k_ClientsToConnect = 4; |
| 15 | + protected override int NumberOfClients => 0; |
16 | 16 | private GameObject m_DontDestroyOnLoadObject;
|
17 | 17 |
|
18 |
| - |
19 |
| - [UnitySetUp] |
20 |
| - public IEnumerator Setup() |
| 18 | + protected override void OnServerAndClientsCreated() |
21 | 19 | {
|
22 |
| - // Create multiple NetworkManager instances |
23 |
| - if (!NetcodeIntegrationTestHelpers.Create(4, out NetworkManager server, out NetworkManager[] clients, 60)) |
24 |
| - { |
25 |
| - Debug.LogError("Failed to create instances"); |
26 |
| - Assert.Fail("Failed to create instances"); |
27 |
| - } |
28 |
| - |
29 |
| - m_PlayerPrefab = new GameObject("Player"); |
30 |
| - var playerNetworkObject = m_PlayerPrefab.AddComponent<NetworkObject>(); |
31 |
| - |
32 |
| - // Make it a prefab |
33 |
| - NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(playerNetworkObject); |
34 |
| - |
35 |
| - m_DontDestroyOnLoadObject = new GameObject("DontDestroyOnLoadObject"); |
36 |
| - var dontDestroyOnLoadNetworkObject = m_DontDestroyOnLoadObject.AddComponent<NetworkObject>(); |
| 20 | + m_DontDestroyOnLoadObject = CreateNetworkObjectPrefab("DDOLObject"); |
37 | 21 | m_DontDestroyOnLoadObject.AddComponent<ObjectToNotDestroyBehaviour>();
|
38 |
| - // Make it a prefab |
39 |
| - NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(dontDestroyOnLoadNetworkObject); |
40 |
| - |
41 |
| - // Set the player prefab |
42 |
| - server.NetworkConfig.PlayerPrefab = m_PlayerPrefab; |
43 |
| - // Add our test NetworkObject to be moved into the DontDestroyOnLoad scene |
44 |
| - server.NetworkConfig.Prefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.None, Prefab = m_DontDestroyOnLoadObject }); |
45 |
| - |
46 |
| - // Apply the same settings for the clients |
47 |
| - for (int i = 0; i < clients.Length; i++) |
48 |
| - { |
49 |
| - clients[i].NetworkConfig.PlayerPrefab = m_PlayerPrefab; |
50 |
| - clients[i].NetworkConfig.Prefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.None, Prefab = m_DontDestroyOnLoadObject }); |
51 |
| - } |
52 |
| - |
53 |
| - m_ServerNetworkManager = server; |
54 |
| - m_ClientNetworkManagers = clients; |
55 |
| - |
56 |
| - yield return null; |
| 22 | + base.OnServerAndClientsCreated(); |
57 | 23 | }
|
58 | 24 |
|
59 |
| - [UnityTearDown] |
60 |
| - public IEnumerator Teardown() |
| 25 | + protected override void OnNewClientCreated(NetworkManager networkManager) |
61 | 26 | {
|
62 |
| - NetcodeIntegrationTestHelpers.CleanUpHandlers(); |
63 |
| - |
64 |
| - m_ServerNetworkManager.Shutdown(); |
65 |
| - foreach (var networkManager in m_ClientNetworkManagers) |
66 |
| - { |
67 |
| - networkManager.Shutdown(); |
68 |
| - } |
69 |
| - int nextFrameNumber = Time.frameCount + 4; |
70 |
| - yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber); |
71 |
| - Object.Destroy(m_PlayerPrefab); |
72 |
| - Object.Destroy(m_DontDestroyOnLoadObject); |
73 |
| - Object.Destroy(m_ServerNetworkManager); |
74 |
| - foreach (var networkManager in m_ClientNetworkManagers) |
75 |
| - { |
76 |
| - Object.Destroy(networkManager); |
77 |
| - } |
78 |
| - |
79 |
| - m_ServerNetworkManager = null; |
80 |
| - m_ClientNetworkManagers = null; |
| 27 | + networkManager.NetworkConfig.Prefabs = m_ServerNetworkManager.NetworkConfig.Prefabs; |
| 28 | + base.OnNewClientCreated(networkManager); |
| 29 | + } |
81 | 30 |
|
82 |
| -#if UNITY_2023_1_OR_NEWER |
83 |
| - var networkObjects = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID); |
84 |
| -#else |
85 |
| - var networkObjects = Object.FindObjectsOfType<NetworkObject>(); |
86 |
| -#endif |
| 31 | + private ulong m_SpawnedNetworkObjectId; |
| 32 | + private StringBuilder m_ErrorLog = new StringBuilder(); |
87 | 33 |
|
88 |
| - foreach (var netObject in networkObjects) |
| 34 | + private bool AllClientsSpawnedObjectIntoDDOL() |
| 35 | + { |
| 36 | + var passed = true; |
| 37 | + m_ErrorLog.Clear(); |
| 38 | + foreach (var client in m_ClientNetworkManagers) |
89 | 39 | {
|
90 |
| - Object.DestroyImmediate(netObject); |
| 40 | + if (!client.SpawnManager.SpawnedObjects.ContainsKey(m_SpawnedNetworkObjectId)) |
| 41 | + { |
| 42 | + m_ErrorLog.AppendLine($"[Client-{client.LocalClientId}] Has not spanwed NetworkObjectId: {m_SpawnedNetworkObjectId}!"); |
| 43 | + passed = false; |
| 44 | + continue; |
| 45 | + } |
| 46 | + |
| 47 | + var spawnedObject = client.SpawnManager.SpawnedObjects[m_SpawnedNetworkObjectId]; |
| 48 | + if (spawnedObject.NetworkManager == client && spawnedObject.gameObject.scene.name != "DontDestroyOnLoad") |
| 49 | + { |
| 50 | + m_ErrorLog.AppendLine($"[Client-{client.LocalClientId}] {spawnedObject.name} is not in DDOL scene but is in scene {spawnedObject.gameObject.scene.name}"); |
| 51 | + passed = false; |
| 52 | + continue; |
| 53 | + } |
91 | 54 | }
|
92 |
| - yield return null; |
| 55 | + return passed; |
93 | 56 | }
|
94 | 57 |
|
95 |
| - |
96 | 58 | [UnityTest]
|
97 | 59 | public IEnumerator ValidateNetworkObjectSynchronization()
|
98 | 60 | {
|
99 |
| - m_ServerNetworkManager.StartHost(); |
100 |
| - NetcodeIntegrationTestHelpers.RegisterHandlers(m_ServerNetworkManager); |
101 |
| - var objectInstance = Object.Instantiate(m_DontDestroyOnLoadObject); |
102 |
| - var instanceNetworkObject = objectInstance.GetComponent<NetworkObject>(); |
103 |
| - instanceNetworkObject.NetworkManagerOwner = m_ServerNetworkManager; |
104 |
| - instanceNetworkObject.Spawn(); |
105 |
| - var serverobjectToNotDestroyBehaviour = objectInstance.GetComponent<ObjectToNotDestroyBehaviour>(); |
106 |
| - var waitForTick = new WaitForSeconds(1.0f / m_ServerNetworkManager.NetworkConfig.TickRate); |
107 |
| - yield return waitForTick; |
| 61 | + var objectInstance = SpawnObject(m_DontDestroyOnLoadObject, m_ServerNetworkManager); |
| 62 | + m_SpawnedNetworkObjectId = objectInstance.GetComponent<NetworkObject>().NetworkObjectId; |
| 63 | + // Wait a tick for the object to be automatically migrated into the DDOL |
| 64 | + yield return s_DefaultWaitForTick; |
108 | 65 |
|
109 | 66 | Assert.IsTrue(objectInstance.scene.name == "DontDestroyOnLoad");
|
110 | 67 |
|
111 |
| - foreach (var networkManager in m_ClientNetworkManagers) |
| 68 | + for (int i = 0; i < k_ClientsToConnect; i++) |
112 | 69 | {
|
113 |
| - networkManager.StartClient(); |
114 |
| - NetcodeIntegrationTestHelpers.RegisterHandlers(networkManager); |
| 70 | + yield return CreateAndStartNewClient(); |
115 | 71 | }
|
116 | 72 |
|
117 |
| - yield return NetcodeIntegrationTestHelpers.WaitForClientsConnected(m_ClientNetworkManagers); |
118 |
| - |
119 |
| - yield return waitForTick; |
120 |
| - var timeOut = Time.realtimeSinceStartup + 2.0f; |
121 |
| - var timedOut = false; |
122 |
| - while (!timedOut) |
123 |
| - { |
124 |
| - var allClientConditionsHaveBeenReached = true; |
125 |
| - foreach (var networkManager in m_ClientNetworkManagers) |
126 |
| - { |
127 |
| - foreach (var spawnedObject in networkManager.SpawnManager.SpawnedObjectsList) |
128 |
| - { |
129 |
| - if (spawnedObject.NetworkManager == networkManager && spawnedObject.gameObject.name.Contains("DontDestroyOnLoadObject")) |
130 |
| - { |
131 |
| - if (spawnedObject.gameObject.scene.name != "DontDestroyOnLoad") |
132 |
| - { |
133 |
| - allClientConditionsHaveBeenReached = false; |
134 |
| - break; |
135 |
| - } |
136 |
| - var objectToNotDestroyBehaviour = spawnedObject.gameObject.GetComponent<ObjectToNotDestroyBehaviour>(); |
137 |
| - if (objectToNotDestroyBehaviour.CurrentPing == 0 || serverobjectToNotDestroyBehaviour.CurrentPing != objectToNotDestroyBehaviour.CurrentPing) |
138 |
| - { |
139 |
| - allClientConditionsHaveBeenReached = false; |
140 |
| - break; |
141 |
| - } |
142 |
| - } |
143 |
| - } |
144 |
| - } |
145 |
| - |
146 |
| - if (allClientConditionsHaveBeenReached) |
147 |
| - { |
148 |
| - break; |
149 |
| - } |
150 |
| - |
151 |
| - yield return waitForTick; |
152 |
| - |
153 |
| - timedOut = timeOut < Time.realtimeSinceStartup; |
154 |
| - } |
155 |
| - Assert.False(timedOut, "Timed out while waiting for all client conditions to be reached!"); |
| 73 | + yield return WaitForConditionOrTimeOut(AllClientsSpawnedObjectIntoDDOL); |
| 74 | + AssertOnTimeout($"[DDOL Test Failure] Reason for failure:\n {m_ErrorLog}"); |
156 | 75 | }
|
157 | 76 | }
|
158 | 77 | }
|
0 commit comments