From ee6684c2b62e9baa5acdd172c1df4993943257b5 Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 12:07:50 -0400 Subject: [PATCH 01/30] chore: Add a DA service unit test --- .yamato/desktop-standalone-tests.yml | 29 +++--- Tools/CI/rust.sh | 27 ++++++ .../Runtime/NetcodeIntegrationTest.cs | 49 ++++++----- .../Runtime/NetcodeIntegrationTestHelpers.cs | 53 +++++++---- .../DistributedAuthorityConnectionTest.cs | 88 +++++++++++++++++++ ...DistributedAuthorityConnectionTest.cs.meta | 3 + 6 files changed, 195 insertions(+), 54 deletions(-) create mode 100755 Tools/CI/rust.sh create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta diff --git a/.yamato/desktop-standalone-tests.yml b/.yamato/desktop-standalone-tests.yml index b6539b1cbf..8f314ba294 100644 --- a/.yamato/desktop-standalone-tests.yml +++ b/.yamato/desktop-standalone-tests.yml @@ -4,7 +4,7 @@ # DESCRIPTION-------------------------------------------------------------------------- # This job is responsible for Desktop platform test validation. # Those tests cover both PlayMode and EditMode tests from package test assemblies. - + # CONFIGURATION STRUCTURE-------------------------------------------------------------- # Jobs are generated using nested loops (separate build phase and run phase). Worth noting that run phase uses the build as dependency: # 1. For all desktop platform (Windows, macOS, Ubuntu) @@ -17,17 +17,17 @@ # 1. Build Phase: Creates standalone players for desktop platforms # 2. Run Phase: Executes runtime tests on actual desktop devices # The Run phase uses build job as dependency - + # Note: More of a Unity specific but test assemblies need to be included in the build phase command # Note: All builds can be made on x64 machines since those are compatible with ARM64 target devices # QUALITY THOUGHTS-------------------------------------------------------------------- # TODO: consider adding all projects that have tests # To see where this job is included (in trigger job definitions) look into _triggers.yml file - + #----------------------------------------------------------------------------------- - - + + # BUILD PHASE CONFIGURATION------------------------------------------------------------------------------------ {% for project in projects.default -%} {% for platform in test_platforms.desktop -%} @@ -58,10 +58,10 @@ desktop_standalone_build_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ {% endfor -%} {% endfor -%} {% endfor -%} - - - - + + + + # RUN PHASE CONFIGURATION------------------------------------------------------------------------------------ {% for project in projects.default -%} {% for platform in test_platforms.desktop -%} @@ -81,21 +81,16 @@ desktop_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ {% if platform.name != "win" %} # Issues with win and mac are tracked in MTT-11606 variables: ECHO_SERVER_PORT: "7788" + COMB_SERVER_PORT: "7789" # Set this to ensure the DA codec tests will fail if they cannot connect to the echo-server # The default is to ignore the codec tests if the echo-server fails to connect ENSURE_CODEC_TESTS: "true" {% endif %} commands: -# If ubuntu, run rust echo server (This is needed ONLY for NGOv2.X because relates to Distributed Authority) +# If not windows, run rust echo server (This is needed ONLY for NGOv2.X because relates to Distributed Authority) {% if platform.name != "win" %} # Issues with win and mac are tracked in MTT-11606 - - git clone https://github.com/Unity-Technologies/mps-common-multiplayer-backend.git - # Install rust - - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - # Build the echo server - - cd ./mps-common-multiplayer-backend/runtime && $HOME/.cargo/bin/cargo build --example ngo_echo_server - # Run the echo server in the background - this will reuse the artifacts from the build - - cd ./mps-common-multiplayer-backend/runtime && $HOME/.cargo/bin/cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & + - ./Tools/CI/rust.sh {% endif %} - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor {% if backend == "il2cpp" %} -c il2cpp {% endif %} {% if platform.name == "mac" %} --arch arm64 {% endif %} # For macOS we use ARM64 models diff --git a/Tools/CI/rust.sh b/Tools/CI/rust.sh new file mode 100755 index 0000000000..8914639611 --- /dev/null +++ b/Tools/CI/rust.sh @@ -0,0 +1,27 @@ +# clone the latest rust repo +git clone https://github.com/Unity-Technologies/mps-common-multiplayer-backend.git +cd ./mps-common-multiplayer-backend/runtime + +# Install rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +export PATH="$HOME/.cargo/bin:$PATH" + +# Build the echo server +cargo build --example ngo_echo_server + +# Run the echo server in the background - this will reuse the artifacts from the build +cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & + +# Build the standalone server +cargo build + +# Run the standalone server loop in the background +runstandalone & + +# Use a function to run the standalone server in a loop, when it exits, it will always restart +runstandalone() { + while :; do + # loop infinitely + cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m + done +} diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index b518f26583..c61e53ba32 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -522,7 +522,8 @@ protected virtual bool ShouldWaitForNewClientToConnect(NetworkManager networkMan /// An IEnumerator to be used in a coroutine for asynchronous execution. protected IEnumerator CreateAndStartNewClient() { - var networkManager = NetcodeIntegrationTestHelpers.CreateNewClient(m_ClientNetworkManagers.Length, m_EnableTimeTravel); + bool useCmbService = UseCMBService() && m_DistributedAuthority; + var networkManager = NetcodeIntegrationTestHelpers.CreateNewClient(m_ClientNetworkManagers.Length, m_EnableTimeTravel, useCmbService); networkManager.NetworkConfig.PlayerPrefab = m_PlayerPrefab; SetDistributedAuthorityProperties(networkManager); @@ -576,14 +577,15 @@ private bool AllPlayerObjectClonesSpawned(NetworkManager joinedClient) // Continue to populate the PlayerObjects list until all player object (local and clone) are found ClientNetworkManagerPostStart(joinedClient); - var playerObjectRelative = m_ServerNetworkManager.SpawnManager.PlayerObjects.Where((c) => c.OwnerClientId == joinedClient.LocalClientId).FirstOrDefault(); - if (playerObjectRelative == null) - { - m_InternalErrorLog.Append($"[AllPlayerObjectClonesSpawned][Server-Side] Joining Client-{joinedClient.LocalClientId} was not populated in the {nameof(NetworkSpawnManager.PlayerObjects)} list!"); - return false; - } - else + if (!(UseCMBService() && m_DistributedAuthority)) { + var playerObjectRelative = m_ServerNetworkManager.SpawnManager.PlayerObjects.Where((c) => c.OwnerClientId == joinedClient.LocalClientId).FirstOrDefault(); + if (playerObjectRelative == null) + { + m_InternalErrorLog.Append($"[AllPlayerObjectClonesSpawned][Server-Side] Joining Client-{joinedClient.LocalClientId} was not populated in the {nameof(NetworkSpawnManager.PlayerObjects)} list!"); + return false; + } + // Go ahead and create an entry for this new client if (!m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId].ContainsKey(joinedClient.LocalClientId)) { @@ -598,19 +600,17 @@ private bool AllPlayerObjectClonesSpawned(NetworkManager joinedClient) continue; } - playerObjectRelative = clientNetworkManager.SpawnManager.PlayerObjects.Where((c) => c.OwnerClientId == joinedClient.LocalClientId).FirstOrDefault(); + var playerObjectRelative = clientNetworkManager.SpawnManager.PlayerObjects.Where((c) => c.OwnerClientId == joinedClient.LocalClientId).FirstOrDefault(); if (playerObjectRelative == null) { m_InternalErrorLog.Append($"[AllPlayerObjectClonesSpawned][Client-{clientNetworkManager.LocalClientId}] Client-{joinedClient.LocalClientId} was not populated in the {nameof(NetworkSpawnManager.PlayerObjects)} list!"); return false; } - else + + // Go ahead and create an entry for this new client + if (!m_PlayerNetworkObjects[clientNetworkManager.LocalClientId].ContainsKey(joinedClient.LocalClientId)) { - // Go ahead and create an entry for this new client - if (!m_PlayerNetworkObjects[clientNetworkManager.LocalClientId].ContainsKey(joinedClient.LocalClientId)) - { - m_PlayerNetworkObjects[clientNetworkManager.LocalClientId].Add(joinedClient.LocalClientId, playerObjectRelative); - } + m_PlayerNetworkObjects[clientNetworkManager.LocalClientId].Add(joinedClient.LocalClientId, playerObjectRelative); } } return true; @@ -722,7 +722,8 @@ protected void CreateServerAndClients(int numberOfClients) } // Create multiple NetworkManager instances - if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_CreateServerFirst, m_EnableTimeTravel)) + var useCmbService = UseCMBService() && m_DistributedAuthority; + if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_CreateServerFirst, m_EnableTimeTravel, useCmbService)) { Debug.LogError("Failed to create instances"); Assert.Fail("Failed to create instances"); @@ -939,8 +940,9 @@ protected IEnumerator StartServerAndClients() if (m_UseHost || m_ServerNetworkManager.IsHost) { #if UNITY_2023_1_OR_NEWER + var manager = startServer ? m_ServerNetworkManager : m_ClientNetworkManagers[0]; // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries - var serverPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); + var serverPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == manager.LocalClientId); #else // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries var serverPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); @@ -952,7 +954,10 @@ protected IEnumerator StartServerAndClients() m_PlayerNetworkObjects.Add(playerNetworkObject.NetworkManager.LocalClientId, new Dictionary()); } - m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); + if (startServer) + { + m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); + } } } if (m_DistributedAuthority) @@ -967,7 +972,7 @@ protected IEnumerator StartServerAndClients() AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); } } - if (m_ServerNetworkManager != null) + if (m_ServerNetworkManager != null && startServer) { yield return WaitForConditionOrTimeOut(() => AllPlayerObjectClonesSpawned(m_ServerNetworkManager)); AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{m_ServerNetworkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); @@ -1534,8 +1539,10 @@ private bool CheckClientsConnected(NetworkManager[] clientsToCheck) m_InternalErrorLog.AppendLine($"[Client-{i + 1}] Client is not connected!"); } } - var expectedCount = m_ServerNetworkManager.IsHost ? clientsToCheck.Length + 1 : clientsToCheck.Length; - var currentCount = m_ServerNetworkManager.ConnectedClients.Count; + + var manager = UseCMBService() ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; + var expectedCount = manager.IsHost ? clientsToCheck.Length + 1 : clientsToCheck.Length; + var currentCount = manager.ConnectedClients.Count; if (currentCount != expectedCount) { diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 2f5f975ecd..3ca3afff6d 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -170,7 +170,20 @@ public static void RegisterHandlers(NetworkManager networkManager, bool serverSi } } - private static void AddUnityTransport(NetworkManager networkManager) + private static readonly string k_TransportHost = Environment.GetEnvironmentVariable("NGO_HOST") ?? "127.0.0.1"; + private static readonly ushort k_TransportPort = GetPortToBind(); + + /// + /// Configures the port to look for the rust service. + /// + /// The port from the environment variable "ECHO_SERVER_PORT" if it is set and valid; otherwise uses port 7777 + private static ushort GetPortToBind() + { + var value = Environment.GetEnvironmentVariable("CMB_SERVICE_PORT"); + return ushort.TryParse(value, out var configuredPort) ? configuredPort : (ushort)7789; + } + + private static void AddUnityTransport(NetworkManager networkManager, bool useCmbService = false) { // Create transport var unityTransport = networkManager.gameObject.AddComponent(); @@ -181,6 +194,12 @@ private static void AddUnityTransport(NetworkManager networkManager) // Allow 4 connection attempts that each will time out after 500ms unityTransport.MaxConnectAttempts = 4; unityTransport.ConnectTimeoutMS = 500; + if (useCmbService) + { + unityTransport.ConnectionData.Address = Dns.GetHostAddresses(k_TransportHost).First().ToString(); + unityTransport.ConnectionData.Port = k_TransportPort; + Debug.Log($"Using CmbService: {k_TransportHost}:{k_TransportPort}"); + } // Set the NetworkConfig networkManager.NetworkConfig ??= new NetworkConfig(); @@ -196,7 +215,7 @@ private static void AddMockTransport(NetworkManager networkManager) networkManager.NetworkConfig.NetworkTransport = mockTransport; } - public static NetworkManager CreateServer(bool mockTransport = false) + public static NetworkManager CreateServer(bool mockTransport = false, bool useCmbService = false) { // Create gameObject var go = new GameObject("NetworkManager - Server"); @@ -210,7 +229,7 @@ public static NetworkManager CreateServer(bool mockTransport = false) } else { - AddUnityTransport(server); + AddUnityTransport(server, useCmbService); } return server; } @@ -223,20 +242,21 @@ public static NetworkManager CreateServer(bool mockTransport = false) /// The clients NetworkManagers /// The targetFrameRate of the Unity engine to use while the multi instance helper is running. Will be reset on shutdown. /// This determines if the server or clients will be instantiated first (defaults to server first) - public static bool Create(int clientCount, out NetworkManager server, out NetworkManager[] clients, int targetFrameRate = 60, bool serverFirst = true, bool useMockTransport = false) + /// If true, the server transport will use a mock transport, and the clients will be created with a connection to a locally hosted da service + public static bool Create(int clientCount, out NetworkManager server, out NetworkManager[] clients, int targetFrameRate = 60, bool serverFirst = true, bool useMockTransport = false, bool useCmbService = false) { s_NetworkManagerInstances = new List(); server = null; if (serverFirst) { - server = CreateServer(useMockTransport); + server = CreateServer(useMockTransport || useCmbService); } - CreateNewClients(clientCount, out clients, useMockTransport); + CreateNewClients(clientCount, out clients, useMockTransport, useCmbService); if (!serverFirst) { - server = CreateServer(useMockTransport); + server = CreateServer(useMockTransport || useCmbService); } s_OriginalTargetFrameRate = Application.targetFrameRate; @@ -245,7 +265,7 @@ public static bool Create(int clientCount, out NetworkManager server, out Networ return true; } - internal static NetworkManager CreateNewClient(int identifier, bool mockTransport = false) + internal static NetworkManager CreateNewClient(int identifier, bool mockTransport = false, bool useCmbService = false) { // Create gameObject var go = new GameObject("NetworkManager - Client - " + identifier); @@ -257,7 +277,7 @@ internal static NetworkManager CreateNewClient(int identifier, bool mockTranspor } else { - AddUnityTransport(networkManager); + AddUnityTransport(networkManager, useCmbService); } return networkManager; } @@ -269,13 +289,14 @@ internal static NetworkManager CreateNewClient(int identifier, bool mockTranspor /// The amount of clients /// Output array containing the created NetworkManager instances /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false - public static bool CreateNewClients(int clientCount, out NetworkManager[] clients, bool useMockTransport = false) + /// If true, each client will be created with transport configured to connect to a locally hosted da service + public static bool CreateNewClients(int clientCount, out NetworkManager[] clients, bool useMockTransport = false, bool useCmbService = false) { clients = new NetworkManager[clientCount]; for (int i = 0; i < clientCount; i++) { // Create networkManager component - clients[i] = CreateNewClient(i, useMockTransport); + clients[i] = CreateNewClient(i, useMockTransport, useCmbService); } NetworkManagerInstances.AddRange(clients); @@ -486,15 +507,15 @@ public static bool Start(bool host, NetworkManager server, NetworkManager[] clie callback?.Invoke(); } - for (int i = 0; i < clients.Length; i++) + foreach (var client in clients) { - clients[i].StartClient(); + client.StartClient(); hooks = new MultiInstanceHooks(); - clients[i].ConnectionManager.MessageManager.Hook(hooks); - s_Hooks[clients[i]] = hooks; + client.ConnectionManager.MessageManager.Hook(hooks); + s_Hooks[client] = hooks; // if set, then invoke this for the client - RegisterHandlers(clients[i]); + RegisterHandlers(client); } return true; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs new file mode 100644 index 0000000000..bf4b7f7d74 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections; +using System.Linq; +using System.Net; +using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; +using Unity.Netcode.Transports.UTP; +using Unity.Networking.Transport; +using UnityEngine; +using UnityEngine.TestTools; + +namespace Unity.Netcode.RuntimeTests +{ + internal class DistributedAuthorityConnectionTest : NetcodeIntegrationTest + { + protected override int NumberOfClients => 1; + + private NetworkManager SessionOwner => m_ClientNetworkManagers[0]; + + // Use the CMB Service for all tests + protected override bool UseCMBService() => true; + + // Set the network topology to distributed authority for all tests + protected override NetworkTopologyTypes OnGetNetworkTopologyType() => NetworkTopologyTypes.DistributedAuthority; + + + public DistributedAuthorityConnectionTest() : base(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost) { } + + + private GameObject m_SpawnObject; + + internal class TestNetworkComponent : NetworkBehaviour + { + } + + /// + /// Add any additional components to default player prefab + /// + protected override void OnCreatePlayerPrefab() + { + m_PlayerPrefab.AddComponent(); + base.OnCreatePlayerPrefab(); + } + + /// + /// Modify NetworkManager instances for settings specific to tests + /// + protected override void OnServerAndClientsCreated() + { + foreach (var client in m_ClientNetworkManagers) + { + client.NetworkConfig.EnableSceneManagement = false; + client.NetworkConfig.AutoSpawnPlayerPrefabClientSide = true; + } + SessionOwner.LogLevel = LogLevel.Developer; + + // Validate we are in distributed authority mode with client side spawning and using CMB Service + Assert.True(SessionOwner.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); + Assert.True(SessionOwner.AutoSpawnPlayerPrefabClientSide, "Client side spawning is not set!"); + Assert.True(SessionOwner.CMBServiceConnection, "CMBServiceConnection is not set!"); + + // Create a prefab for creating and destroying tests (auto-registers with NetworkManagers) + m_SpawnObject = CreateNetworkObjectPrefab("TestObject"); + } + + [UnityTest] + public IEnumerator CreateObjectNew() + { + SpawnObject(m_SpawnObject, SessionOwner); + + yield return WaitForConditionOrTimeOut(CheckObjectExists); + AssertOnTimeout("failed to spawn object!"); + } + + + private bool CheckObjectExists() + { + foreach (var client in m_ClientNetworkManagers) + { + if (!s_GlobalNetworkObjects.ContainsKey(client.LocalClientId)) + { + return false; + } + } + return true; + } + } +} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta new file mode 100644 index 0000000000..f48f5f3f2c --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e31522b786a5480fac291bbbc17e0d31 +timeCreated: 1745437205 \ No newline at end of file From acdc79848e72b979bf00fab4c1dfc4b9deb75d14 Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 12:12:58 -0400 Subject: [PATCH 02/30] temp trigger update for faster iteration --- .yamato/_triggers.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.yamato/_triggers.yml b/.yamato/_triggers.yml index 3018bc5176..46fd7205d3 100644 --- a/.yamato/_triggers.yml +++ b/.yamato/_triggers.yml @@ -46,17 +46,17 @@ pull_request_trigger: name: Pull Request Trigger (develop, develop-2.0.0, & release branches) dependencies: - # Run package EditMode and Playmode package tests on trunk - - .yamato/_run-all.yml#run_all_package_tests_trunk - # Run package EditMode and Playmode package tests on minimum supported editor (6000.0 in case of NGOv2.X) - - .yamato/_run-all.yml#run_all_package_tests_6000 - # Run project EditMode and PLaymode project tests on trunk - - .yamato/_run-all.yml#run_all_project_tests_trunk - # Run project EditMode and PLaymode project tests on minimum supported editor (6000.0 in case of NGOv2.X) - - .yamato/_run-all.yml#run_all_project_tests_6000 - # Run standalone test with mixture of parameters to make sure there are no obvious issues with most common platform (for example --fail-on-assert option is not present with package/project tests). We run 2 different combinations with different platform/editor/scripting backend. + # # Run package EditMode and Playmode package tests on trunk + # - .yamato/_run-all.yml#run_all_package_tests_trunk + # # Run package EditMode and Playmode package tests on minimum supported editor (6000.0 in case of NGOv2.X) + # - .yamato/_run-all.yml#run_all_package_tests_6000 + # # Run project EditMode and PLaymode project tests on trunk + # - .yamato/_run-all.yml#run_all_project_tests_trunk + # # Run project EditMode and PLaymode project tests on minimum supported editor (6000.0 in case of NGOv2.X) + # - .yamato/_run-all.yml#run_all_project_tests_6000 + # # Run standalone test with mixture of parameters to make sure there are no obvious issues with most common platform (for example --fail-on-assert option is not present with package/project tests). We run 2 different combinations with different platform/editor/scripting backend. - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_mac_il2cpp_trunk - - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_win_mono_6000.0 + # - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_win_mono_6000.0 triggers: cancel_old_ci: true pull_requests: @@ -134,4 +134,4 @@ develop_weekly_trunk: # Build player for webgl platform on trunk - .yamato/_run-all.yml#run_all_webgl_builds # Run code coverage test - - .yamato/code-coverage.yml#code_coverage_ubuntu_trunk \ No newline at end of file + - .yamato/code-coverage.yml#code_coverage_ubuntu_trunk From 9f9ab40db1503aeefa63d4f49e2e824570ba303d Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 12:25:10 -0400 Subject: [PATCH 03/30] fix pvp exceptions --- .../Runtime/NetcodeIntegrationTestHelpers.cs | 14 +++++++++++--- pvpExceptions.json | 4 ---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 3ca3afff6d..74a409e035 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -215,7 +215,12 @@ private static void AddMockTransport(NetworkManager networkManager) networkManager.NetworkConfig.NetworkTransport = mockTransport; } - public static NetworkManager CreateServer(bool mockTransport = false, bool useCmbService = false) + /// + /// Creates and configures a new server instance for integration testing. + /// + /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false + /// The created server instance. + public static NetworkManager CreateServer(bool mockTransport = false) { // Create gameObject var go = new GameObject("NetworkManager - Server"); @@ -229,7 +234,7 @@ public static NetworkManager CreateServer(bool mockTransport = false, bool useCm } else { - AddUnityTransport(server, useCmbService); + AddUnityTransport(server); } return server; } @@ -242,7 +247,9 @@ public static NetworkManager CreateServer(bool mockTransport = false, bool useCm /// The clients NetworkManagers /// The targetFrameRate of the Unity engine to use while the multi instance helper is running. Will be reset on shutdown. /// This determines if the server or clients will be instantiated first (defaults to server first) - /// If true, the server transport will use a mock transport, and the clients will be created with a connection to a locally hosted da service + /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false + /// If true, all clients will be created with a connection to a locally hosted da service. The server transport will use a mock transport as it is not needed. + /// Returns `true` if the server and client instances were successfully created and configured, otherwise `false` public static bool Create(int clientCount, out NetworkManager server, out NetworkManager[] clients, int targetFrameRate = 60, bool serverFirst = true, bool useMockTransport = false, bool useCmbService = false) { s_NetworkManagerInstances = new List(); @@ -290,6 +297,7 @@ internal static NetworkManager CreateNewClient(int identifier, bool mockTranspor /// Output array containing the created NetworkManager instances /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false /// If true, each client will be created with transport configured to connect to a locally hosted da service + /// Returns `true` if the clients were successfully created and configured, otherwise `false` public static bool CreateNewClients(int clientCount, out NetworkManager[] clients, bool useMockTransport = false, bool useCmbService = false) { clients = new NetworkManager[clientCount]; diff --git a/pvpExceptions.json b/pvpExceptions.json index c004d0ed32..d70527ca25 100644 --- a/pvpExceptions.json +++ b/pvpExceptions.json @@ -179,10 +179,6 @@ "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: NetworkManagerInstances: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: void RegisterHandlers(NetworkManager, bool): missing ", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: void RegisterHandlers(NetworkManager, bool): missing ", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: NetworkManager CreateServer(bool): undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: bool Create(int, out NetworkManager, out NetworkManager[], int, bool, bool): missing ", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: bool Create(int, out NetworkManager, out NetworkManager[], int, bool, bool): missing ", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: bool CreateNewClients(int, out NetworkManager[], bool): missing ", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: bool Start(bool, NetworkManager, NetworkManager[], BeforeClientStartCallback, bool): missing ", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: uint GetNextGlobalIdHashValue(): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTestHelpers: IsNetcodeIntegrationTestRunning: undocumented", From 4a04ed9f14b5673aef4fb02832857e7544124bdc Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 13:04:18 -0400 Subject: [PATCH 04/30] Fix code docs --- .../TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 74a409e035..cbeff62ed7 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -218,7 +218,7 @@ private static void AddMockTransport(NetworkManager networkManager) /// /// Creates and configures a new server instance for integration testing. /// - /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false + /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false /// The created server instance. public static NetworkManager CreateServer(bool mockTransport = false) { From d86da3ebbd4a395274e4cf573e48ee9d49876972 Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 13:17:40 -0400 Subject: [PATCH 05/30] fix formatting --- .../DistributedAuthorityConnectionTest.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs index bf4b7f7d74..56501f0415 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -1,11 +1,6 @@ -using System; using System.Collections; -using System.Linq; -using System.Net; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; -using Unity.Netcode.Transports.UTP; -using Unity.Networking.Transport; using UnityEngine; using UnityEngine.TestTools; From 16b504b76008ccd598407353ee724cd77b0bfc5a Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 13:28:55 -0400 Subject: [PATCH 06/30] remove backticks --- .../TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index cbeff62ed7..67fc3be35c 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -249,7 +249,7 @@ public static NetworkManager CreateServer(bool mockTransport = false) /// This determines if the server or clients will be instantiated first (defaults to server first) /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false /// If true, all clients will be created with a connection to a locally hosted da service. The server transport will use a mock transport as it is not needed. - /// Returns `true` if the server and client instances were successfully created and configured, otherwise `false` + /// Returns true if the server and client instances were successfully created and configured, otherwise false public static bool Create(int clientCount, out NetworkManager server, out NetworkManager[] clients, int targetFrameRate = 60, bool serverFirst = true, bool useMockTransport = false, bool useCmbService = false) { s_NetworkManagerInstances = new List(); @@ -297,7 +297,7 @@ internal static NetworkManager CreateNewClient(int identifier, bool mockTranspor /// Output array containing the created NetworkManager instances /// When true, uses mock transport for testing, otherwise uses real transport. Default value is false /// If true, each client will be created with transport configured to connect to a locally hosted da service - /// Returns `true` if the clients were successfully created and configured, otherwise `false` + /// Returns true if the clients were successfully created and configured, otherwise false public static bool CreateNewClients(int clientCount, out NetworkManager[] clients, bool useMockTransport = false, bool useCmbService = false) { clients = new NetworkManager[clientCount]; From b2fed7f659d59700bcb01579a26661e1b8c33046 Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 13:40:54 -0400 Subject: [PATCH 07/30] Add missing import --- .../TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 67fc3be35c..301af290ac 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Net; using NUnit.Framework; using Unity.Netcode.Transports.UTP; using UnityEngine; From a10e61f808d8783a03557c8aa2cc6c0b62c4d575 Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 14:52:09 -0400 Subject: [PATCH 08/30] Swap the tests to run on ubuntu --- .yamato/_triggers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.yamato/_triggers.yml b/.yamato/_triggers.yml index 46fd7205d3..e3b3add45d 100644 --- a/.yamato/_triggers.yml +++ b/.yamato/_triggers.yml @@ -55,7 +55,7 @@ pull_request_trigger: # # Run project EditMode and PLaymode project tests on minimum supported editor (6000.0 in case of NGOv2.X) # - .yamato/_run-all.yml#run_all_project_tests_6000 # # Run standalone test with mixture of parameters to make sure there are no obvious issues with most common platform (for example --fail-on-assert option is not present with package/project tests). We run 2 different combinations with different platform/editor/scripting backend. - - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_mac_il2cpp_trunk + - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_trunk # - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_win_mono_6000.0 triggers: cancel_old_ci: true From e5d76bbf2fe6a4e8365d2697333436fa40d8ce54 Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 17:14:59 -0400 Subject: [PATCH 09/30] use inline command instead of funtion --- Tools/CI/rust.sh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Tools/CI/rust.sh b/Tools/CI/rust.sh index 8914639611..6c67f3239f 100755 --- a/Tools/CI/rust.sh +++ b/Tools/CI/rust.sh @@ -15,13 +15,5 @@ cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & # Build the standalone server cargo build -# Run the standalone server loop in the background -runstandalone & - -# Use a function to run the standalone server in a loop, when it exits, it will always restart -runstandalone() { - while :; do - # loop infinitely - cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m - done -} +# Run the standalone server on an infinite loop in the background +while :; do cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m done & From d0e8d14fb0e67c2bd206772049bf4e984aff61ea Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 19:45:43 -0400 Subject: [PATCH 10/30] Fix while loop issue --- .yamato/desktop-standalone-tests.yml | 5 +++-- Tools/CI/rust.sh | 10 +++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.yamato/desktop-standalone-tests.yml b/.yamato/desktop-standalone-tests.yml index 8f314ba294..b04e897c64 100644 --- a/.yamato/desktop-standalone-tests.yml +++ b/.yamato/desktop-standalone-tests.yml @@ -81,14 +81,15 @@ desktop_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ {% if platform.name != "win" %} # Issues with win and mac are tracked in MTT-11606 variables: ECHO_SERVER_PORT: "7788" - COMB_SERVER_PORT: "7789" + COMB_SERVER_PORT: "7799" # Set this to ensure the DA codec tests will fail if they cannot connect to the echo-server # The default is to ignore the codec tests if the echo-server fails to connect ENSURE_CODEC_TESTS: "true" + USE_CMB_SERVICE: "true" {% endif %} commands: -# If not windows, run rust echo server (This is needed ONLY for NGOv2.X because relates to Distributed Authority) +# If ubuntu, run rust echo server (This is needed ONLY for NGOv2.X because relates to Distributed Authority) {% if platform.name != "win" %} # Issues with win and mac are tracked in MTT-11606 - ./Tools/CI/rust.sh {% endif %} diff --git a/Tools/CI/rust.sh b/Tools/CI/rust.sh index 6c67f3239f..5c3fd47ac9 100755 --- a/Tools/CI/rust.sh +++ b/Tools/CI/rust.sh @@ -16,4 +16,12 @@ cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & cargo build # Run the standalone server on an infinite loop in the background -while :; do cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m done & +while :; do cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m; done & + +# Use a function to run the standalone server in a loop, when it exits, it will always restart +runstandalone() { + while :; do + # loop infinitely + cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m + done +} From 58aefa918053cdb54d0505ca624f24476ea81dcc Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 24 Apr 2025 19:51:54 -0400 Subject: [PATCH 11/30] Stop changeownership message on spawn --- .../Runtime/Core/NetworkObject.cs | 5 ++++- .../Runtime/Spawning/NetworkSpawnManager.cs | 20 ++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index 64c8e96076..65413c09e4 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -628,7 +628,10 @@ public bool SetOwnershipLock(bool lockOwnership = true) RemoveOwnershipExtended(OwnershipStatusExtended.Locked); } - SendOwnershipStatusUpdate(); + if (IsSpawned) + { + SendOwnershipStatusUpdate(); + } return true; } diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs index 19227c82ba..b8190ccbaf 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs @@ -1118,7 +1118,6 @@ private void SpawnNetworkObjectLocallyCommon(NetworkObject networkObject, ulong return; } - networkObject.IsSpawned = true; networkObject.IsSceneObject = sceneObject; // Always check to make sure our scene of origin is properly set for in-scene placed NetworkObjects @@ -1151,6 +1150,8 @@ private void SpawnNetworkObjectLocallyCommon(NetworkObject networkObject, ulong { networkObject.SetOwnershipLock(); } + + networkObject.IsSpawned = true; SpawnedObjects.Add(networkObject.NetworkObjectId, networkObject); SpawnedObjectsList.Add(networkObject); @@ -2228,14 +2229,15 @@ internal void SynchronizeObjectsToNewlyJoinedClient(ulong newClientId) { if (networkObject.Observers.Contains(newClientId)) { - if (NetworkManager.LogLevel <= LogLevel.Developer) - { - // Temporary tracking to make sure we are not showing something already visibile (should never be the case for this) - Debug.LogWarning($"[{nameof(SynchronizeObjectsToNewlyJoinedClient)}][{networkObject.name}] New client as already an observer!"); - } - // For now, remove the client (impossible for the new client to have an instance since the session owner doesn't) to make sure newly added - // code to handle this edge case works. - networkObject.Observers.Remove(newClientId); + // if (NetworkManager.LogLevel <= LogLevel.Developer) + // { + // // Temporary tracking to make sure we are not showing something already visibile (should never be the case for this) + // Debug.LogWarning($"[{nameof(SynchronizeObjectsToNewlyJoinedClient)}][{networkObject.name}] New client as already an observer!"); + // } + // // For now, remove the client (impossible for the new client to have an instance since the session owner doesn't) to make sure newly added + // // code to handle this edge case works. + // networkObject.Observers.Remove(newClientId); + continue; } networkObject.NetworkShow(newClientId); } From c4498e509502b322f10bb4eb2e29751a5c8c5eae Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 12:14:08 -0400 Subject: [PATCH 12/30] try connect to service utp only --- .yamato/desktop-standalone-tests.yml | 2 +- .../DistributedAuthorityConnectionTest.cs | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/.yamato/desktop-standalone-tests.yml b/.yamato/desktop-standalone-tests.yml index b04e897c64..93055247a8 100644 --- a/.yamato/desktop-standalone-tests.yml +++ b/.yamato/desktop-standalone-tests.yml @@ -81,7 +81,7 @@ desktop_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ {% if platform.name != "win" %} # Issues with win and mac are tracked in MTT-11606 variables: ECHO_SERVER_PORT: "7788" - COMB_SERVER_PORT: "7799" + COMB_SERVER_PORT: "7789" # Set this to ensure the DA codec tests will fail if they cannot connect to the echo-server # The default is to ignore the codec tests if the echo-server fails to connect ENSURE_CODEC_TESTS: "true" diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs index 56501f0415..3e021e660e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -1,6 +1,10 @@ +using System; using System.Collections; +using System.Linq; +using System.Net; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; +using Unity.Networking.Transport; using UnityEngine; using UnityEngine.TestTools; @@ -67,6 +71,54 @@ public IEnumerator CreateObjectNew() AssertOnTimeout("failed to spawn object!"); } + private static readonly string k_TransportHost = GetAddressToBind(); + private static readonly ushort k_TransportPort = GetPortToBind(); + + /// + /// Configures the port to look for the rust service. + /// + /// The port from the environment variable "CMB_SERVICE_PORT" if it is set and valid; otherwise uses port 7789 + private static ushort GetPortToBind() + { + var value = Environment.GetEnvironmentVariable("CMB_SERVICE_PORT"); + return ushort.TryParse(value, out var configuredPort) ? configuredPort : (ushort)7789; + } + + /// + /// Configures the address to look for the rust service. + /// + /// The address from the environment variable "NGO_HOST" if it is set and valid; otherwise uses "127.0.0.1" + private static string GetAddressToBind() + { + var value = Environment.GetEnvironmentVariable("NGO_HOST") ?? "127.0.0.1"; + return Dns.GetHostAddresses(value).First().ToString(); + } + + [Test] + public void CanConnectToServer() + { + var address = Dns.GetHostAddresses(k_TransportHost).First(); + var endpoint = NetworkEndpoint.Parse(address.ToString(), k_TransportPort); + + var driver = NetworkDriver.Create(); + var connection = driver.Connect(endpoint); + + var start = DateTime.Now; + var ev = Networking.Transport.NetworkEvent.Type.Empty; + while (ev != Networking.Transport.NetworkEvent.Type.Connect) + { + driver.ScheduleUpdate().Complete(); + ev = driver.PopEventForConnection(connection, out _, out _); + + if (DateTime.Now - start > TimeSpan.FromMilliseconds(100)) + { + Assert.Fail("Failed to connect to comb service within time!"); + } + } + + driver.Disconnect(connection); + } + private bool CheckObjectExists() { From 8d07f340eb70244aa4d9d99280b82346d0b50b72 Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 12:17:51 -0400 Subject: [PATCH 13/30] update standalone service timeout to 1h --- Tools/CI/rust.sh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Tools/CI/rust.sh b/Tools/CI/rust.sh index 5c3fd47ac9..dedacaad96 100755 --- a/Tools/CI/rust.sh +++ b/Tools/CI/rust.sh @@ -16,12 +16,4 @@ cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & cargo build # Run the standalone server on an infinite loop in the background -while :; do cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m; done & - -# Use a function to run the standalone server in a loop, when it exits, it will always restart -runstandalone() { - while :; do - # loop infinitely - cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 10m - done -} +while :; do cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 60m; done & From 60ca952130799b98da99ca03e4c77d0cb4730334 Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 12:18:14 -0400 Subject: [PATCH 14/30] ensure active scene hash is always synchroniszed to the service --- .../Runtime/SceneManagement/NetworkSceneManager.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index 331d5ff112..9a85c510b7 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -2042,6 +2042,7 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic } // Organize how (and when) we serialize our NetworkObjects + var hasSynchronizedActive = false; for (int i = 0; i < SceneManager.sceneCount; i++) { var scene = SceneManager.GetSceneAt(i); @@ -2067,6 +2068,10 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic continue; } sceneEventData.SceneHash = SceneHashFromNameOrPath(scene.path); + if (sceneEventData.SceneHash == sceneEventData.ActiveSceneHash) + { + hasSynchronizedActive = true; + } // If we are just a normal client, then always use the server scene handle if (NetworkManager.DistributedAuthorityMode) @@ -2085,7 +2090,7 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic } // If we are just a normal client and in distributed authority mode, then always use the known server scene handle - if (NetworkManager.DistributedAuthorityMode && !NetworkManager.DAHost) + if (NetworkManager.DistributedAuthorityMode && NetworkManager.CMBServiceConnection) { sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), ClientSceneHandleToServerSceneHandle[scene.handle]); } @@ -2095,6 +2100,11 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic } } + if (!hasSynchronizedActive && NetworkManager.CMBServiceConnection && synchronizingService) + { + sceneEventData.AddSceneToSynchronize(BuildIndexToHash[activeScene.buildIndex], ClientSceneHandleToServerSceneHandle[activeScene.handle]); + } + sceneEventData.AddSpawnedNetworkObjects(); sceneEventData.AddDespawnedInSceneNetworkObjects(); var message = new SceneEventMessage From 8c5745d95ea87f0e9e402529ce29d557c6012bb4 Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 14:26:24 -0400 Subject: [PATCH 15/30] Add timeout between rust tests --- .../DistributedAuthorityConnectionTest.cs | 31 ++++++------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs index 3e021e660e..df42359824 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -28,19 +28,6 @@ public DistributedAuthorityConnectionTest() : base(NetworkTopologyTypes.Distribu private GameObject m_SpawnObject; - internal class TestNetworkComponent : NetworkBehaviour - { - } - - /// - /// Add any additional components to default player prefab - /// - protected override void OnCreatePlayerPrefab() - { - m_PlayerPrefab.AddComponent(); - base.OnCreatePlayerPrefab(); - } - /// /// Modify NetworkManager instances for settings specific to tests /// @@ -50,13 +37,12 @@ protected override void OnServerAndClientsCreated() { client.NetworkConfig.EnableSceneManagement = false; client.NetworkConfig.AutoSpawnPlayerPrefabClientSide = true; - } - SessionOwner.LogLevel = LogLevel.Developer; - // Validate we are in distributed authority mode with client side spawning and using CMB Service - Assert.True(SessionOwner.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); - Assert.True(SessionOwner.AutoSpawnPlayerPrefabClientSide, "Client side spawning is not set!"); - Assert.True(SessionOwner.CMBServiceConnection, "CMBServiceConnection is not set!"); + // Validate we are in distributed authority mode with client side spawning and using CMB Service + Assert.True(client.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); + Assert.True(client.CMBServiceConnection, "CMBServiceConnection is not set!"); + + } // Create a prefab for creating and destroying tests (auto-registers with NetworkManagers) m_SpawnObject = CreateNetworkObjectPrefab("TestObject"); @@ -94,8 +80,8 @@ private static string GetAddressToBind() return Dns.GetHostAddresses(value).First().ToString(); } - [Test] - public void CanConnectToServer() + [UnityTest] + public IEnumerator CanConnectToServer() { var address = Dns.GetHostAddresses(k_TransportHost).First(); var endpoint = NetworkEndpoint.Parse(address.ToString(), k_TransportPort); @@ -117,6 +103,9 @@ public void CanConnectToServer() } driver.Disconnect(connection); + + // Ensure the rust server fully times out and disconnects + yield return new WaitForSeconds(2f); } From 9ec7b4386751fbbaba26373b528cddaedee17862 Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 15:13:44 -0400 Subject: [PATCH 16/30] unbreak test --- .../DistributedAuthorityConnectionTest.cs | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs index df42359824..3d384de7ee 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -14,17 +14,10 @@ internal class DistributedAuthorityConnectionTest : NetcodeIntegrationTest { protected override int NumberOfClients => 1; - private NetworkManager SessionOwner => m_ClientNetworkManagers[0]; - - // Use the CMB Service for all tests - protected override bool UseCMBService() => true; - // Set the network topology to distributed authority for all tests protected override NetworkTopologyTypes OnGetNetworkTopologyType() => NetworkTopologyTypes.DistributedAuthority; - - public DistributedAuthorityConnectionTest() : base(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost) { } - + public DistributedAuthorityConnectionTest() : base(HostOrServer.DAHost) { } private GameObject m_SpawnObject; @@ -36,7 +29,6 @@ protected override void OnServerAndClientsCreated() foreach (var client in m_ClientNetworkManagers) { client.NetworkConfig.EnableSceneManagement = false; - client.NetworkConfig.AutoSpawnPlayerPrefabClientSide = true; // Validate we are in distributed authority mode with client side spawning and using CMB Service Assert.True(client.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); @@ -47,11 +39,10 @@ protected override void OnServerAndClientsCreated() // Create a prefab for creating and destroying tests (auto-registers with NetworkManagers) m_SpawnObject = CreateNetworkObjectPrefab("TestObject"); } - [UnityTest] public IEnumerator CreateObjectNew() { - SpawnObject(m_SpawnObject, SessionOwner); + SpawnObject(m_SpawnObject, m_ClientNetworkManagers[0]); yield return WaitForConditionOrTimeOut(CheckObjectExists); AssertOnTimeout("failed to spawn object!"); @@ -80,8 +71,8 @@ private static string GetAddressToBind() return Dns.GetHostAddresses(value).First().ToString(); } - [UnityTest] - public IEnumerator CanConnectToServer() + [Test] + public void CanConnectToServer() { var address = Dns.GetHostAddresses(k_TransportHost).First(); var endpoint = NetworkEndpoint.Parse(address.ToString(), k_TransportPort); @@ -103,9 +94,6 @@ public IEnumerator CanConnectToServer() } driver.Disconnect(connection); - - // Ensure the rust server fully times out and disconnects - yield return new WaitForSeconds(2f); } From b08c482ee07ea8524e9e623b95fdb079b9612e81 Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 16:54:24 -0400 Subject: [PATCH 17/30] actually use the hosted service --- .../DistributedAuthorityConnectionTest.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs index 3d384de7ee..cd997a1bbd 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -21,6 +21,12 @@ public DistributedAuthorityConnectionTest() : base(HostOrServer.DAHost) { } private GameObject m_SpawnObject; + protected override bool UseCMBService() + { + return true; + } + + /// /// Modify NetworkManager instances for settings specific to tests /// @@ -33,7 +39,6 @@ protected override void OnServerAndClientsCreated() // Validate we are in distributed authority mode with client side spawning and using CMB Service Assert.True(client.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); Assert.True(client.CMBServiceConnection, "CMBServiceConnection is not set!"); - } // Create a prefab for creating and destroying tests (auto-registers with NetworkManagers) From d000e5aadc488458348db6fe1fb6c7e82ff8c898 Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 18:20:52 -0400 Subject: [PATCH 18/30] Remove can connect test, we can connect. Run only CreateObjectNew() --- .../DistributedAuthorityConnectionTest.cs | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs index cd997a1bbd..2b0d8f1f63 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -53,54 +53,6 @@ public IEnumerator CreateObjectNew() AssertOnTimeout("failed to spawn object!"); } - private static readonly string k_TransportHost = GetAddressToBind(); - private static readonly ushort k_TransportPort = GetPortToBind(); - - /// - /// Configures the port to look for the rust service. - /// - /// The port from the environment variable "CMB_SERVICE_PORT" if it is set and valid; otherwise uses port 7789 - private static ushort GetPortToBind() - { - var value = Environment.GetEnvironmentVariable("CMB_SERVICE_PORT"); - return ushort.TryParse(value, out var configuredPort) ? configuredPort : (ushort)7789; - } - - /// - /// Configures the address to look for the rust service. - /// - /// The address from the environment variable "NGO_HOST" if it is set and valid; otherwise uses "127.0.0.1" - private static string GetAddressToBind() - { - var value = Environment.GetEnvironmentVariable("NGO_HOST") ?? "127.0.0.1"; - return Dns.GetHostAddresses(value).First().ToString(); - } - - [Test] - public void CanConnectToServer() - { - var address = Dns.GetHostAddresses(k_TransportHost).First(); - var endpoint = NetworkEndpoint.Parse(address.ToString(), k_TransportPort); - - var driver = NetworkDriver.Create(); - var connection = driver.Connect(endpoint); - - var start = DateTime.Now; - var ev = Networking.Transport.NetworkEvent.Type.Empty; - while (ev != Networking.Transport.NetworkEvent.Type.Connect) - { - driver.ScheduleUpdate().Complete(); - ev = driver.PopEventForConnection(connection, out _, out _); - - if (DateTime.Now - start > TimeSpan.FromMilliseconds(100)) - { - Assert.Fail("Failed to connect to comb service within time!"); - } - } - - driver.Disconnect(connection); - } - private bool CheckObjectExists() { From ae2ddf08791bfb68df7121bbf31969c385cb1dfb Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 19:40:12 -0400 Subject: [PATCH 19/30] Fix formatting --- .../DistributedAuthorityConnectionTest.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs index 2b0d8f1f63..b23a7509db 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs @@ -1,10 +1,6 @@ -using System; using System.Collections; -using System.Linq; -using System.Net; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; -using Unity.Networking.Transport; using UnityEngine; using UnityEngine.TestTools; From 07a51ffe4938be4dedcfbd30386f51112d024d80 Mon Sep 17 00:00:00 2001 From: Emma Date: Fri, 25 Apr 2025 21:56:37 -0400 Subject: [PATCH 20/30] lets go --- .../Runtime/NetcodeIntegrationTest.cs | 232 +++++++++++------- .../Runtime/NetcodeIntegrationTestHelpers.cs | 36 ++- .../Connection/ClientConnectionTests.cs | 6 + .../DeferredDespawningTests.cs | 6 + .../DistributeObjectsTests.cs | 68 +++-- .../ExtendedNetworkShowAndHideTests.cs | 45 +--- .../NetworkClientAndPlayerObjectTests.cs | 74 ++---- .../OwnershipPermissionsTests.cs | 48 ++-- .../ParentChildDistibutionTests.cs | 51 ++-- .../SessionVersionConnectionRequest.cs | 19 +- .../SpawnDuringSynchronizationTests.cs | 19 +- .../Tests/Runtime/ListChangedTest.cs | 5 +- .../NetworkBehaviourPrePostSpawnTests.cs | 6 + .../NetworkObjectDestroyTests.cs | 6 + .../NetworkObjectDontDestroyWithOwnerTests.cs | 6 + .../NetworkObjectOnNetworkDespawnTests.cs | 6 + .../NetworkObjectOnSpawnTests.cs | 6 + .../NetworkObjectOwnershipPropertiesTests.cs | 6 + .../NetworkObjectOwnershipTests.cs | 129 +++++----- .../NetworkObjectSpawnManyObjectsTests.cs | 6 +- .../NetworkObjectSynchronizationTests.cs | 6 + .../Tests/Runtime/NetworkShowHideTests.cs | 6 + .../Tests/Runtime/NetworkSpawnManagerTests.cs | 7 +- .../InterpolationStopAndStartMotionTest.cs | 14 +- .../NetworkTransformGeneral.cs | 1 - .../NetworkTransformMixedAuthorityTests.cs | 5 - .../NetworkTransformOwnershipTests.cs | 28 +-- .../NetworkTransform/NetworkTransformTests.cs | 6 + .../NetworkVarBufferCopyTest.cs | 11 +- ...orkVariableBaseInitializesWhenPersisted.cs | 15 +- .../NetworkVariableCollectionsTests.cs | 40 ++- .../NetworkVariableInheritanceTests.cs | 8 +- .../NetworkVariable/OwnerModifiedTests.cs | 6 + .../Tests/Runtime/NetworkVisibilityTests.cs | 41 ++-- .../Runtime/ParentingDuringSpawnTests.cs | 19 +- .../Runtime/Physics/NetworkRigidbodyTest.cs | 46 ++-- .../Tests/Runtime/PlayerObjectTests.cs | 84 ++++--- .../Prefabs/NetworkPrefabOverrideTests.cs | 59 ++--- .../Tests/Runtime/UniversalRpcTests.cs | 6 + pvpExceptions.json | 3 - .../Assets/DefaultNetworkPrefabs.asset | 106 ++++++++ .../ParentPlayerToInSceneNetworkObject.cs | 5 + .../Runtime/Animation/NetworkAnimatorTests.cs | 7 +- .../NetworkBehaviourSessionSynchronized.cs | 10 +- .../Tests/Runtime/NetworkObjectSpawning.cs | 6 + .../ClientSynchronizationValidationTest.cs | 6 + .../InScenePlacedNetworkObjectTests.cs | 6 + .../NetworkSceneManagerEventCallbacks.cs | 6 + .../NetworkSceneManagerEventDataPoolTest.cs | 5 + .../NetworkSceneManagerEventNotifications.cs | 6 + ...NetworkSceneManagerPopulateInSceneTests.cs | 5 + .../NetworkSceneManagerSeneVerification.cs | 6 + .../NetworkSceneManagerUsageTests.cs | 7 + .../SceneEventProgressTests.cs | 6 + .../ParentDynamicUnderInScenePlaced.cs | 6 + .../ParentingInSceneObjectsTests.cs | 6 + .../ParentingWorldPositionStaysTests.cs | 6 + .../RespawnInSceneObjectsAfterShutdown.cs | 6 + .../Assets/Tests/Runtime/SenderIdTests.cs | 6 + .../Runtime/ServerDisconnectsClientTest.cs | 6 + 60 files changed, 840 insertions(+), 574 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index c61e53ba32..a3acaa2f9a 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -96,11 +96,9 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj } } - protected int TotalClients => m_UseHost ? m_NumberOfClients + 1 : m_NumberOfClients; + protected int TotalClients => m_UseHost ? NumberOfClients + 1 : NumberOfClients; protected const uint k_DefaultTickRate = 30; - - private int m_NumberOfClients; protected abstract int NumberOfClients { get; } /// @@ -127,8 +125,47 @@ public enum HostOrServer } protected GameObject m_PlayerPrefab; + + /// The Server instance protected NetworkManager m_ServerNetworkManager; + /// All the client instances protected NetworkManager[] m_ClientNetworkManagers; + /// All the instances + protected NetworkManager[] m_NetworkManagers; + + /// + /// Gets the current authority. + /// When using the hosted CMB service this will be the client who is the session owner. + /// Otherwise, returns the server + /// + /// The instance that is the current authority + protected NetworkManager GetAuthorityNetworkManager() + { + if (m_UseCmbService) + { + foreach (var client in m_NetworkManagers) + { + // If client isn't approved we are still in setup and want to return the first client + // otherwise look for the session owner + if (!client.LocalClient.IsApproved || client.LocalClient.IsSessionOwner) + { + return client; + } + } + Assert.Fail("No DA session owner found!"); + } + + return m_ServerNetworkManager; + } + + /// + /// Gets a non-session owner . + /// + /// A instance that will not be the session owner + protected NetworkManager GetNonAuthorityNetworkManager() + { + return m_ClientNetworkManagers.First(client => !client.LocalClient.IsSessionOwner); + } /// /// Contains each client relative set of player NetworkObject instances @@ -143,9 +180,22 @@ public enum HostOrServer protected bool m_DistributedAuthority; protected NetworkTopologyTypes m_NetworkTopologyType = NetworkTopologyTypes.ClientServer; + protected bool m_UseCmbService; + + /// + /// Indicates whether a hosted CMB service is available. + /// + /// Override to return false to ensure a set of tests never runs against the hosted service + /// true if a DAHost test should run against a hosted CMB service instance; otherwise false protected virtual bool UseCMBService() { - return false; +#if USE_CMB_SERVICE + return true; +#else + var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "unset"; + Debug.Log($"Using CMB service: {useCmbService}"); + return useCmbService.ToLower() == "true"; +#endif } protected virtual NetworkTopologyTypes OnGetNetworkTopologyType() @@ -157,7 +207,7 @@ protected void SetDistributedAuthorityProperties(NetworkManager networkManager) { networkManager.NetworkConfig.NetworkTopology = m_NetworkTopologyType; networkManager.NetworkConfig.AutoSpawnPlayerPrefabClientSide = m_DistributedAuthority; - networkManager.NetworkConfig.UseCMBService = UseCMBService() && m_DistributedAuthority; + networkManager.NetworkConfig.UseCMBService = m_UseCmbService; } protected int m_TargetFrameRate = 60; @@ -293,7 +343,6 @@ protected virtual void OnOneTimeSetup() public void OneTimeSetup() { Application.runInBackground = true; - m_NumberOfClients = NumberOfClients; IsRunning = true; m_EnableVerboseDebug = OnSetVerboseDebug(); IntegrationTestSceneHandler.VerboseDebugMode = m_EnableVerboseDebug; @@ -364,8 +413,11 @@ public IEnumerator SetUp() // Setup the frames per tick for time travel advance to next tick ConfigureFramesPerTick(); } + if (m_SetupIsACoroutine) { + yield return NetcodeIntegrationTestHelpers.WaitBetweenCmbServiceTests(m_UseCmbService); + yield return OnSetup(); } else @@ -462,7 +514,12 @@ private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetw } m_ClientNetworkManagers = clientNetworkManagersList.ToArray(); - m_NumberOfClients = clientNetworkManagersList.Count; + + if (!m_UseCmbService) + { + clientNetworkManagersList.Insert(0, m_ServerNetworkManager); + } + m_NetworkManagers = clientNetworkManagersList.ToArray(); } /// @@ -522,8 +579,7 @@ protected virtual bool ShouldWaitForNewClientToConnect(NetworkManager networkMan /// An IEnumerator to be used in a coroutine for asynchronous execution. protected IEnumerator CreateAndStartNewClient() { - bool useCmbService = UseCMBService() && m_DistributedAuthority; - var networkManager = NetcodeIntegrationTestHelpers.CreateNewClient(m_ClientNetworkManagers.Length, m_EnableTimeTravel, useCmbService); + var networkManager = NetcodeIntegrationTestHelpers.CreateNewClient(m_ClientNetworkManagers.Length, m_EnableTimeTravel, m_UseCmbService); networkManager.NetworkConfig.PlayerPrefab = m_PlayerPrefab; SetDistributedAuthorityProperties(networkManager); @@ -577,40 +633,25 @@ private bool AllPlayerObjectClonesSpawned(NetworkManager joinedClient) // Continue to populate the PlayerObjects list until all player object (local and clone) are found ClientNetworkManagerPostStart(joinedClient); - if (!(UseCMBService() && m_DistributedAuthority)) - { - var playerObjectRelative = m_ServerNetworkManager.SpawnManager.PlayerObjects.Where((c) => c.OwnerClientId == joinedClient.LocalClientId).FirstOrDefault(); - if (playerObjectRelative == null) - { - m_InternalErrorLog.Append($"[AllPlayerObjectClonesSpawned][Server-Side] Joining Client-{joinedClient.LocalClientId} was not populated in the {nameof(NetworkSpawnManager.PlayerObjects)} list!"); - return false; - } - // Go ahead and create an entry for this new client - if (!m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId].ContainsKey(joinedClient.LocalClientId)) - { - m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId].Add(joinedClient.LocalClientId, playerObjectRelative); - } - } - - foreach (var clientNetworkManager in m_ClientNetworkManagers) + foreach (var networkManager in m_NetworkManagers) { - if (clientNetworkManager.LocalClientId == joinedClient.LocalClientId) + if (networkManager.LocalClientId == joinedClient.LocalClientId) { continue; } - var playerObjectRelative = clientNetworkManager.SpawnManager.PlayerObjects.Where((c) => c.OwnerClientId == joinedClient.LocalClientId).FirstOrDefault(); + var playerObjectRelative = networkManager.SpawnManager.PlayerObjects.FirstOrDefault(c => c.OwnerClientId == joinedClient.LocalClientId); if (playerObjectRelative == null) { - m_InternalErrorLog.Append($"[AllPlayerObjectClonesSpawned][Client-{clientNetworkManager.LocalClientId}] Client-{joinedClient.LocalClientId} was not populated in the {nameof(NetworkSpawnManager.PlayerObjects)} list!"); + m_InternalErrorLog.Append($"[AllPlayerObjectClonesSpawned][Client-{networkManager.LocalClientId}] Client-{joinedClient.LocalClientId} was not populated in the {nameof(NetworkSpawnManager.PlayerObjects)} list!"); return false; } // Go ahead and create an entry for this new client - if (!m_PlayerNetworkObjects[clientNetworkManager.LocalClientId].ContainsKey(joinedClient.LocalClientId)) + if (!m_PlayerNetworkObjects[networkManager.LocalClientId].ContainsKey(joinedClient.LocalClientId)) { - m_PlayerNetworkObjects[clientNetworkManager.LocalClientId].Add(joinedClient.LocalClientId, playerObjectRelative); + m_PlayerNetworkObjects[networkManager.LocalClientId].Add(joinedClient.LocalClientId, playerObjectRelative); } } return true; @@ -721,9 +762,14 @@ protected void CreateServerAndClients(int numberOfClients) m_TargetFrameRate = -1; } + // Add an extra session owner client when using the cmb service + if (m_UseCmbService) + { + numberOfClients += 1; + } + // Create multiple NetworkManager instances - var useCmbService = UseCMBService() && m_DistributedAuthority; - if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_CreateServerFirst, m_EnableTimeTravel, useCmbService)) + if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_CreateServerFirst, m_EnableTimeTravel, m_UseCmbService)) { Debug.LogError("Failed to create instances"); Assert.Fail("Failed to create instances"); @@ -732,20 +778,20 @@ protected void CreateServerAndClients(int numberOfClients) m_ClientNetworkManagers = clients; m_ServerNetworkManager = server; - if (m_ServerNetworkManager != null) + var managers = clients.ToList(); + if (!m_UseCmbService) { - s_DefaultWaitForTick = new WaitForSecondsRealtime(1.0f / m_ServerNetworkManager.NetworkConfig.TickRate); + managers.Insert(0, m_ServerNetworkManager); } + m_NetworkManagers = managers.ToArray(); - // Set the player prefab for the server and clients - m_ServerNetworkManager.NetworkConfig.PlayerPrefab = m_PlayerPrefab; + s_DefaultWaitForTick = new WaitForSecondsRealtime(1.0f / m_ServerNetworkManager.NetworkConfig.TickRate); - SetDistributedAuthorityProperties(m_ServerNetworkManager); - - foreach (var client in m_ClientNetworkManagers) + // Set the player prefab for the server and clients + foreach (var manager in m_NetworkManagers) { - client.NetworkConfig.PlayerPrefab = m_PlayerPrefab; - SetDistributedAuthorityProperties(client); + manager.NetworkConfig.PlayerPrefab = m_PlayerPrefab; + SetDistributedAuthorityProperties(manager); } // Provides opportunity to allow child derived classes to @@ -899,9 +945,10 @@ protected IEnumerator StartServerAndClients() // Start the instances and pass in our SceneManagerInitialization action that is invoked immediately after host-server // is started and after each client is started. - // When using the CMBService, don't start the server. - bool startServer = !(UseCMBService() && m_DistributedAuthority); - if (!NetcodeIntegrationTestHelpers.Start(m_UseHost, startServer, m_ServerNetworkManager, m_ClientNetworkManagers)) + // When using the CMBService, we don't have a server, so get the appropriate authority network manager + var authorityManager = GetAuthorityNetworkManager(); + + if (!NetcodeIntegrationTestHelpers.Start(m_UseHost, !m_UseCmbService, m_ServerNetworkManager, m_ClientNetworkManagers)) { Debug.LogError("Failed to start instances"); Assert.Fail("Failed to start instances"); @@ -910,13 +957,10 @@ protected IEnumerator StartServerAndClients() // When scene management is enabled, we need to re-apply the scenes populated list since we have overriden the ISceneManagerHandler // imeplementation at this point. This assures any pre-loaded scenes will be automatically assigned to the server and force clients // to load their own scenes. - if (m_ServerNetworkManager.NetworkConfig.EnableSceneManagement) + if (authorityManager.NetworkConfig.EnableSceneManagement) { - if (startServer) - { - var scenesLoaded = m_ServerNetworkManager.SceneManager.ScenesLoaded; - m_ServerNetworkManager.SceneManager.SceneManagerHandler.PopulateLoadedScenes(ref scenesLoaded, m_ServerNetworkManager); - } + var scenesLoaded = authorityManager.SceneManager.ScenesLoaded; + authorityManager.SceneManager.SceneManagerHandler.PopulateLoadedScenes(ref scenesLoaded, authorityManager); } if (LogAllMessages) @@ -940,12 +984,11 @@ protected IEnumerator StartServerAndClients() if (m_UseHost || m_ServerNetworkManager.IsHost) { #if UNITY_2023_1_OR_NEWER - var manager = startServer ? m_ServerNetworkManager : m_ClientNetworkManagers[0]; // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries - var serverPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == manager.LocalClientId); + var serverPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == authorityManager.LocalClientId); #else // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries - var serverPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); + var serverPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == authorityManager.LocalClientId); #endif foreach (var playerNetworkObject in serverPlayerClones) { @@ -954,7 +997,7 @@ protected IEnumerator StartServerAndClients() m_PlayerNetworkObjects.Add(playerNetworkObject.NetworkManager.LocalClientId, new Dictionary()); } - if (startServer) + if (!m_UseCmbService) { m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); } @@ -962,20 +1005,10 @@ protected IEnumerator StartServerAndClients() } if (m_DistributedAuthority) { - //yield return WaitForConditionOrTimeOut(AllClientPlayersSpawned); - //AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn all player objects!"); foreach (var networkManager in m_ClientNetworkManagers) { - if (networkManager.DistributedAuthorityMode) - { - yield return WaitForConditionOrTimeOut(() => AllPlayerObjectClonesSpawned(networkManager)); - AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); - } - } - if (m_ServerNetworkManager != null && startServer) - { - yield return WaitForConditionOrTimeOut(() => AllPlayerObjectClonesSpawned(m_ServerNetworkManager)); - AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{m_ServerNetworkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); + yield return WaitForConditionOrTimeOut(() => AllPlayerObjectClonesSpawned(networkManager)); + AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); } } @@ -1006,17 +1039,18 @@ protected void StartServerAndClientsWithTimeTravel() // Start the instances and pass in our SceneManagerInitialization action that is invoked immediately after host-server // is started and after each client is started. // When using the CMBService, don't start the server. - var usingCMBService = UseCMBService() && m_DistributedAuthority; - if (!NetcodeIntegrationTestHelpers.Start(m_UseHost, !usingCMBService, m_ServerNetworkManager, m_ClientNetworkManagers)) + if (!NetcodeIntegrationTestHelpers.Start(m_UseHost, !m_UseCmbService, m_ServerNetworkManager, m_ClientNetworkManagers)) { Debug.LogError("Failed to start instances"); Assert.Fail("Failed to start instances"); } + var authorityManager = GetAuthorityNetworkManager(); + // Time travel does not play nice with scene loading, clear out server side pre-loaded scenes. - if (m_ServerNetworkManager.NetworkConfig.EnableSceneManagement) + if (authorityManager.NetworkConfig.EnableSceneManagement) { - m_ServerNetworkManager.SceneManager.ScenesLoaded.Clear(); + authorityManager.SceneManager.ScenesLoaded.Clear(); } if (LogAllMessages) @@ -1041,10 +1075,10 @@ protected void StartServerAndClientsWithTimeTravel() { #if UNITY_2023_1_OR_NEWER // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries - var serverPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); + var serverPlayerClones = Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsPlayerObject && c.OwnerClientId == authorityManager.LocalClientId); #else // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries - var serverPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == m_ServerNetworkManager.LocalClientId); + var serverPlayerClones = Object.FindObjectsOfType().Where((c) => c.IsPlayerObject && c.OwnerClientId == authorityManager.LocalClientId); #endif foreach (var playerNetworkObject in serverPlayerClones) { @@ -1053,14 +1087,17 @@ protected void StartServerAndClientsWithTimeTravel() m_PlayerNetworkObjects.Add(playerNetworkObject.NetworkManager.LocalClientId, new Dictionary()); } - m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); + if (!m_UseCmbService) + { + m_PlayerNetworkObjects[playerNetworkObject.NetworkManager.LocalClientId].Add(m_ServerNetworkManager.LocalClientId, playerNetworkObject); + } } } if (m_DistributedAuthority) { - foreach (var networkManager in m_ClientNetworkManagers) + foreach (var networkManager in m_NetworkManagers) { if (networkManager.DistributedAuthorityMode) { @@ -1068,11 +1105,6 @@ protected void StartServerAndClientsWithTimeTravel() AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!"); } } - if (m_ServerNetworkManager != null) - { - WaitForConditionOrTimeOutWithTimeTravel(() => AllPlayerObjectClonesSpawned(m_ServerNetworkManager)); - AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{m_ServerNetworkManager.LocalClientId}'s player object!"); - } } if (ShouldCheckForSpawnedPlayers()) @@ -1216,7 +1248,7 @@ protected IEnumerator CoroutineShutdownAndCleanUp() } // Allow time for NetworkManagers to fully shutdown - yield return s_DefaultWaitForTick; + yield return k_DefaultTickRate; // Cleanup any remaining NetworkObjects DestroySceneNetworkObjects(); @@ -1289,6 +1321,7 @@ private void DestroyNetworkManagers() var networkManagers = Object.FindObjectsByType(FindObjectsSortMode.None); foreach (var networkManager in networkManagers) { + Object.DestroyImmediate(networkManager.gameObject); } } @@ -1540,7 +1573,7 @@ private bool CheckClientsConnected(NetworkManager[] clientsToCheck) } } - var manager = UseCMBService() ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; + var manager = GetAuthorityNetworkManager(); var expectedCount = manager.IsHost ? clientsToCheck.Length + 1 : clientsToCheck.Length; var currentCount = manager.ConnectedClients.Count; @@ -1801,22 +1834,18 @@ private List SpawnObjects(NetworkObject prefabNetworkObject, Network /// public NetcodeIntegrationTest() { - m_NetworkTopologyType = OnGetNetworkTopologyType(); - m_DistributedAuthority = m_NetworkTopologyType == NetworkTopologyTypes.DistributedAuthority; - NetworkMessageManager.EnableMessageOrderConsoleLog = false; + var topologyType = OnGetNetworkTopologyType(); + InitializeTestConfiguration(topologyType, null); } public NetcodeIntegrationTest(NetworkTopologyTypes networkTopologyType) { - m_NetworkTopologyType = networkTopologyType; - m_DistributedAuthority = m_NetworkTopologyType == NetworkTopologyTypes.DistributedAuthority; + InitializeTestConfiguration(networkTopologyType, null); } public NetcodeIntegrationTest(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) { - m_NetworkTopologyType = networkTopologyType; - m_DistributedAuthority = m_NetworkTopologyType == NetworkTopologyTypes.DistributedAuthority; - m_UseHost = hostOrServer == HostOrServer.Host || hostOrServer == HostOrServer.DAHost; + InitializeTestConfiguration(networkTopologyType, hostOrServer); } /// @@ -1837,9 +1866,29 @@ public NetcodeIntegrationTest(NetworkTopologyTypes networkTopologyType, HostOrSe /// Specifies whether to run the test as a Host or Server configuration public NetcodeIntegrationTest(HostOrServer hostOrServer) { - m_UseHost = hostOrServer == HostOrServer.Host || hostOrServer == HostOrServer.DAHost; m_NetworkTopologyType = hostOrServer == HostOrServer.DAHost ? NetworkTopologyTypes.DistributedAuthority : NetworkTopologyTypes.ClientServer; - m_DistributedAuthority = OnGetNetworkTopologyType() == NetworkTopologyTypes.DistributedAuthority; + InitializeTestConfiguration(m_NetworkTopologyType, hostOrServer); + } + + private void InitializeTestConfiguration(NetworkTopologyTypes networkTopologyType, HostOrServer? hostOrServer) + { + if (!hostOrServer.HasValue) + { + // Always default to hosting, set the type of host based on the topology type + hostOrServer = networkTopologyType == NetworkTopologyTypes.DistributedAuthority ? HostOrServer.DAHost : HostOrServer.Host; + } + + NetworkMessageManager.EnableMessageOrderConsoleLog = false; + + m_NetworkTopologyType = networkTopologyType; + m_DistributedAuthority = m_NetworkTopologyType == NetworkTopologyTypes.DistributedAuthority; + m_UseHost = hostOrServer == HostOrServer.Host || hostOrServer == HostOrServer.DAHost; + + if (UseCMBService()) + { + m_UseCmbService = m_DistributedAuthority && hostOrServer == HostOrServer.DAHost; + + } } /// @@ -1852,6 +1901,7 @@ protected void AssertOnTimeout(string timeOutErrorMessage, TimeoutHelper assigne Assert.False(timeoutHelper.TimedOut, timeOutErrorMessage); } + private void UnloadRemainingScenes() { // Unload any remaining scenes loaded but the test runner scene diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 301af290ac..6233898a0f 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -171,19 +171,30 @@ public static void RegisterHandlers(NetworkManager networkManager, bool serverSi } } - private static readonly string k_TransportHost = Environment.GetEnvironmentVariable("NGO_HOST") ?? "127.0.0.1"; + private static readonly string k_TransportHost = GetAddressToBind(); private static readonly ushort k_TransportPort = GetPortToBind(); /// /// Configures the port to look for the rust service. /// - /// The port from the environment variable "ECHO_SERVER_PORT" if it is set and valid; otherwise uses port 7777 + /// The port from the environment variable "CMB_SERVICE_PORT" if it is set and valid; otherwise uses port 7789 private static ushort GetPortToBind() { var value = Environment.GetEnvironmentVariable("CMB_SERVICE_PORT"); return ushort.TryParse(value, out var configuredPort) ? configuredPort : (ushort)7789; } + /// + /// Configures the address to look for the rust service. + /// + /// The address from the environment variable "NGO_HOST" if it is set and valid; otherwise uses "127.0.0.1" + private static string GetAddressToBind() + { + var value = Environment.GetEnvironmentVariable("NGO_HOST") ?? "127.0.0.1"; + return Dns.GetHostAddresses(value).First().ToString(); + } + + private static void AddUnityTransport(NetworkManager networkManager, bool useCmbService = false) { // Create transport @@ -197,7 +208,7 @@ private static void AddUnityTransport(NetworkManager networkManager, bool useCmb unityTransport.ConnectTimeoutMS = 500; if (useCmbService) { - unityTransport.ConnectionData.Address = Dns.GetHostAddresses(k_TransportHost).First().ToString(); + unityTransport.ConnectionData.Address = k_TransportHost; unityTransport.ConnectionData.Port = k_TransportPort; Debug.Log($"Using CmbService: {k_TransportHost}:{k_TransportPort}"); } @@ -1005,9 +1016,24 @@ private static IEnumerator ExecuteWaitForHook(MessageHandleCheckWithResult check result.Result = res; } - public static uint GetGlobalObjectIdHash(NetworkObject networkObject) + + private static bool s_PreviousWasCmbServiceTest; + + /// + /// Waits for a second if the previous and current tests are using the hosted CMB Service. + /// This is necessary as the CMB Service does not restart fast enough when running multiple tests. + /// + /// + /// An that will wait for a second + public static IEnumerator WaitBetweenCmbServiceTests(bool isCmbServiceTest) { - return networkObject.GlobalObjectIdHash; + if (isCmbServiceTest && s_PreviousWasCmbServiceTest) + { + Debug.Log("Waiting for CMB service to be shut down during test setup."); + yield return new WaitForSeconds(1f); + } + + s_PreviousWasCmbServiceTest = isCmbServiceTest; } #if UNITY_EDITOR diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientConnectionTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientConnectionTests.cs index d4c1550b8d..2c1f412b23 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientConnectionTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientConnectionTests.cs @@ -17,6 +17,12 @@ internal class ClientConnectionTests : IntegrationTestWithApproximation private HashSet m_ServerCallbackCalled = new HashSet(); private HashSet m_ClientCallbackCalled = new HashSet(); + // TODO: [CmbServiceTests] Enable once the cmb service sceneManagementEnabled OnClientConnected flow is fixed + protected override bool UseCMBService() + { + return false; + } + public ClientConnectionTests(SceneManagementState sceneManagementState, NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { m_SceneManagementEnabled = sceneManagementState == SceneManagementState.SceneManagementEnabled; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DeferredDespawningTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DeferredDespawningTests.cs index 5787f169f1..fdfe2402be 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DeferredDespawningTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DeferredDespawningTests.cs @@ -18,6 +18,12 @@ internal class DeferredDespawningTests : IntegrationTestWithApproximation private List m_DaisyChainedDespawnObjects = new List(); private List m_HasReachedEnd = new List(); + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public enum SetDestroyGameObject { DestroyGameObject, diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs index 69680d96f2..7af663db1a 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs @@ -26,6 +26,7 @@ internal class DistributeObjectsTests : IntegrationTestWithApproximation private const int k_LateJoinClientCount = 4; protected override int NumberOfClients => 0; + public DistributeObjectsTests() : base(HostOrServer.DAHost) { } @@ -38,9 +39,13 @@ protected override IEnumerator OnSetup() protected override void OnServerAndClientsCreated() { - var serverTransport = m_ServerNetworkManager.NetworkConfig.NetworkTransport as UnityTransport; - // I hate having to add time to our tests, but in case a VM is running slow the disconnect timeout needs to be reasonably high - serverTransport.DisconnectTimeoutMS = 1000; + if (!m_UseCmbService) + { + var serverTransport = m_ServerNetworkManager.NetworkConfig.NetworkTransport as UnityTransport; + // I hate having to add time to our tests, but in case a VM is running slow the disconnect timeout needs to be reasonably high + serverTransport.DisconnectTimeoutMS = 1000; + } + m_DistributeObject = CreateNetworkObjectPrefab("DisObject"); m_DistributeObject.AddComponent(); m_DistributeObject.AddComponent(); @@ -52,13 +57,6 @@ protected override void OnServerAndClientsCreated() base.OnServerAndClientsCreated(); } - protected override IEnumerator OnServerAndClientsConnected() - { - m_ServerNetworkManager.SpawnManager.EnableDistributeLogging = m_EnableVerboseDebug; - m_ServerNetworkManager.ConnectionManager.EnableDistributeLogging = m_EnableVerboseDebug; - return base.OnServerAndClientsConnected(); - } - private NetworkObject m_ObjectToValidate; private bool ValidateObjectSpawnedOnAllClients() @@ -67,17 +65,11 @@ private bool ValidateObjectSpawnedOnAllClients() var networkObjectId = m_ObjectToValidate.NetworkObjectId; var name = m_ObjectToValidate.name; - if (!UseCMBService() && !m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId)) + foreach (var manager in m_NetworkManagers) { - m_ErrorLog.Append($"Client-{m_ServerNetworkManager.LocalClientId} has not spawned {name}!"); - return false; - } - - foreach (var client in m_ClientNetworkManagers) - { - if (!client.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId)) + if (!manager.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId)) { - m_ErrorLog.Append($"Client-{client.LocalClientId} has not spawned {name}!"); + m_ErrorLog.Append($"Client-{manager.LocalClientId} has not spawned {name}!"); return false; } } @@ -89,7 +81,7 @@ private bool ValidateObjectSpawnedOnAllClients() private bool ValidateDistributedObjectsSpawned(bool lateJoining) { m_ErrorLog.Clear(); - var hostId = m_ServerNetworkManager.LocalClientId; + var hostId = GetAuthorityNetworkManager().LocalClientId; if (!DistributeObjectsTestHelper.DistributedObjects.ContainsKey(hostId)) { m_ErrorLog.AppendLine($"[Client-{hostId}] Does not have an entry in the root of the {nameof(DistributeObjectsTestHelper.DistributedObjects)} table!"); @@ -106,11 +98,11 @@ private bool ValidateDistributedObjectsSpawned(bool lateJoining) var expected = 0; if (lateJoining) { - expected = k_ObjectCount / (m_ClientNetworkManagers.Count() + 1); + expected = k_ObjectCount / m_NetworkManagers.Length; } else { - expected = k_ObjectCount / (m_ClientNetworkManagers.Where((c) => c.IsConnectedClient).Count() + 1); + expected = k_ObjectCount / m_NetworkManagers.Count(c => c.IsConnectedClient); } // It should theoretically be the expected or... @@ -140,8 +132,8 @@ private bool ValidateDistributedObjectsSpawned(bool lateJoining) private bool ValidateOwnershipTablesMatch() { m_ErrorLog.Clear(); - var hostId = m_ServerNetworkManager.LocalClientId; - var expectedEntries = m_ClientNetworkManagers.Where((c) => c.IsListening && c.IsConnectedClient).Count() + 1; + var hostId = GetAuthorityNetworkManager().LocalClientId; + var expectedEntries = m_NetworkManagers.Count(c => c.IsListening && c.IsConnectedClient); // Make sure all clients have an table created if (DistributeObjectsTestHelper.DistributedObjects.Count < expectedEntries) { @@ -160,7 +152,7 @@ private bool ValidateOwnershipTablesMatch() m_ErrorLog.AppendLine($"[Client-{hostId}] Does not have a local an entry in the {nameof(DistributeObjectsTestHelper.DistributedObjects)} table!"); return false; } - var clients = m_ServerNetworkManager.ConnectedClientsIds.ToList(); + var clients = GetAuthorityNetworkManager().ConnectedClientsIds.ToList(); clients.Remove(0); // Cycle through each client's entry on the DAHost to run a comparison @@ -206,9 +198,9 @@ private bool ValidateOwnershipTablesMatch() private bool ValidateTransformsMatch() { m_ErrorLog.Clear(); - var hostId = m_ServerNetworkManager.LocalClientId; + var hostId = GetAuthorityNetworkManager().LocalClientId; var daHostEntries = DistributeObjectsTestHelper.DistributedObjects[hostId]; - var clients = m_ServerNetworkManager.ConnectedClientsIds.ToList(); + var clients = GetAuthorityNetworkManager().ConnectedClientsIds.ToList(); foreach (var clientOwner in daHostEntries.Keys) { // Cycle through the owner's objects @@ -238,16 +230,9 @@ private bool ValidateTransformsMatch() private bool SpawnCountsMatch() { var passed = true; - var spawnCount = 0; m_ErrorLog.Clear(); - if (!UseCMBService()) - { - spawnCount = m_ServerNetworkManager.SpawnManager.SpawnedObjects.Count; - } - else - { - spawnCount = m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects.Count; - } + + var spawnCount = GetAuthorityNetworkManager().SpawnManager.SpawnedObjects.Count; foreach (var client in m_ClientNetworkManagers) { var clientCount = client.SpawnManager.SpawnedObjects.Count; @@ -272,7 +257,7 @@ public IEnumerator DistributeNetworkObjects() { for (int i = 0; i < k_ObjectCount; i++) { - SpawnObject(m_DistributeObject, m_ServerNetworkManager); + SpawnObject(m_DistributeObject, GetAuthorityNetworkManager()); } // Validate NetworkObjects get redistributed properly when a client joins @@ -321,8 +306,10 @@ public IEnumerator DistributeNetworkObjects() yield return WaitForConditionOrTimeOut(ValidateTransformsMatch); AssertOnTimeout($"[Client-{j + 1}][Transform Mismatch] {m_ErrorLog}"); - // DANGO-TODO: Make this tied to verbose mode once we know the CMB Service integration works properly - DisplayOwnership(); + if (m_EnableVerboseDebug) + { + DisplayOwnership(); + } yield return WaitForConditionOrTimeOut(SpawnCountsMatch); AssertOnTimeout($"[Spawn Count Mismatch] {m_ErrorLog}"); @@ -332,8 +319,9 @@ public IEnumerator DistributeNetworkObjects() private void DisplayOwnership() { m_ErrorLog.Clear(); - var daHostEntries = DistributeObjectsTestHelper.DistributedObjects[0]; + var authorityId = GetAuthorityNetworkManager().LocalClientId; + var daHostEntries = DistributeObjectsTestHelper.DistributedObjects[authorityId]; foreach (var entry in daHostEntries) { m_ErrorLog.AppendLine($"[Client-{entry.Key}][Owned Objects: {entry.Value.Count}]"); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs index 94cdd8b02b..2f569622bc 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs @@ -18,6 +18,12 @@ public class ExtendedNetworkShowAndHideTests : NetcodeIntegrationTest private NetworkManager m_LateJoinClient; private NetworkManager m_SpawnOwner; + // TODO: [CmbServiceTests] Adapt to run with the service (can't control who becomes the session owner, needs a logic rework) + protected override bool UseCMBService() + { + return false; + } + public ExtendedNetworkShowAndHideTests(HostOrServer hostOrServer, bool enableSceneManagement) : base(hostOrServer) { m_EnableSceneManagement = enableSceneManagement; @@ -25,12 +31,7 @@ public ExtendedNetworkShowAndHideTests(HostOrServer hostOrServer, bool enableSce protected override void OnServerAndClientsCreated() { - if (!UseCMBService()) - { - m_ServerNetworkManager.NetworkConfig.EnableSceneManagement = m_EnableSceneManagement; - } - - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { client.NetworkConfig.EnableSceneManagement = m_EnableSceneManagement; } @@ -43,19 +44,7 @@ protected override void OnServerAndClientsCreated() private bool AllClientsSpawnedObject() { - if (!UseCMBService()) - { - if (!s_GlobalNetworkObjects.ContainsKey(m_ServerNetworkManager.LocalClientId)) - { - return false; - } - if (!s_GlobalNetworkObjects[m_ServerNetworkManager.LocalClientId].ContainsKey(m_SpawnedObject.NetworkObjectId)) - { - return false; - } - } - - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { if (!s_GlobalNetworkObjects.ContainsKey(client.LocalClientId)) { @@ -71,15 +60,7 @@ private bool AllClientsSpawnedObject() private bool IsClientPromotedToSessionOwner() { - if (!UseCMBService()) - { - if (m_ServerNetworkManager.CurrentSessionOwner != m_ClientToHideFrom.LocalClientId) - { - return false; - } - } - - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { if (!client.IsConnectedClient) { @@ -112,9 +93,9 @@ protected override void OnNewClientCreated(NetworkManager networkManager) public IEnumerator HiddenObjectPromotedSessionOwnerNewClientSynchronizes() { // Get the test relative session owner - var sessionOwner = UseCMBService() ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; - m_SpawnOwner = UseCMBService() ? m_ClientNetworkManagers[1] : m_ClientNetworkManagers[0]; - m_ClientToHideFrom = UseCMBService() ? m_ClientNetworkManagers[NumberOfClients - 1] : m_ClientNetworkManagers[1]; + var sessionOwner = GetAuthorityNetworkManager(); + m_SpawnOwner = m_UseCmbService ? m_ClientNetworkManagers[1] : m_ClientNetworkManagers[0]; + m_ClientToHideFrom = m_UseCmbService ? m_ClientNetworkManagers[NumberOfClients - 1] : m_ClientNetworkManagers[1]; m_ObjectToSpawn.SetActive(true); // Spawn the object with a non-session owner client @@ -129,7 +110,7 @@ public IEnumerator HiddenObjectPromotedSessionOwnerNewClientSynchronizes() AssertOnTimeout($"{m_SpawnedObject.name} was not hidden from Client-{m_ClientToHideFrom.LocalClientId}!"); // Promoted a new session owner (DAHost promotes while CMB Session we disconnect the current session owner) - if (!UseCMBService()) + if (!m_UseCmbService) { m_ServerNetworkManager.PromoteSessionOwner(m_ClientToHideFrom.LocalClientId); } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/NetworkClientAndPlayerObjectTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/NetworkClientAndPlayerObjectTests.cs index d768f60939..5697833bbc 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/NetworkClientAndPlayerObjectTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/NetworkClientAndPlayerObjectTests.cs @@ -99,8 +99,8 @@ private bool ValidateNetworkManagerNetworkClients(NetworkManager networkManager) var success = true; m_ErrorLogLevel2.Clear(); - // Number of connected clients plus the DAHost - var expectedCount = m_ClientNetworkManagers.Length + (m_UseHost ? 1 : 0); + // Number of tracked network managers + var expectedCount = m_NetworkManagers.Length - (m_UseHost ? 0 : 1); if (networkManager.ConnectedClients.Count != expectedCount) { @@ -138,21 +138,11 @@ private bool AllNetworkClientsValidated() m_ErrorLogLevel1.Clear(); var success = true; - if (!UseCMBService()) + foreach (var networkManager in m_NetworkManagers) { - if (!ValidateNetworkManagerNetworkClients(m_ServerNetworkManager)) + if (!ValidateNetworkManagerNetworkClients(networkManager)) { - m_ErrorLogLevel1.AppendLine($"[Client-{m_ServerNetworkManager.LocalClientId}]{m_ErrorLogLevel2}"); - // Log error - success = false; - } - } - - foreach (var clientNetworkManager in m_ClientNetworkManagers) - { - if (!ValidateNetworkManagerNetworkClients(clientNetworkManager)) - { - m_ErrorLogLevel1.AppendLine($"[Client-{clientNetworkManager.LocalClientId}]{m_ErrorLogLevel2}"); + m_ErrorLogLevel1.AppendLine($"[Client-{networkManager.LocalClientId}]{m_ErrorLogLevel2}"); // Log error success = false; } @@ -238,23 +228,14 @@ private bool ValidateAllPlayerObjects() { m_ErrorLogLevel1.Clear(); var success = true; - if (m_UseHost && !UseCMBService()) - { - if (!ValidatePlayerObjectOnClients(m_ServerNetworkManager)) - { - m_ErrorLogLevel1.AppendLine($"[Client-{m_ServerNetworkManager.LocalClientId}]{m_ErrorLogLevel2}"); - success = false; - } - if (m_ServerNetworkManager.LocalClient.PlayerObject == null) + foreach (var client in m_NetworkManagers) + { + if (!m_UseHost && client == m_ServerNetworkManager) { - m_ErrorLogLevel1.AppendLine($"[Client-{m_ServerNetworkManager.LocalClientId}] Local {nameof(NetworkClient.PlayerObject)} is null!"); - success = false; + continue; } - } - foreach (var client in m_ClientNetworkManagers) - { if (!ValidatePlayerObjectOnClients(client)) { m_ErrorLogLevel1.AppendLine($"[Client-{client.LocalClientId}]{m_ErrorLogLevel2}"); @@ -301,56 +282,35 @@ public IEnumerator ValidatePlayerObjects([Values] PlayerSpawnTypes playerSpawnTy // Now, have each client spawn a new player object m_ChangedPlayerPrefabs.Clear(); - var playerInstance = (GameObject)null; - var playerPrefabToSpawn = (NetworkObject)null; - if (m_UseHost) + foreach (var client in m_NetworkManagers) { - playerPrefabToSpawn = GetRandomPlayerPrefab(); - switch (playerSpawnType) + if (!m_UseHost && client == m_ServerNetworkManager) { - case PlayerSpawnTypes.Normal: - { - playerInstance = SpawnPlayerObject(playerPrefabToSpawn.gameObject, m_ServerNetworkManager); - break; - } - case PlayerSpawnTypes.NetworkObject: - { - playerInstance = NetworkObject.InstantiateAndSpawn(playerPrefabToSpawn.gameObject, m_ServerNetworkManager, isPlayerObject: true).gameObject; - break; - } - case PlayerSpawnTypes.SpawnManager: - { - playerInstance = m_ServerNetworkManager.SpawnManager.InstantiateAndSpawn(playerPrefabToSpawn, isPlayerObject: true).gameObject; - break; - } + continue; } - m_ChangedPlayerPrefabs.Add(m_ServerNetworkManager.LocalClientId, playerPrefabToSpawn.GlobalObjectIdHash); - } - - foreach (var client in m_ClientNetworkManagers) - { - playerPrefabToSpawn = GetRandomPlayerPrefab(); + var playerPrefabToSpawn = GetRandomPlayerPrefab(); var networkManager = m_DistributedAuthority ? client : m_ServerNetworkManager; switch (playerSpawnType) { case PlayerSpawnTypes.Normal: { - playerInstance = SpawnPlayerObject(playerPrefabToSpawn.gameObject, client); + SpawnPlayerObject(playerPrefabToSpawn.gameObject, client); break; } case PlayerSpawnTypes.NetworkObject: { - playerInstance = NetworkObject.InstantiateAndSpawn(playerPrefabToSpawn.gameObject, networkManager, client.LocalClientId, isPlayerObject: true).gameObject; + NetworkObject.InstantiateAndSpawn(playerPrefabToSpawn.gameObject, networkManager, client.LocalClientId, isPlayerObject: true); break; } case PlayerSpawnTypes.SpawnManager: { - playerInstance = networkManager.SpawnManager.InstantiateAndSpawn(playerPrefabToSpawn, client.LocalClientId, isPlayerObject: true).gameObject; + networkManager.SpawnManager.InstantiateAndSpawn(playerPrefabToSpawn, client.LocalClientId, isPlayerObject: true); break; } } + m_ChangedPlayerPrefabs.Add(client.LocalClientId, playerPrefabToSpawn.GlobalObjectIdHash); } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs index 4f70a864ad..b87b5a529a 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs @@ -17,6 +17,12 @@ internal class OwnershipPermissionsTests : IntegrationTestWithApproximation protected override int NumberOfClients => 4; + // TODO: [CmbServiceTests] Adapt to run with the service - daHostInstance will be firstInstance with cmbService + protected override bool UseCMBService() + { + return false; + } + public OwnershipPermissionsTests() : base(HostOrServer.DAHost) { } @@ -44,13 +50,8 @@ private bool ValidateObjectSpawnedOnAllClients() var networkObjectId = m_ObjectToValidate.NetworkObjectId; var name = m_ObjectToValidate.name; - if (!UseCMBService() && !m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId)) - { - m_ErrorLog.Append($"Client-{m_ServerNetworkManager.LocalClientId} has not spawned {name}!"); - return false; - } - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { if (!client.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId)) { @@ -64,23 +65,13 @@ private bool ValidateObjectSpawnedOnAllClients() private bool ValidatePermissionsOnAllClients() { var currentPermissions = (ushort)m_ObjectToValidate.Ownership; - var otherPermissions = (ushort)0; var networkObjectId = m_ObjectToValidate.NetworkObjectId; var objectName = m_ObjectToValidate.name; m_ErrorLog.Clear(); - if (!UseCMBService()) - { - otherPermissions = (ushort)m_ServerNetworkManager.SpawnManager.SpawnedObjects[networkObjectId].Ownership; - if (currentPermissions != otherPermissions) - { - m_ErrorLog.Append($"Client-{m_ServerNetworkManager.LocalClientId} permissions for {objectName} is {otherPermissions} when it should be {currentPermissions}!"); - return false; - } - } - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { - otherPermissions = (ushort)client.SpawnManager.SpawnedObjects[networkObjectId].Ownership; + var otherPermissions = (ushort)client.SpawnManager.SpawnedObjects[networkObjectId].Ownership; if (currentPermissions != otherPermissions) { m_ErrorLog.Append($"Client-{client.LocalClientId} permissions for {objectName} is {otherPermissions} when it should be {currentPermissions}!"); @@ -92,22 +83,12 @@ private bool ValidatePermissionsOnAllClients() private bool ValidateAllInstancesAreOwnedByClient(ulong clientId) { - var networkObjectId = m_ObjectToValidate.NetworkObjectId; - var otherNetworkObject = (NetworkObject)null; m_ErrorLog.Clear(); - if (!UseCMBService()) - { - otherNetworkObject = m_ServerNetworkManager.SpawnManager.SpawnedObjects[networkObjectId]; - if (otherNetworkObject.OwnerClientId != clientId) - { - m_ErrorLog.Append($"[Client-{m_ServerNetworkManager.LocalClientId}][{otherNetworkObject.name}] Expected owner to be {clientId} but it was {otherNetworkObject.OwnerClientId}!"); - return false; - } - } - foreach (var client in m_ClientNetworkManagers) + var networkObjectId = m_ObjectToValidate.NetworkObjectId; + foreach (var client in m_NetworkManagers) { - otherNetworkObject = client.SpawnManager.SpawnedObjects[networkObjectId]; + var otherNetworkObject = client.SpawnManager.SpawnedObjects[networkObjectId]; if (otherNetworkObject.OwnerClientId != clientId) { m_ErrorLog.Append($"[Client-{client.LocalClientId}][{otherNetworkObject.name}] Expected owner to be {clientId} but it was {otherNetworkObject.OwnerClientId}!"); @@ -254,7 +235,7 @@ public IEnumerator ValidateOwnershipPermissionsTest() requestStatus = thirdInstance.RequestOwnership(); // We expect the 3rd client's request should be able to be sent at this time as well (i.e. creates the race condition between two clients) - Assert.True(requestStatus == NetworkObject.OwnershipRequestStatus.RequestSent, $"Client-{m_ServerNetworkManager.LocalClientId} was unable to send a request for ownership because: {requestStatus}!"); + Assert.True(requestStatus == NetworkObject.OwnershipRequestStatus.RequestSent, $"Client-{thirdInstance.NetworkManager.LocalClientId} was unable to send a request for ownership because: {requestStatus}!"); // We expect the first requesting client to be given ownership yield return WaitForConditionOrTimeOut(() => firstInstance.IsOwner); @@ -311,7 +292,8 @@ public IEnumerator ValidateOwnershipPermissionsTest() /////////////////////////////////////////////// // Now get the DAHost's client's instance - var daHostInstance = m_ServerNetworkManager.SpawnManager.SpawnedObjects[networkObjectId]; + var authority = GetAuthorityNetworkManager(); + var daHostInstance = authority.SpawnManager.SpawnedObjects[networkObjectId]; var daHostInstanceHelper = daHostInstance.GetComponent(); secondInstanceHelper.AllowOwnershipRequest = true; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs index bd74d710a2..f3bf6371ec 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs @@ -8,6 +8,8 @@ namespace Unity.Netcode.RuntimeTests { + [TestFixture(DistributionTypes.UponConnect)] + [TestFixture(DistributionTypes.UponDisconnect)] internal class ParentChildDistibutionTests : IntegrationTestWithApproximation { protected override int NumberOfClients => 4; @@ -17,16 +19,22 @@ internal class ParentChildDistibutionTests : IntegrationTestWithApproximation private List m_TargetSpawnedObjects = new List(); private List m_AltTargetSpawnedObjects = new List(); private Dictionary> m_AncillarySpawnedObjects = new Dictionary>(); - private List m_NetworkManagers = new List(); private StringBuilder m_ErrorMsg = new StringBuilder(); + private DistributionTypes m_DistributionType; - public ParentChildDistibutionTests() : base(HostOrServer.DAHost) + // TODO: [CmbServiceTesting] Update UponDisconnect tests to work with the rust service + protected override bool UseCMBService() { + return false; + } + + public ParentChildDistibutionTests(DistributionTypes distributionType) : base(HostOrServer.DAHost) + { + m_DistributionType = distributionType; } protected override IEnumerator OnTearDown() { - m_NetworkManagers.Clear(); m_TargetSpawnedObjects.Clear(); m_AncillarySpawnedObjects.Clear(); m_AltTargetSpawnedObjects.Clear(); @@ -46,6 +54,10 @@ private bool AllTargetedInstancesSpawned() m_ErrorMsg.Clear(); foreach (var client in m_NetworkManagers) { + if (!client.IsConnectedClient) + { + continue; + } foreach (var spawnedObject in m_TargetSpawnedObjects) { if (!client.SpawnManager.SpawnedObjects.ContainsKey(spawnedObject.NetworkObjectId)) @@ -63,6 +75,10 @@ private bool AllAncillaryInstancesSpawned() m_ErrorMsg.Clear(); foreach (var client in m_NetworkManagers) { + if (!client.IsConnectedClient) + { + continue; + } foreach (var clientObjects in m_AncillarySpawnedObjects) { foreach (var spawnedObject in clientObjects.Value) @@ -147,30 +163,19 @@ public enum OwnershipLocking [UnityTest] - public IEnumerator DistributeOwnerHierarchy([Values] DistributionTypes distributionType, [Values] OwnershipLocking ownershipLock) + public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipLock) { - m_NetworkManagers.Clear(); m_TargetSpawnedObjects.Clear(); m_AncillarySpawnedObjects.Clear(); m_AltTargetSpawnedObjects.Clear(); - if (distributionType == DistributionTypes.UponConnect) + if (m_DistributionType == DistributionTypes.UponConnect) { m_ClientNetworkManagers[3].Shutdown(); } - if (!UseCMBService()) - { - m_NetworkManagers.Add(m_ServerNetworkManager); - } - m_NetworkManagers.AddRange(m_ClientNetworkManagers); - if (distributionType == DistributionTypes.UponConnect) - { - m_NetworkManagers.Remove(m_ClientNetworkManagers[3]); - } - - // When testing connect redistribution, - var instances = distributionType == DistributionTypes.UponDisconnect ? 1 : 2; + // When testing connect redistribution, + var instances = m_DistributionType == DistributionTypes.UponDisconnect ? 1 : 2; var rootObject = (GameObject)null; var childOne = (GameObject)null; var childTwo = (GameObject)null; @@ -181,7 +186,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] DistributionTypes distribut rootObject = SpawnObject(m_GenericPrefab, m_ClientNetworkManagers[0]); networkObject = rootObject.GetComponent(); networkObject.SetOwnershipStatus(NetworkObject.OwnershipStatus.Distributable); - if (ownershipLock == OwnershipLocking.LockRootParent && distributionType == DistributionTypes.UponConnect) + if (ownershipLock == OwnershipLocking.LockRootParent && m_DistributionType == DistributionTypes.UponConnect) { networkObject.SetOwnershipLock(true); } @@ -197,7 +202,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] DistributionTypes distribut childTwo = SpawnObject(m_GenericPrefab, m_ClientNetworkManagers[0]); networkObject = childTwo.GetComponent(); networkObject.SetOwnershipStatus(NetworkObject.OwnershipStatus.Distributable); - if (ownershipLock == OwnershipLocking.LockTargetChild && distributionType == DistributionTypes.UponConnect) + if (ownershipLock == OwnershipLocking.LockTargetChild && m_DistributionType == DistributionTypes.UponConnect) { networkObject.SetOwnershipLock(true); } @@ -244,7 +249,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] DistributionTypes distribut // Get the original clientId m_OriginalOwnerId = m_ClientNetworkManagers[0].LocalClientId; - if (distributionType == DistributionTypes.UponDisconnect) + if (m_DistributionType == DistributionTypes.UponDisconnect) { // Swap out the original owner's NetworkObject with one of the other client's since those instances will // be destroyed when the client disconnects. @@ -268,7 +273,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] DistributionTypes distribut // When enabled, you should see one of the two root instances that have children get distributed to // the reconnected client. - if (m_EnableVerboseDebug && distributionType == DistributionTypes.UponConnect) + if (m_EnableVerboseDebug && m_DistributionType == DistributionTypes.UponConnect) { m_ErrorMsg.Clear(); m_ErrorMsg.AppendLine($"Original targeted objects owner: {m_OriginalOwnerId}"); @@ -280,7 +285,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] DistributionTypes distribut } // We only want to make sure no other children owned by still connected clients change ownership - if (distributionType == DistributionTypes.UponDisconnect) + if (m_DistributionType == DistributionTypes.UponDisconnect) { // Verify the ancillary objects kept the same ownership yield return WaitForConditionOrTimeOut(AncillaryObjectsKeptOwnership); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SessionVersionConnectionRequest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SessionVersionConnectionRequest.cs index cb37362f44..d537903d8e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SessionVersionConnectionRequest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SessionVersionConnectionRequest.cs @@ -9,6 +9,12 @@ internal class SessionVersionConnectionRequest : NetcodeIntegrationTest { protected override int NumberOfClients => 0; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public SessionVersionConnectionRequest() : base(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost) { } private bool m_UseValidSessionVersion; @@ -21,7 +27,8 @@ public SessionVersionConnectionRequest() : base(NetworkTopologyTypes.Distributed /// private SessionConfig GetInavlidSessionConfig() { - return new SessionConfig(m_ServerNetworkManager.SessionConfig.SessionVersion - 1); + var authority = GetAuthorityNetworkManager(); + return new SessionConfig(authority.SessionConfig.SessionVersion - 1); } /// @@ -63,6 +70,12 @@ protected override bool ShouldWaitForNewClientToConnect(NetworkManager networkMa return m_UseValidSessionVersion; } + internal enum SessionVersionType + { + Valid, + Invalid, + } + /// /// Validates that when the client's session config version is valid a client will be /// allowed to connect and when it is not valid the client will be disconnected. @@ -73,10 +86,10 @@ protected override bool ShouldWaitForNewClientToConnect(NetworkManager networkMa /// /// true = use valid session version | false = use invalid session version [UnityTest] - public IEnumerator ValidateSessionVersion([Values] bool useValidSessionVersion) + public IEnumerator ValidateSessionVersion([Values] SessionVersionType type) { // Test client being disconnected due to invalid session version - m_UseValidSessionVersion = useValidSessionVersion; + m_UseValidSessionVersion = type == SessionVersionType.Valid; yield return CreateAndStartNewClient(); yield return s_DefaultWaitForTick; if (!m_UseValidSessionVersion) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SpawnDuringSynchronizationTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SpawnDuringSynchronizationTests.cs index 6c91112259..513bcb326b 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SpawnDuringSynchronizationTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SpawnDuringSynchronizationTests.cs @@ -1,5 +1,4 @@ using System.Collections; -using System.Collections.Generic; using System.Text; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; @@ -18,7 +17,6 @@ internal class SpawnDuringSynchronizationTests : NetcodeIntegrationTest { protected override int NumberOfClients => 2; - private List m_AllNetworkManagers = new List(); private StringBuilder m_ErrorLog = new StringBuilder(); private NetworkBehaviourSpawnTimes m_SpawnTime; @@ -89,11 +87,7 @@ protected override void OnServerAndClientsCreated() var spawnTestComponent = m_PlayerPrefab.GetComponent(); spawnTestComponent.PrefabToSpawn = CreateNetworkObjectPrefab("ObjToSpawn"); spawnTestComponent.PrefabToSpawn.GetComponent().SetOwnershipStatus(NetworkObject.OwnershipStatus.Transferable); - if (!UseCMBService()) - { - m_ServerNetworkManager.NetworkConfig.EnableSceneManagement = m_EnableSceneManagement; - } - foreach (var networkManager in m_ClientNetworkManagers) + foreach (var networkManager in m_NetworkManagers) { networkManager.NetworkConfig.EnableSceneManagement = m_EnableSceneManagement; } @@ -104,7 +98,7 @@ private bool AllClientsSpawnedObject() { m_ErrorLog.Clear(); var spawnTestComponent = (SpawnTestComponent)null; - foreach (var networkManager in m_AllNetworkManagers) + foreach (var networkManager in m_NetworkManagers) { spawnTestComponent = networkManager.LocalClient.PlayerObject.GetComponent(); if (spawnTestComponent.SpawnedObject == null || !spawnTestComponent.SpawnedObject.IsSpawned) @@ -112,7 +106,7 @@ private bool AllClientsSpawnedObject() m_ErrorLog.AppendLine($"{networkManager.name}'s player failed to spawn the network prefab!"); break; } - foreach (var networkManagerToCheck in m_AllNetworkManagers) + foreach (var networkManagerToCheck in m_NetworkManagers) { if (networkManagerToCheck == networkManager) { @@ -133,13 +127,6 @@ private bool AllClientsSpawnedObject() [UnityTest] public IEnumerator SpawnDuringSynchronization() { - m_AllNetworkManagers.Clear(); - m_AllNetworkManagers.AddRange(m_ClientNetworkManagers); - if (!UseCMBService()) - { - m_AllNetworkManagers.Add(m_ServerNetworkManager); - } - yield return WaitForConditionOrTimeOut(AllClientsSpawnedObject); AssertOnTimeout(m_ErrorLog.ToString()); } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/ListChangedTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/ListChangedTest.cs index 3f47ae9fcc..3b646ea00f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/ListChangedTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/ListChangedTest.cs @@ -52,7 +52,6 @@ internal class NetworkListChangedTests : NetcodeIntegrationTest { protected override int NumberOfClients => 2; - private ulong m_ClientId0; private GameObject m_PrefabToSpawn; private NetworkObject m_NetSpawnedObject1; @@ -68,10 +67,10 @@ protected override void OnServerAndClientsCreated() [UnityTest] public IEnumerator NetworkListChangedTest() { - m_ClientId0 = m_ClientNetworkManagers[0].LocalClientId; + var authority = GetAuthorityNetworkManager(); // create 3 objects - var spawnedObject1 = SpawnObject(m_PrefabToSpawn, m_ServerNetworkManager); + var spawnedObject1 = SpawnObject(m_PrefabToSpawn, authority); m_NetSpawnedObject1 = spawnedObject1.GetComponent(); m_NetSpawnedObject1.GetComponent().MyNetworkList.Add(42); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourPrePostSpawnTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourPrePostSpawnTests.cs index fc233a8653..a85d26dd88 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourPrePostSpawnTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkBehaviourPrePostSpawnTests.cs @@ -12,6 +12,12 @@ internal class NetworkBehaviourPrePostSpawnTests : NetcodeIntegrationTest { protected override int NumberOfClients => 0; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + private bool m_AllowServerToStart; private GameObject m_PrePostSpawnObject; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDestroyTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDestroyTests.cs index 1c65d3572d..de0aa18732 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDestroyTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDestroyTests.cs @@ -21,6 +21,12 @@ internal class NetworkObjectDestroyTests : NetcodeIntegrationTest { protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public NetworkObjectDestroyTests(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } protected override void OnCreatePlayerPrefab() diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDontDestroyWithOwnerTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDontDestroyWithOwnerTests.cs index 51e86ea496..2c59647aa9 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDontDestroyWithOwnerTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectDontDestroyWithOwnerTests.cs @@ -16,6 +16,12 @@ internal class NetworkObjectDontDestroyWithOwnerTests : NetcodeIntegrationTest private const int k_NumberObjectsToSpawn = 32; protected override int NumberOfClients => 1; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + protected GameObject m_PrefabToSpawn; public NetworkObjectDontDestroyWithOwnerTests(HostOrServer hostOrServer) : base(hostOrServer) { } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnNetworkDespawnTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnNetworkDespawnTests.cs index 9a737a4d3e..1d1b6c518c 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnNetworkDespawnTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnNetworkDespawnTests.cs @@ -28,6 +28,12 @@ public enum InstanceTypes private HostOrServer m_HostOrServer; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public NetworkObjectOnNetworkDespawnTests(HostOrServer hostOrServer) : base(hostOrServer) { m_HostOrServer = hostOrServer; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnSpawnTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnSpawnTests.cs index 8d8f02311f..5fd114714b 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnSpawnTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOnSpawnTests.cs @@ -17,6 +17,12 @@ internal class NetworkObjectOnSpawnTests : NetcodeIntegrationTest protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public enum ObserverTestTypes { WithObservers, diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipPropertiesTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipPropertiesTests.cs index 6ae761b360..94653f1e77 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipPropertiesTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipPropertiesTests.cs @@ -31,6 +31,12 @@ private class DummyNetworkBehaviour : NetworkBehaviour private bool m_InitialOwnerOwnedBySever; private bool m_TargetOwnerOwnedBySever; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public NetworkObjectOwnershipPropertiesTests(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } protected override IEnumerator OnTearDown() diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs index 16670bf855..e7fc968de1 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs @@ -106,12 +106,7 @@ public void TestPlayerIsOwned() private bool AllObjectsSpawnedOnClients() { - if (!NetworkObjectOwnershipComponent.SpawnedInstances.ContainsKey(m_ServerNetworkManager.LocalClientId)) - { - return false; - } - - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { if (!NetworkObjectOwnershipComponent.SpawnedInstances.ContainsKey(client.LocalClientId)) { @@ -124,17 +119,20 @@ private bool AllObjectsSpawnedOnClients() [UnityTest] public IEnumerator TestOwnershipCallbacks([Values] OwnershipChecks ownershipChecks) { - m_OwnershipObject = SpawnObject(m_OwnershipPrefab, m_ServerNetworkManager); + var authority = GetAuthorityNetworkManager(); + var nonAuthority = GetNonAuthorityNetworkManager(); + + m_OwnershipObject = SpawnObject(m_OwnershipPrefab, authority); m_OwnershipNetworkObject = m_OwnershipObject.GetComponent(); - yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeHandled(m_ClientNetworkManagers[0]); + yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeHandled(nonAuthority); yield return WaitForConditionOrTimeOut(AllObjectsSpawnedOnClients); AssertOnTimeout($"Timed out waiting for all clients to spawn the ownership object!"); var ownershipNetworkObjectId = m_OwnershipNetworkObject.NetworkObjectId; Assert.That(ownershipNetworkObjectId, Is.GreaterThan(0)); - Assert.That(m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId)); + Assert.That(authority.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId)); foreach (var clientNetworkManager in m_ClientNetworkManagers) { Assert.That(clientNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId)); @@ -147,39 +145,42 @@ public IEnumerator TestOwnershipCallbacks([Values] OwnershipChecks ownershipChec m_ServerNetworkManager.SpawnManager.RemoveOwnership(m_OwnershipNetworkObject); } - var serverObject = m_ServerNetworkManager.SpawnManager.SpawnedObjects[ownershipNetworkObjectId]; - var clientObject = m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects[ownershipNetworkObjectId]; - Assert.That(serverObject, Is.Not.Null); + var authorityObject = authority.SpawnManager.SpawnedObjects[ownershipNetworkObjectId]; + var clientObject = nonAuthority.SpawnManager.SpawnedObjects[ownershipNetworkObjectId]; + + Assert.That(authorityObject, Is.Not.Null); Assert.That(clientObject, Is.Not.Null); - var serverComponent = serverObject.GetComponent(); + var authorityComponent = authorityObject.GetComponent(); var clientComponent = clientObject.GetComponent(); - Assert.That(serverComponent, Is.Not.Null); + Assert.That(authorityComponent, Is.Not.Null); Assert.That(clientComponent, Is.Not.Null); - Assert.That(serverObject.OwnerClientId, Is.EqualTo(NetworkManager.ServerClientId)); - Assert.That(clientObject.OwnerClientId, Is.EqualTo(NetworkManager.ServerClientId)); + var expectedOwnerId = m_UseCmbService ? authority.LocalClientId : NetworkManager.ServerClientId; - Assert.That(m_ServerNetworkManager.ConnectedClients.ContainsKey(m_ClientNetworkManagers[0].LocalClientId)); + Assert.That(authorityObject.OwnerClientId, Is.EqualTo(expectedOwnerId)); + Assert.That(clientObject.OwnerClientId, Is.EqualTo(expectedOwnerId)); - serverObject.ChangeOwnership(clientComponent.NetworkManager.LocalClientId); + Assert.That(authority.ConnectedClients.ContainsKey(nonAuthority.LocalClientId)); + + authorityObject.ChangeOwnership(clientComponent.NetworkManager.LocalClientId); yield return s_DefaultWaitForTick; - Assert.That(serverComponent.OnLostOwnershipFired); - Assert.That(serverComponent.OwnerClientId, Is.EqualTo(m_ClientNetworkManagers[0].LocalClientId)); + Assert.That(authorityComponent.OnLostOwnershipFired); + Assert.That(authorityComponent.OwnerClientId, Is.EqualTo(nonAuthority.LocalClientId)); yield return WaitForConditionOrTimeOut(() => clientComponent.OnGainedOwnershipFired); Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for client to gain ownership!"); Assert.That(clientComponent.OnGainedOwnershipFired); - Assert.That(clientComponent.OwnerClientId, Is.EqualTo(m_ClientNetworkManagers[0].LocalClientId)); + Assert.That(clientComponent.OwnerClientId, Is.EqualTo(nonAuthority.LocalClientId)); - serverComponent.ResetFlags(); + authorityComponent.ResetFlags(); clientComponent.ResetFlags(); if (ownershipChecks == OwnershipChecks.Change) { // Validates that when ownership is changed back to the server it will get an OnGainedOwnership notification - serverObject.ChangeOwnership(NetworkManager.ServerClientId); + authorityObject.ChangeOwnership(expectedOwnerId); } else { @@ -187,18 +188,18 @@ public IEnumerator TestOwnershipCallbacks([Values] OwnershipChecks ownershipChec // In distributed authority mode, the current owner just rolls the ownership back over to the DAHost client (i.e. host mocking CMB Service) if (m_DistributedAuthority) { - clientObject.ChangeOwnership(NetworkManager.ServerClientId); + clientObject.ChangeOwnership(expectedOwnerId); } else { - serverObject.RemoveOwnership(); + authorityObject.RemoveOwnership(); } } - yield return WaitForConditionOrTimeOut(() => serverComponent.OnGainedOwnershipFired && serverComponent.OwnerClientId == m_ServerNetworkManager.LocalClientId); - AssertOnTimeout($"Timed out waiting for ownership to be transfered back to the host instance!"); + yield return WaitForConditionOrTimeOut(() => authorityComponent.OnGainedOwnershipFired && authorityComponent.OwnerClientId == authority.LocalClientId); + AssertOnTimeout($"Timed out waiting for ownership to be transferred back to the host instance!"); - yield return WaitForConditionOrTimeOut(() => clientComponent.OnLostOwnershipFired && clientComponent.OwnerClientId == m_ServerNetworkManager.LocalClientId); + yield return WaitForConditionOrTimeOut(() => clientComponent.OnLostOwnershipFired && clientComponent.OwnerClientId == authority.LocalClientId); AssertOnTimeout($"Timed out waiting for client-side lose ownership event to trigger or owner identifier to be equal to the host!"); } @@ -208,11 +209,17 @@ public IEnumerator TestOwnershipCallbacks([Values] OwnershipChecks ownershipChec [UnityTest] public IEnumerator TestOwnershipCallbacksSeveralClients([Values] OwnershipChecks ownershipChecks) { + var authority = GetAuthorityNetworkManager(); + // Build our message hook entries tables so we can determine if all clients received spawn or ownership messages var messageHookEntriesForSpawn = new List(); var messageHookEntriesForOwnership = new List(); foreach (var clientNetworkManager in m_ClientNetworkManagers) { + if (clientNetworkManager == authority) + { + continue; + } var messageHook = new MessageHookEntry(clientNetworkManager); messageHook.AssignMessageType(); messageHookEntriesForSpawn.Add(messageHook); @@ -227,7 +234,7 @@ public IEnumerator TestOwnershipCallbacksSeveralClients([Values] OwnershipChecks var ownershipMessageHooks = new MessageHooksConditional(messageHookEntriesForOwnership); // Spawn our test object from server with server ownership - m_OwnershipObject = SpawnObject(m_OwnershipPrefab, m_ServerNetworkManager); + m_OwnershipObject = SpawnObject(m_OwnershipPrefab, authority); m_OwnershipNetworkObject = m_OwnershipObject.GetComponent(); // Wait for all clients to receive the CreateObjectMessage @@ -237,7 +244,7 @@ public IEnumerator TestOwnershipCallbacksSeveralClients([Values] OwnershipChecks // Validate the NetworkObjectId and that the server and all clients have this NetworkObject var ownershipNetworkObjectId = m_OwnershipNetworkObject.NetworkObjectId; Assert.That(ownershipNetworkObjectId, Is.GreaterThan(0)); - Assert.That(m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId)); + Assert.That(authority.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId)); bool WaitForClientsToSpawnNetworkObject() { @@ -261,7 +268,7 @@ bool WaitForClientsToSpawnNetworkObject() m_ServerNetworkManager.SpawnManager.RemoveOwnership(m_OwnershipNetworkObject); } - var serverObject = m_ServerNetworkManager.SpawnManager.SpawnedObjects[ownershipNetworkObjectId]; + var serverObject = authority.SpawnManager.SpawnedObjects[ownershipNetworkObjectId]; Assert.That(serverObject, Is.Not.Null); var clientObject = (NetworkObject)null; var clientObjects = new List(); @@ -273,15 +280,16 @@ bool WaitForClientsToSpawnNetworkObject() } // Verify the server side component + var authorityId = m_UseCmbService ? authority.LocalClientId : NetworkManager.ServerClientId; var serverComponent = serverObject.GetComponent(); Assert.That(serverComponent, Is.Not.Null); - Assert.That(serverObject.OwnerClientId, Is.EqualTo(NetworkManager.ServerClientId)); + Assert.That(serverObject.OwnerClientId, Is.EqualTo(authorityId)); // Verify the clients components for (int i = 0; i < NumberOfClients; i++) { var clientComponent = clientObjects[i].GetComponent(); - Assert.That(clientComponent.OwnerClientId, Is.EqualTo(NetworkManager.ServerClientId)); + Assert.That(clientComponent.OwnerClientId, Is.EqualTo(authorityId)); clientComponent.ResetFlags(); } @@ -295,20 +303,26 @@ bool WaitForClientsToSpawnNetworkObject() clientObject = clientObjects[clientIndex]; var clientId = m_ClientNetworkManagers[clientIndex].LocalClientId; - Assert.That(m_ServerNetworkManager.ConnectedClients.ContainsKey(clientId)); + if (clientId == authority.LocalClientId) + { + continue; + } + + Assert.That(authority.ConnectedClients.ContainsKey(clientId)); serverObject.ChangeOwnership(clientId); - yield return s_DefaultWaitForTick; + yield return WaitForConditionOrTimeOut(() => serverObject.OwnerClientId == clientId); + Assert.That(serverComponent.OnLostOwnershipFired); Assert.That(serverComponent.OwnerClientId, Is.EqualTo(clientId)); // Wait for all clients to receive the CreateObjectMessage yield return WaitForConditionOrTimeOut(ownershipMessageHooks); Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for all clients to receive the {nameof(ChangeOwnershipMessage)} message."); - var previousNetworkManager = m_ServerNetworkManager; + var previousNetworkManager = authority; if (previousClientComponent != null) { // Once we have a previousClientComponent, we want to verify the server is keeping track for the removal of ownership in the OwnershipToObjectsTable - Assert.That(!m_ServerNetworkManager.SpawnManager.OwnershipToObjectsTable[m_ServerNetworkManager.LocalClientId].ContainsKey(serverObject.NetworkObjectId)); + Assert.That(!authority.SpawnManager.OwnershipToObjectsTable[authority.LocalClientId].ContainsKey(serverObject.NetworkObjectId)); previousNetworkManager = previousClientComponent.NetworkManager; Assert.That(previousClientComponent.OnLostOwnershipFired); Assert.That(previousClientComponent.OwnerClientId, Is.EqualTo(clientId)); @@ -339,7 +353,7 @@ bool WaitForClientsToSpawnNetworkObject() if (ownershipChecks == OwnershipChecks.Change) { // Validates that when ownership is changed back to the server it will get an OnGainedOwnership notification - serverObject.ChangeOwnership(NetworkManager.ServerClientId); + serverObject.ChangeOwnership(authorityId); } else { @@ -349,7 +363,7 @@ bool WaitForClientsToSpawnNetworkObject() { // In distributed authority, we have to clear out the NetworkManager instances as this changes relative to authority. networkManagersDAMode.Clear(); - foreach (var clientNetworkManager in m_ClientNetworkManagers) + foreach (var clientNetworkManager in m_NetworkManagers) { if (clientNetworkManager.LocalClientId == clientObject.OwnerClientId) { @@ -357,12 +371,7 @@ bool WaitForClientsToSpawnNetworkObject() } networkManagersDAMode.Add(clientNetworkManager); } - - if (!UseCMBService() && clientObject.OwnerClientId != m_ServerNetworkManager.LocalClientId) - { - networkManagersDAMode.Add(m_ServerNetworkManager); - } - clientObject.ChangeOwnership(NetworkManager.ServerClientId); + clientObject.ChangeOwnership(authorityId); } else { @@ -374,7 +383,7 @@ bool WaitForClientsToSpawnNetworkObject() { // We use an alternate method (other than message hooks) to verify each client received the ownership message since message hooks becomes problematic when you need // to make dynamic changes to your targets. - yield return WaitForConditionOrTimeOut(() => OwnershipChangedOnAllTargetedClients(networkManagersDAMode, clientObject.NetworkObjectId, NetworkManager.ServerClientId)); + yield return WaitForConditionOrTimeOut(() => OwnershipChangedOnAllTargetedClients(networkManagersDAMode, clientObject.NetworkObjectId, authorityId)); } else { @@ -385,7 +394,7 @@ bool WaitForClientsToSpawnNetworkObject() Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for all clients to receive the {nameof(ChangeOwnershipMessage)} message (back to server)."); Assert.That(serverComponent.OnGainedOwnershipFired); - Assert.That(serverComponent.OwnerClientId, Is.EqualTo(m_ServerNetworkManager.LocalClientId)); + Assert.That(serverComponent.OwnerClientId, Is.EqualTo(authorityId)); yield return WaitForConditionOrTimeOut(() => previousClientComponent.OnLostOwnershipFired); @@ -396,7 +405,7 @@ bool WaitForClientsToSpawnNetworkObject() { var clientComponent = clientObjects[i].GetComponent(); Assert.That(clientComponent, Is.Not.Null); - Assert.That(clientComponent.OwnerClientId, Is.EqualTo(m_ServerNetworkManager.LocalClientId)); + Assert.That(clientComponent.OwnerClientId, Is.EqualTo(authorityId)); clientComponent.ResetFlags(); } serverComponent.ResetFlags(); @@ -422,7 +431,6 @@ private bool OwnershipChangedOnAllTargetedClients(List networkMa private bool AllClientsHaveCorrectObjectCount() { - foreach (var clientNetworkManager in m_ClientNetworkManagers) { if (clientNetworkManager.LocalClient.OwnedObjects.Length < k_NumberOfSpawnedObjects) @@ -436,16 +444,17 @@ private bool AllClientsHaveCorrectObjectCount() private bool ServerHasCorrectClientOwnedObjectCount() { + var authority = GetAuthorityNetworkManager(); // Only check when we are the host - if (m_ServerNetworkManager.IsHost) + if (authority.IsHost) { - if (m_ServerNetworkManager.LocalClient.OwnedObjects.Length < k_NumberOfSpawnedObjects) + if (authority.LocalClient.OwnedObjects.Length < k_NumberOfSpawnedObjects) { return false; } } - foreach (var connectedClient in m_ServerNetworkManager.ConnectedClients) + foreach (var connectedClient in authority.ConnectedClients) { if (connectedClient.Value.OwnedObjects.Length < k_NumberOfSpawnedObjects) { @@ -458,19 +467,11 @@ private bool ServerHasCorrectClientOwnedObjectCount() [UnityTest] public IEnumerator TestOwnedObjectCounts() { - if (m_ServerNetworkManager.IsHost) - { - for (int i = 0; i < 5; i++) - { - SpawnObject(m_OwnershipPrefab, m_ServerNetworkManager); - } - } - - foreach (var clientNetworkManager in m_ClientNetworkManagers) + foreach (var manager in m_NetworkManagers) { for (int i = 0; i < 5; i++) { - SpawnObject(m_OwnershipPrefab, clientNetworkManager); + SpawnObject(m_OwnershipPrefab, manager); } } @@ -491,8 +492,6 @@ public IEnumerator TestOwnedObjectCounts() public IEnumerator TestAuthorityChangingOwnership() { var authorityManager = (NetworkManager)null; - var allNetworkManagers = m_ClientNetworkManagers.ToList(); - allNetworkManagers.Add(m_ServerNetworkManager); if (m_DistributedAuthority) { @@ -542,7 +541,7 @@ bool WaitForAllInstancesToChangeOwnership() // Change ownership a few times and as long as the previous and current owners are not the same when // OnOwnershipChanged is invoked then the test passed. - foreach (var networkManager in allNetworkManagers) + foreach (var networkManager in m_NetworkManagers) { if (networkManager == authorityManager) { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs index b80e055f0f..5db4c0a3b8 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSpawnManyObjectsTests.cs @@ -42,8 +42,7 @@ protected override void OnServerAndClientsCreated() m_PrefabToSpawn = new NetworkPrefab() { Prefab = gameObject }; - m_ServerNetworkManager.NetworkConfig.Prefabs.Add(m_PrefabToSpawn); - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { client.NetworkConfig.Prefabs.Add(m_PrefabToSpawn); } @@ -53,10 +52,11 @@ protected override void OnServerAndClientsCreated() public IEnumerator WhenManyObjectsAreSpawnedAtOnce_AllAreReceived() { var timeStarted = Time.realtimeSinceStartup; + var authority = GetAuthorityNetworkManager(); for (int x = 0; x < k_SpawnedObjects; x++) { NetworkObject serverObject = Object.Instantiate(m_PrefabToSpawn.Prefab).GetComponent(); - serverObject.NetworkManagerOwner = m_ServerNetworkManager; + serverObject.NetworkManagerOwner = authority; serverObject.Spawn(); } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSynchronizationTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSynchronizationTests.cs index fc59ad09dc..934eb68188 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSynchronizationTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectSynchronizationTests.cs @@ -27,6 +27,12 @@ internal class NetworkObjectSynchronizationTests : NetcodeIntegrationTest private LogLevel m_CurrentLogLevel; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public enum VariableLengthSafety { DisableNetVarSafety, diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkShowHideTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkShowHideTests.cs index ea0107384d..bd8d0d3fbe 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkShowHideTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkShowHideTests.cs @@ -132,6 +132,12 @@ internal class NetworkShowHideTests : NetcodeIntegrationTest { protected override int NumberOfClients => 4; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + private ulong m_ClientId0; private GameObject m_PrefabToSpawn; private GameObject m_PrefabSpawnWithoutObservers; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkSpawnManagerTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkSpawnManagerTests.cs index 7835bfeb20..3039ea298c 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkSpawnManagerTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkSpawnManagerTests.cs @@ -15,6 +15,12 @@ internal class NetworkSpawnManagerTests : NetcodeIntegrationTest protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service. Combine server and client tests + protected override bool UseCMBService() + { + return false; + } + public NetworkSpawnManagerTests(HostOrServer hostOrServer) : base(hostOrServer) { } [Test] @@ -44,7 +50,6 @@ public IEnumerator TestServerCanAccessOtherPlayers() var serverSideOtherClientPlayerObject = m_ServerNetworkManager.SpawnManager.GetPlayerNetworkObject(otherClientSideClientId); Assert.NotNull(serverSideOtherClientPlayerObject); Assert.AreEqual(otherClientSideClientId, serverSideOtherClientPlayerObject.OwnerClientId); - } [Test] diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs index 99df6b2f16..cce925eacd 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs @@ -17,13 +17,18 @@ internal class InterpolationStopAndStartMotionTest : IntegrationTestWithApproxim { protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Update the Lerp test to work with the service + protected override bool UseCMBService() + { + return false; + } + private GameObject m_TestPrefab; private TestStartStopTransform m_AuthorityInstance; private List m_NonAuthorityInstances = new List(); private NetworkTransform.InterpolationTypes m_InterpolationType; - private List m_NetworkManagers = new List(); private NetworkManager m_AuthorityNetworkManager; private int m_NumberOfUpdates; @@ -97,12 +102,7 @@ private bool WaitForInstancesToFinishInterpolation() [UnityTest] public IEnumerator StopAndStartMotion() { - m_NetworkManagers.AddRange(m_ClientNetworkManagers); - if (!UseCMBService()) - { - m_NetworkManagers.Insert(0, m_ServerNetworkManager); - } - m_AuthorityNetworkManager = m_NetworkManagers[0]; + m_AuthorityNetworkManager = GetAuthorityNetworkManager(); m_AuthorityInstance = SpawnObject(m_TestPrefab, m_AuthorityNetworkManager).GetComponent(); // Wait for all clients to spawn the instance diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformGeneral.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformGeneral.cs index 92c47522c1..57ea6df51c 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformGeneral.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformGeneral.cs @@ -300,7 +300,6 @@ public void NonAuthorityOwnerSettingStateTest([Values] Interpolation interpolati m_NonAuthoritativeTransform.Interpolate = interpolate; m_NonAuthoritativeTransform.RotAngleThreshold = m_AuthoritativeTransform.RotAngleThreshold = 0.1f; - m_EnableVerboseDebug = true; VerboseDebug($"Target Frame Rate: {Application.targetFrameRate}"); // Test one parameter at a time first var newPosition = usingSmoothLerp ? new Vector3(15f, -12f, 10f) : new Vector3(55f, -24f, 20f); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformMixedAuthorityTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformMixedAuthorityTests.cs index 663ba49810..760e916bda 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformMixedAuthorityTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformMixedAuthorityTests.cs @@ -1,5 +1,4 @@ using System.Collections; -using System.Collections.Generic; using System.Text; using Unity.Netcode.Components; using Unity.Netcode.TestHelpers.Runtime; @@ -16,7 +15,6 @@ internal class NetworkTransformMixedAuthorityTests : IntegrationTestWithApproxim protected override int NumberOfClients => 2; private StringBuilder m_ErrorMsg = new StringBuilder(); - private List m_NetworkManagers = new List(); protected override void OnCreatePlayerPrefab() { @@ -89,9 +87,6 @@ private bool AllInstancePositionsMatch() [UnityTest] public IEnumerator MixedAuthorityTest() { - m_NetworkManagers.Add(m_ServerNetworkManager); - m_NetworkManagers.AddRange(m_ClientNetworkManagers); - for (int i = 0; i < k_Iterations; i++) { MovePlayers(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOwnershipTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOwnershipTests.cs index 64f6646005..b4da043e29 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOwnershipTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOwnershipTests.cs @@ -27,6 +27,12 @@ public enum MotionModels private MotionModels m_MotionModel; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public NetworkTransformOwnershipTests(HostOrServer hostOrServer, MotionModels motionModel) : base(hostOrServer) { m_MotionModel = motionModel; @@ -119,8 +125,10 @@ private bool ClientIsOwner() [UnityTest] public IEnumerator LateJoinedNonOwnerClientCannotChangeTransform() { + var authority = GetAuthorityNetworkManager(); + // Spawn the m_ClientNetworkTransformPrefab with the host starting as the owner - var hostInstance = SpawnObject(m_ClientNetworkTransformPrefab, m_ServerNetworkManager); + var hostInstance = SpawnObject(m_ClientNetworkTransformPrefab, authority); // Wait for the client to spawn it yield return WaitForConditionOrTimeOut(() => VerifyObjectIsSpawnedOnClient.GetClientsThatSpawnedThisPrefab().Contains(m_ClientNetworkManagers[0].LocalClientId)); @@ -619,7 +627,6 @@ internal class NestedNetworkTransformTests : IntegrationTestWithApproximation private StringBuilder m_ErrorLog = new StringBuilder(); - private List m_NetworkManagers = new List(); private List m_SpawnedObjects = new List(); public NestedNetworkTransformTests(HostOrServer hostOrServer, NetworkTransform.AuthorityModes authorityMode) : base(hostOrServer) @@ -702,14 +709,9 @@ protected override void OnServerAndClientsCreated() if (m_DistributedAuthority) { - if (!UseCMBService()) + foreach (var manager in m_NetworkManagers) { - m_ServerNetworkManager.OnFetchLocalPlayerPrefabToSpawn = FetchLocalPlayerPrefabToSpawn; - } - - foreach (var client in m_ClientNetworkManagers) - { - client.OnFetchLocalPlayerPrefabToSpawn = FetchLocalPlayerPrefabToSpawn; + manager.OnFetchLocalPlayerPrefabToSpawn = FetchLocalPlayerPrefabToSpawn; } } else @@ -844,12 +846,6 @@ private bool AllSpawnedObjectsSynchronized() [UnityTest] public IEnumerator NestedNetworkTransformSpawnPositionTest() { - if (!m_DistributedAuthority || (m_DistributedAuthority && !UseCMBService())) - { - m_NetworkManagers.Add(m_ServerNetworkManager); - } - m_NetworkManagers.AddRange(m_ClientNetworkManagers); - yield return WaitForConditionOrTimeOut(AllClientInstancesSynchronized); AssertOnTimeout($"Failed to synchronize all client instances!\n{m_ErrorLog}"); @@ -867,14 +863,12 @@ public IEnumerator NestedNetworkTransformSpawnPositionTest() yield return WaitForConditionOrTimeOut(AllSpawnedObjectsSynchronized); AssertOnTimeout($"Failed to synchronize all spawned NetworkObject instances!\n{m_ErrorLog}"); m_SpawnedObjects.Clear(); - m_NetworkManagers.Clear(); } protected override IEnumerator OnTearDown() { // In case there was a failure, go ahead and clear these lists out for any pending TextFixture passes m_SpawnedObjects.Clear(); - m_NetworkManagers.Clear(); return base.OnTearDown(); } } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs index d4f22c11c5..02b02e8fd3 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs @@ -92,6 +92,12 @@ public NetworkTransformTests(HostOrServer testWithHost, Authority authority, Rot NetworkTransform.DefaultInterpolationType = interpolation; } + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + protected override void OnOneTimeTearDown() { NetworkTransform.AssignDefaultInterpolationType = false; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs index 892e70d6fd..1de2aa1c36 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVarBufferCopyTest.cs @@ -127,10 +127,13 @@ protected override void OnCreatePlayerPrefab() public IEnumerator TestEntireBufferIsCopiedOnNetworkVariableDelta() { // This is the *SERVER VERSION* of the *CLIENT PLAYER* + var authority = GetAuthorityNetworkManager(); + var nonAuthority = GetNonAuthorityNetworkManager(); + var serverClientPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper(); yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation( - x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId, - m_ServerNetworkManager, serverClientPlayerResult); + x => x.IsPlayerObject && x.OwnerClientId == nonAuthority.LocalClientId, + authority, serverClientPlayerResult); var serverSideClientPlayer = serverClientPlayerResult.Result; var serverComponent = serverSideClientPlayer.GetComponent(); @@ -138,8 +141,8 @@ public IEnumerator TestEntireBufferIsCopiedOnNetworkVariableDelta() // This is the *CLIENT VERSION* of the *CLIENT PLAYER* var clientClientPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper(); yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation( - x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId, - m_ClientNetworkManagers[0], clientClientPlayerResult); + x => x.IsPlayerObject && x.OwnerClientId == nonAuthority.LocalClientId, + nonAuthority, clientClientPlayerResult); var clientSideClientPlayer = clientClientPlayerResult.Result; var clientComponent = clientSideClientPlayer.GetComponent(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableBaseInitializesWhenPersisted.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableBaseInitializesWhenPersisted.cs index 7ae68bb53f..9ff1ae1a0d 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableBaseInitializesWhenPersisted.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableBaseInitializesWhenPersisted.cs @@ -37,23 +37,19 @@ protected override void OnOneTimeSetup() protected override void OnServerAndClientsCreated() { - // Assign one of the precreated prefab instance handlers to the server - PrefabInstanceHandler.AssignHandler(m_ServerNetworkManager); - // Add the network prefab to the server networkmanager - m_ServerNetworkManager.AddNetworkPrefab(s_NetworkPrefab); // Repeat these steps for clients - foreach (var client in m_ClientNetworkManagers) + foreach (var manager in m_NetworkManagers) { - PrefabInstanceHandler.AssignHandler(client); - client.AddNetworkPrefab(s_NetworkPrefab); + PrefabInstanceHandler.AssignHandler(manager); + manager.AddNetworkPrefab(s_NetworkPrefab); } + // !!! IMPORTANT !!! // Disable the persisted network prefab so it isn't spawned nor destroyed s_NetworkPrefab.SetActive(false); base.OnServerAndClientsCreated(); } - private List m_NetworkManagers = new List(); private List m_SpawnedObjects = new List(); [UnityTest] @@ -65,8 +61,6 @@ public IEnumerator PrefabSessionIstantiationPass([Values(4, 3, 2, 1)] int iterat // is being spawned. var baseWaitTime = 0.35f; var waitPeriod = baseWaitTime * iterationsLeft; - m_NetworkManagers.Add(m_ServerNetworkManager); - m_NetworkManagers.AddRange(m_ClientNetworkManagers); foreach (var networkManager in m_NetworkManagers) { @@ -163,7 +157,6 @@ bool AllSpawnedObjectsUpdatedWithinTimeSpan() protected override IEnumerator OnTearDown() { - m_NetworkManagers.Clear(); m_SpawnedObjects.Clear(); PrefabInstanceHandler.ReleaseAll(); yield return base.OnTearDown(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableCollectionsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableCollectionsTests.cs index 3276b3d3df..4cff83a3a5 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableCollectionsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableCollectionsTests.cs @@ -1257,15 +1257,7 @@ protected override void OnServerAndClientsCreated() private bool AllInstancesSpawned() { - if (!UseCMBService()) - { - if (!m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(m_Instance.NetworkObjectId)) - { - return false; - } - } - - foreach (var client in m_ClientNetworkManagers) + foreach (var client in m_NetworkManagers) { if (!client.SpawnManager.SpawnedObjects.ContainsKey(m_Instance.NetworkObjectId)) { @@ -1275,25 +1267,25 @@ private bool AllInstancesSpawned() return true; } - private Dictionary m_NetworkManagers = new Dictionary(); + private Dictionary m_Managers = new Dictionary(); private bool ValidateAllInstances() { - if (!m_NetworkManagers.ContainsKey(m_Instance.OwnerClientId)) + if (!m_Managers.ContainsKey(m_Instance.OwnerClientId)) { return false; } - if (!m_NetworkManagers[m_Instance.OwnerClientId].SpawnManager.SpawnedObjects.ContainsKey(m_Instance.NetworkObjectId)) + if (!m_Managers[m_Instance.OwnerClientId].SpawnManager.SpawnedObjects.ContainsKey(m_Instance.NetworkObjectId)) { return false; } - var ownerNetworkManager = m_NetworkManagers[m_Instance.OwnerClientId]; + var ownerNetworkManager = m_Managers[m_Instance.OwnerClientId]; - var ownerClientInstance = m_NetworkManagers[m_Instance.OwnerClientId].SpawnManager.SpawnedObjects[m_Instance.NetworkObjectId].GetComponent(); + var ownerClientInstance = m_Managers[m_Instance.OwnerClientId].SpawnManager.SpawnedObjects[m_Instance.NetworkObjectId].GetComponent(); - foreach (var client in m_NetworkManagers) + foreach (var client in m_Managers) { if (client.Value == ownerNetworkManager) { @@ -1312,7 +1304,7 @@ private bool ValidateAllInstances() private bool OwnershipChangedOnAllClients(ulong expectedOwner) { m_ErrorLog.Clear(); - foreach (var client in m_NetworkManagers) + foreach (var client in m_Managers) { var otherInstance = client.Value.SpawnManager.SpawnedObjects[m_Instance.NetworkObjectId].GetComponent(); if (otherInstance.OwnerClientId != expectedOwner) @@ -1326,8 +1318,8 @@ private bool OwnershipChangedOnAllClients(ulong expectedOwner) private BaseCollectionUpdateHelper GetOwnerInstance() { - var ownerNetworkManager = m_NetworkManagers[m_Instance.OwnerClientId]; - return m_NetworkManagers[m_Instance.OwnerClientId].SpawnManager.SpawnedObjects[m_Instance.NetworkObjectId].GetComponent(); + var ownerNetworkManager = m_Managers[m_Instance.OwnerClientId]; + return m_Managers[m_Instance.OwnerClientId].SpawnManager.SpawnedObjects[m_Instance.NetworkObjectId].GetComponent(); } /// @@ -1353,17 +1345,13 @@ public IEnumerator CollectionAndOwnershipChangingTest() { BaseCollectionUpdateHelper.VerboseMode = m_EnableVerboseDebug; var runWaitPeriod = new WaitForSeconds(0.5f); - m_NetworkManagers.Clear(); - if (!UseCMBService() && m_UseHost) - { - m_NetworkManagers.Add(m_ServerNetworkManager.LocalClientId, m_ServerNetworkManager); - } - foreach (var client in m_ClientNetworkManagers) + m_Managers.Clear(); + foreach (var manager in m_NetworkManagers) { - m_NetworkManagers.Add(client.LocalClientId, client); + m_Managers.Add(manager.LocalClientId, manager); } - var authorityNetworkManager = UseCMBService() || !m_UseHost ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; + var authorityNetworkManager = GetAuthorityNetworkManager(); var instance = SpawnObject(m_TestPrefab, authorityNetworkManager); m_Instance = instance.GetComponent(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableInheritanceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableInheritanceTests.cs index 1a3a6d3513..6bc5677466 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableInheritanceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableInheritanceTests.cs @@ -111,7 +111,8 @@ protected override void OnServerAndClientsCreated() protected override IEnumerator OnServerAndClientsConnected() { - var serverTestObject = SpawnObject(m_TestObjectPrefab, m_ServerNetworkManager).GetComponent(); + var authority = GetAuthorityNetworkManager(); + var serverTestObject = SpawnObject(m_TestObjectPrefab, authority).GetComponent(); m_TestObjectId = serverTestObject.NetworkObjectId; var serverTestComponentA = serverTestObject.GetComponent(); @@ -125,12 +126,13 @@ protected override IEnumerator OnServerAndClientsConnected() serverTestComponentC.ChangeValuesB(1100, 2200, 3300); serverTestComponentC.ChangeValuesC(1110, 2220, 3330); - yield return WaitForTicks(m_ServerNetworkManager, 2); + yield return WaitForTicks(authority, 2); } private bool CheckTestObjectComponentValuesOnAll() { - var serverTestObject = m_ServerNetworkManager.SpawnManager.SpawnedObjects[m_TestObjectId]; + var authority = GetAuthorityNetworkManager(); + var serverTestObject = authority.SpawnManager.SpawnedObjects[m_TestObjectId]; var serverTestComponentA = serverTestObject.GetComponent(); var serverTestComponentB = serverTestObject.GetComponent(); var serverTestComponentC = serverTestObject.GetComponent(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/OwnerModifiedTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/OwnerModifiedTests.cs index 3a925b9332..83947888b4 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/OwnerModifiedTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/OwnerModifiedTests.cs @@ -80,6 +80,12 @@ internal class OwnerModifiedTests : NetcodeIntegrationTest { protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public OwnerModifiedTests(HostOrServer hostOrServer) : base(hostOrServer) { } protected override void OnCreatePlayerPrefab() diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs index 670bd9d091..c786734a7d 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs @@ -25,18 +25,23 @@ public NetworkVisibilityTests(SceneManagementState sceneManagementState, Network m_SceneManagementEnabled = sceneManagementState == SceneManagementState.SceneManagementEnabled; } + protected override IEnumerator OnSetup() + { + // TODO: [CmbServiceTests] remove this wait once the delay in service restart is fixed + if (m_UseCmbService) + { + yield return new WaitForSeconds(0.5f); + } + } + protected override void OnServerAndClientsCreated() { m_TestNetworkPrefab = CreateNetworkObjectPrefab("Object"); m_TestNetworkPrefab.AddComponent(); - if (!UseCMBService()) - { - m_ServerNetworkManager.NetworkConfig.EnableSceneManagement = m_SceneManagementEnabled; - } - foreach (var clientNetworkManager in m_ClientNetworkManagers) + foreach (var manager in m_NetworkManagers) { - clientNetworkManager.NetworkConfig.EnableSceneManagement = m_SceneManagementEnabled; + manager.NetworkConfig.EnableSceneManagement = m_SceneManagementEnabled; } base.OnServerAndClientsCreated(); } @@ -44,7 +49,7 @@ protected override void OnServerAndClientsCreated() protected override IEnumerator OnServerAndClientsConnected() { - m_SessionOwner = UseCMBService() ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; + m_SessionOwner = GetAuthorityNetworkManager(); m_SpawnedObject = SpawnObject(m_TestNetworkPrefab, m_SessionOwner); yield return base.OnServerAndClientsConnected(); @@ -53,7 +58,7 @@ protected override IEnumerator OnServerAndClientsConnected() [UnityTest] public IEnumerator HiddenObjectsTest() { - var expectedCount = UseCMBService() ? 2 : 3; + var expectedCount = NumberOfClients + (m_UseHost ? 1 : 0); #if UNITY_2023_1_OR_NEWER yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == expectedCount); #else @@ -66,17 +71,17 @@ public IEnumerator HiddenObjectsTest() [UnityTest] public IEnumerator HideShowAndDeleteTest() { - var expectedCount = UseCMBService() ? 2 : 3; + var expectedCount = NumberOfClients + (m_UseHost ? 1 : 0); #if UNITY_2023_1_OR_NEWER - yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == expectedCount); + yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Count(c => c.IsSpawned) == expectedCount); #else yield return WaitForConditionOrTimeOut(() => Object.FindObjectsOfType().Where((c) => c.IsSpawned).Count() == expectedCount); #endif - AssertOnTimeout("Timed out waiting for the visible object count to equal 2!"); + AssertOnTimeout($"Timed out waiting for the visible object count to equal 2! Actual count {Object.FindObjectsByType(FindObjectsSortMode.None).Count(c => c.IsSpawned)}"); var sessionOwnerNetworkObject = m_SpawnedObject.GetComponent(); - var clientIndex = UseCMBService() ? 1 : 0; - sessionOwnerNetworkObject.NetworkHide(m_ClientNetworkManagers[clientIndex].LocalClientId); + var nonAuthority = GetNonAuthorityNetworkManager(); + sessionOwnerNetworkObject.NetworkHide(nonAuthority.LocalClientId); #if UNITY_2023_1_OR_NEWER yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == expectedCount - 1); #else @@ -84,16 +89,16 @@ public IEnumerator HideShowAndDeleteTest() #endif AssertOnTimeout($"Timed out waiting for {m_SpawnedObject.name} to be hidden from client!"); var networkObjectId = sessionOwnerNetworkObject.NetworkObjectId; - sessionOwnerNetworkObject.NetworkShow(m_ClientNetworkManagers[clientIndex].LocalClientId); + sessionOwnerNetworkObject.NetworkShow(nonAuthority.LocalClientId); sessionOwnerNetworkObject.Despawn(true); // Expect no exceptions while waiting to show the object and wait for the client id to be removed - yield return WaitForConditionOrTimeOut(() => !m_SessionOwner.SpawnManager.ObjectsToShowToClient.ContainsKey(m_ClientNetworkManagers[clientIndex].LocalClientId)); - AssertOnTimeout($"Timed out waiting for client-{m_ClientNetworkManagers[clientIndex].LocalClientId} to be removed from the {nameof(NetworkSpawnManager.ObjectsToShowToClient)} table!"); + yield return WaitForConditionOrTimeOut(() => !m_SessionOwner.SpawnManager.ObjectsToShowToClient.ContainsKey(nonAuthority.LocalClientId)); + AssertOnTimeout($"Timed out waiting for client-{nonAuthority.LocalClientId} to be removed from the {nameof(NetworkSpawnManager.ObjectsToShowToClient)} table!"); // Now force a scenario where it normally would have caused an exception - m_SessionOwner.SpawnManager.ObjectsToShowToClient.Add(m_ClientNetworkManagers[clientIndex].LocalClientId, new System.Collections.Generic.List()); - m_SessionOwner.SpawnManager.ObjectsToShowToClient[m_ClientNetworkManagers[clientIndex].LocalClientId].Add(null); + m_SessionOwner.SpawnManager.ObjectsToShowToClient.Add(nonAuthority.LocalClientId, new System.Collections.Generic.List()); + m_SessionOwner.SpawnManager.ObjectsToShowToClient[nonAuthority.LocalClientId].Add(null); // Expect no exceptions yield return s_DefaultWaitForTick; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs index 9623c997a8..2f0554c6be 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs @@ -1,5 +1,4 @@ using System.Collections; -using System.Collections.Generic; using System.Text; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; @@ -27,7 +26,6 @@ public enum NetworkSpawnTypes private GameObject m_ParentPrefab; private GameObject m_ChildPrefab; private NetworkObject m_AuthorityInstance; - private List m_NetworkManagers = new List(); private StringBuilder m_Errors = new StringBuilder(); public class ParentDuringSpawnBehaviour : NetworkBehaviour @@ -73,6 +71,14 @@ public ParentingDuringSpawnTests(NetworkTopologyTypes networkTopology, NetworkSp m_NetworkSpawnType = networkSpawnType; } + protected override IEnumerator OnSetup() + { + if (m_UseCmbService) + { + yield return new WaitForSeconds(0.5f); + } + } + protected override void OnServerAndClientsCreated() { m_ParentPrefab = CreateNetworkObjectPrefab("Parent"); @@ -144,14 +150,7 @@ private bool NonAuthorityInstancesParentedChild() [UnityTest] public IEnumerator ParentDuringSpawn() { - m_NetworkManagers.Clear(); - var authorityNetworkManager = m_DistributedAuthority ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; - - m_NetworkManagers.AddRange(m_ClientNetworkManagers); - if (!UseCMBService()) - { - m_NetworkManagers.Add(m_ServerNetworkManager); - } + var authorityNetworkManager = GetAuthorityNetworkManager(); m_AuthorityInstance = SpawnObject(m_ParentPrefab, authorityNetworkManager).GetComponent(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs index 601a1baccb..af92c49e9b 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs @@ -394,44 +394,47 @@ protected override void OnCreatePlayerPrefab() private bool PlayersSpawnedInRightLocation() { - var position = m_ServerNetworkManager.LocalClient.PlayerObject.transform.position; + var authority = GetAuthorityNetworkManager(); + var nonAuthority = GetNonAuthorityNetworkManager(); + + var position = authority.LocalClient.PlayerObject.transform.position; if (!Approximately(ContactEventTransformHelper.SessionOwnerSpawnPoint, position)) { - m_ErrorLogger.AppendLine($"Client-{m_ServerNetworkManager.LocalClientId} player position {position} does not match the assigned player position {ContactEventTransformHelper.SessionOwnerSpawnPoint}!"); + m_ErrorLogger.AppendLine($"Client-{authority.LocalClientId} player position {position} does not match the assigned player position {ContactEventTransformHelper.SessionOwnerSpawnPoint}!"); return false; } - position = m_ClientNetworkManagers[0].LocalClient.PlayerObject.transform.position; + position = nonAuthority.LocalClient.PlayerObject.transform.position; if (!Approximately(ContactEventTransformHelper.ClientSpawnPoint, position)) { - m_ErrorLogger.AppendLine($"Client-{m_ClientNetworkManagers[0].LocalClientId} player position {position} does not match the assigned player position {ContactEventTransformHelper.ClientSpawnPoint}!"); + m_ErrorLogger.AppendLine($"Client-{nonAuthority.LocalClientId} player position {position} does not match the assigned player position {ContactEventTransformHelper.ClientSpawnPoint}!"); return false; } var playerObject = (NetworkObject)null; - if (!m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(m_ClientNetworkManagers[0].LocalClient.PlayerObject.NetworkObjectId)) + if (!authority.SpawnManager.SpawnedObjects.ContainsKey(nonAuthority.LocalClient.PlayerObject.NetworkObjectId)) { - m_ErrorLogger.AppendLine($"Client-{m_ServerNetworkManager.LocalClientId} cannot find a local spawned instance of Client-{m_ClientNetworkManagers[0].LocalClientId}'s player object!"); + m_ErrorLogger.AppendLine($"Client-{authority.LocalClientId} cannot find a local spawned instance of Client-{nonAuthority.LocalClientId}'s player object!"); return false; } - playerObject = m_ServerNetworkManager.SpawnManager.SpawnedObjects[m_ClientNetworkManagers[0].LocalClient.PlayerObject.NetworkObjectId]; + playerObject = authority.SpawnManager.SpawnedObjects[nonAuthority.LocalClient.PlayerObject.NetworkObjectId]; position = playerObject.transform.position; if (!Approximately(ContactEventTransformHelper.ClientSpawnPoint, position)) { - m_ErrorLogger.AppendLine($"Client-{m_ServerNetworkManager.LocalClientId} player position {position} for Client-{playerObject.OwnerClientId} does not match the assigned player position {ContactEventTransformHelper.ClientSpawnPoint}!"); + m_ErrorLogger.AppendLine($"Client-{authority.LocalClientId} player position {position} for Client-{playerObject.OwnerClientId} does not match the assigned player position {ContactEventTransformHelper.ClientSpawnPoint}!"); return false; } - if (!m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects.ContainsKey(m_ServerNetworkManager.LocalClient.PlayerObject.NetworkObjectId)) + if (!nonAuthority.SpawnManager.SpawnedObjects.ContainsKey(authority.LocalClient.PlayerObject.NetworkObjectId)) { - m_ErrorLogger.AppendLine($"Client-{m_ClientNetworkManagers[0].LocalClientId} cannot find a local spawned instance of Client-{m_ServerNetworkManager.LocalClientId}'s player object!"); + m_ErrorLogger.AppendLine($"Client-{nonAuthority.LocalClientId} cannot find a local spawned instance of Client-{authority.LocalClientId}'s player object!"); return false; } - playerObject = m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects[m_ServerNetworkManager.LocalClient.PlayerObject.NetworkObjectId]; + playerObject = nonAuthority.SpawnManager.SpawnedObjects[authority.LocalClient.PlayerObject.NetworkObjectId]; position = playerObject.transform.position; if (!Approximately(ContactEventTransformHelper.SessionOwnerSpawnPoint, playerObject.transform.position)) { - m_ErrorLogger.AppendLine($"Client-{m_ClientNetworkManagers[0].LocalClientId} player position {position} for Client-{playerObject.OwnerClientId} does not match the assigned player position {ContactEventTransformHelper.SessionOwnerSpawnPoint}!"); + m_ErrorLogger.AppendLine($"Client-{nonAuthority.LocalClientId} player position {position} for Client-{playerObject.OwnerClientId} does not match the assigned player position {ContactEventTransformHelper.SessionOwnerSpawnPoint}!"); return false; } return true; @@ -450,10 +453,13 @@ public IEnumerator TestContactEvents() AssertOnTimeout($"Timed out waiting for all player instances to spawn in the corect location:\n {m_ErrorLogger}"); m_ErrorLogger.Clear(); - var sessionOwnerPlayer = m_ContactEventType == ContactEventTypes.Default ? m_ServerNetworkManager.LocalClient.PlayerObject.GetComponent() : - m_ServerNetworkManager.LocalClient.PlayerObject.GetComponent(); - var clientPlayer = m_ContactEventType == ContactEventTypes.Default ? m_ClientNetworkManagers[0].LocalClient.PlayerObject.GetComponent() : - m_ClientNetworkManagers[0].LocalClient.PlayerObject.GetComponent(); + var authority = GetAuthorityNetworkManager(); + var nonAuthority = GetNonAuthorityNetworkManager(); + + var sessionOwnerPlayer = m_ContactEventType == ContactEventTypes.Default ? authority.LocalClient.PlayerObject.GetComponent() : + authority.LocalClient.PlayerObject.GetComponent(); + var clientPlayer = m_ContactEventType == ContactEventTypes.Default ? nonAuthority.LocalClient.PlayerObject.GetComponent() : + nonAuthority.LocalClient.PlayerObject.GetComponent(); // Get both players to point towards each other sessionOwnerPlayer.Target = clientPlayer; @@ -468,11 +474,11 @@ public IEnumerator TestContactEvents() clientPlayer.RegisterForContactEvents(false); sessionOwnerPlayer.RegisterForContactEvents(false); - var otherPlayer = m_ContactEventType == ContactEventTypes.Default ? m_ServerNetworkManager.SpawnManager.SpawnedObjects[clientPlayer.NetworkObjectId].GetComponent() : - m_ServerNetworkManager.SpawnManager.SpawnedObjects[clientPlayer.NetworkObjectId].GetComponent(); + var otherPlayer = m_ContactEventType == ContactEventTypes.Default ? authority.SpawnManager.SpawnedObjects[clientPlayer.NetworkObjectId].GetComponent() : + authority.SpawnManager.SpawnedObjects[clientPlayer.NetworkObjectId].GetComponent(); otherPlayer.RegisterForContactEvents(false); - otherPlayer = m_ContactEventType == ContactEventTypes.Default ? m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects[sessionOwnerPlayer.NetworkObjectId].GetComponent() : - m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects[sessionOwnerPlayer.NetworkObjectId].GetComponent(); + otherPlayer = m_ContactEventType == ContactEventTypes.Default ? nonAuthority.SpawnManager.SpawnedObjects[sessionOwnerPlayer.NetworkObjectId].GetComponent() : + nonAuthority.SpawnManager.SpawnedObjects[sessionOwnerPlayer.NetworkObjectId].GetComponent(); otherPlayer.RegisterForContactEvents(false); Object.Destroy(m_RigidbodyContactEventManager); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs index 4ffb78395b..118a8336c7 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs @@ -18,6 +18,11 @@ internal class PlayerObjectTests : NetcodeIntegrationTest protected GameObject m_NewPlayerToSpawn; + // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart + protected override bool UseCMBService() + { + return false; + } public PlayerObjectTests(HostOrServer hostOrServer) : base(hostOrServer) { } protected override void OnServerAndClientsCreated() @@ -29,20 +34,23 @@ protected override void OnServerAndClientsCreated() [UnityTest] public IEnumerator SpawnAndReplaceExistingPlayerObject() { - yield return WaitForConditionOrTimeOut(() => m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId].ContainsKey(m_ClientNetworkManagers[0].LocalClientId)); + var authority = GetAuthorityNetworkManager(); + var nonAuthority = GetNonAuthorityNetworkManager(); + + yield return WaitForConditionOrTimeOut(() => m_PlayerNetworkObjects[authority.LocalClientId].ContainsKey(nonAuthority.LocalClientId)); AssertOnTimeout("Timed out waiting for client-side player object to spawn!"); // Get the server-side player NetworkObject - var originalPlayer = m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][m_ClientNetworkManagers[0].LocalClientId]; + var originalPlayer = m_PlayerNetworkObjects[authority.LocalClientId][nonAuthority.LocalClientId]; // Get the client-side player NetworkObject - var playerLocalClient = m_ClientNetworkManagers[0].LocalClient.PlayerObject; + var playerLocalClient = nonAuthority.LocalClient.PlayerObject; // Create a new player prefab instance var newPlayer = Object.Instantiate(m_NewPlayerToSpawn); var newPlayerNetworkObject = newPlayer.GetComponent(); // In distributed authority mode, the client owner spawns its new player - newPlayerNetworkObject.NetworkManagerOwner = m_DistributedAuthority ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; + newPlayerNetworkObject.NetworkManagerOwner = m_DistributedAuthority ? nonAuthority : authority; // Spawn this instance as a new player object for the client who already has an assigned player object - newPlayerNetworkObject.SpawnAsPlayerObject(m_ClientNetworkManagers[0].LocalClientId); + newPlayerNetworkObject.SpawnAsPlayerObject(nonAuthority.LocalClientId); // Make sure server-side changes are detected, the original player object should no longer be marked as a player // and the local new player object should. @@ -50,8 +58,8 @@ public IEnumerator SpawnAndReplaceExistingPlayerObject() Assert.False(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for server-side player object to change!"); // Make sure the client-side changes are the same - yield return WaitForConditionOrTimeOut(() => m_ClientNetworkManagers[0].LocalClient.PlayerObject != playerLocalClient && !playerLocalClient.IsPlayerObject - && m_ClientNetworkManagers[0].LocalClient.PlayerObject.IsPlayerObject); + yield return WaitForConditionOrTimeOut(() => nonAuthority.LocalClient.PlayerObject != playerLocalClient && !playerLocalClient.IsPlayerObject + && nonAuthority.LocalClient.PlayerObject.IsPlayerObject); Assert.False(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for client-side player object to change!"); } } @@ -67,6 +75,11 @@ internal class PlayerSpawnNoObserversTest : NetcodeIntegrationTest { protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart + protected override bool UseCMBService() + { + return false; + } public PlayerSpawnNoObserversTest(HostOrServer hostOrServer) : base(hostOrServer) { } protected override bool ShouldCheckForSpawnedPlayers() @@ -100,17 +113,10 @@ public IEnumerator SpawnWithNoObservers() else { // For distributed authority, we want to make sure the player object is only spawned on the authority side and all non-authority instances did not spawn it. - var playerObjectId = m_ServerNetworkManager.LocalClient.PlayerObject.NetworkObjectId; - foreach (var client in m_ClientNetworkManagers) - { - Assert.IsFalse(client.SpawnManager.SpawnedObjects.ContainsKey(playerObjectId), $"Client-{client.LocalClientId} spawned player object for Client-{m_ServerNetworkManager.LocalClientId}!"); - } - - foreach (var clientPlayer in m_ClientNetworkManagers) + foreach (var clientPlayer in m_NetworkManagers) { - playerObjectId = clientPlayer.LocalClient.PlayerObject.NetworkObjectId; - Assert.IsFalse(m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(playerObjectId), $"Client-{m_ServerNetworkManager.LocalClientId} spawned player object for Client-{clientPlayer.LocalClientId}!"); - foreach (var client in m_ClientNetworkManagers) + var playerObjectId = clientPlayer.LocalClient.PlayerObject.NetworkObjectId; + foreach (var client in m_NetworkManagers) { if (clientPlayer == client) { @@ -135,6 +141,11 @@ internal class PlayerSpawnPositionTests : IntegrationTestWithApproximation { protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart + protected override bool UseCMBService() + { + return false; + } public PlayerSpawnPositionTests(HostOrServer hostOrServer) : base(hostOrServer) { } private Vector3 m_PlayerPosition; @@ -161,23 +172,24 @@ private void PlayerTransformMatches(NetworkObject player) [UnityTest] public IEnumerator PlayerSpawnPosition() { - if (m_ServerNetworkManager.IsHost) + var authority = GetAuthorityNetworkManager(); + if (authority.IsHost) { - PlayerTransformMatches(m_ServerNetworkManager.LocalClient.PlayerObject); + PlayerTransformMatches(authority.LocalClient.PlayerObject); foreach (var client in m_ClientNetworkManagers) { - yield return WaitForConditionOrTimeOut(() => client.SpawnManager.SpawnedObjects.ContainsKey(m_ServerNetworkManager.LocalClient.PlayerObject.NetworkObjectId)); - AssertOnTimeout($"Client-{client.LocalClientId} does not contain a player prefab instance for client-{m_ServerNetworkManager.LocalClientId}!"); - PlayerTransformMatches(client.SpawnManager.SpawnedObjects[m_ServerNetworkManager.LocalClient.PlayerObject.NetworkObjectId]); + yield return WaitForConditionOrTimeOut(() => client.SpawnManager.SpawnedObjects.ContainsKey(authority.LocalClient.PlayerObject.NetworkObjectId)); + AssertOnTimeout($"Client-{client.LocalClientId} does not contain a player prefab instance for client-{authority.LocalClientId}!"); + PlayerTransformMatches(client.SpawnManager.SpawnedObjects[authority.LocalClient.PlayerObject.NetworkObjectId]); } } foreach (var client in m_ClientNetworkManagers) { - yield return WaitForConditionOrTimeOut(() => m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(client.LocalClient.PlayerObject.NetworkObjectId)); - AssertOnTimeout($"Client-{m_ServerNetworkManager.LocalClientId} does not contain a player prefab instance for client-{client.LocalClientId}!"); - PlayerTransformMatches(m_ServerNetworkManager.SpawnManager.SpawnedObjects[client.LocalClient.PlayerObject.NetworkObjectId]); + yield return WaitForConditionOrTimeOut(() => authority.SpawnManager.SpawnedObjects.ContainsKey(client.LocalClient.PlayerObject.NetworkObjectId)); + AssertOnTimeout($"Client-{authority.LocalClientId} does not contain a player prefab instance for client-{client.LocalClientId}!"); + PlayerTransformMatches(authority.SpawnManager.SpawnedObjects[client.LocalClient.PlayerObject.NetworkObjectId]); foreach (var subClient in m_ClientNetworkManagers) { yield return WaitForConditionOrTimeOut(() => subClient.SpawnManager.SpawnedObjects.ContainsKey(client.LocalClient.PlayerObject.NetworkObjectId)); @@ -203,6 +215,12 @@ internal class PlayerSpawnAndDespawnTests : NetcodeIntegrationTest private StringBuilder m_ErrorLog = new StringBuilder(); + // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart + protected override bool UseCMBService() + { + return false; + } + public PlayerSpawnAndDespawnTests(HostOrServer hostOrServer) : base(hostOrServer) { } private bool ValidateObservers(ulong playerClientId, NetworkObject player, ref List networkManagers) @@ -264,19 +282,15 @@ private bool ValidateAllClientPlayerObservers() { var networkManagers = new List(); - if (m_ServerNetworkManager.IsHost) - { - networkManagers.Add(m_ServerNetworkManager); - } - foreach (var networkManager in m_ClientNetworkManagers) - { - networkManagers.Add(networkManager); - } - m_ErrorLog.Clear(); var success = true; - foreach (var networkManager in networkManagers) + foreach (var networkManager in m_NetworkManagers) { + if (networkManager.IsServer && !networkManager.IsHost) + { + continue; + } + var spawnedOrNot = networkManager.LocalClient.PlayerObject == null ? "despawned" : "spawned"; m_ErrorLog.AppendLine($"Validating Client-{networkManager.LocalClientId} {spawnedOrNot} player."); if (networkManager.LocalClient == null) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs index f016286ac0..d6d97619a9 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs @@ -217,12 +217,7 @@ public IEnumerator PrefabOverrideTests() var prefabNetworkObject = (NetworkObject)null; var spawnedGlobalObjectId = (uint)0; - var networkManagers = m_ClientNetworkManagers.ToList(); - if (m_UseHost) - { - networkManagers.Insert(0, m_ServerNetworkManager); - } - else + if (!m_UseHost) { // If running as just a server, validate that all player prefab clone instances are the server side version prefabNetworkObject = GetPlayerNetworkPrefabObject(m_ServerNetworkManager).GetComponent(); @@ -235,7 +230,7 @@ public IEnumerator PrefabOverrideTests() // Validates prefab overrides via the NetworkPrefabHandler. // Validate the player prefab instance clones relative to all NetworkManagers. - foreach (var networkManager in networkManagers) + foreach (var networkManager in m_NetworkManagers) { // Get the expected player prefab to be spawned based on the NetworkManager prefabNetworkObject = GetPlayerNetworkPrefabObject(networkManager).GetComponent(); @@ -263,11 +258,11 @@ public IEnumerator PrefabOverrideTests() if (m_DistributedAuthority) { - networkManagerOwner = m_ClientNetworkManagers[0]; + networkManagerOwner = m_ClientNetworkManagers[1]; } // Clients and Host will spawn the OverridingTargetPrefab while a dedicated server will spawn the SourcePrefabToOverride - var expectedServerGlobalObjectIdHash = networkManagerOwner.IsClient ? m_PrefabOverride.OverridingTargetPrefab.GetComponent().GlobalObjectIdHash : m_PrefabOverride.SourcePrefabToOverride.GetComponent().GlobalObjectIdHash; + var expectedServerGlobalObjectIdHash = m_PrefabOverride.SourcePrefabToOverride.GetComponent().GlobalObjectIdHash; var expectedClientGlobalObjectIdHash = m_PrefabOverride.OverridingTargetPrefab.GetComponent().GlobalObjectIdHash; spawnedInstance = NetworkObject.InstantiateAndSpawn(m_PrefabOverride.SourcePrefabToOverride, networkManagerOwner, networkManagerOwner.LocalClientId); @@ -275,29 +270,18 @@ public IEnumerator PrefabOverrideTests() bool ObjectSpawnedOnAllNetworkMangers() { builder.Clear(); - if (!m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(spawnedInstance.NetworkObjectId)) - { - builder.AppendLine($"Client-{m_ServerNetworkManager.LocalClientId} failed to spawn {spawnedInstance.name}-{spawnedInstance.NetworkObjectId}!"); - return false; - } - var instanceGID = m_ServerNetworkManager.SpawnManager.SpawnedObjects[spawnedInstance.NetworkObjectId].GlobalObjectIdHash; - if (instanceGID != expectedServerGlobalObjectIdHash) - { - builder.AppendLine($"Client-{m_ServerNetworkManager.LocalClientId} instance {spawnedInstance.name}-{spawnedInstance.NetworkObjectId} GID is {instanceGID} but was expected to be {expectedServerGlobalObjectIdHash}!"); - return false; - } - - foreach (var networkManger in m_ClientNetworkManagers) + foreach (var networkManger in m_NetworkManagers) { if (!networkManger.SpawnManager.SpawnedObjects.ContainsKey(spawnedInstance.NetworkObjectId)) { builder.AppendLine($"Client-{networkManger.LocalClientId} failed to spawn {spawnedInstance.name}-{spawnedInstance.NetworkObjectId}!"); return false; } - instanceGID = networkManger.SpawnManager.SpawnedObjects[spawnedInstance.NetworkObjectId].GlobalObjectIdHash; - if (instanceGID != expectedClientGlobalObjectIdHash) + var instanceGlobalId = networkManger.SpawnManager.SpawnedObjects[spawnedInstance.NetworkObjectId].GlobalObjectIdHash; + var expectedHash = networkManger.IsClient ? expectedClientGlobalObjectIdHash : expectedServerGlobalObjectIdHash; + if (instanceGlobalId != expectedHash) { - builder.AppendLine($"Client-{networkManger.LocalClientId} instance {spawnedInstance.name}-{spawnedInstance.NetworkObjectId} GID is {instanceGID} but was expected to be {expectedClientGlobalObjectIdHash}!"); + builder.AppendLine($"Client-{networkManger.LocalClientId} instance {spawnedInstance.name}-{spawnedInstance.NetworkObjectId} GID is {instanceGlobalId} but was expected to be {expectedHash}!"); return false; } } @@ -308,33 +292,34 @@ bool ObjectSpawnedOnAllNetworkMangers() AssertOnTimeout($"The spawned prefab override validation failed!\n {builder}"); // Verify that the despawn and destroy order of operations is correct for client owned NetworkObjects and the nunmber of times each is invoked is correct - expectedServerGlobalObjectIdHash = networkManagerOwner.IsClient ? m_PrefabOverride.OverridingTargetPrefab.GetComponent().GlobalObjectIdHash : m_PrefabOverride.SourcePrefabToOverride.GetComponent().GlobalObjectIdHash; - expectedClientGlobalObjectIdHash = m_PrefabOverride.OverridingTargetPrefab.GetComponent().GlobalObjectIdHash; - spawnedInstance = NetworkObject.InstantiateAndSpawn(m_PrefabOverride.SourcePrefabToOverride, networkManagerOwner, m_ClientNetworkManagers[0].LocalClientId); yield return WaitForConditionOrTimeOut(ObjectSpawnedOnAllNetworkMangers); AssertOnTimeout($"The spawned prefab override validation failed!\n {builder}"); + var clientId = m_ClientNetworkManagers[0].LocalClientId; m_ClientNetworkManagers[0].Shutdown(); // Wait until all of the client's owned objects are destroyed // If no asserts occur, then the despawn & destroy order of operations and invocation count is correct - /// For more information look at: + // For more information look at: bool ClientDisconnected(ulong clientId) { - var clientOwnedObjects = m_ServerNetworkManager.SpawnManager.SpawnedObjects.Where((c) => c.Value.OwnerClientId == clientId).ToList(); - if (clientOwnedObjects.Count > 0) + foreach (var manager in m_NetworkManagers) { - return false; - } + if (manager.LocalClientId == clientId) + { + continue; + } - clientOwnedObjects = m_ClientNetworkManagers[1].SpawnManager.SpawnedObjects.Where((c) => c.Value.OwnerClientId == clientId).ToList(); - if (clientOwnedObjects.Count > 0) - { - return false; + var clientOwnedObjects = manager.SpawnManager.SpawnedObjects.Where((c) => c.Value.OwnerClientId == clientId).ToList(); + if (clientOwnedObjects.Count > 0) + { + return false; + } } + return true; } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs index 3aeb06d05d..72b71ccbf5 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/UniversalRpcTests.cs @@ -538,6 +538,12 @@ internal class UniversalRpcTestsBase : NetcodeIntegrationTest { protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public UniversalRpcTestsBase(HostOrServer hostOrServer) : base(hostOrServer) { } diff --git a/pvpExceptions.json b/pvpExceptions.json index d70527ca25..8c448d01ea 100644 --- a/pvpExceptions.json +++ b/pvpExceptions.json @@ -85,12 +85,9 @@ "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: k_DefaultTickRate: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: NumberOfClients: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_PlayerPrefab: undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_ServerNetworkManager: undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_ClientNetworkManagers: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_UseHost: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_DistributedAuthority: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_NetworkTopologyType: undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: bool UseCMBService(): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: NetworkTopologyTypes OnGetNetworkTopologyType(): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void SetDistributedAuthorityProperties(NetworkManager): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_TargetFrameRate: undocumented", diff --git a/testproject/Assets/DefaultNetworkPrefabs.asset b/testproject/Assets/DefaultNetworkPrefabs.asset index a5e491547f..8414b17a83 100644 --- a/testproject/Assets/DefaultNetworkPrefabs.asset +++ b/testproject/Assets/DefaultNetworkPrefabs.asset @@ -224,3 +224,109 @@ MonoBehaviour: SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 296612175404815451, guid: 9501b2f26df3884488e1699035fd634b, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 771575417923360811, guid: 44d487c39a833b445beef6e9e39a5731, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 6307603743893504780, guid: 0a46b240b37c5b74786b1938e8fd2eae, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 5911443254905569495, guid: 67daf9621f0d6d74c9a9bb4f81438061, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 296612175404815451, guid: 280da53b37f0d2546ab4d7b7da446545, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 5911443254905569495, guid: 12cead04031f30a4aaae7427341502fa, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 771575417923360811, guid: d7447e326e807754d81428939a14058f, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 6994329648695279756, guid: 5c4a10e01b6668147ba4ccda6a584181, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 479369275288778692, guid: 4d47e418fec779e4eb616d66d61c3231, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 5911443254905569495, guid: d88eb84e4c4e82b4b81d577a6c8e818e, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 479369275288778692, guid: ce3279d5e4f8e0342acdb2ce118f2be5, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 296612175404815451, guid: 61e89146f864ef2478af3da9d7dda1e2, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 6994329648695279756, guid: a67d0c2ee5d39fb4f9f0667f244d9e58, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 1923233254652950715, guid: d166e48a59e24924199f3ec3b2bc3b64, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 5507278367988661157, guid: c2db148a1fac379449a31b5430f4c6ac, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 296612175404815451, guid: fda785b5a15c5a94f9f3e93e635827a7, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 5911443254905569495, guid: 1e7fa5aea121ba0459459b497c2f03e8, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 8188135024827620138, guid: c000e98bc12da2941a59ec61c260dd6a, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 6958138586392507362, guid: 4b31f769283d3c24ca2a5d6baf28a806, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} diff --git a/testproject/Assets/Tests/Manual/Scripts/ParentPlayerToInSceneNetworkObject.cs b/testproject/Assets/Tests/Manual/Scripts/ParentPlayerToInSceneNetworkObject.cs index 6aa6985962..98f9f155d6 100644 --- a/testproject/Assets/Tests/Manual/Scripts/ParentPlayerToInSceneNetworkObject.cs +++ b/testproject/Assets/Tests/Manual/Scripts/ParentPlayerToInSceneNetworkObject.cs @@ -1,4 +1,5 @@ using Unity.Netcode; +using UnityEngine; using UnityEngine.SceneManagement; namespace TestProject.ManualTests @@ -33,6 +34,10 @@ private void SetPlayerParent(ulong clientId) if (IsSpawned) { var playerObject = NetworkManager.SpawnManager.GetPlayerNetworkObject(clientId); + if (!playerObject) + { + Debug.LogError("Player object not spawned"); + } if (playerObject.gameObject.scene != gameObject.scene) { SceneManager.MoveGameObjectToScene(playerObject.gameObject, gameObject.scene); diff --git a/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs b/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs index 7befcfab22..e0f3b384aa 100644 --- a/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs +++ b/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs @@ -53,6 +53,11 @@ public class NetworkAnimatorTests : NetcodeIntegrationTest private OwnerShipMode m_OwnerShipMode; private AuthoritativeMode m_AuthoritativeMode; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } public NetworkAnimatorTests(HostOrServer hostOrServer, OwnerShipMode ownerShipMode, AuthoritativeMode authoritative) { @@ -851,7 +856,7 @@ public IEnumerator LateJoinSynchronizationTest() // Make sure the AnimatorTestHelper client side instances is the same as the TotalClients var calculatedClients = (AnimatorTestHelper.ClientSideInstances.Count + (m_UseHost ? 1 : 0)); - Assert.True(calculatedClients == TotalClients, $"Number of client"); + Assert.True(calculatedClients == TotalClients, $"Incorrect number of clients: expected {calculatedClients}, actual {TotalClients}. network managers: {m_NetworkManagers.Length}, client side: {AnimatorTestHelper.ClientSideInstances.Count}"); var lateJoinObjectInstance = AnimatorTestHelper.ClientSideInstances[m_ClientNetworkManagers[NumberOfClients].LocalClientId]; yield return WaitForConditionOrTimeOut(() => Mathf.Approximately(lateJoinObjectInstance.transform.rotation.eulerAngles.y, 180.0f)); diff --git a/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs b/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs index 714b87b88b..771a90b9b8 100644 --- a/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs +++ b/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs @@ -22,8 +22,9 @@ public NetworkBehaviourSessionSynchronized(HostOrServer hostOrServer) : base(hos public IEnumerator InScenePlacedSessionSynchronized() { m_SceneLoaded = false; - m_ServerNetworkManager.SceneManager.OnSceneEvent += OnSceneEvent; - m_ServerNetworkManager.SceneManager.LoadScene(k_SceneToLoad, UnityEngine.SceneManagement.LoadSceneMode.Additive); + var authority = GetAuthorityNetworkManager(); + authority.SceneManager.OnSceneEvent += OnSceneEvent; + authority.SceneManager.LoadScene(k_SceneToLoad, UnityEngine.SceneManagement.LoadSceneMode.Additive); yield return WaitForConditionOrTimeOut(() => m_SceneLoaded); AssertOnTimeout($"Timed out waiting for scene {k_SceneToLoad} to load!"); yield return CreateAndStartNewClient(); @@ -41,10 +42,11 @@ public IEnumerator InScenePlacedSessionSynchronized() private void OnSceneEvent(SceneEvent sceneEvent) { - if (sceneEvent.ClientId == m_ServerNetworkManager.LocalClientId && sceneEvent.SceneEventType == SceneEventType.LoadEventCompleted) + var authority = GetAuthorityNetworkManager(); + if (sceneEvent.ClientId == authority.LocalClientId && sceneEvent.SceneEventType == SceneEventType.LoadEventCompleted) { m_SceneLoaded = true; - m_ServerNetworkManager.SceneManager.OnSceneEvent -= OnSceneEvent; + authority.SceneManager.OnSceneEvent -= OnSceneEvent; } } } diff --git a/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs b/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs index dbf2120411..6ed56b04ed 100644 --- a/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs +++ b/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs @@ -21,6 +21,12 @@ internal class NetworkObjectSpawning : NetcodeIntegrationTest protected override int NumberOfClients => 1; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public NetworkObjectSpawning(NetworkTopologyTypes networkTopology) : base(networkTopology) { } diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationValidationTest.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationValidationTest.cs index 99781be873..32f88e9221 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationValidationTest.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/ClientSynchronizationValidationTest.cs @@ -22,6 +22,12 @@ public class ClientSynchronizationValidationTest : NetcodeIntegrationTest private bool m_IncludeSceneVerificationHandler; private bool m_RuntimeSceneWasExcludedFromSynch; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + private List m_ClientSceneVerifiers = new List(); public ClientSynchronizationValidationTest(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { } diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs index 32eb3be776..481ee15f8f 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs @@ -27,6 +27,12 @@ public class InScenePlacedNetworkObjectTests : IntegrationTestWithApproximation private bool m_CanStartServerAndClients; private string m_SceneLoading = k_SceneToLoad; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public InScenePlacedNetworkObjectTests(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { } protected override IEnumerator OnSetup() diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventCallbacks.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventCallbacks.cs index 505088dd8e..6ece25a527 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventCallbacks.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventCallbacks.cs @@ -20,6 +20,12 @@ public class NetworkSceneManagerEventCallbacks : NetcodeIntegrationTest private Scene m_CurrentScene; private bool m_CanStartServerOrClients = false; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + private class SceneEventNotificationTestInfo { public ulong ClientId; diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventDataPoolTest.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventDataPoolTest.cs index 73349a49a1..7c448830f6 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventDataPoolTest.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventDataPoolTest.cs @@ -23,6 +23,11 @@ public class NetworkSceneManagerEventDataPoolTest : NetcodeIntegrationTest protected override bool m_EnableTimeTravel => true; protected override bool m_SetupIsACoroutine => false; protected override bool m_TearDownIsACoroutine => false; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } public NetworkSceneManagerEventDataPoolTest(HostOrServer hostOrServer, LoadSceneMode loadSceneMode) : base(hostOrServer) { m_LoadSceneMode = loadSceneMode; diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventNotifications.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventNotifications.cs index 34a2078499..b641a1a3e6 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventNotifications.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerEventNotifications.cs @@ -27,6 +27,12 @@ public class NetworkSceneManagerEventNotifications : NetcodeIntegrationTest private bool m_CanStartServerOrClients = false; private bool m_LoadEventCompleted = false; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + internal class SceneTestInfo { public bool ShouldWait; diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerPopulateInSceneTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerPopulateInSceneTests.cs index 4af8737c44..bc3a24cb78 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerPopulateInSceneTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerPopulateInSceneTests.cs @@ -18,6 +18,11 @@ public class NetworkSceneManagerPopulateInSceneTests : NetcodeIntegrationTest { protected override int NumberOfClients => 0; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } protected Dictionary m_InSceneObjectList = new Dictionary(); diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerSeneVerification.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerSeneVerification.cs index 9f92f4bd28..cef95b2acd 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerSeneVerification.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerSeneVerification.cs @@ -18,6 +18,12 @@ namespace TestProject.RuntimeTests public class NetworkSceneManagerSceneVerification : NetcodeIntegrationTest { protected override int NumberOfClients => 4; + + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } public NetworkSceneManagerSceneVerification(HostOrServer hostOrServer, LoadSceneMode loadSceneMode) : base(hostOrServer) { m_LoadSceneMode = loadSceneMode; diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerUsageTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerUsageTests.cs index e05d292c36..8b2daf803c 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerUsageTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkSceneManagerUsageTests.cs @@ -19,6 +19,13 @@ public class NetworkSceneManagerUsageTests : NetcodeIntegrationTest private Scene m_CurrentScene; protected override int NumberOfClients => 1; + + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public NetworkSceneManagerUsageTests(HostOrServer hostOrServer) : base(hostOrServer) { } /// diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventProgressTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventProgressTests.cs index 7d61f2c7dc..7e070712ca 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventProgressTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventProgressTests.cs @@ -19,6 +19,12 @@ public class SceneEventProgressTests : NetcodeIntegrationTest protected override int NumberOfClients => 4; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + private bool m_SceneEventProgressCompleted; private SceneEventProgress m_CurrentSceneEventProgress; diff --git a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentDynamicUnderInScenePlaced.cs b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentDynamicUnderInScenePlaced.cs index 5acf256de1..3bf12e7011 100644 --- a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentDynamicUnderInScenePlaced.cs +++ b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentDynamicUnderInScenePlaced.cs @@ -36,6 +36,12 @@ public class ParentDynamicUnderInScenePlaced : NetcodeIntegrationTest private GameObject m_DynamicallySpawned; private bool m_SceneIsLoaded; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public ParentDynamicUnderInScenePlaced(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } protected override IEnumerator OnSetup() diff --git a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs index 5b5458e17b..b0321a949d 100644 --- a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs +++ b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingInSceneObjectsTests.cs @@ -24,6 +24,12 @@ public class ParentingInSceneObjectsTests : IntegrationTestWithApproximation protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public ParentingInSceneObjectsTests(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } protected override void OnOneTimeSetup() diff --git a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingWorldPositionStaysTests.cs b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingWorldPositionStaysTests.cs index 84829a6c8e..04eb18c713 100644 --- a/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingWorldPositionStaysTests.cs +++ b/testproject/Assets/Tests/Runtime/ObjectParenting/ParentingWorldPositionStaysTests.cs @@ -21,6 +21,12 @@ public class ParentingWorldPositionStaysTests : IntegrationTestWithApproximation protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + internal class TestComponentHelper : NetworkBehaviour { internal class ChildInfo diff --git a/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs b/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs index c8f441b6e1..7dbdc2635f 100644 --- a/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs +++ b/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs @@ -17,6 +17,12 @@ public class RespawnInSceneObjectsAfterShutdown : NetcodeIntegrationTest protected override int NumberOfClients => 0; protected Scene m_SceneLoaded; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public RespawnInSceneObjectsAfterShutdown(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } protected override void OnOneTimeSetup() diff --git a/testproject/Assets/Tests/Runtime/SenderIdTests.cs b/testproject/Assets/Tests/Runtime/SenderIdTests.cs index d0ee7eaa30..ba71242392 100644 --- a/testproject/Assets/Tests/Runtime/SenderIdTests.cs +++ b/testproject/Assets/Tests/Runtime/SenderIdTests.cs @@ -17,6 +17,12 @@ public class SenderIdTests : NetcodeIntegrationTest { protected override int NumberOfClients => 2; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + private NetworkManager FirstClient => m_ClientNetworkManagers[0]; private NetworkManager SecondClient => m_ClientNetworkManagers[1]; diff --git a/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs b/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs index 4702ba74ec..d93f038a78 100644 --- a/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs +++ b/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs @@ -15,6 +15,12 @@ public class ServerDisconnectsClientTest : NetcodeIntegrationTest { protected override int NumberOfClients => 1; + // TODO: [CmbServiceTests] Adapt to run with the service + protected override bool UseCMBService() + { + return false; + } + public ServerDisconnectsClientTest(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } protected override void OnCreatePlayerPrefab() From 1324963ccd425acbb76ed652f6d3e69c9fc93b84 Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 28 Apr 2025 14:56:42 -0400 Subject: [PATCH 21/30] All tests passing --- .../Editor/Analytics/NetcodeAnalytics.cs | 23 +++-- .../Runtime/NetcodeIntegrationTest.cs | 18 ++-- .../Runtime/NetcodeIntegrationTestHelpers.cs | 5 +- .../ExtendedNetworkShowAndHideTests.cs | 1 + .../Assets/DefaultNetworkPrefabs.asset | 96 +------------------ .../Assets/Tests/Runtime/AddressablesTests.cs | 1 + .../Assets/Tests/Runtime/AnalyticsTests.cs | 4 +- .../Runtime/Animation/NetworkAnimatorTests.cs | 4 +- .../InScenePlacedNetworkObjectTests.cs | 5 + testproject/testproject.sln.DotSettings | 2 + 10 files changed, 37 insertions(+), 122 deletions(-) create mode 100644 testproject/testproject.sln.DotSettings diff --git a/com.unity.netcode.gameobjects/Editor/Analytics/NetcodeAnalytics.cs b/com.unity.netcode.gameobjects/Editor/Analytics/NetcodeAnalytics.cs index 4f1c4f8084..0a18028c84 100644 --- a/com.unity.netcode.gameobjects/Editor/Analytics/NetcodeAnalytics.cs +++ b/com.unity.netcode.gameobjects/Editor/Analytics/NetcodeAnalytics.cs @@ -29,26 +29,21 @@ internal class NetcodeAnalytics : NetworkManager.NetcodeAnalytics /// Determines if we are running an integration test of the analytics integration /// internal static bool IsIntegrationTest = false; + internal static bool EnableIntegrationTestAnalytics = false; #if ENABLE_NGO_ANALYTICS_LOGGING internal static bool EnableLogging = true; #else internal static bool EnableLogging = false; #endif - // Preserves the analytics enabled flag - private bool m_OriginalAnalyticsEnabled; - internal override void OnOneTimeSetup() { - m_OriginalAnalyticsEnabled = EditorAnalytics.enabled; - // By default, we always disable analytics during integration testing - EditorAnalytics.enabled = false; + IsIntegrationTest = true; } internal override void OnOneTimeTearDown() { - // Reset analytics to the original value - EditorAnalytics.enabled = m_OriginalAnalyticsEnabled; + IsIntegrationTest = false; } internal List AnalyticsTestResults = new List(); @@ -80,6 +75,11 @@ internal override void ModeChanged(PlayModeStateChange playModeState, NetworkMan } } + private bool ShouldLogAnalytics() + { + return (IsIntegrationTest && EnableIntegrationTestAnalytics) || (!IsIntegrationTest && EditorAnalytics.enabled); + } + /// /// Editor Only /// Invoked when the session is started. @@ -87,8 +87,7 @@ internal override void ModeChanged(PlayModeStateChange playModeState, NetworkMan /// The instance when the session is started. internal override void SessionStarted(NetworkManager networkManager) { - // If analytics is disabled and we are not running an integration test, then exit early. - if (!EditorAnalytics.enabled && !IsIntegrationTest) + if (!ShouldLogAnalytics()) { return; } @@ -112,7 +111,7 @@ internal override void SessionStarted(NetworkManager networkManager) internal override void SessionStopped(NetworkManager networkManager) { // If analytics is disabled and we are not running an integration test or there are no sessions, then exit early. - if ((!EditorAnalytics.enabled && !IsIntegrationTest) || RecentSessions.Count == 0) + if (!ShouldLogAnalytics() || RecentSessions.Count == 0) { return; } @@ -135,7 +134,7 @@ internal override void SessionStopped(NetworkManager networkManager) private void UpdateAnalytics(NetworkManager networkManager) { // If analytics is disabled and we are not running an integration test or there are no sessions to process, then exit early. - if ((!EditorAnalytics.enabled && !IsIntegrationTest) || RecentSessions.Count == 0) + if (!ShouldLogAnalytics() || RecentSessions.Count == 0) { return; } diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index a3acaa2f9a..2b25b6786e 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -180,6 +180,10 @@ protected NetworkManager GetNonAuthorityNetworkManager() protected bool m_DistributedAuthority; protected NetworkTopologyTypes m_NetworkTopologyType = NetworkTopologyTypes.ClientServer; + /// + /// Indicates whether the currently running tests are targeting the hosted CMB Service + /// + /// Can only be true if returns true. protected bool m_UseCmbService; /// @@ -193,7 +197,6 @@ protected virtual bool UseCMBService() return true; #else var useCmbService = Environment.GetEnvironmentVariable("USE_CMB_SERVICE") ?? "unset"; - Debug.Log($"Using CMB service: {useCmbService}"); return useCmbService.ToLower() == "true"; #endif } @@ -398,6 +401,7 @@ public IEnumerator SetUp() { VerboseDebugLog.Clear(); VerboseDebug($"Entering {nameof(SetUp)}"); + m_NumberOfClients = NumberOfClients; NetcodeLogAssert = new NetcodeLogAssert(); if (m_EnableTimeTravel) { @@ -417,7 +421,6 @@ public IEnumerator SetUp() if (m_SetupIsACoroutine) { yield return NetcodeIntegrationTestHelpers.WaitBetweenCmbServiceTests(m_UseCmbService); - yield return OnSetup(); } else @@ -514,6 +517,7 @@ private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetw } m_ClientNetworkManagers = clientNetworkManagersList.ToArray(); + m_NumberOfClients = clientNetworkManagersList.Count; if (!m_UseCmbService) { @@ -948,6 +952,7 @@ protected IEnumerator StartServerAndClients() // When using the CMBService, we don't have a server, so get the appropriate authority network manager var authorityManager = GetAuthorityNetworkManager(); + VerboseDebug($"Starting with useCmbService: {m_UseCmbService}"); if (!NetcodeIntegrationTestHelpers.Start(m_UseHost, !m_UseCmbService, m_ServerNetworkManager, m_ClientNetworkManagers)) { Debug.LogError("Failed to start instances"); @@ -1005,7 +1010,7 @@ protected IEnumerator StartServerAndClients() } if (m_DistributedAuthority) { - foreach (var networkManager in m_ClientNetworkManagers) + foreach (var networkManager in m_NetworkManagers) { yield return WaitForConditionOrTimeOut(() => AllPlayerObjectClonesSpawned(networkManager)); AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); @@ -1099,11 +1104,8 @@ protected void StartServerAndClientsWithTimeTravel() foreach (var networkManager in m_NetworkManagers) { - if (networkManager.DistributedAuthorityMode) - { - WaitForConditionOrTimeOutWithTimeTravel(() => AllPlayerObjectClonesSpawned(m_ServerNetworkManager)); - AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!"); - } + WaitForConditionOrTimeOutWithTimeTravel(() => AllPlayerObjectClonesSpawned(m_ServerNetworkManager)); + AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!"); } } diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 6233898a0f..dca5de1b5d 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -210,7 +210,6 @@ private static void AddUnityTransport(NetworkManager networkManager, bool useCmb { unityTransport.ConnectionData.Address = k_TransportHost; unityTransport.ConnectionData.Port = k_TransportPort; - Debug.Log($"Using CmbService: {k_TransportHost}:{k_TransportPort}"); } // Set the NetworkConfig @@ -1023,13 +1022,13 @@ private static IEnumerator ExecuteWaitForHook(MessageHandleCheckWithResult check /// Waits for a second if the previous and current tests are using the hosted CMB Service. /// This is necessary as the CMB Service does not restart fast enough when running multiple tests. /// - /// + /// Whether the currently running test is running against a hosted CMB service instance /// An that will wait for a second public static IEnumerator WaitBetweenCmbServiceTests(bool isCmbServiceTest) { if (isCmbServiceTest && s_PreviousWasCmbServiceTest) { - Debug.Log("Waiting for CMB service to be shut down during test setup."); + // TODO: [CmbServiceTests] investigate whether we can reduce this timeout yield return new WaitForSeconds(1f); } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs index 2f569622bc..bb77ddf926 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ExtendedNetworkShowAndHideTests.cs @@ -19,6 +19,7 @@ public class ExtendedNetworkShowAndHideTests : NetcodeIntegrationTest private NetworkManager m_SpawnOwner; // TODO: [CmbServiceTests] Adapt to run with the service (can't control who becomes the session owner, needs a logic rework) + /// protected override bool UseCMBService() { return false; diff --git a/testproject/Assets/DefaultNetworkPrefabs.asset b/testproject/Assets/DefaultNetworkPrefabs.asset index 8414b17a83..d2ef286f81 100644 --- a/testproject/Assets/DefaultNetworkPrefabs.asset +++ b/testproject/Assets/DefaultNetworkPrefabs.asset @@ -11,7 +11,7 @@ MonoBehaviour: m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: e651dbb3fbac04af2b8f5abf007ddc23, type: 3} m_Name: DefaultNetworkPrefabs - m_EditorClassIdentifier: + m_EditorClassIdentifier: IsDefault: 1 List: - Override: 0 @@ -224,100 +224,6 @@ MonoBehaviour: SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 296612175404815451, guid: 9501b2f26df3884488e1699035fd634b, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 771575417923360811, guid: 44d487c39a833b445beef6e9e39a5731, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 6307603743893504780, guid: 0a46b240b37c5b74786b1938e8fd2eae, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 5911443254905569495, guid: 67daf9621f0d6d74c9a9bb4f81438061, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 296612175404815451, guid: 280da53b37f0d2546ab4d7b7da446545, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 5911443254905569495, guid: 12cead04031f30a4aaae7427341502fa, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 771575417923360811, guid: d7447e326e807754d81428939a14058f, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 6994329648695279756, guid: 5c4a10e01b6668147ba4ccda6a584181, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 479369275288778692, guid: 4d47e418fec779e4eb616d66d61c3231, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 5911443254905569495, guid: d88eb84e4c4e82b4b81d577a6c8e818e, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 479369275288778692, guid: ce3279d5e4f8e0342acdb2ce118f2be5, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 296612175404815451, guid: 61e89146f864ef2478af3da9d7dda1e2, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 6994329648695279756, guid: a67d0c2ee5d39fb4f9f0667f244d9e58, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 1923233254652950715, guid: d166e48a59e24924199f3ec3b2bc3b64, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 5507278367988661157, guid: c2db148a1fac379449a31b5430f4c6ac, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 296612175404815451, guid: fda785b5a15c5a94f9f3e93e635827a7, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 5911443254905569495, guid: 1e7fa5aea121ba0459459b497c2f03e8, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - Override: 0 Prefab: {fileID: 8188135024827620138, guid: c000e98bc12da2941a59ec61c260dd6a, type: 3} diff --git a/testproject/Assets/Tests/Runtime/AddressablesTests.cs b/testproject/Assets/Tests/Runtime/AddressablesTests.cs index 8af531b0b2..e8805d24ba 100644 --- a/testproject/Assets/Tests/Runtime/AddressablesTests.cs +++ b/testproject/Assets/Tests/Runtime/AddressablesTests.cs @@ -27,6 +27,7 @@ public class AddressablesTests : NetcodeIntegrationTest public AddressablesTests(HostOrServer hostOrServer) { + m_EnableVerboseDebug = true; m_UseHost = hostOrServer == HostOrServer.Host; } protected override NetworkManagerInstatiationMode OnSetIntegrationTestMode() diff --git a/testproject/Assets/Tests/Runtime/AnalyticsTests.cs b/testproject/Assets/Tests/Runtime/AnalyticsTests.cs index 3db6bc103f..a841333900 100644 --- a/testproject/Assets/Tests/Runtime/AnalyticsTests.cs +++ b/testproject/Assets/Tests/Runtime/AnalyticsTests.cs @@ -21,14 +21,14 @@ internal class AnalyticsTests : NetcodeIntegrationTest protected override IEnumerator OnSetup() { - NetcodeAnalytics.IsIntegrationTest = true; + NetcodeAnalytics.EnableIntegrationTestAnalytics = true; m_NetcodeAnalytics = Unity.Netcode.Editor.NetworkManagerHelper.Singleton.NetcodeAnalytics; yield return base.OnSetup(); } protected override IEnumerator OnTearDown() { - NetcodeAnalytics.IsIntegrationTest = false; + NetcodeAnalytics.EnableIntegrationTestAnalytics = false; yield return base.OnTearDown(); } diff --git a/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs b/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs index e0f3b384aa..7f59706b60 100644 --- a/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs +++ b/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs @@ -855,8 +855,8 @@ public IEnumerator LateJoinSynchronizationTest() Assert.True(success, $"Timed out waiting for the late joining client-side instance of {GetNetworkAnimatorName(m_AuthoritativeMode)} to be spawned!"); // Make sure the AnimatorTestHelper client side instances is the same as the TotalClients - var calculatedClients = (AnimatorTestHelper.ClientSideInstances.Count + (m_UseHost ? 1 : 0)); - Assert.True(calculatedClients == TotalClients, $"Incorrect number of clients: expected {calculatedClients}, actual {TotalClients}. network managers: {m_NetworkManagers.Length}, client side: {AnimatorTestHelper.ClientSideInstances.Count}"); + var calculatedClients = AnimatorTestHelper.ClientSideInstances.Count + (m_UseHost ? 1 : 0); + Assert.True(calculatedClients == TotalClients, $"Incorrect number of clients: actual {calculatedClients}, expected {TotalClients}. network managers: {m_NetworkManagers.Length}, client side: {AnimatorTestHelper.ClientSideInstances.Count}"); var lateJoinObjectInstance = AnimatorTestHelper.ClientSideInstances[m_ClientNetworkManagers[NumberOfClients].LocalClientId]; yield return WaitForConditionOrTimeOut(() => Mathf.Approximately(lateJoinObjectInstance.transform.rotation.eulerAngles.y, 180.0f)); diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs index 481ee15f8f..e71842ce3d 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs @@ -38,6 +38,7 @@ public InScenePlacedNetworkObjectTests(NetworkTopologyTypes networkTopologyType, protected override IEnumerator OnSetup() { NetworkObjectTestComponent.Reset(); + m_EnableVerboseDebug = true; NetworkObjectTestComponent.VerboseDebug = m_EnableVerboseDebug; m_CanStartServerAndClients = false; return base.OnSetup(); @@ -104,10 +105,14 @@ public IEnumerator InSceneNetworkObjectSynchAndSpawn([Values] DespawnMode despaw Assert.IsTrue(status == SceneEventProgressStatus.Started, $"When attempting to load scene {k_SceneToLoad} was returned the following progress status: {status}"); // We removed a client from the initial spawn and server should spawn too var clientCount = TotalClients - (m_UseHost ? 1 : 0); + // This verifies the scene loaded and the in-scene placed NetworkObjects spawned. yield return WaitForConditionOrTimeOut(() => NetworkObjectTestComponent.SpawnedInstances.Count == clientCount); AssertOnTimeout($"Timed out waiting for total spawned in-scene placed NetworkObjects to reach a count of {clientCount} and is currently {NetworkObjectTestComponent.SpawnedInstances.Count}"); + yield return WaitForConditionOrTimeOut(() => m_ServerSideSceneLoaded.IsValid() && m_ServerSideSceneLoaded.isLoaded); + AssertOnTimeout($"Timed out waiting for server to finish loading scene {k_SceneToLoad}!"); + // Get the server-side instance of the in-scene NetworkObject Assert.True(s_GlobalNetworkObjects.ContainsKey(m_ServerNetworkManager.LocalClientId), $"Could not find server instance of the test in-scene NetworkObject!"); var serverObject = NetworkObjectTestComponent.ServerNetworkObjectInstance; diff --git a/testproject/testproject.sln.DotSettings b/testproject/testproject.sln.DotSettings new file mode 100644 index 0000000000..b3f3826446 --- /dev/null +++ b/testproject/testproject.sln.DotSettings @@ -0,0 +1,2 @@ + + CMB \ No newline at end of file From 5b6266a67bd9eb4115fa96a1906b4b06807b13bc Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 28 Apr 2025 15:20:09 -0400 Subject: [PATCH 22/30] Run tests against release rust build --- .yamato/desktop-standalone-tests.yml | 2 +- Tools/CI/{rust.sh => run_cmb_service.sh} | 6 +++--- .../Runtime/NetcodeIntegrationTest.cs | 9 +++++++-- .../Runtime/NetcodeIntegrationTestHelpers.cs | 20 ------------------- .../Tests/Runtime/PlayerObjectTests.cs | 8 ++++---- 5 files changed, 15 insertions(+), 30 deletions(-) rename Tools/CI/{rust.sh => run_cmb_service.sh} (74%) diff --git a/.yamato/desktop-standalone-tests.yml b/.yamato/desktop-standalone-tests.yml index 93055247a8..d8c8944d95 100644 --- a/.yamato/desktop-standalone-tests.yml +++ b/.yamato/desktop-standalone-tests.yml @@ -91,7 +91,7 @@ desktop_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ commands: # If ubuntu, run rust echo server (This is needed ONLY for NGOv2.X because relates to Distributed Authority) {% if platform.name != "win" %} # Issues with win and mac are tracked in MTT-11606 - - ./Tools/CI/rust.sh + - ./Tools/CI/run_cmb_service.sh {% endif %} - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor {% if backend == "il2cpp" %} -c il2cpp {% endif %} {% if platform.name == "mac" %} --arch arm64 {% endif %} # For macOS we use ARM64 models diff --git a/Tools/CI/rust.sh b/Tools/CI/run_cmb_service.sh similarity index 74% rename from Tools/CI/rust.sh rename to Tools/CI/run_cmb_service.sh index dedacaad96..8e2520042b 100755 --- a/Tools/CI/rust.sh +++ b/Tools/CI/run_cmb_service.sh @@ -12,8 +12,8 @@ cargo build --example ngo_echo_server # Run the echo server in the background - this will reuse the artifacts from the build cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & -# Build the standalone server -cargo build +# Build a release version of the standalone server +cargo build --release --locked # Run the standalone server on an infinite loop in the background -while :; do cargo run -- --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 60m; done & +while :; do ./target/release/comb-server --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 60m; done & diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 2b25b6786e..e37767f37b 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -96,9 +96,14 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj } } - protected int TotalClients => m_UseHost ? NumberOfClients + 1 : NumberOfClients; + /// + /// Total number of clients that should be connected at any point during a test + /// + protected int TotalClients => m_UseHost ? m_NumberOfClients + 1 : m_NumberOfClients; protected const uint k_DefaultTickRate = 30; + + private int m_NumberOfClients; protected abstract int NumberOfClients { get; } /// @@ -420,7 +425,7 @@ public IEnumerator SetUp() if (m_SetupIsACoroutine) { - yield return NetcodeIntegrationTestHelpers.WaitBetweenCmbServiceTests(m_UseCmbService); + // yield return NetcodeIntegrationTestHelpers.WaitBetweenCmbServiceTests(m_UseCmbService); yield return OnSetup(); } else diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index dca5de1b5d..107bcb237d 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -1015,26 +1015,6 @@ private static IEnumerator ExecuteWaitForHook(MessageHandleCheckWithResult check result.Result = res; } - - private static bool s_PreviousWasCmbServiceTest; - - /// - /// Waits for a second if the previous and current tests are using the hosted CMB Service. - /// This is necessary as the CMB Service does not restart fast enough when running multiple tests. - /// - /// Whether the currently running test is running against a hosted CMB service instance - /// An that will wait for a second - public static IEnumerator WaitBetweenCmbServiceTests(bool isCmbServiceTest) - { - if (isCmbServiceTest && s_PreviousWasCmbServiceTest) - { - // TODO: [CmbServiceTests] investigate whether we can reduce this timeout - yield return new WaitForSeconds(1f); - } - - s_PreviousWasCmbServiceTest = isCmbServiceTest; - } - #if UNITY_EDITOR public static void SetRefreshAllPrefabsCallback(Action scenesProcessed) { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs index 118a8336c7..2a3303e5e1 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs @@ -21,7 +21,7 @@ internal class PlayerObjectTests : NetcodeIntegrationTest // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart protected override bool UseCMBService() { - return false; + return true; } public PlayerObjectTests(HostOrServer hostOrServer) : base(hostOrServer) { } @@ -78,7 +78,7 @@ internal class PlayerSpawnNoObserversTest : NetcodeIntegrationTest // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart protected override bool UseCMBService() { - return false; + return true; } public PlayerSpawnNoObserversTest(HostOrServer hostOrServer) : base(hostOrServer) { } @@ -144,7 +144,7 @@ internal class PlayerSpawnPositionTests : IntegrationTestWithApproximation // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart protected override bool UseCMBService() { - return false; + return true; } public PlayerSpawnPositionTests(HostOrServer hostOrServer) : base(hostOrServer) { } @@ -218,7 +218,7 @@ internal class PlayerSpawnAndDespawnTests : NetcodeIntegrationTest // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart protected override bool UseCMBService() { - return false; + return true; } public PlayerSpawnAndDespawnTests(HostOrServer hostOrServer) : base(hostOrServer) { } From 82138d50c92ead01a088f0fa9f7f7dc280e3f91a Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 28 Apr 2025 21:32:06 -0400 Subject: [PATCH 23/30] Fix InScenePlacedNetworkObjectTests --- .../Runtime/NetcodeIntegrationTest.cs | 9 +- .../Runtime/NetcodeIntegrationTestHelpers.cs | 3 + .../Assets/Tests/Runtime/AddressablesTests.cs | 1 - .../InScenePlacedNetworkObjectTests.cs | 96 ++++--------------- .../NestedNetworkTransformTests.cs | 2 - testproject/testproject.sln.DotSettings | 4 +- 6 files changed, 35 insertions(+), 80 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index e37767f37b..7f62364e6d 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -425,7 +425,6 @@ public IEnumerator SetUp() if (m_SetupIsACoroutine) { - // yield return NetcodeIntegrationTestHelpers.WaitBetweenCmbServiceTests(m_UseCmbService); yield return OnSetup(); } else @@ -650,6 +649,11 @@ private bool AllPlayerObjectClonesSpawned(NetworkManager joinedClient) continue; } + // if (networkManager.SpawnManager == null) + // { + // return false; + // } + var playerObjectRelative = networkManager.SpawnManager.PlayerObjects.FirstOrDefault(c => c.OwnerClientId == joinedClient.LocalClientId); if (playerObjectRelative == null) { @@ -963,6 +967,7 @@ protected IEnumerator StartServerAndClients() Debug.LogError("Failed to start instances"); Assert.Fail("Failed to start instances"); } + Debug.Log($"Server has SpawnManager after start : {m_ServerNetworkManager.SpawnManager != null}"); // When scene management is enabled, we need to re-apply the scenes populated list since we have overriden the ISceneManagerHandler // imeplementation at this point. This assures any pre-loaded scenes will be automatically assigned to the server and force clients @@ -990,6 +995,7 @@ protected IEnumerator StartServerAndClients() yield return WaitForClientsConnectedOrTimeOut(); AssertOnTimeout($"{nameof(StartServerAndClients)} timed out waiting for all clients to be connected!\n {m_InternalErrorLog}"); + Debug.Log($"all clients should be connected. SpawnManger exists: {m_ServerNetworkManager.SpawnManager != null}"); if (m_UseHost || m_ServerNetworkManager.IsHost) { @@ -1017,6 +1023,7 @@ protected IEnumerator StartServerAndClients() { foreach (var networkManager in m_NetworkManagers) { + Debug.Log($"Attempting to check spawn manager of client: {networkManager.LocalClientId}. Has spawned manager: {networkManager.SpawnManager != null}"); yield return WaitForConditionOrTimeOut(() => AllPlayerObjectClonesSpawned(networkManager)); AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); } diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs index 107bcb237d..579e62b1c4 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTestHelpers.cs @@ -341,6 +341,9 @@ public static void StopOneClient(NetworkManager clientToStop, bool destroy = tru /// /// Starts one single client and makes sure to register the required hooks and handlers /// + /// + /// Do not call this function directly. Use instead. + /// /// The NetworkManager instance to start public static void StartOneClient(NetworkManager clientToStart) { diff --git a/testproject/Assets/Tests/Runtime/AddressablesTests.cs b/testproject/Assets/Tests/Runtime/AddressablesTests.cs index e8805d24ba..8af531b0b2 100644 --- a/testproject/Assets/Tests/Runtime/AddressablesTests.cs +++ b/testproject/Assets/Tests/Runtime/AddressablesTests.cs @@ -27,7 +27,6 @@ public class AddressablesTests : NetcodeIntegrationTest public AddressablesTests(HostOrServer hostOrServer) { - m_EnableVerboseDebug = true; m_UseHost = hostOrServer == HostOrServer.Host; } protected override NetworkManagerInstatiationMode OnSetIntegrationTestMode() diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs index e71842ce3d..bff15bcdc0 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs @@ -18,14 +18,14 @@ namespace TestProject.RuntimeTests [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Server)] public class InScenePlacedNetworkObjectTests : IntegrationTestWithApproximation { - protected override int NumberOfClients => 3; + protected override int NumberOfClients => 2; private const string k_SceneToLoad = "InSceneNetworkObject"; private const string k_InSceneUnder = "InSceneUnderGameObject"; private const string k_InSceneUnderWithNT = "InSceneUnderGameObjectWithNT"; private Scene m_ServerSideSceneLoaded; - private bool m_CanStartServerAndClients; private string m_SceneLoading = k_SceneToLoad; + private NetworkManager m_LateJoinClient; // TODO: [CmbServiceTests] Adapt to run with the service protected override bool UseCMBService() @@ -38,9 +38,7 @@ public InScenePlacedNetworkObjectTests(NetworkTopologyTypes networkTopologyType, protected override IEnumerator OnSetup() { NetworkObjectTestComponent.Reset(); - m_EnableVerboseDebug = true; NetworkObjectTestComponent.VerboseDebug = m_EnableVerboseDebug; - m_CanStartServerAndClients = false; return base.OnSetup(); } @@ -52,12 +50,14 @@ protected override IEnumerator OnSetup() /// protected override IEnumerator OnTearDown() { + m_LateJoinClient = null; yield return CleanUpLoadedScene(); } - protected override bool CanStartServerAndClients() + protected override void OnNewClientCreated(NetworkManager networkManager) { - return m_CanStartServerAndClients; + m_LateJoinClient = networkManager; + base.OnNewClientCreated(networkManager); } public enum DespawnMode @@ -81,30 +81,11 @@ public IEnumerator InSceneNetworkObjectSynchAndSpawn([Values] DespawnMode despaw Assert.Ignore($"Test ignored as DeferDespawn is only valid with Distributed Authority mode."); } - NetworkObjectTestComponent.VerboseDebug = false; - // Because despawning a client will cause it to shutdown and clean everything in the - // scene hierarchy, we have to prevent one of the clients from spawning initially before - // we test synchronizing late joining clients with despawned in-scene placed NetworkObjects. - // So, we prevent the automatic starting of the server and clients, remove the client we - // will be targeting to join late from the m_ClientNetworkManagers array, start the server - // and the remaining client, despawn the in-scene NetworkObject, and then start and synchronize - // the clientToTest. - var clientToTest = m_ClientNetworkManagers[2]; - var clients = m_ClientNetworkManagers.ToList(); - clients.Remove(clientToTest); - m_ClientNetworkManagers = clients.ToArray(); - m_CanStartServerAndClients = true; - NetworkObjectTestComponent.Reset(); - yield return StartServerAndClients(); - clients.Add(clientToTest); - m_ClientNetworkManagers = clients.ToArray(); - - m_ServerNetworkManager.SceneManager.OnSceneEvent += Server_OnSceneEvent; var status = m_ServerNetworkManager.SceneManager.LoadScene(k_SceneToLoad, LoadSceneMode.Additive); Assert.IsTrue(status == SceneEventProgressStatus.Started, $"When attempting to load scene {k_SceneToLoad} was returned the following progress status: {status}"); - // We removed a client from the initial spawn and server should spawn too - var clientCount = TotalClients - (m_UseHost ? 1 : 0); + + var clientCount = NumberOfClients + 1; // This verifies the scene loaded and the in-scene placed NetworkObjects spawned. yield return WaitForConditionOrTimeOut(() => NetworkObjectTestComponent.SpawnedInstances.Count == clientCount); @@ -136,24 +117,24 @@ public IEnumerator InSceneNetworkObjectSynchAndSpawn([Values] DespawnMode despaw // Now late join a client NetworkObjectTestComponent.OnInSceneObjectDespawned += OnInSceneObjectDespawned; - NetcodeIntegrationTestHelpers.StartOneClient(clientToTest); + yield return CreateAndStartNewClient(); // Spawned another client clientCount++; - yield return WaitForConditionOrTimeOut(() => (clientToTest.IsConnectedClient && clientToTest.IsListening)); - AssertOnTimeout($"Timed out waiting for {clientToTest.name} to reconnect!"); + yield return WaitForConditionOrTimeOut(() => (m_LateJoinClient.IsConnectedClient && m_LateJoinClient.IsListening)); + AssertOnTimeout($"Timed out waiting for {m_LateJoinClient.name} to connect!"); yield return s_DefaultWaitForTick; // Make sure the late-joining client's in-scene placed NetworkObject received the despawn notification during synchronization - Assert.IsNotNull(m_JoinedClientDespawnedNetworkObject, $"{clientToTest.name} did not despawn the in-scene placed NetworkObject when connecting and synchronizing!"); + Assert.IsNotNull(m_JoinedClientDespawnedNetworkObject, $"{m_LateJoinClient.name} did not despawn the in-scene placed NetworkObject when connecting and synchronizing!"); // Update the newly joined client information ClientNetworkManagerPostStartInit(); // We should still have no spawned in-scene placed NetworkObjects at this point yield return WaitForConditionOrTimeOut(() => NetworkObjectTestComponent.SpawnedInstances.Count == 0); - AssertOnTimeout($"{clientToTest.name} spawned in-scene placed NetworkObject!"); + AssertOnTimeout($"{m_LateJoinClient.name} spawned in-scene placed NetworkObject!"); // Now test that the despawned in-scene placed NetworkObject can be re-spawned (without having been registered as a NetworkPrefab) serverObject.Spawn(); @@ -185,22 +166,6 @@ public IEnumerator InSceneNetworkObjectSynchAndSpawn([Values] DespawnMode despaw [UnityTest] public IEnumerator ParentedInSceneObjectLateJoiningClient() { - // Because despawning a client will cause it to shutdown and clean everything in the - // scene hierarchy, we have to prevent one of the clients from spawning initially before - // we test synchronizing late joining clients. - // So, we prevent the automatic starting of the server and clients, remove the client we - // will be targeting to join late from the m_ClientNetworkManagers array, start the server - // and the remaining client, despawn the in-scene NetworkObject, and then start and synchronize - // the clientToTest. - var clientToTest = m_ClientNetworkManagers[2]; - var clients = m_ClientNetworkManagers.ToList(); - clients.Remove(clientToTest); - m_ClientNetworkManagers = clients.ToArray(); - m_CanStartServerAndClients = true; - yield return StartServerAndClients(); - clients.Add(clientToTest); - m_ClientNetworkManagers = clients.ToArray(); - NetworkObjectTestComponent.ServerNetworkObjectInstance = null; m_ClientNetworkManagers[0].SceneManager.OnSceneEvent += OnSceneEvent; @@ -232,9 +197,9 @@ public IEnumerator ParentedInSceneObjectLateJoiningClient() yield return WaitForConditionOrTimeOut(() => firstClientInSceneObjectInstance.transform.parent != null && firstClientInSceneObjectInstance.transform.parent == clientSidePlayer.transform); AssertOnTimeout($"Timed out waiting for the client-side id ({m_ClientNetworkManagers[0].LocalClientId}) server player transform to be set on the client-side in-scene object!"); // Now late join a client - NetcodeIntegrationTestHelpers.StartOneClient(clientToTest); - yield return WaitForConditionOrTimeOut(() => (clientToTest.IsConnectedClient && clientToTest.IsListening)); - AssertOnTimeout($"Timed out waiting for {clientToTest.name} to reconnect!"); + yield return CreateAndStartNewClient(); + yield return WaitForConditionOrTimeOut(() => (m_LateJoinClient.IsConnectedClient && m_LateJoinClient.IsListening)); + AssertOnTimeout($"Timed out waiting for {m_LateJoinClient.name} to reconnect!"); yield return s_DefaultWaitForTick; @@ -245,7 +210,7 @@ public IEnumerator ParentedInSceneObjectLateJoiningClient() Assert.IsNotNull(lateJoinClientInSceneObjectInstance, $"Could not get the client-side registration of {nameof(NetworkObjectTestComponent)} for the late joining client!"); // Now get the late-joining client's instance for the server player - clientSidePlayer = m_PlayerNetworkObjects[clientToTest.LocalClientId][clientSidePlayer.OwnerClientId]; + clientSidePlayer = m_PlayerNetworkObjects[m_LateJoinClient.LocalClientId][clientSidePlayer.OwnerClientId]; // Validate the late joined client's in-scene NetworkObject is parented to the server-side player yield return WaitForConditionOrTimeOut(() => lateJoinClientInSceneObjectInstance.transform.parent != null && lateJoinClientInSceneObjectInstance.transform.parent == clientSidePlayer.transform); @@ -360,11 +325,8 @@ public IEnumerator EnableDisableInSceneObjectTests() // Enabled disabling the NetworkObject when it is despawned NetworkObjectTestComponent.DisableOnDespawn = true; // Set the number of instances to expect - m_NumberOfInstancesCheck = NumberOfClients + (m_UseHost ? 1 : 0); + m_NumberOfInstancesCheck = TotalClients; - // Start the host and clients and load the in-scene object scene additively - m_CanStartServerAndClients = true; - yield return StartServerAndClients(); m_ServerNetworkManager.SceneManager.OnLoadEventCompleted += SceneManager_OnLoadEventCompleted; m_ServerNetworkManager.SceneManager.LoadScene(k_SceneToLoad, LoadSceneMode.Additive); yield return WaitForConditionOrTimeOut(() => m_AllClientsLoadedScene); @@ -499,28 +461,12 @@ public IEnumerator ParentedInSceneObjectUnderGameObject([Values(k_InSceneUnder, var useNetworkTransform = m_SceneLoading == k_InSceneUnderWithNT; m_SceneLoading = inSceneUnderToLoad; - // Because despawning a client will cause it to shutdown and clean everything in the - // scene hierarchy, we have to prevent one of the clients from spawning initially before - // we test synchronizing late joining clients. - // So, we prevent the automatic starting of the server and clients, remove the client we - // will be targeting to join late from the m_ClientNetworkManagers array, start the server - // and the remaining client, despawn the in-scene NetworkObject, and then start and synchronize - // the clientToTest. - var clientToTest = m_ClientNetworkManagers[1]; - var clients = m_ClientNetworkManagers.ToList(); // Note: This test is a modified copy of ParentedInSceneObjectLateJoiningClient. // The 1st client is being ignored in this test and the focus is primarily on the late joining // 2nd client after adjustments have been made to the child NetworkBehaviour and if applicable // NetworkTransform. - clients.Remove(clientToTest); - m_ClientNetworkManagers = clients.ToArray(); - m_CanStartServerAndClients = true; - yield return StartServerAndClients(); - clients.Add(clientToTest); - m_ClientNetworkManagers = clients.ToArray(); - NetworkObjectTestComponent.ServerNetworkObjectInstance = null; m_ClientNetworkManagers[0].SceneManager.OnSceneEvent += OnSceneEvent; @@ -545,9 +491,9 @@ public IEnumerator ParentedInSceneObjectUnderGameObject([Values(k_InSceneUnder, } // Now late join a client - NetcodeIntegrationTestHelpers.StartOneClient(clientToTest); - yield return WaitForConditionOrTimeOut(() => (clientToTest.IsConnectedClient && clientToTest.IsListening)); - AssertOnTimeout($"Timed out waiting for {clientToTest.name} to reconnect!"); + yield return CreateAndStartNewClient(); + yield return WaitForConditionOrTimeOut(() => (m_LateJoinClient.IsConnectedClient && m_LateJoinClient.IsListening)); + AssertOnTimeout($"Timed out waiting for {m_LateJoinClient.name} to reconnect!"); yield return s_DefaultWaitForTick; diff --git a/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs b/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs index dc5b2b4e9d..b99e044727 100644 --- a/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkTransform/NestedNetworkTransformTests.cs @@ -360,7 +360,6 @@ public void NestedNetworkTransformSynchronization() { var timeStarted = Time.realtimeSinceStartup; var startFrameCount = Time.frameCount; - m_EnableVerboseDebug = true; AutomatedPlayerMover.StopMovement = false; ChildMoverManager.StopMovement = false; m_ValidationErrors = new StringBuilder(); @@ -399,7 +398,6 @@ public void NestedNetworkTransformSynchronization() // If we have 5 precision failures in a row and fail to correct, then fail this test if (precisionFailures > k_MaximumPrecisionFailures) { - m_EnableVerboseDebug = true; DisplayFrameAndTimeInfo(timeStarted, startFrameCount, false); Assert.True(success, $"[{m_Interpolation}][{m_Precision}][{m_Authority}][Iteration: {i}]\n[Precision Failure] Exceeded Precision Failure Count " + $"({precisionFailures})\n Timed out waiting for all nested NetworkTransform cloned instances to match!\n{m_ValidationErrors}"); diff --git a/testproject/testproject.sln.DotSettings b/testproject/testproject.sln.DotSettings index b3f3826446..bbd7eada00 100644 --- a/testproject/testproject.sln.DotSettings +++ b/testproject/testproject.sln.DotSettings @@ -1,2 +1,4 @@  - CMB \ No newline at end of file + CMB + DDOL + True \ No newline at end of file From 666e1d4ac1aaf1e95c190f301677360f917be492 Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 28 Apr 2025 21:32:27 -0400 Subject: [PATCH 24/30] Only log cmb error logs --- Tools/CI/run_cmb_service.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/CI/run_cmb_service.sh b/Tools/CI/run_cmb_service.sh index 8e2520042b..221f063665 100755 --- a/Tools/CI/run_cmb_service.sh +++ b/Tools/CI/run_cmb_service.sh @@ -16,4 +16,4 @@ cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & cargo build --release --locked # Run the standalone server on an infinite loop in the background -while :; do ./target/release/comb-server --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 60m; done & +while :; do ./target/release/comb-server -l error --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 60m; done & From 48aa4cdaab85f8d3c841e8389ea001a9ec3ad607 Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 28 Apr 2025 22:49:55 -0400 Subject: [PATCH 25/30] remove log lines --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index 7f62364e6d..e0a077d469 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -649,11 +649,6 @@ private bool AllPlayerObjectClonesSpawned(NetworkManager joinedClient) continue; } - // if (networkManager.SpawnManager == null) - // { - // return false; - // } - var playerObjectRelative = networkManager.SpawnManager.PlayerObjects.FirstOrDefault(c => c.OwnerClientId == joinedClient.LocalClientId); if (playerObjectRelative == null) { @@ -967,7 +962,6 @@ protected IEnumerator StartServerAndClients() Debug.LogError("Failed to start instances"); Assert.Fail("Failed to start instances"); } - Debug.Log($"Server has SpawnManager after start : {m_ServerNetworkManager.SpawnManager != null}"); // When scene management is enabled, we need to re-apply the scenes populated list since we have overriden the ISceneManagerHandler // imeplementation at this point. This assures any pre-loaded scenes will be automatically assigned to the server and force clients @@ -995,7 +989,6 @@ protected IEnumerator StartServerAndClients() yield return WaitForClientsConnectedOrTimeOut(); AssertOnTimeout($"{nameof(StartServerAndClients)} timed out waiting for all clients to be connected!\n {m_InternalErrorLog}"); - Debug.Log($"all clients should be connected. SpawnManger exists: {m_ServerNetworkManager.SpawnManager != null}"); if (m_UseHost || m_ServerNetworkManager.IsHost) { @@ -1023,7 +1016,6 @@ protected IEnumerator StartServerAndClients() { foreach (var networkManager in m_NetworkManagers) { - Debug.Log($"Attempting to check spawn manager of client: {networkManager.LocalClientId}. Has spawned manager: {networkManager.SpawnManager != null}"); yield return WaitForConditionOrTimeOut(() => AllPlayerObjectClonesSpawned(networkManager)); AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!\n {m_InternalErrorLog}"); } From 7611a51e6233e0dbbe0a4ded5510f3245dea75b4 Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 28 Apr 2025 22:50:18 -0400 Subject: [PATCH 26/30] update port env variable --- .yamato/desktop-standalone-tests.yml | 2 +- Tools/CI/run_cmb_service.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.yamato/desktop-standalone-tests.yml b/.yamato/desktop-standalone-tests.yml index d8c8944d95..e4be195f95 100644 --- a/.yamato/desktop-standalone-tests.yml +++ b/.yamato/desktop-standalone-tests.yml @@ -81,7 +81,7 @@ desktop_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ {% if platform.name != "win" %} # Issues with win and mac are tracked in MTT-11606 variables: ECHO_SERVER_PORT: "7788" - COMB_SERVER_PORT: "7789" + CMB_SERVICE_PORT: "7799" # Set this to ensure the DA codec tests will fail if they cannot connect to the echo-server # The default is to ignore the codec tests if the echo-server fails to connect ENSURE_CODEC_TESTS: "true" diff --git a/Tools/CI/run_cmb_service.sh b/Tools/CI/run_cmb_service.sh index 221f063665..28d50e1f3c 100755 --- a/Tools/CI/run_cmb_service.sh +++ b/Tools/CI/run_cmb_service.sh @@ -16,4 +16,4 @@ cargo run --example ngo_echo_server -- --port $ECHO_SERVER_PORT & cargo build --release --locked # Run the standalone server on an infinite loop in the background -while :; do ./target/release/comb-server -l error --metrics-port 5000 standalone --port $COMB_SERVER_PORT -t 60m; done & +while :; do ./target/release/comb-server -l error --metrics-port 5000 standalone --port $CMB_SERVICE_PORT -t 60m; done & From 4ef95a28cf188f9a2841c360a98cafdff262af53 Mon Sep 17 00:00:00 2001 From: Emma Date: Tue, 29 Apr 2025 01:30:01 -0400 Subject: [PATCH 27/30] remove connection test --- .../DistributedAuthorityConnectionTest.cs | 65 ------------------- ...DistributedAuthorityConnectionTest.cs.meta | 3 - 2 files changed, 68 deletions(-) delete mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs delete mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs deleted file mode 100644 index b23a7509db..0000000000 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections; -using NUnit.Framework; -using Unity.Netcode.TestHelpers.Runtime; -using UnityEngine; -using UnityEngine.TestTools; - -namespace Unity.Netcode.RuntimeTests -{ - internal class DistributedAuthorityConnectionTest : NetcodeIntegrationTest - { - protected override int NumberOfClients => 1; - - // Set the network topology to distributed authority for all tests - protected override NetworkTopologyTypes OnGetNetworkTopologyType() => NetworkTopologyTypes.DistributedAuthority; - - public DistributedAuthorityConnectionTest() : base(HostOrServer.DAHost) { } - - private GameObject m_SpawnObject; - - protected override bool UseCMBService() - { - return true; - } - - - /// - /// Modify NetworkManager instances for settings specific to tests - /// - protected override void OnServerAndClientsCreated() - { - foreach (var client in m_ClientNetworkManagers) - { - client.NetworkConfig.EnableSceneManagement = false; - - // Validate we are in distributed authority mode with client side spawning and using CMB Service - Assert.True(client.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, "Distributed authority topology is not set!"); - Assert.True(client.CMBServiceConnection, "CMBServiceConnection is not set!"); - } - - // Create a prefab for creating and destroying tests (auto-registers with NetworkManagers) - m_SpawnObject = CreateNetworkObjectPrefab("TestObject"); - } - [UnityTest] - public IEnumerator CreateObjectNew() - { - SpawnObject(m_SpawnObject, m_ClientNetworkManagers[0]); - - yield return WaitForConditionOrTimeOut(CheckObjectExists); - AssertOnTimeout("failed to spawn object!"); - } - - - private bool CheckObjectExists() - { - foreach (var client in m_ClientNetworkManagers) - { - if (!s_GlobalNetworkObjects.ContainsKey(client.LocalClientId)) - { - return false; - } - } - return true; - } - } -} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta deleted file mode 100644 index f48f5f3f2c..0000000000 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributedAuthorityConnectionTest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: e31522b786a5480fac291bbbc17e0d31 -timeCreated: 1745437205 \ No newline at end of file From 4a3804cc528d5dc65ebffe6607c5674207ff1f08 Mon Sep 17 00:00:00 2001 From: Emma Date: Tue, 29 Apr 2025 01:30:34 -0400 Subject: [PATCH 28/30] fix bug in StartServerAndClientsWithTimeTravel --- .../TestHelpers/Runtime/NetcodeIntegrationTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index e0a077d469..d3d3cce74e 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -1105,10 +1105,9 @@ protected void StartServerAndClientsWithTimeTravel() if (m_DistributedAuthority) { - foreach (var networkManager in m_NetworkManagers) { - WaitForConditionOrTimeOutWithTimeTravel(() => AllPlayerObjectClonesSpawned(m_ServerNetworkManager)); + WaitForConditionOrTimeOutWithTimeTravel(() => AllPlayerObjectClonesSpawned(networkManager)); AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!"); } } From 41307ba744f6e53fcd661cf4531f172c8f400924 Mon Sep 17 00:00:00 2001 From: Emma Date: Tue, 29 Apr 2025 09:18:45 -0400 Subject: [PATCH 29/30] cleanup --- .yamato/_triggers.yml | 27 +++++++++---------- .../Tests/Runtime/PlayerObjectTests.cs | 21 --------------- testproject/testproject.sln.DotSettings | 4 --- 3 files changed, 13 insertions(+), 39 deletions(-) delete mode 100644 testproject/testproject.sln.DotSettings diff --git a/.yamato/_triggers.yml b/.yamato/_triggers.yml index e3b3add45d..cbbbaf48aa 100644 --- a/.yamato/_triggers.yml +++ b/.yamato/_triggers.yml @@ -42,21 +42,21 @@ # In order to have better coverage we run desktop standalone tests with different configurations which allows to mostly cover for different platforms, scripting backends and editor versions. # This job will FIRST run "run_quick_checks" jobs (defined in _run-all.yml) since it's the dependency of project pack jobs which is on the lowest dependency tier. This runs the fastest checks (like PVP or code standards) and ONLY IF those pass it will run the rest of the tests. # This optimization allows to speed up feedback look for any "obvious" errors and save resources. -# Since standards job is a part of initial checks it's not present as direct dependency here +# Since standards job is a part of initial checks it's not present as direct dependency here!!!!!!!!!!!!!!!!!!!! pull_request_trigger: name: Pull Request Trigger (develop, develop-2.0.0, & release branches) dependencies: - # # Run package EditMode and Playmode package tests on trunk - # - .yamato/_run-all.yml#run_all_package_tests_trunk - # # Run package EditMode and Playmode package tests on minimum supported editor (6000.0 in case of NGOv2.X) - # - .yamato/_run-all.yml#run_all_package_tests_6000 - # # Run project EditMode and PLaymode project tests on trunk - # - .yamato/_run-all.yml#run_all_project_tests_trunk - # # Run project EditMode and PLaymode project tests on minimum supported editor (6000.0 in case of NGOv2.X) - # - .yamato/_run-all.yml#run_all_project_tests_6000 - # # Run standalone test with mixture of parameters to make sure there are no obvious issues with most common platform (for example --fail-on-assert option is not present with package/project tests). We run 2 different combinations with different platform/editor/scripting backend. - - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_trunk - # - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_win_mono_6000.0 + # Run package EditMode and Playmode package tests on trunk + - .yamato/_run-all.yml#run_all_package_tests_trunk + # Run package EditMode and Playmode package tests on minimum supported editor (6000.0 in case of NGOv2.X) + - .yamato/_run-all.yml#run_all_package_tests_6000 + # Run project EditMode and PLaymode project tests on trunk + - .yamato/_run-all.yml#run_all_project_tests_trunk + # Run project EditMode and PLaymode project tests on minimum supported editor (6000.0 in case of NGOv2.X) + - .yamato/_run-all.yml#run_all_project_tests_6000 + # Run standalone test. We run it only on Ubuntu since it's the fastest machine, and it was noted that for example distribution on macOS is taking 40m since we switched to Apple Silicon + # Coverage on other standalone machines is present in Nightly job so it's enough to not run all of them for PRs + - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_6000.0 triggers: cancel_old_ci: true pull_requests: @@ -81,7 +81,6 @@ develop_nightly: dependencies: # Run project standards to verify package/default project - .yamato/project-standards.yml#standards_ubuntu_testproject_trunk - - .yamato/project-standards.yml#standards_ubuntu_testproject_6000.0 # Run APV jobs to make sure the change won't break any dependants - .yamato/wrench/preview-a-p-v.yml#all_preview_apv_jobs # Run package EditMode and Playmode tests on desktop platforms on trunk and 6000.0 @@ -134,4 +133,4 @@ develop_weekly_trunk: # Build player for webgl platform on trunk - .yamato/_run-all.yml#run_all_webgl_builds # Run code coverage test - - .yamato/code-coverage.yml#code_coverage_ubuntu_trunk + - .yamato/code-coverage.yml#code_coverage_ubuntu_trunk \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs index 2a3303e5e1..e011d94c8a 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/PlayerObjectTests.cs @@ -18,11 +18,6 @@ internal class PlayerObjectTests : NetcodeIntegrationTest protected GameObject m_NewPlayerToSpawn; - // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart - protected override bool UseCMBService() - { - return true; - } public PlayerObjectTests(HostOrServer hostOrServer) : base(hostOrServer) { } protected override void OnServerAndClientsCreated() @@ -75,11 +70,6 @@ internal class PlayerSpawnNoObserversTest : NetcodeIntegrationTest { protected override int NumberOfClients => 2; - // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart - protected override bool UseCMBService() - { - return true; - } public PlayerSpawnNoObserversTest(HostOrServer hostOrServer) : base(hostOrServer) { } protected override bool ShouldCheckForSpawnedPlayers() @@ -141,11 +131,6 @@ internal class PlayerSpawnPositionTests : IntegrationTestWithApproximation { protected override int NumberOfClients => 2; - // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart - protected override bool UseCMBService() - { - return true; - } public PlayerSpawnPositionTests(HostOrServer hostOrServer) : base(hostOrServer) { } private Vector3 m_PlayerPosition; @@ -215,12 +200,6 @@ internal class PlayerSpawnAndDespawnTests : NetcodeIntegrationTest private StringBuilder m_ErrorLog = new StringBuilder(); - // TODO: [CmbServiceTests] Clients are disconnecting in a way that makes the cmb service slow to close and restart - protected override bool UseCMBService() - { - return true; - } - public PlayerSpawnAndDespawnTests(HostOrServer hostOrServer) : base(hostOrServer) { } private bool ValidateObservers(ulong playerClientId, NetworkObject player, ref List networkManagers) diff --git a/testproject/testproject.sln.DotSettings b/testproject/testproject.sln.DotSettings deleted file mode 100644 index bbd7eada00..0000000000 --- a/testproject/testproject.sln.DotSettings +++ /dev/null @@ -1,4 +0,0 @@ - - CMB - DDOL - True \ No newline at end of file From eaf54a19a9e3925b85daac561c41d67975295aa7 Mon Sep 17 00:00:00 2001 From: Emma Date: Tue, 29 Apr 2025 11:41:07 -0400 Subject: [PATCH 30/30] further cleanup --- .../Runtime/Spawning/NetworkSpawnManager.cs | 8 --- .../Runtime/NetcodeIntegrationTest.cs | 51 +++++++++++++++---- .../Tests/Runtime/DisconnectTests.cs | 19 +++---- .../DistributeObjectsTests.cs | 1 - .../ParentChildDistibutionTests.cs | 43 ++++++---------- .../Tests/Runtime/NetworkVisibilityTests.cs | 9 ---- .../Runtime/ParentingDuringSpawnTests.cs | 8 --- .../Prefabs/NetworkPrefabOverrideTests.cs | 2 +- pvpExceptions.json | 7 --- .../Assets/DefaultNetworkPrefabs.asset | 14 +---- .../Runtime/Animation/NetworkAnimatorTests.cs | 2 +- 11 files changed, 70 insertions(+), 94 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs index b8190ccbaf..50c1e008d0 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs @@ -2229,14 +2229,6 @@ internal void SynchronizeObjectsToNewlyJoinedClient(ulong newClientId) { if (networkObject.Observers.Contains(newClientId)) { - // if (NetworkManager.LogLevel <= LogLevel.Developer) - // { - // // Temporary tracking to make sure we are not showing something already visibile (should never be the case for this) - // Debug.LogWarning($"[{nameof(SynchronizeObjectsToNewlyJoinedClient)}][{networkObject.name}] New client as already an observer!"); - // } - // // For now, remove the client (impossible for the new client to have an instance since the session owner doesn't) to make sure newly added - // // code to handle this edge case works. - // networkObject.Observers.Remove(newClientId); continue; } networkObject.NetworkShow(newClientId); diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs index d3d3cce74e..762c8ca494 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs @@ -103,8 +103,16 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj protected const uint k_DefaultTickRate = 30; - private int m_NumberOfClients; + /// + /// Specifies the number of client instances to be created for the integration test. + /// + /// + /// When running with a hosted CMB Service, NumberOfClients + 1 clients are created. + /// This holds assumptions throughout the test suite that when running with a host, there is an extra client. + /// For example, see the calculation for . + /// protected abstract int NumberOfClients { get; } + private int m_NumberOfClients; /// /// Set this to false to create the clients first. @@ -131,11 +139,11 @@ public enum HostOrServer protected GameObject m_PlayerPrefab; - /// The Server instance + /// The Server instance instantiated and tracked within the current test protected NetworkManager m_ServerNetworkManager; - /// All the client instances + /// All the client instances instantiated and tracked within the current test protected NetworkManager[] m_ClientNetworkManagers; - /// All the instances + /// All the instances instantiated and tracked within the current test protected NetworkManager[] m_NetworkManagers; /// @@ -595,6 +603,17 @@ protected IEnumerator CreateAndStartNewClient() // in the event any modifications need to be made before starting the client OnNewClientCreated(networkManager); + yield return StartClient(networkManager); + } + + /// + /// Starts and connects the given networkManager as a client while in the middle of an + /// integration test. + /// + /// The network manager to start and connect + /// An IEnumerator to be used in a coroutine for asynchronous execution. + protected IEnumerator StartClient(NetworkManager networkManager) + { NetcodeIntegrationTestHelpers.StartOneClient(networkManager); if (LogAllMessages) @@ -706,21 +725,33 @@ protected void CreateAndStartNewClientWithTimeTravel() } /// - /// This will stop a client while in the middle of an integration test + /// This will stop the given instance while in the middle of an integration test. + /// The instance is then removed from the lists of managed instances (, ). /// + /// + /// If there are no other references to the managed instance, it will be destroyed regardless of the destroy parameter. + /// To avoid this, save a reference to the instance before calling this method. + /// + /// The instance of the client to stop. + /// Whether the instance should be destroyed after stopping. Defaults to false. + /// An to be used in a coroutine for asynchronous execution. protected IEnumerator StopOneClient(NetworkManager networkManager, bool destroy = false) { NetcodeIntegrationTestHelpers.StopOneClient(networkManager, destroy); - if (destroy) - { - AddRemoveNetworkManager(networkManager, false); - } + AddRemoveNetworkManager(networkManager, false); yield return WaitForConditionOrTimeOut(() => !networkManager.IsConnectedClient); } /// - /// This will stop a client while in the middle of an integration test + /// This will stop the given instance while in the middle of a time travel integration test. + /// The instance is then removed from the lists of managed instances (, ). /// + /// + /// If there are no other references to the managed instance, it will be destroyed regardless of the destroy parameter. + /// To avoid this, save a reference to the instance before calling this method. + /// + /// The instance of the client to stop. + /// Whether the instance should be destroyed after stopping. Defaults to false. protected void StopOneClientWithTimeTravel(NetworkManager networkManager, bool destroy = false) { NetcodeIntegrationTestHelpers.StopOneClient(networkManager, destroy); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs index af001655ae..e48557b9c8 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs @@ -139,7 +139,8 @@ private bool DoesServerStillHaveSpawnedPlayerObject() [UnityTest] public IEnumerator ClientPlayerDisconnected([Values] ClientDisconnectType clientDisconnectType) { - m_ClientId = m_ClientNetworkManagers[0].LocalClientId; + var clientNetworkManager = m_ClientNetworkManagers[0]; + m_ClientId = clientNetworkManager.LocalClientId; m_ClientDisconnectType = clientDisconnectType; var serverSideClientPlayer = m_ServerNetworkManager.ConnectionManager.ConnectedClients[m_ClientId].PlayerObject; @@ -148,8 +149,8 @@ public IEnumerator ClientPlayerDisconnected([Values] ClientDisconnectType client if (clientDisconnectType == ClientDisconnectType.ServerDisconnectsClient) { - m_ClientNetworkManagers[0].OnClientDisconnectCallback += OnClientDisconnectCallback; - m_ClientNetworkManagers[0].OnConnectionEvent += OnConnectionEvent; + clientNetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback; + clientNetworkManager.OnConnectionEvent += OnConnectionEvent; m_ServerNetworkManager.OnConnectionEvent += OnConnectionEvent; m_ServerNetworkManager.DisconnectClient(m_ClientId); } @@ -157,9 +158,9 @@ public IEnumerator ClientPlayerDisconnected([Values] ClientDisconnectType client { m_ServerNetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback; m_ServerNetworkManager.OnConnectionEvent += OnConnectionEvent; - m_ClientNetworkManagers[0].OnConnectionEvent += OnConnectionEvent; + clientNetworkManager.OnConnectionEvent += OnConnectionEvent; - yield return StopOneClient(m_ClientNetworkManagers[0]); + yield return StopOneClient(clientNetworkManager); } yield return WaitForConditionOrTimeOut(() => m_ClientDisconnected); @@ -169,8 +170,8 @@ public IEnumerator ClientPlayerDisconnected([Values] ClientDisconnectType client { Assert.IsTrue(m_DisconnectedEvent.ContainsKey(m_ServerNetworkManager), $"Could not find the server {nameof(NetworkManager)} disconnect event entry!"); Assert.IsTrue(m_DisconnectedEvent[m_ServerNetworkManager].ClientId == m_ClientId, $"Expected ClientID {m_ClientId} but found ClientID {m_DisconnectedEvent[m_ServerNetworkManager].ClientId} for the server {nameof(NetworkManager)} disconnect event entry!"); - Assert.IsTrue(m_DisconnectedEvent.ContainsKey(m_ClientNetworkManagers[0]), $"Could not find the client {nameof(NetworkManager)} disconnect event entry!"); - Assert.IsTrue(m_DisconnectedEvent[m_ClientNetworkManagers[0]].ClientId == m_ClientId, $"Expected ClientID {m_ClientId} but found ClientID {m_DisconnectedEvent[m_ServerNetworkManager].ClientId} for the client {nameof(NetworkManager)} disconnect event entry!"); + Assert.IsTrue(m_DisconnectedEvent.ContainsKey(clientNetworkManager), $"Could not find the client {nameof(NetworkManager)} disconnect event entry!"); + Assert.IsTrue(m_DisconnectedEvent[clientNetworkManager].ClientId == m_ClientId, $"Expected ClientID {m_ClientId} but found ClientID {m_DisconnectedEvent[m_ServerNetworkManager].ClientId} for the client {nameof(NetworkManager)} disconnect event entry!"); // Unregister for this event otherwise it will be invoked during teardown m_ServerNetworkManager.OnConnectionEvent -= OnConnectionEvent; } @@ -178,8 +179,8 @@ public IEnumerator ClientPlayerDisconnected([Values] ClientDisconnectType client { Assert.IsTrue(m_DisconnectedEvent.ContainsKey(m_ServerNetworkManager), $"Could not find the server {nameof(NetworkManager)} disconnect event entry!"); Assert.IsTrue(m_DisconnectedEvent[m_ServerNetworkManager].ClientId == m_ClientId, $"Expected ClientID {m_ClientId} but found ClientID {m_DisconnectedEvent[m_ServerNetworkManager].ClientId} for the server {nameof(NetworkManager)} disconnect event entry!"); - Assert.IsTrue(m_DisconnectedEvent.ContainsKey(m_ClientNetworkManagers[0]), $"Could not find the client {nameof(NetworkManager)} disconnect event entry!"); - Assert.IsTrue(m_DisconnectedEvent[m_ClientNetworkManagers[0]].ClientId == m_ClientId, $"Expected ClientID {m_ClientId} but found ClientID {m_DisconnectedEvent[m_ServerNetworkManager].ClientId} for the client {nameof(NetworkManager)} disconnect event entry!"); + Assert.IsTrue(m_DisconnectedEvent.ContainsKey(clientNetworkManager), $"Could not find the client {nameof(NetworkManager)} disconnect event entry!"); + Assert.IsTrue(m_DisconnectedEvent[clientNetworkManager].ClientId == m_ClientId, $"Expected ClientID {m_ClientId} but found ClientID {m_DisconnectedEvent[m_ServerNetworkManager].ClientId} for the client {nameof(NetworkManager)} disconnect event entry!"); Assert.IsTrue(m_ServerNetworkManager.ConnectedClientsIds.Count == 1, $"Expected connected client identifiers count to be 1 but it was {m_ServerNetworkManager.ConnectedClientsIds.Count}!"); Assert.IsTrue(m_ServerNetworkManager.ConnectedClients.Count == 1, $"Expected connected client identifiers count to be 1 but it was {m_ServerNetworkManager.ConnectedClients.Count}!"); Assert.IsTrue(m_ServerNetworkManager.ConnectedClientsList.Count == 1, $"Expected connected client identifiers count to be 1 but it was {m_ServerNetworkManager.ConnectedClientsList.Count}!"); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs index 7af663db1a..087156dfed 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/DistributeObjectsTests.cs @@ -26,7 +26,6 @@ internal class DistributeObjectsTests : IntegrationTestWithApproximation private const int k_LateJoinClientCount = 4; protected override int NumberOfClients => 0; - public DistributeObjectsTests() : base(HostOrServer.DAHost) { } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs index f3bf6371ec..269adf7349 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/ParentChildDistibutionTests.cs @@ -8,9 +8,7 @@ namespace Unity.Netcode.RuntimeTests { - [TestFixture(DistributionTypes.UponConnect)] - [TestFixture(DistributionTypes.UponDisconnect)] - internal class ParentChildDistibutionTests : IntegrationTestWithApproximation + internal class ParentChildDistributionTests : IntegrationTestWithApproximation { protected override int NumberOfClients => 4; @@ -20,7 +18,6 @@ internal class ParentChildDistibutionTests : IntegrationTestWithApproximation private List m_AltTargetSpawnedObjects = new List(); private Dictionary> m_AncillarySpawnedObjects = new Dictionary>(); private StringBuilder m_ErrorMsg = new StringBuilder(); - private DistributionTypes m_DistributionType; // TODO: [CmbServiceTesting] Update UponDisconnect tests to work with the rust service protected override bool UseCMBService() @@ -28,9 +25,8 @@ protected override bool UseCMBService() return false; } - public ParentChildDistibutionTests(DistributionTypes distributionType) : base(HostOrServer.DAHost) + public ParentChildDistributionTests() : base(HostOrServer.DAHost) { - m_DistributionType = distributionType; } protected override IEnumerator OnTearDown() @@ -54,10 +50,6 @@ private bool AllTargetedInstancesSpawned() m_ErrorMsg.Clear(); foreach (var client in m_NetworkManagers) { - if (!client.IsConnectedClient) - { - continue; - } foreach (var spawnedObject in m_TargetSpawnedObjects) { if (!client.SpawnManager.SpawnedObjects.ContainsKey(spawnedObject.NetworkObjectId)) @@ -75,10 +67,6 @@ private bool AllAncillaryInstancesSpawned() m_ErrorMsg.Clear(); foreach (var client in m_NetworkManagers) { - if (!client.IsConnectedClient) - { - continue; - } foreach (var clientObjects in m_AncillarySpawnedObjects) { foreach (var spawnedObject in clientObjects.Value) @@ -163,19 +151,20 @@ public enum OwnershipLocking [UnityTest] - public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipLock) + public IEnumerator DistributeOwnerHierarchy([Values] DistributionTypes distributionType, [Values] OwnershipLocking ownershipLock) { m_TargetSpawnedObjects.Clear(); m_AncillarySpawnedObjects.Clear(); m_AltTargetSpawnedObjects.Clear(); - if (m_DistributionType == DistributionTypes.UponConnect) + var clientToReconnect = m_ClientNetworkManagers[3]; + if (distributionType == DistributionTypes.UponConnect) { - m_ClientNetworkManagers[3].Shutdown(); + yield return StopOneClient(clientToReconnect); } // When testing connect redistribution, - var instances = m_DistributionType == DistributionTypes.UponDisconnect ? 1 : 2; + var instances = distributionType == DistributionTypes.UponDisconnect ? 1 : 2; var rootObject = (GameObject)null; var childOne = (GameObject)null; var childTwo = (GameObject)null; @@ -186,7 +175,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipL rootObject = SpawnObject(m_GenericPrefab, m_ClientNetworkManagers[0]); networkObject = rootObject.GetComponent(); networkObject.SetOwnershipStatus(NetworkObject.OwnershipStatus.Distributable); - if (ownershipLock == OwnershipLocking.LockRootParent && m_DistributionType == DistributionTypes.UponConnect) + if (ownershipLock == OwnershipLocking.LockRootParent && distributionType == DistributionTypes.UponConnect) { networkObject.SetOwnershipLock(true); } @@ -202,7 +191,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipL childTwo = SpawnObject(m_GenericPrefab, m_ClientNetworkManagers[0]); networkObject = childTwo.GetComponent(); networkObject.SetOwnershipStatus(NetworkObject.OwnershipStatus.Distributable); - if (ownershipLock == OwnershipLocking.LockTargetChild && m_DistributionType == DistributionTypes.UponConnect) + if (ownershipLock == OwnershipLocking.LockTargetChild && distributionType == DistributionTypes.UponConnect) { networkObject.SetOwnershipLock(true); } @@ -249,7 +238,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipL // Get the original clientId m_OriginalOwnerId = m_ClientNetworkManagers[0].LocalClientId; - if (m_DistributionType == DistributionTypes.UponDisconnect) + if (distributionType == DistributionTypes.UponDisconnect) { // Swap out the original owner's NetworkObject with one of the other client's since those instances will // be destroyed when the client disconnects. @@ -258,13 +247,13 @@ public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipL m_AltTargetSpawnedObjects.Add(m_ClientNetworkManagers[1].SpawnManager.SpawnedObjects[entry.NetworkObjectId]); } // Disconnect the client to trigger object redistribution - m_ClientNetworkManagers[0].Shutdown(); + yield return StopOneClient(m_ClientNetworkManagers[0]); } else { - m_ClientNetworkManagers[3].StartClient(); - yield return WaitForConditionOrTimeOut(() => m_ClientNetworkManagers[3].IsConnectedClient); - AssertOnTimeout($"{m_ClientNetworkManagers[3].name} failed to reconnect!"); + yield return StartClient(clientToReconnect); + yield return WaitForConditionOrTimeOut(() => clientToReconnect.IsConnectedClient); + AssertOnTimeout($"{clientToReconnect.name} failed to reconnect!"); } // Verify all of the targeted objects changed ownership to the same client @@ -273,7 +262,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipL // When enabled, you should see one of the two root instances that have children get distributed to // the reconnected client. - if (m_EnableVerboseDebug && m_DistributionType == DistributionTypes.UponConnect) + if (m_EnableVerboseDebug && distributionType == DistributionTypes.UponConnect) { m_ErrorMsg.Clear(); m_ErrorMsg.AppendLine($"Original targeted objects owner: {m_OriginalOwnerId}"); @@ -285,7 +274,7 @@ public IEnumerator DistributeOwnerHierarchy([Values] OwnershipLocking ownershipL } // We only want to make sure no other children owned by still connected clients change ownership - if (m_DistributionType == DistributionTypes.UponDisconnect) + if (distributionType == DistributionTypes.UponDisconnect) { // Verify the ancillary objects kept the same ownership yield return WaitForConditionOrTimeOut(AncillaryObjectsKeptOwnership); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs index c786734a7d..0cbef0f4dc 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs @@ -25,15 +25,6 @@ public NetworkVisibilityTests(SceneManagementState sceneManagementState, Network m_SceneManagementEnabled = sceneManagementState == SceneManagementState.SceneManagementEnabled; } - protected override IEnumerator OnSetup() - { - // TODO: [CmbServiceTests] remove this wait once the delay in service restart is fixed - if (m_UseCmbService) - { - yield return new WaitForSeconds(0.5f); - } - } - protected override void OnServerAndClientsCreated() { m_TestNetworkPrefab = CreateNetworkObjectPrefab("Object"); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs index 2f0554c6be..a44f7919c5 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/ParentingDuringSpawnTests.cs @@ -71,14 +71,6 @@ public ParentingDuringSpawnTests(NetworkTopologyTypes networkTopology, NetworkSp m_NetworkSpawnType = networkSpawnType; } - protected override IEnumerator OnSetup() - { - if (m_UseCmbService) - { - yield return new WaitForSeconds(0.5f); - } - } - protected override void OnServerAndClientsCreated() { m_ParentPrefab = CreateNetworkObjectPrefab("Parent"); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs index d6d97619a9..db50428f7f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabOverrideTests.cs @@ -258,7 +258,7 @@ public IEnumerator PrefabOverrideTests() if (m_DistributedAuthority) { - networkManagerOwner = m_ClientNetworkManagers[1]; + networkManagerOwner = GetNonAuthorityNetworkManager(); } // Clients and Host will spawn the OverridingTargetPrefab while a dedicated server will spawn the SourcePrefabToOverride diff --git a/pvpExceptions.json b/pvpExceptions.json index 8c448d01ea..7f54933590 100644 --- a/pvpExceptions.json +++ b/pvpExceptions.json @@ -81,9 +81,7 @@ "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void RegisterNetworkObject(NetworkObject): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void DeregisterNetworkObject(NetworkObject): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void DeregisterNetworkObject(ulong, ulong): undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: TotalClients: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: k_DefaultTickRate: undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: NumberOfClients: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_PlayerPrefab: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_UseHost: undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: m_DistributedAuthority: undocumented", @@ -98,11 +96,6 @@ "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void OneTimeSetup(): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: IEnumerator OnSetup(): missing ", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: IEnumerator SetUp(): undocumented", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: IEnumerator StopOneClient(NetworkManager, bool): missing ", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: IEnumerator StopOneClient(NetworkManager, bool): missing ", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: IEnumerator StopOneClient(NetworkManager, bool): missing ", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void StopOneClientWithTimeTravel(NetworkManager, bool): missing ", - "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void StopOneClientWithTimeTravel(NetworkManager, bool): missing ", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void SetTimeTravelSimulatedLatency(float): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void SetTimeTravelSimulatedDropRate(float): undocumented", "Unity.Netcode.TestHelpers.Runtime.NetcodeIntegrationTest: void SetTimeTravelSimulatedLatencyJitter(float): undocumented", diff --git a/testproject/Assets/DefaultNetworkPrefabs.asset b/testproject/Assets/DefaultNetworkPrefabs.asset index d2ef286f81..a5e491547f 100644 --- a/testproject/Assets/DefaultNetworkPrefabs.asset +++ b/testproject/Assets/DefaultNetworkPrefabs.asset @@ -11,7 +11,7 @@ MonoBehaviour: m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: e651dbb3fbac04af2b8f5abf007ddc23, type: 3} m_Name: DefaultNetworkPrefabs - m_EditorClassIdentifier: + m_EditorClassIdentifier: IsDefault: 1 List: - Override: 0 @@ -224,15 +224,3 @@ MonoBehaviour: SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 8188135024827620138, guid: c000e98bc12da2941a59ec61c260dd6a, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 6958138586392507362, guid: 4b31f769283d3c24ca2a5d6baf28a806, - type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} diff --git a/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs b/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs index 7f59706b60..af15783841 100644 --- a/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs +++ b/testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs @@ -856,7 +856,7 @@ public IEnumerator LateJoinSynchronizationTest() // Make sure the AnimatorTestHelper client side instances is the same as the TotalClients var calculatedClients = AnimatorTestHelper.ClientSideInstances.Count + (m_UseHost ? 1 : 0); - Assert.True(calculatedClients == TotalClients, $"Incorrect number of clients: actual {calculatedClients}, expected {TotalClients}. network managers: {m_NetworkManagers.Length}, client side: {AnimatorTestHelper.ClientSideInstances.Count}"); + Assert.True(calculatedClients == TotalClients, $"Incorrect number of clients: actual {calculatedClients}, expected {TotalClients}."); var lateJoinObjectInstance = AnimatorTestHelper.ClientSideInstances[m_ClientNetworkManagers[NumberOfClients].LocalClientId]; yield return WaitForConditionOrTimeOut(() => Mathf.Approximately(lateJoinObjectInstance.transform.rotation.eulerAngles.y, 180.0f));