diff --git a/.pr_agent.toml b/.pr_agent.toml index 71d8783c0c..9a8dba21cd 100644 --- a/.pr_agent.toml +++ b/.pr_agent.toml @@ -4,6 +4,5 @@ # https://developer.portal.internal.unity.com/catalog/default/component/u-pr/docs/configuration/automatic_runs/ [github_app] -handle_pr_actions = ['opened', 'ready_for_review'] # PR events that auto-run pr_commands pr_commands = ["/harness-review"] # what runs on those events reviewer_commands = ["/harness-review"] # what runs when @u-pr is added as reviewer diff --git a/.yamato/cmb-service-standalone-tests.yml b/.yamato/cmb-service-standalone-tests.yml index 145a9c1618..6cd8bfa375 100644 --- a/.yamato/cmb-service-standalone-tests.yml +++ b/.yamato/cmb-service-standalone-tests.yml @@ -56,8 +56,7 @@ cmb_service_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }} # run_cmb_service.sh builds and starts a release version of the full CMB service (along with the limited echo server) - ./Tools/CI/service.cmb/run_cmb_service.sh -e $ECHO_SERVER_PORT -s $CMB_SERVICE_PORT -l artifacts - - 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 - - UnifiedTestRunner --suite=playmode --player-load-path=build/players --artifacts-path=test-results --testproject={{ project.path }} --editor-location=.Editor --playergraphicsapi=Null --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }} + - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --scripting-backend={{ backend }} --player-load-path=build/players --artifacts-path=test-results --testproject={{ project.path }} --extra-player-arg=-batchmode --extra-player-arg=-nographics --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --timeout={{ test_timeout }} artifacts: logs: paths: diff --git a/.yamato/console-standalone-test.yml b/.yamato/console-standalone-test.yml index 9574e07e1b..3aa654e718 100644 --- a/.yamato/console-standalone-test.yml +++ b/.yamato/console-standalone-test.yml @@ -50,7 +50,7 @@ console_standalone_build_{{ project.name }}_{{ platform.name }}_{{ editor }}: {% endif %} commands: - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor -c il2cpp -c {{ platform.name }} - - UnifiedTestRunner --testproject={{ project.path }} --architecture={% if platform.name == "switch" %}arm64{% else %}x64{% endif %} --scripting-backend=il2cpp --suite=playmode --platform={{ platform.standalone }} --editor-location=.Editor --artifacts-path=artifacts --player-save-path=build/players --testfilter="Unity.Netcode.RuntimeTests.*" --extra-editor-arg=-batchmode --extra-editor-arg=-nographics{% if platform.name == "switch" %} --extra-editor-arg=-overrideTextureCompression --extra-editor-arg=ForceUncompressed{% endif %} --reruncount=1 --clean-library-on-rerun --build-only --timeout={{ test_timeout}} + - UnifiedTestRunner --testproject={{ project.path }} --architecture={% if platform.name == "switch" %}arm64{% else %}x64{% endif %} --scripting-backend=il2cpp --suite=playmode --platform={{ platform.standalone }} --editor-location=.Editor --artifacts-path=artifacts --player-save-path=build/players --testfilter="Unity.Netcode.RuntimeTests.*" --extra-editor-arg=-batchmode --extra-editor-arg=-nographics{% if platform.name == "switch" %} --extra-editor-arg=-overrideTextureCompression --extra-editor-arg=ForceUncompressed{% endif %} --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --build-only --timeout={{ test_timeout}} variables: # PS4 related SCE_ORBIS_SDK_DIR: 'C:\Users\bokken\SCE\ps4_sdk_12_00' @@ -88,8 +88,17 @@ console_standalone_test_{{ project.name }}_{{ platform.name }}_{{ editor }}: model: {{ platform.model }} # This is set only in platforms where we want non-default model to use (more information in project.metafile) {% endif %} commands: - - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor -c il2cpp -c {{ platform.name }} - - UnifiedTestRunner --suite=playmode --testproject={{ project.path }} --editor-location=.Editor --artifacts-path=test-results --player-load-path=build/players --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }} + # Console players connect back to UTR's player connection listener on this VM, so the firewall must allow it + - command: gsudo NetSh Advfirewall set allprofiles state off + # Register the Bokken devkit with the platform's target tools so UTR can deploy and run the prebuilt player +{% if platform.name == "ps5" %} + - command: gsudo prospero-ctrl target add %BOKKEN_DEVICE_IP% +{% elsif platform.name == "ps4" %} + - command: orbis-ctrl add %BOKKEN_DEVICE_IP% +{% else %} + - command: '"%GameDK%/bin/xbconnect" /WS %BOKKEN_DEVICE_IP%' +{% endif %} + - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --scripting-backend=il2cpp --testproject={{ project.path }} --artifacts-path=test-results --player-load-path=build/players --player-connection-ip=%BOKKEN_HOST_IP% --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --timeout={{ test_timeout }} variables: # PS4 related SCE_ORBIS_SDK_DIR: 'C:\Users\bokken\SCE\ps4_sdk_12_00' diff --git a/.yamato/desktop-standalone-tests.yml b/.yamato/desktop-standalone-tests.yml index 551b8a91d3..9c83b2986a 100644 --- a/.yamato/desktop-standalone-tests.yml +++ b/.yamato/desktop-standalone-tests.yml @@ -44,7 +44,7 @@ desktop_standalone_build_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ {% endif %} commands: - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor {% if backend == "il2cpp" %} -c il2cpp {% endif %} - - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --editor-location=.Editor --testproject={{ project.path }} --scripting-backend={{ backend }} --testfilter="Unity.Netcode.RuntimeTests.*" --player-save-path=build/players --artifacts-path=artifacts --extra-editor-arg=-batchmode --extra-editor-arg=-nographics --reruncount=1 --clean-library-on-rerun --build-only --timeout={{ test_timeout }} + - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --editor-location=.Editor --testproject={{ project.path }} --scripting-backend={{ backend }} --testfilter="Unity.Netcode.RuntimeTests.*;TestProject.RuntimeTests.*" --playergraphicsapi=Null --player-save-path=build/players --artifacts-path=artifacts --extra-editor-arg=-batchmode --extra-editor-arg=-nographics --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --build-only --timeout={{ test_timeout }} artifacts: players: paths: @@ -79,8 +79,7 @@ desktop_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{ {% endif %} commands: - - 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 - - UnifiedTestRunner --suite=playmode --player-load-path=build/players --artifacts-path=test-results --testproject={{ project.path }} --editor-location=.Editor --playergraphicsapi=Null --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }} + - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --scripting-backend={{ backend }} --player-load-path=build/players --artifacts-path=test-results --testproject={{ project.path }} --extra-player-arg=-batchmode --extra-player-arg=-nographics --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --timeout={{ test_timeout }} artifacts: logs: paths: diff --git a/.yamato/mobile-standalone-test.yml b/.yamato/mobile-standalone-test.yml index 4bb41db94e..59c8f344cb 100644 --- a/.yamato/mobile-standalone-test.yml +++ b/.yamato/mobile-standalone-test.yml @@ -55,7 +55,7 @@ mobile_standalone_build_{{ project.name }}_{{ platform.name }}_{{ editor }}: UNITY_HANDLEUIINTERRUPTIONS: 1 commands: - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor -c il2cpp {% if platform.base == "mac" %} -c ios {% else %} -c android {% endif %} - - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --testproject={{ project.path }} --architecture={{ platform.architecture }} --scripting-backend=il2cpp --editor-location=.Editor --artifacts-path=artifacts --testfilter="Unity.Netcode.RuntimeTests.*" --player-save-path=build/players --extra-editor-arg=-batchmode --extra-editor-arg=-nographics --reruncount=1 --clean-library-on-rerun --build-only --timeout={{ test_timeout }} + - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --testproject={{ project.path }} --architecture={{ platform.architecture }} --scripting-backend=il2cpp --editor-location=.Editor --artifacts-path=artifacts --testfilter="Unity.Netcode.RuntimeTests.*" --player-save-path=build/players --extra-editor-arg=-batchmode --extra-editor-arg=-nographics --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --build-only --timeout={{ test_timeout }} artifacts: players: paths: @@ -82,9 +82,6 @@ mobile_standalone_test_{{ project.name }}_{{ platform.name }}_{{ editor }}: model: {{ platform.model }} # This is set only in platforms where we want non-default model to use (more information in project.metafile) {% endif %} commands: - # Installing editor. We still need the editor to run tests on standalone build and for that the Editor is required - - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor -c il2cpp {% if platform.base == "mac" %} -c ios {% else %} -c android {% endif %} - {% if platform.standalone == "Android" %} # Download standalone UnityTestRunner and ADB setup - command: wget http://artifactory-slo.bf.unity3d.com/artifactory/mobile-generic/android/ADBKeys.zip!/adbkey.pub -O %USERPROFILE%/.android/adbkey.pub @@ -97,11 +94,11 @@ mobile_standalone_test_{{ project.name }}_{{ platform.name }}_{{ editor }}: # Run tests for Android devices - | set ANDROID_DEVICE_CONNECTION=%BOKKEN_DEVICE_IP% - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --artifacts-path=test-results --player-load-path=build/players --testproject={{ project.path }} --editor-location=.Editor --player-connection-ip=%BOKKEN_HOST_IP% --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }} + UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --artifacts-path=test-results --player-load-path=build/players --testproject={{ project.path }} --player-connection-ip=%BOKKEN_HOST_IP% --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --timeout={{ test_timeout }} {% else %} # Run tests for non-Android devices - - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --artifacts-path=test-results --player-load-path=build/players --testproject={{ project.path }} --editor-location=.Editor --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }} --device-id=%BOKKEN_DEVICE_ID% + - UnifiedTestRunner --suite=playmode --platform={{ platform.standalone }} --artifacts-path=test-results --player-load-path=build/players --testproject={{ project.path }} --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --timeout={{ test_timeout }} --device-id=%BOKKEN_DEVICE_ID% {% endif %} artifacts: logs: diff --git a/.yamato/ngo-publish.yml b/.yamato/ngo-publish.yml index 81f9f57b3b..62fc14a11b 100644 --- a/.yamato/ngo-publish.yml +++ b/.yamato/ngo-publish.yml @@ -1,10 +1,6 @@ ngo_release_preparation: name: "NGO release preparation" agent: { type: Unity::VM, flavor: b1.small, image: package-ci/ubuntu-22.04:v4 } - triggers: - recurring: - - branch: develop-2.0.0 # We make new releases from this branch - frequency: "10 ? * 1" # Runs every Sunday at 10:00 AM commands: - pip install PyGithub - pip install GitPython diff --git a/.yamato/webgl-build.yml b/.yamato/webgl-build.yml index 1f028ce10f..47feed0ce5 100644 --- a/.yamato/webgl-build.yml +++ b/.yamato/webgl-build.yml @@ -45,7 +45,7 @@ webgl_build_{{ project.name }}_{{ platform.name }}_{{ editor }}: # Engine is initialized in ‘nographics’ mode since we don't need any graphics for this case (--extra-editor-arg=-nographics) # In case of failure the job will be rerunned once (--reruncount=1) with clean library (--clean-library-on-rerun). Note that this is build only step so no tests are being executed # This will perform only building phase (--build-only) with a timeout set by the test_timeout variable in the project metafile. - - UnifiedTestRunner --suite=playmode --platform=WebGL --scripting-backend=il2cpp --testproject={{ project.path }} --editor-location=.Editor --artifacts_path=artifacts --player-save-path=build/players --extra-editor-arg=-batchmode --extra-editor-arg=-nographics --reruncount=1 --clean-library-on-rerun --build-only --timeout={{ test_timeout }} + - UnifiedTestRunner --suite=playmode --platform=WebGL --scripting-backend=il2cpp --testproject={{ project.path }} --editor-location=.Editor --artifacts_path=artifacts --player-save-path=build/players --extra-editor-arg=-batchmode --extra-editor-arg=-nographics --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --build-only --timeout={{ test_timeout }} artifacts: logs: paths: diff --git a/Tools/CI/service.cmb/run_cmb_service.sh b/Tools/CI/service.cmb/run_cmb_service.sh index 8dd26df88a..05fe686538 100755 --- a/Tools/CI/service.cmb/run_cmb_service.sh +++ b/Tools/CI/service.cmb/run_cmb_service.sh @@ -171,8 +171,8 @@ cargo build --release --locked # The infinite loop is required as the service will exit each time all connected clients disconnect. # This means the service will exit after each test. The infinite loop will immediately restart the service each time it exits. logMessage "Running service integration tests..." -echo "comb-server -l error --metrics-port 5000 standalone --port $service_port -t 60m --unity-version $unity_version" +echo "comb-server -l warn -l ngo::session=info -l comb_server::session=info --metrics-port 5000 standalone --port $service_port -t 60m --unity-version $unity_version" while :; do - ./target/release/comb-server -l error --metrics-port 5000 standalone --port $service_port -t 60m --unity-version $unity_version; + ./target/release/comb-server -l warn -l ngo::session=info -l comb_server::session=info --metrics-port 5000 standalone --port $service_port -t 60m --unity-version $unity_version; done & # <- use & to run the entire loop in the background diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs index f8ce9d815c..1e23226161 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs @@ -1144,7 +1144,7 @@ private bool ProcessEvent() // means a clean disconnect that doesn't require logging. if (!m_Driver.Listening && m_ServerClientId == default) { - Debug.LogError("Failed to connect to server."); + LogClientConnectionFailureMessage(); } // Set the disconnect event error code @@ -1172,6 +1172,40 @@ private bool ProcessEvent() return false; } + private void LogClientConnectionFailureMessage() + { + if (OnCurrentTopology() == NetworkTopologyTypes.ClientServer) + { + var reasons = new List { "Server/host is not running." }; + + if (m_ProtocolType == ProtocolType.RelayUnityTransport && !m_UseWebSockets) + { + reasons.Add("Relay port might be blocked on your network. Try using WebSockets."); + if (m_RelayServerData.IsSecure != 0) + { + reasons.Add("DTLS might be blocked on your network. Try using UDP or WebSockets."); + } + } + else if (m_ProtocolType != ProtocolType.RelayUnityTransport) + { + reasons.Add($"Server/host might not be reachable. Try \"ping {ConnectionData.Address}\" in a terminal."); + reasons.Add("The firewall on the server/host might be blocking the connection attempts."); + if (m_UseEncryption && !m_UseWebSockets) + { + reasons.Add("DTLS might be blocked on your network. Try using WebSockets."); + } + } + + const string prefix = "\n\t- "; + Debug.LogError("Failed to connect to server. Possible reasons:" + prefix + string.Join(prefix, reasons)); + } + else + { + // If using DA the SDK should have logged an actual useful error. + Debug.LogError("Failed to connect to server."); + } + } + /// /// Handles accepting new connections and processing transport events. /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientOnlyConnectionTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientOnlyConnectionTests.cs index 549f0d8d23..7e0dfb997d 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientOnlyConnectionTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientOnlyConnectionTests.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Text.RegularExpressions; using NUnit.Framework; using Unity.Netcode.TestHelpers.Runtime; using Unity.Netcode.Transports.UTP; @@ -48,7 +49,7 @@ public IEnumerator ClientFailsToConnect() m_ClientNetworkManager.StartClient(); // Unity Transport throws an error when it times out - LogAssert.Expect(LogType.Error, "Failed to connect to server."); + LogAssert.Expect(LogType.Error, new Regex("^Failed to connect to server\\.")); yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => m_WasDisconnected, m_TimeoutHelper); Assert.False(m_TimeoutHelper.TimedOut, "Timed out waiting for client to timeout waiting to connect!"); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOrderOfOperations.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOrderOfOperations.cs index 20630f0803..2f128459ec 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOrderOfOperations.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformOrderOfOperations.cs @@ -24,6 +24,7 @@ namespace Unity.Netcode.RuntimeTests [TestFixture(HostOrServer.DAHost)] [TestFixture(HostOrServer.Host)] [TestFixture(HostOrServer.Server)] + [UnityPlatform(exclude = new[] { RuntimePlatform.PS4 })] // Ignored test tracked in MTT-16494 internal class NetworkTransformOrderOfOperations : IntegrationTestWithApproximation { #region Configuration, Properties, and Overrides diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTests.cs index a8aa926709..9f7b4c7a7b 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTests.cs @@ -1935,7 +1935,6 @@ public string ArrayStr(NativeArray arr) where T : unmanaged [Test] [UnityPlatform(exclude = new[] { RuntimePlatform.Android, RuntimePlatform.IPhonePlayer })] // Ignored test tracked in MTT-11343 - [Repeat(5)] #if ENABLE_CORECLR [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] #endif @@ -1998,7 +1997,7 @@ public void WhenSerializingAndDeserializingVeryLargeValueTypeNativeArrayNetworkV } else if (testType == typeof(bool)) { - (var original, var original2, var changed, var changed2) = GetArarys(RandGenBytes); + (var original, var original2, var changed, var changed2) = GetArarys((rand) => rand.Next(2) == 1); TestValueTypeNativeArray(original, changed); TestValueTypeNativeArray(original2, changed2); } @@ -2400,7 +2399,6 @@ public string DictionaryStr(Dictionary list) [Test] [UnityPlatform(exclude = new[] { RuntimePlatform.Android, RuntimePlatform.IPhonePlayer })] // Ignored test tracked in MTT-11343 - [Repeat(5)] #if ENABLE_CORECLR [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] #endif @@ -2598,7 +2596,6 @@ public void WhenSerializingAndDeserializingVeryLargeListNetworkVariables_ValuesA [Test] [UnityPlatform(exclude = new[] { RuntimePlatform.Android, RuntimePlatform.IPhonePlayer })] // Ignored test tracked in MTT-11343 - [Repeat(5)] #if ENABLE_CORECLR [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] #endif @@ -2764,8 +2761,7 @@ public void WhenSerializingAndDeserializingVeryLargeHashSetNetworkVariables_Valu } [Test] - [UnityPlatform(exclude = new[] { RuntimePlatform.Android, RuntimePlatform.IPhonePlayer })] // Ignored test tracked in MTT-11343 - [Repeat(5)] + [UnityPlatform(exclude = new[] { RuntimePlatform.Android, RuntimePlatform.IPhonePlayer, RuntimePlatform.PS4, RuntimePlatform.PS5 })] // Ignored test tracked in MTT-11343, MTT-16494 #if ENABLE_CORECLR [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] #endif @@ -3910,7 +3906,6 @@ public string NativeHashMapStr(NativeHashMap list) } [Test] - [Repeat(5)] public void WhenSerializingAndDeserializingVeryLargeValueTypeNativeListNetworkVariables_ValuesAreSerializedCorrectly( [Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), @@ -4101,11 +4096,10 @@ public void WhenSerializingAndDeserializingVeryLargeValueTypeNativeListNetworkVa } [Test] - [Repeat(5)] public void WhenSerializingAndDeserializingVeryLargeValueTypeNativeHashSetNetworkVariables_ValuesAreSerializedCorrectly( [Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), - typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double), + typeof(long), typeof(ulong), typeof(char), typeof(float), typeof(double), typeof(Vector2), typeof(Vector3), typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Pose), typeof(HashableNetworkVariableTestStruct), typeof(FixedString32Bytes))] Type testType) @@ -4261,7 +4255,6 @@ public void WhenSerializingAndDeserializingVeryLargeValueTypeNativeHashSetNetwor } [Test] - [Repeat(5)] public void WhenSerializingAndDeserializingVeryLargeValueTypeNativeHashMapNetworkVariables_ValuesAreSerializedCorrectly( [Values(typeof(byte), typeof(ulong), typeof(Vector2), typeof(HashMapKeyStruct))] Type keyType, diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTraitsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTraitsTests.cs index 0672b50077..acdd07cddd 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTraitsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableTraitsTests.cs @@ -100,7 +100,7 @@ public IEnumerator WhenNewValueIsLessThanThresholdButMaxTimeHasPassed_VariableIs var authorityComponent = GetAuthorityComponent(); authorityComponent.TheVariable.CheckExceedsDirtinessThreshold = (in float value, in float newValue) => Mathf.Abs(newValue - value) >= 0.1; authorityComponent.TheVariable.SetUpdateTraits(new NetworkVariableUpdateTraits { MaxSecondsBetweenUpdates = 1.0f }); - authorityComponent.TheVariable.LastUpdateSent = authorityComponent.NetworkManager.NetworkTimeSystem.LocalTime; + authorityComponent.TheVariable.UpdateLastSentTime(); var timeoutHelper = new TimeoutHelper(0.62f); var newValue = 0.05f; @@ -120,7 +120,7 @@ public IEnumerator WhenNewValueIsGreaterThanThresholdButMinTimeHasNotPassed_Vari var authorityComponent = GetAuthorityComponent(); authorityComponent.TheVariable.CheckExceedsDirtinessThreshold = (in float value, in float newValue) => Mathf.Abs(newValue - value) >= 0.1; authorityComponent.TheVariable.SetUpdateTraits(new NetworkVariableUpdateTraits { MinSecondsBetweenUpdates = 1 }); - authorityComponent.TheVariable.LastUpdateSent = authorityComponent.NetworkManager.NetworkTimeSystem.LocalTime; + authorityComponent.TheVariable.UpdateLastSentTime(); var timeoutHelper = new TimeoutHelper(0.62f); var newValue = 0.15f; @@ -139,7 +139,7 @@ public IEnumerator WhenNoThresholdIsSetButMinTimeHasNotPassed_VariableIsNotSeria { var authorityComponent = GetAuthorityComponent(); authorityComponent.TheVariable.SetUpdateTraits(new NetworkVariableUpdateTraits { MinSecondsBetweenUpdates = 1 }); - authorityComponent.TheVariable.LastUpdateSent = authorityComponent.NetworkManager.NetworkTimeSystem.LocalTime; + authorityComponent.TheVariable.UpdateLastSentTime(); var timeoutHelper = new TimeoutHelper(0.62f); var newValue = 0.15f; @@ -163,7 +163,7 @@ public IEnumerator WhenNonTraitsIsDirtyButTraitsIsNotReadyToSend() { var authorityComponent = GetAuthorityComponent(); authorityComponent.TheVariable.SetUpdateTraits(new NetworkVariableUpdateTraits { MinSecondsBetweenUpdates = 1 }); - authorityComponent.TheVariable.LastUpdateSent = authorityComponent.NetworkManager.NetworkTimeSystem.LocalTime; + authorityComponent.TheVariable.UpdateLastSentTime(); var timeoutHelper = new TimeoutHelper(0.62f); var firstValue = 0.15f; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/Components/ObjectNameIdentifier.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/Components/ObjectNameIdentifier.cs index e33b6ea313..4df4cdd352 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/Components/ObjectNameIdentifier.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/Components/ObjectNameIdentifier.cs @@ -9,7 +9,7 @@ namespace Unity.Netcode.TestHelpers.Runtime /// public class ObjectNameIdentifier : NetworkBehaviour { - private ulong m_CurrentOwner; + private ulong m_RegisteredLocalClientId; private ulong m_CurrentNetworkObjectId; private bool m_IsRegistered; @@ -45,18 +45,18 @@ protected void RegisterAndLabelNetworkObject() // This is required otherwise it will try to continue to update the NetworkBehaviour even if // it has been destroyed. m_NetworkObject = NetworkObject; - m_CurrentOwner = OwnerClientId; + m_RegisteredLocalClientId = NetworkManager.LocalClientId; m_CurrentNetworkObjectId = NetworkObjectId; var serverOrClient = IsServer ? "Server" : "Client"; if (NetworkObject.IsPlayerObject) { - gameObject.name = NetworkManager.LocalClientId == OwnerClientId ? $"{m_OriginalName}-{k_TagInfoStart}{OwnerClientId}{k_TagInfoStop}-Local{m_OriginalName}" : - $"{m_OriginalName}-{k_TagInfoStart}{OwnerClientId}{k_TagInfoStop}- On{serverOrClient}{k_TagInfoStart}{NetworkManager.LocalClientId}{k_TagInfoStop}"; + gameObject.name = m_RegisteredLocalClientId == OwnerClientId ? $"{m_OriginalName}-{k_TagInfoStart}{OwnerClientId}{k_TagInfoStop}-Local{m_OriginalName}" : + $"{m_OriginalName}-{k_TagInfoStart}{OwnerClientId}{k_TagInfoStop}- On{serverOrClient}{k_TagInfoStart}{m_RegisteredLocalClientId}{k_TagInfoStop}"; } else { - gameObject.name = $"{m_OriginalName}{k_TagInfoStart}{NetworkObjectId}{k_TagInfoStop}-On{serverOrClient}{k_TagInfoStart}{NetworkManager.LocalClientId}{k_TagInfoStop}"; + gameObject.name = $"{m_OriginalName}{k_TagInfoStart}{NetworkObjectId}{k_TagInfoStop}-On{serverOrClient}{k_TagInfoStart}{m_RegisteredLocalClientId}{k_TagInfoStop}"; } // Don't add the player objects to the global list of NetworkObjects @@ -75,7 +75,7 @@ protected void DeRegisterNetworkObject() { if (m_IsRegistered) { - NetcodeIntegrationTest.DeregisterNetworkObject(m_CurrentOwner, m_CurrentNetworkObjectId); + NetcodeIntegrationTest.DeregisterNetworkObject(m_RegisteredLocalClientId, m_CurrentNetworkObjectId); m_IsRegistered = false; } } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/IntegrationTestSceneHandler.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/IntegrationTestSceneHandler.cs index 209caf300b..22d37621d4 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/IntegrationTestSceneHandler.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/IntegrationTestSceneHandler.cs @@ -372,7 +372,8 @@ private bool ExcludeSceneFromSynchronizationCheck(Scene scene) public void ClearSceneTracking(NetworkManager networkManager) { - SceneNameToSceneHandles.Clear(); + // Only clear the calling NetworkManager's tracking, other NetworkManagers may still be tracking their own scenes + SceneNameToSceneHandles.Remove(networkManager); } public void StopTrackingScene(NetworkSceneHandle handle, string name, NetworkManager networkManager) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs index fe1185462b..2f6b0becff 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs @@ -691,6 +691,8 @@ public IEnumerator SetUp() // In addition to setting the number of clients in the OneTimeSetup, we need to re-apply the number of clients for each unique test // in the event that a previous test stopped a client. m_NumberOfClients = NumberOfClients; + // Clear any time out state left by a previous test so it cannot fail this test's assertions + s_GlobalTimeoutHelper.TimedOut = false; VerboseDebugLog.Clear(); VerboseDebug($"Entering {nameof(SetUp)}"); NetcodeLogAssert = new NetcodeLogAssert(); @@ -1076,7 +1078,7 @@ protected void CreateAndStartNewClientWithTimeTravel() // Wait for the new client to connect var connected = WaitForClientsConnectedOrTimeOutWithTimeTravel(); - AssertOnTimeout($"{nameof(CreateAndStartNewClientWithTimeTravel)} timed out waiting for all clients to be connected!\n {m_InternalErrorLog}"); + Assert.IsTrue(connected, $"{nameof(CreateAndStartNewClientWithTimeTravel)} timed out waiting for all clients to be connected!\n {m_InternalErrorLog}"); OnNewClientStartedAndConnected(networkManager); if (!connected) @@ -1459,9 +1461,9 @@ protected void StartServerAndClientsWithTimeTravel() if (!m_BypassConnectionTimeout) { // Wait for all clients to connect - WaitForClientsConnectedOrTimeOutWithTimeTravel(); + var connected = WaitForClientsConnectedOrTimeOutWithTimeTravel(); - AssertOnTimeout($"{nameof(StartServerAndClients)} timed out waiting for all clients to be connected!\n {m_InternalErrorLog}"); + Assert.IsTrue(connected, $"{nameof(StartServerAndClients)} timed out waiting for all clients to be connected!\n {m_InternalErrorLog}"); if (m_UseHost || authorityManager.IsHost) { @@ -1484,8 +1486,8 @@ protected void StartServerAndClientsWithTimeTravel() { foreach (var networkManager in m_NetworkManagers) { - WaitForConditionOrTimeOutWithTimeTravel(() => AllPlayerObjectClonesSpawned(networkManager)); - AssertOnTimeout($"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!"); + var spawned = WaitForConditionOrTimeOutWithTimeTravel(() => AllPlayerObjectClonesSpawned(networkManager)); + Assert.IsTrue(spawned, $"{nameof(CreateAndStartNewClient)} timed out waiting for all sessions to spawn Client-{networkManager.LocalClientId}'s player object!"); } } @@ -1586,7 +1588,7 @@ protected void ShutdownAndCleanUp() } catch (Exception e) { - throw e; + Debug.LogException(e); } finally { @@ -1706,6 +1708,9 @@ public IEnumerator TearDown() { ShutdownAndCleanUp(); } + + // Wait until all the scene from this test are unloaded before starting the next test. + yield return WaitForRemainingScenesUnloaded(); } if (m_EnableTimeTravel) @@ -2588,22 +2593,84 @@ protected void AssertOnTimeout(string timeOutErrorMessage, TimeoutHelper assigne } - private void UnloadRemainingScenes() + private const float k_SceneUnloadTimeout = 5.0f; + private readonly List m_PendingSceneUnloads = new List(); + + /// true if any scene (other than the test runner scene) is still loading and could not be unloaded yet + private bool UnloadRemainingScenes() { // Unload any remaining scenes loaded but the test runner scene // Note: Some tests only unload the server-side instance, and this // just assures no currently loaded scenes will impact the next test + Scene testRunnerScene = default; + var sceneStillLoading = false; for (int i = 0; i < SceneManager.sceneCount; i++) { var scene = SceneManager.GetSceneAt(i); - if (!scene.IsValid() || !scene.isLoaded || scene.name.Contains(NetcodeIntegrationTestHelpers.FirstPartOfTestRunnerSceneName) || !OnCanSceneCleanUpUnload(scene)) + if (scene.name.Contains(NetcodeIntegrationTestHelpers.FirstPartOfTestRunnerSceneName)) + { + testRunnerScene = scene; + continue; + } + if (scene.IsValid() && !scene.isLoaded) + { + // Can't unload a scene that is still loading + sceneStillLoading = true; + continue; + } + if (!scene.IsValid() || !OnCanSceneCleanUpUnload(scene)) { continue; } VerboseDebug($"Unloading scene {scene.name}-{scene.handle}"); var asyncOperation = SceneManager.UnloadSceneAsync(scene); + if (asyncOperation != null) + { + m_PendingSceneUnloads.Add(asyncOperation); + } + } + + // Ensure the test runner scene is reset to be the active scene. + if (testRunnerScene.IsValid()) + { + if (SceneManager.GetActiveScene() != testRunnerScene) + { + SceneManager.SetActiveScene(testRunnerScene); + } + } + + return sceneStillLoading; + } + + /// + /// Waits (in real time) for all scenes left over by the test to finish unloading. + /// Scenes that finish loading after tear down started are also unloaded. + /// + private IEnumerator WaitForRemainingScenesUnloaded() + { + var timeOut = Time.realtimeSinceStartup + k_SceneUnloadTimeout; + while (true) + { + // Pick up any scenes that finished loading after the clean up started + var sceneStillLoading = UnloadRemainingScenes(); + + // Keep waiting while a scene is still loading so it can be unloaded once it finishes loading + if (!sceneStillLoading && m_PendingSceneUnloads.All(c => c.isDone)) + { + break; + } + + if (Time.realtimeSinceStartup >= timeOut) + { + Debug.LogWarning($"[{nameof(WaitForRemainingScenesUnloaded)}] Timed out waiting for scenes to unload!"); + break; + } + yield return null; + } + + m_PendingSceneUnloads.Clear(); } private StringBuilder m_WaitForLog = new StringBuilder(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs index 2bdce8f205..16ae641a6a 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportConnectionTests.cs @@ -132,6 +132,7 @@ public IEnumerator ConnectSingleClient_WebSocket_IPAddressAndPath() #if HOSTNAME_RESOLUTION_AVAILABLE // Check connection with a single client (hostname). [UnityTest] + [UnityPlatform(exclude = new[] { RuntimePlatform.PS4, RuntimePlatform.PS5 })] // Ignored test tracked in MTT-16494 public IEnumerator ConnectSingleClient_Hostname() { InitializeTransport(out m_Server, out m_ServerEvents); diff --git a/testproject/Assets/AddressableAssetsData/AddressableAssetSettings.asset b/testproject/Assets/AddressableAssetsData/AddressableAssetSettings.asset index 69bec9b722..f44168c06f 100644 --- a/testproject/Assets/AddressableAssetsData/AddressableAssetSettings.asset +++ b/testproject/Assets/AddressableAssetsData/AddressableAssetSettings.asset @@ -59,7 +59,7 @@ MonoBehaviour: m_ContentStateBuildPathProfileVariableName: m_CustomContentStateBuildPath: m_ContentStateBuildPath: - m_BuildAddressablesWithPlayerBuild: 2 + m_BuildAddressablesWithPlayerBuild: 1 m_overridePlayerVersion: m_GroupAssets: - {fileID: 11400000, guid: 783a7ba7cfd87084388760e6c08547b4, type: 2}