11using System . Collections ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Text ;
45using NUnit . Framework ;
56using Unity . Netcode ;
67using Unity . Netcode . TestHelpers . Runtime ;
@@ -26,12 +27,7 @@ public class NetworkSceneManagerEventNotifications : NetcodeIntegrationTest
2627 private LoadSceneMode m_LoadSceneMode ;
2728 private bool m_CanStartServerOrClients = false ;
2829 private bool m_LoadEventCompleted = false ;
29-
30- // TODO: [CmbServiceTests] Adapt to run with the service
31- protected override bool UseCMBService ( )
32- {
33- return false ;
34- }
30+ private NetworkManager m_ClientToTestLoading ;
3531
3632 internal class SceneTestInfo
3733 {
@@ -78,11 +74,16 @@ protected override IEnumerator OnTearDown()
7874
7975 protected override IEnumerator OnStartedServerAndClients ( )
8076 {
81- m_ServerNetworkManager . SceneManager . OnSceneEvent += ServerSceneManager_OnSceneEvent ;
82- foreach ( var client in m_ClientNetworkManagers )
77+ foreach ( var manager in m_NetworkManagers )
8378 {
84- client . SceneManager . ClientSynchronizationMode = m_LoadSceneMode ;
85- client . SceneManager . OnSceneEvent += ClientSceneManager_OnSceneEvent ;
79+ if ( manager . IsServer || manager . LocalClient . IsSessionOwner )
80+ {
81+ manager . SceneManager . OnSceneEvent += ServerSceneManager_OnSceneEvent ;
82+ continue ;
83+ }
84+
85+ manager . SceneManager . ClientSynchronizationMode = m_LoadSceneMode ;
86+ manager . SceneManager . OnSceneEvent += ClientSceneManager_OnSceneEvent ;
8687 }
8788 return base . OnStartedServerAndClients ( ) ;
8889 }
@@ -93,17 +94,19 @@ private void ClientSceneManager_OnSceneEvent(SceneEvent sceneEvent)
9394 {
9495 // Validate that the clients finish synchronization and they used the proper synchronization mode
9596 case SceneEventType . SynchronizeComplete :
96- {
97- var matchedClient = m_ClientNetworkManagers . Where ( c => c . LocalClientId == sceneEvent . ClientId ) ;
98- Assert . True ( matchedClient . Count ( ) > 0 , $ "Found no client { nameof ( NetworkManager ) } s that had a { nameof ( NetworkManager . LocalClientId ) } of { sceneEvent . ClientId } ") ;
99- Assert . AreEqual ( matchedClient . First ( ) . SceneManager . ClientSynchronizationMode , m_ServerNetworkManager . SceneManager . ClientSynchronizationMode ) ;
100- break ;
101- }
97+ {
98+ var authority = GetAuthorityNetworkManager ( ) ;
99+ var matchedClient = m_ClientNetworkManagers . FirstOrDefault ( c => c . LocalClientId == sceneEvent . ClientId ) ;
100+ Assert . That ( matchedClient , Is . Not . Null , $ "Found no client { nameof ( NetworkManager ) } s that had a { nameof ( NetworkManager . LocalClientId ) } of { sceneEvent . ClientId } ") ;
101+ Assert . AreEqual ( matchedClient . SceneManager . ClientSynchronizationMode , authority . SceneManager . ClientSynchronizationMode ) ;
102+ break ;
103+ }
102104 }
103105 }
104106
105107 private void ServerSceneManager_OnSceneEvent ( SceneEvent sceneEvent )
106108 {
109+ var authority = GetAuthorityNetworkManager ( ) ;
107110 VerboseDebug ( $ "[SceneEvent] ClientId:{ sceneEvent . ClientId } | EventType: { sceneEvent . SceneEventType } ") ;
108111 switch ( sceneEvent . SceneEventType )
109112 {
@@ -126,16 +129,16 @@ private void ServerSceneManager_OnSceneEvent(SceneEvent sceneEvent)
126129 }
127130 case SceneEventType . LoadComplete :
128131 {
129- if ( sceneEvent . ClientId == NetworkManager . ServerClientId )
132+ if ( sceneEvent . ClientId == authority . LocalClientId )
130133 {
131134 var scene = sceneEvent . Scene ;
132135 m_CurrentScene = scene ;
133136 }
134- if ( sceneEvent . ClientId == m_ClientNetworkManagers [ 0 ] . LocalClientId )
137+ if ( sceneEvent . ClientId == m_ClientToTestLoading . LocalClientId )
135138 {
136139 if ( ! m_ScenesLoaded . Contains ( sceneEvent . SceneName ) )
137140 {
138- Debug . Log ( $ "Loaded { sceneEvent . SceneName } ") ;
141+ VerboseLog ( $ "Loaded { sceneEvent . SceneName } ") ;
139142 m_ScenesLoaded . Add ( sceneEvent . SceneName ) ;
140143 }
141144 }
@@ -162,10 +165,10 @@ private void ServerSceneManager_OnSceneEvent(SceneEvent sceneEvent)
162165
163166 // If we are a server and this is being processed by the server, then add the server to the completed list
164167 // to validate that the event completed on all clients (and the server).
165- if ( ! m_ServerNetworkManager . IsHost && sceneEvent . ClientId == m_ServerNetworkManager . LocalClientId &&
166- ! sceneEvent . ClientsThatCompleted . Contains ( m_ServerNetworkManager . LocalClientId ) )
168+ if ( ! authority . IsHost && sceneEvent . ClientId == authority . LocalClientId &&
169+ ! sceneEvent . ClientsThatCompleted . Contains ( authority . LocalClientId ) )
167170 {
168- sceneEvent . ClientsThatCompleted . Add ( m_ServerNetworkManager . LocalClientId ) ;
171+ sceneEvent . ClientsThatCompleted . Add ( authority . LocalClientId ) ;
169172 }
170173 if ( sceneEvent . SceneEventType == SceneEventType . LoadEventCompleted )
171174 {
@@ -180,16 +183,16 @@ private void ServerSceneManager_OnSceneEvent(SceneEvent sceneEvent)
180183 }
181184 private void SceneManager_OnSceneEvent ( SceneEvent sceneEvent )
182185 {
183- Debug . Log ( $ "[SceneEvent] ClientId:{ sceneEvent . ClientId } | EventType: { sceneEvent . SceneEventType } ") ;
186+ VerboseLog ( $ "[SceneEvent] ClientId:{ sceneEvent . ClientId } | EventType: { sceneEvent . SceneEventType } ") ;
184187 switch ( sceneEvent . SceneEventType )
185188 {
186189 case SceneEventType . LoadComplete :
187190 {
188- if ( sceneEvent . ClientId == m_ClientNetworkManagers [ 0 ] . LocalClientId )
191+ if ( sceneEvent . ClientId == m_ClientToTestLoading . LocalClientId )
189192 {
190193 if ( ! m_ScenesLoaded . Contains ( sceneEvent . SceneName ) )
191194 {
192- Debug . Log ( $ "Loaded { sceneEvent . SceneName } ") ;
195+ VerboseLog ( $ "Loaded { sceneEvent . SceneName } ") ;
193196 m_ScenesLoaded . Add ( sceneEvent . SceneName ) ;
194197 }
195198 }
@@ -198,11 +201,11 @@ private void SceneManager_OnSceneEvent(SceneEvent sceneEvent)
198201
199202 case SceneEventType . UnloadComplete :
200203 {
201- if ( sceneEvent . ClientId == m_ClientNetworkManagers [ 0 ] . LocalClientId )
204+ if ( sceneEvent . ClientId == m_ClientToTestLoading . LocalClientId )
202205 {
203206 if ( m_ScenesLoaded . Contains ( sceneEvent . SceneName ) )
204207 {
205- Debug . Log ( $ "Unloaded { sceneEvent . SceneName } ") ;
208+ VerboseLog ( $ "Unloaded { sceneEvent . SceneName } ") ;
206209 // We check here for single mode because the final scene event
207210 // will be SceneEventType.LoadEventCompleted (easier to trap for it here)
208211 m_ScenesLoaded . Remove ( sceneEvent . SceneName ) ;
@@ -226,26 +229,29 @@ protected override bool CanStartServerAndClients()
226229 [ UnityTest ]
227230 public IEnumerator SceneLoadingAndNotifications ( [ Values ] LoadSceneMode loadSceneMode )
228231 {
232+ var authority = GetAuthorityNetworkManager ( ) ;
233+ var nonAuthority = GetNonAuthorityNetworkManager ( ) ;
234+ m_ClientToTestLoading = nonAuthority ;
229235
230236 m_LoadSceneMode = loadSceneMode ;
231237 m_CurrentSceneName = k_SceneToLoad ;
232238 m_CanStartServerOrClients = true ;
233239 yield return StartServerAndClients ( ) ;
234240
235- yield return WaitForConditionOrTimeOut ( ( ) => m_ClientsReceivedSynchronize . Count == ( m_ClientNetworkManagers . Length ) ) ;
236- Assert . False ( s_GlobalTimeoutHelper . TimedOut , $ "Timed out waiting for all clients to receive synchronization event! Received: { m_ClientsReceivedSynchronize . Count } | Expected: { m_ClientNetworkManagers . Length } ") ;
241+ yield return WaitForConditionOrTimeOut ( ( ) => m_ClientsReceivedSynchronize . Count == NumberOfClients ) ;
242+ AssertOnTimeout ( $ "Timed out waiting for all clients to receive synchronization event! Received: { m_ClientsReceivedSynchronize . Count } | Expected: { NumberOfClients } ") ;
237243 if ( loadSceneMode == LoadSceneMode . Single )
238244 {
239- m_ClientNetworkManagers [ 0 ] . SceneManager . OnSceneEvent += SceneManager_OnSceneEvent ;
245+ m_ClientToTestLoading . SceneManager . OnSceneEvent += SceneManager_OnSceneEvent ;
240246 }
241247 // Now prepare for the scene testing
242248 InitializeSceneTestInfo ( ) ;
243249
244250 // Test loading scenes and the associated event messaging and notification pipelines
245251 ResetWait ( ) ;
246- Assert . AreEqual ( m_ServerNetworkManager . SceneManager . LoadScene ( m_CurrentSceneName , loadSceneMode ) , SceneEventProgressStatus . Started ) ;
252+ Assert . AreEqual ( authority . SceneManager . LoadScene ( m_CurrentSceneName , loadSceneMode ) , SceneEventProgressStatus . Started ) ;
247253 // Check error status for trying to load during an already in progress scene event
248- Assert . AreEqual ( m_ServerNetworkManager . SceneManager . LoadScene ( m_CurrentSceneName , loadSceneMode ) , SceneEventProgressStatus . SceneEventInProgress ) ;
254+ Assert . AreEqual ( authority . SceneManager . LoadScene ( m_CurrentSceneName , loadSceneMode ) , SceneEventProgressStatus . SceneEventInProgress ) ;
249255
250256 // Wait for all clients to load the scene
251257 yield return WaitForConditionOrTimeOut ( ConditionPassed ) ;
@@ -262,7 +268,7 @@ public IEnumerator SceneLoadingAndNotifications([Values] LoadSceneMode loadScene
262268
263269 m_CurrentSceneName = k_InSceneNetworkObject ;
264270 ResetWait ( ) ;
265- Assert . AreEqual ( m_ServerNetworkManager . SceneManager . LoadScene ( k_InSceneNetworkObject , LoadSceneMode . Additive ) , SceneEventProgressStatus . Started ) ;
271+ Assert . AreEqual ( authority . SceneManager . LoadScene ( k_InSceneNetworkObject , LoadSceneMode . Additive ) , SceneEventProgressStatus . Started ) ;
266272
267273 // Wait for all clients to additively load this additional scene
268274 yield return WaitForConditionOrTimeOut ( ConditionPassed ) ;
@@ -272,40 +278,39 @@ public IEnumerator SceneLoadingAndNotifications([Values] LoadSceneMode loadScene
272278 // Now single mode load a new scene (i.e. "scene switch")
273279 m_CurrentSceneName = k_BaseUnitTestSceneName ;
274280 ResetWait ( ) ;
275- Assert . AreEqual ( m_ServerNetworkManager . SceneManager . LoadScene ( m_CurrentSceneName , loadSceneMode ) , SceneEventProgressStatus . Started ) ;
281+ Assert . AreEqual ( authority . SceneManager . LoadScene ( m_CurrentSceneName , loadSceneMode ) , SceneEventProgressStatus . Started ) ;
276282 // Wait for all clients to perform scene switch
277283 yield return WaitForConditionOrTimeOut ( ConditionPassed ) ;
278284 AssertOnTimeout ( $ "Timed out waiting for all clients to switch to scene { m_CurrentSceneName } !") ;
279285 // Make sure the server scene is the active scene
280286 SceneManager . SetActiveScene ( m_CurrentScene ) ;
281287
282- yield return WaitForConditionOrTimeOut ( ( ) => ! m_ScenesLoaded . Contains ( k_SceneToLoad ) && ! m_ScenesLoaded . Contains ( k_InSceneNetworkObject ) ) ;
283- var additionalInfo = string . Empty ;
284- if ( s_GlobalTimeoutHelper . TimedOut )
288+ var helper = new TimeoutHelper ( ) ;
289+ yield return WaitForConditionOrTimeOut ( ( ) => ! m_ScenesLoaded . Contains ( k_SceneToLoad ) && ! m_ScenesLoaded . Contains ( k_InSceneNetworkObject ) , helper ) ;
290+ var additionalInfo = new StringBuilder ( ) ;
291+ if ( helper . TimedOut )
285292 {
286- foreach ( var sceneName in m_ScenesLoaded )
287- {
288- additionalInfo += $ "{ sceneName } ,";
289- }
290- Debug . Break ( ) ;
293+ additionalInfo . Append ( "Scenes currently loaded: [" ) ;
294+ additionalInfo . AppendJoin ( ", " , m_ScenesLoaded ) ;
295+ additionalInfo . Append ( "]" ) ;
291296 }
292- AssertOnTimeout ( $ "{ nameof ( m_ScenesLoaded ) } still contains some of the scenes that were expected to be unloaded!\n { additionalInfo } ") ;
297+ AssertOnTimeout ( $ "{ nameof ( m_ScenesLoaded ) } still contains some of the scenes that were expected to be unloaded!\n { additionalInfo } ", helper ) ;
293298 }
294299
295300 // Test unloading additive scenes and the associated event messaging and notification pipelines
296301 ResetWait ( ) ;
297- Assert . AreEqual ( m_ServerNetworkManager . SceneManager . UnloadScene ( m_CurrentScene ) , SceneEventProgressStatus . Started ) ;
302+ Assert . AreEqual ( authority . SceneManager . UnloadScene ( m_CurrentScene ) , SceneEventProgressStatus . Started ) ;
298303
299304 yield return WaitForConditionOrTimeOut ( ConditionPassed ) ;
300305 AssertOnTimeout ( $ "Timed out waiting for all clients to unload { m_CurrentSceneName } !") ;
301306
302307 // Check error status for trying to unloading something not loaded
303308 ResetWait ( ) ;
304- Assert . AreEqual ( m_ServerNetworkManager . SceneManager . UnloadScene ( m_CurrentScene ) , SceneEventProgressStatus . SceneNotLoaded ) ;
309+ Assert . AreEqual ( authority . SceneManager . UnloadScene ( m_CurrentScene ) , SceneEventProgressStatus . SceneNotLoaded ) ;
305310
306311 // Check error status for trying to load an invalid scene name
307312 LogAssert . Expect ( LogType . Error , $ "Scene '{ k_InvalidSceneName } ' couldn't be loaded because it has not been added to the build settings scenes in build list.") ;
308- Assert . AreEqual ( m_ServerNetworkManager . SceneManager . LoadScene ( k_InvalidSceneName , LoadSceneMode . Additive ) , SceneEventProgressStatus . InvalidSceneName ) ;
313+ Assert . AreEqual ( authority . SceneManager . LoadScene ( k_InvalidSceneName , LoadSceneMode . Additive ) , SceneEventProgressStatus . InvalidSceneName ) ;
309314 }
310315
311316
@@ -329,9 +334,7 @@ private void ResetWait()
329334 /// </summary>
330335 private void InitializeSceneTestInfo ( )
331336 {
332- m_ShouldWaitList . Add ( new SceneTestInfo ( ) { ClientId = NetworkManager . ServerClientId , ShouldWait = false } ) ;
333-
334- foreach ( var manager in m_ClientNetworkManagers )
337+ foreach ( var manager in m_NetworkManagers )
335338 {
336339 m_ShouldWaitList . Add ( new SceneTestInfo ( ) { ClientId = manager . LocalClientId , ShouldWait = false } ) ;
337340 }
@@ -343,38 +346,64 @@ private void InitializeSceneTestInfo()
343346 /// </summary>
344347 private bool ConditionPassed ( )
345348 {
346- var completed = true ;
347- if ( m_LoadSceneMode == LoadSceneMode . Single )
349+ if ( m_LoadSceneMode == LoadSceneMode . Single && ! m_LoadEventCompleted )
348350 {
349- completed = m_LoadEventCompleted ;
351+ return false ;
350352 }
351- return completed && ! ( m_ShouldWaitList . Select ( c => c ) . Where ( c => c . ProcessedEvent != true && c . ShouldWait == true ) . Count ( ) > 0 ) ;
353+
354+ foreach ( var client in m_ShouldWaitList )
355+ {
356+ if ( ! client . ProcessedEvent || client . ShouldWait )
357+ {
358+ return false ;
359+ }
360+ }
361+
362+ return true ;
352363 }
353364
354365 /// <summary>
355366 /// Determines if the clientId is valid
356367 /// </summary>
357368 private bool ContainsClient ( ulong clientId )
358369 {
359- return m_ShouldWaitList . Select ( c => c . ClientId ) . Where ( c => c == clientId ) . Count ( ) > 0 ;
370+ foreach ( var client in m_ShouldWaitList )
371+ {
372+ if ( client . ClientId == clientId )
373+ {
374+ return true ;
375+ }
376+ }
377+
378+ return false ;
360379 }
361380
362381 /// <summary>
363382 /// Sets the specific clientId entry as having processed the current event
364383 /// </summary>
365384 private void SetClientProcessedEvent ( ulong clientId )
366385 {
367- m_ShouldWaitList . Select ( c => c ) . Where ( c => c . ClientId == clientId ) . First ( ) . ProcessedEvent = true ;
386+ foreach ( var client in m_ShouldWaitList )
387+ {
388+ if ( client . ClientId == clientId )
389+ {
390+ client . ProcessedEvent = true ;
391+ }
392+ }
368393 }
369394
370395 /// <summary>
371396 /// Sets all known clients' ShouldWait value to false
372397 /// </summary>
373398 private void SetClientWaitDone ( List < ulong > clients )
374399 {
375- foreach ( var clientId in clients )
400+ var lookup = clients . ToHashSet ( ) ;
401+ foreach ( var client in m_ShouldWaitList )
376402 {
377- m_ShouldWaitList . Select ( c => c ) . Where ( c => c . ClientId == clientId ) . First ( ) . ShouldWait = false ;
403+ if ( lookup . Contains ( client . ClientId ) )
404+ {
405+ client . ShouldWait = false ;
406+ }
378407 }
379408 }
380409
@@ -401,5 +430,13 @@ private bool ContainsAllClients(List<ulong> clients)
401430 }
402431 return true ;
403432 }
433+
434+ private void VerboseLog ( string message )
435+ {
436+ if ( OnSetVerboseDebug ( ) )
437+ {
438+ Debug . Log ( message ) ;
439+ }
440+ }
404441 }
405442}
0 commit comments