From 6d185e5d24a9836b164a0ddd6a7f79775bd3f69e Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 15:58:36 -0400 Subject: [PATCH 01/32] moving orchestration to this branch from test/multiprocess-testing/wip --- ...nity.multiplayer.mlapi.runtimetests.asmdef | 20 ++- testproject/.gitignore | 3 + testproject/Assets/StreamingAssets.meta | 8 ++ testproject/Assets/StreamingAssets/empty.txt | 0 .../Assets/StreamingAssets/empty.txt.meta | 7 ++ .../Helpers/BuildMultiprocessTestPlayer.cs | 118 ++++++++++++++++++ .../BuildMultiprocessTestPlayer.cs.meta | 11 ++ .../Helpers/MultiprocessOrchestration.cs | 61 +++++++++ .../Helpers/MultiprocessOrchestration.cs.meta | 11 ++ .../Runtime/testproject.runtimetests.asmdef | 22 +++- 10 files changed, 253 insertions(+), 8 deletions(-) create mode 100644 testproject/Assets/StreamingAssets.meta create mode 100644 testproject/Assets/StreamingAssets/empty.txt create mode 100644 testproject/Assets/StreamingAssets/empty.txt.meta create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs.meta create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs.meta diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef b/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef index efbf850de3..07a21b8196 100644 --- a/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef @@ -1,12 +1,24 @@ { "name": "Unity.Multiplayer.MLAPI.RuntimeTests", + "rootNamespace": "", "references": [ "Unity.Multiplayer.MLAPI.Runtime", + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", "Unity.Multiplayer.MLAPI.Editor" ], - "optionalUnityReferences": [ - "TestAssemblies" - ], "includePlatforms": [], - "excludePlatforms": [] + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS", + "UNITY_EDITOR" + ], + "versionDefines": [], + "noEngineReferences": false } \ No newline at end of file diff --git a/testproject/.gitignore b/testproject/.gitignore index 72c27e4fe2..933758634d 100644 --- a/testproject/.gitignore +++ b/testproject/.gitignore @@ -69,3 +69,6 @@ crashlytics-build.properties # Temporary auto-generated Android Assets /[Aa]ssets/[Ss]treamingAssets/aa.meta /[Aa]ssets/[Ss]treamingAssets/aa/* + +/[Aa]ssets/[Ss]treamingAssets/buildInfo.txt +/[Aa]ssets/[Ss]treamingAssets/buildInfo.txt.meta diff --git a/testproject/Assets/StreamingAssets.meta b/testproject/Assets/StreamingAssets.meta new file mode 100644 index 0000000000..2926e11ded --- /dev/null +++ b/testproject/Assets/StreamingAssets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 50c3bcef4ad84445a1f9eb2246d2e172 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/StreamingAssets/empty.txt b/testproject/Assets/StreamingAssets/empty.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testproject/Assets/StreamingAssets/empty.txt.meta b/testproject/Assets/StreamingAssets/empty.txt.meta new file mode 100644 index 0000000000..faaff388a0 --- /dev/null +++ b/testproject/Assets/StreamingAssets/empty.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ab2fb420f22574b13b33f6913b8736d8 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs new file mode 100644 index 0000000000..b7917a266b --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -0,0 +1,118 @@ +using System; +using System.IO; +#if UNITY_EDITOR +using UnityEditor; +using UnityEditor.Build.Reporting; +#endif +using UnityEngine; + +/// +/// This is needed as Unity throws "An abnormal situation has occurred: the PlayerLoop internal function has been called recursively. Please contact Customer Support with a sample project so that we can reproduce the problem and troubleshoot it." +/// when trying to build from Setup() steps in tests. +/// +public class BuildMultiprocessTestPlayer : MonoBehaviour +{ + public const string multiprocessBaseMenuName = "MLAPI Multiprocess Test"; + public const string BuildAndExecuteMenuName = multiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; + public static string buildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); + public const string mainSceneName = "MultiprocessTestingScene"; + + +#if UNITY_EDITOR + [MenuItem(multiprocessBaseMenuName+"/Build Test Player #t")] + public static void BuildNoExecute() + { + var success = Build(); + if (!success) + { + throw new Exception("Build failed!"); + } + } + + [MenuItem(multiprocessBaseMenuName+"/Build Test Player in debug mode")] + public static void BuildDebug() + { + var success = Build(true); + if (!success) + { + throw new Exception("Build failed!"); + } + } + + [MenuItem(multiprocessBaseMenuName+"/Delete Test Build")] + public static void DeleteBuild() + { + switch (Application.platform) + { + case RuntimePlatform.WindowsPlayer: + case RuntimePlatform.WindowsEditor: + var exePath = $"{buildPath}.exe"; + if (File.Exists(exePath)) + { + File.Delete(exePath); + } + else + { + Debug.Log($"exe {exePath} doesn't exists"); + } + break; + case RuntimePlatform.OSXPlayer: + case RuntimePlatform.OSXEditor: + var toDelete = buildPath + ".app"; + if (Directory.Exists(toDelete)) + { + Directory.Delete(toDelete, recursive: true); + } + else + { + Debug.Log($"directory {toDelete} doesn't exists"); + } + break; + default: + throw new NotImplementedException(); + } + } + + /// + /// Needs a separate build than the standalone test builds since we don't want the player to try to connect to the editor to do test + /// reporting. We only want to main node to do that, worker nodes should be dumb + /// + /// + public static bool Build(bool isDebug = false) + { + // Save standalone build path to file + var f = File.CreateText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.buildInfoFileName)); + f.Write(buildPath); + f.Close(); + + // var buildPath = Application.streamingAssetsPath; + // deleting so we don't end up testing on outdated builds if there's a build failure + DeleteBuild(); + + var buildOptions = BuildOptions.None; + buildOptions |= BuildOptions.IncludeTestAssemblies; + buildOptions |= BuildOptions.StrictMode; + if (isDebug) + { + buildOptions |= BuildOptions.Development; + buildOptions |= BuildOptions.AllowDebugging; // enable this if you want to debug your players. Your players + // will have more connection permission popups when launching though + } + + var buildPathToUse = buildPath; + if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) + { + buildPathToUse += ".exe"; + } + + buildOptions &= ~BuildOptions.AutoRunPlayer; + var buildReport = BuildPipeline.BuildPlayer( + new[] { $"Assets/Scenes/{mainSceneName}.unity" }, + buildPathToUse, + EditorUserBuildSettings.activeBuildTarget, + buildOptions); + + return buildReport.summary.result == BuildResult.Succeeded; + } +#endif +} diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs.meta new file mode 100644 index 0000000000..87acf05da8 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b389565fd8544431db4c24940cb569c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs new file mode 100644 index 0000000000..7f9f84d82c --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs @@ -0,0 +1,61 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using UnityEditor; +using UnityEngine; +using Debug = UnityEngine.Debug; + +public class MultiprocessOrchestration +{ + public const string buildInfoFileName = "buildInfo.txt"; + public const string isWorkerArg = "-isWorker"; + + public static void StartWorkerNode() + { + var workerNode = new Process(); + + //TODO this should be replaced eventually by proper orchestration for all supported platforms + string buildInstructions = $"You probably didn't generate your build. Please make sure you build a player using the '{BuildMultiprocessTestPlayer.BuildAndExecuteMenuName}' menu"; + try + { + var buildInfo = File.ReadAllText(Path.Combine(Application.streamingAssetsPath, buildInfoFileName)); + switch (Application.platform) + { + case RuntimePlatform.OSXPlayer: + case RuntimePlatform.OSXEditor: + workerNode.StartInfo.FileName = $"{buildInfo}.app/Contents/MacOS/testproject"; + break; + case RuntimePlatform.WindowsPlayer: + case RuntimePlatform.WindowsEditor: + workerNode.StartInfo.FileName = $"{buildInfo}.exe"; + break; + default: + throw new NotImplementedException("StartWorkerNode: Current platform not supported"); + } + } + catch (FileNotFoundException) + { + throw new Exception($"Couldn't find build info file. {buildInstructions}"); + } + + workerNode.StartInfo.UseShellExecute = false; + workerNode.StartInfo.RedirectStandardError = true; + workerNode.StartInfo.RedirectStandardOutput = true; + workerNode.StartInfo.Arguments = $"{isWorkerArg} -popupwindow -screen-width 100 -screen-height 100"; + // workerNode.StartInfo.Arguments += " -deepprofiling"; // enable for deep profiling + try + { + var newProcessStarted = workerNode.Start(); + if (!newProcessStarted) + { + throw new Exception("Process not started!"); + } + } + catch (Win32Exception e) + { + Debug.LogError($"Error starting player, {buildInstructions}, {e.Message} {e.Data} {e.ErrorCode}"); + throw; + } + } +} diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs.meta new file mode 100644 index 0000000000..4797a6c5a7 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b59a46cbb2c54f4d977a05103227453 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef b/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef index 2aa7afc6f7..45c640863c 100644 --- a/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef +++ b/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef @@ -1,11 +1,25 @@ { "name": "TestProject.RuntimeTests", + "rootNamespace": "", "references": [ "Unity.Multiplayer.MLAPI.Runtime", "Unity.Multiplayer.MLAPI.RuntimeTests", - "TestProject.ManualTests" + "TestProject.ManualTests", + "UnityEngine.TestRunner", + "UnityEditor.TestRunner" ], - "optionalUnityReferences": [ - "TestAssemblies" - ] + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS", + "UNITY_EDITOR" + ], + "versionDefines": [], + "noEngineReferences": false } \ No newline at end of file From 4f6d799560c3d5da95364c835174330a56e426f9 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 16:10:49 -0400 Subject: [PATCH 02/32] moving base for multiprocess tests to this branch from test/multiprocess-testing/wip --- .../Prefabs/PerfTestNetworkObject.prefab | 49 + .../Prefabs/PerfTestNetworkObject.prefab.meta | 7 + .../PerfTestVisualNetworkObject.prefab | 100 ++ .../PerfTestVisualNetworkObject.prefab.meta | 7 + .../Scenes/MultiprocessTestingScene.unity | 922 ++++++++++++++++++ .../MultiprocessTestingScene.unity.meta | 7 + .../BaseMultiprocessTests.cs | 87 ++ .../BaseMultiprocessTests.cs.meta | 11 + .../TestCoordinatorTests.cs | 70 ++ .../TestCoordinatorTests.cs.meta | 11 + ...ltiplayer.mlapi.multiprocessruntime.asmdef | 25 + ...ayer.mlapi.multiprocessruntime.asmdef.meta | 7 + 12 files changed, 1303 insertions(+) create mode 100644 testproject/Assets/Prefabs/PerfTestNetworkObject.prefab create mode 100644 testproject/Assets/Prefabs/PerfTestNetworkObject.prefab.meta create mode 100644 testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab create mode 100644 testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab.meta create mode 100644 testproject/Assets/Scenes/MultiprocessTestingScene.unity create mode 100644 testproject/Assets/Scenes/MultiprocessTestingScene.unity.meta create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs.meta create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs.meta create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef.meta diff --git a/testproject/Assets/Prefabs/PerfTestNetworkObject.prefab b/testproject/Assets/Prefabs/PerfTestNetworkObject.prefab new file mode 100644 index 0000000000..91de39f222 --- /dev/null +++ b/testproject/Assets/Prefabs/PerfTestNetworkObject.prefab @@ -0,0 +1,49 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &5637023994061915634 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5637023994061915632} + - component: {fileID: 5637023994061915633} + m_Layer: 0 + m_Name: PerfTestNetworkObject + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5637023994061915632 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5637023994061915634} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &5637023994061915633 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5637023994061915634} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 951099334 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 diff --git a/testproject/Assets/Prefabs/PerfTestNetworkObject.prefab.meta b/testproject/Assets/Prefabs/PerfTestNetworkObject.prefab.meta new file mode 100644 index 0000000000..feebc7c48c --- /dev/null +++ b/testproject/Assets/Prefabs/PerfTestNetworkObject.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b0952a471c5a147cb92f6afcdb648f8a +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab b/testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab new file mode 100644 index 0000000000..6673fbefcd --- /dev/null +++ b/testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab @@ -0,0 +1,100 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &9115731988109684252 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9115731988109684241} + - component: {fileID: 9115731988109684240} + - component: {fileID: 9115731988109684243} + - component: {fileID: 9115731988109684253} + m_Layer: 0 + m_Name: PerfTestVisualNetworkObject + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &9115731988109684241 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9115731988109684252} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &9115731988109684240 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9115731988109684252} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &9115731988109684243 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9115731988109684252} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &9115731988109684253 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9115731988109684252} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 951099334 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 diff --git a/testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab.meta b/testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab.meta new file mode 100644 index 0000000000..f268093417 --- /dev/null +++ b/testproject/Assets/Prefabs/PerfTestVisualNetworkObject.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c2851feb7276442cc86a6f2d1d69ea11 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Scenes/MultiprocessTestingScene.unity b/testproject/Assets/Scenes/MultiprocessTestingScene.unity new file mode 100644 index 0000000000..65e0b7ee89 --- /dev/null +++ b/testproject/Assets/Scenes/MultiprocessTestingScene.unity @@ -0,0 +1,922 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657874, g: 0.49641275, b: 0.5748172, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 130932425} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &127222500 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 127222502} + - component: {fileID: 127222501} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &127222501 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 127222500} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &127222502 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 127222500} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!850595691 &130932425 +LightingSettings: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + serializedVersion: 3 + m_GIWorkflowMode: 1 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_RealtimeEnvironmentLighting: 1 + m_BounceScale: 1 + m_AlbedoBoost: 1 + m_IndirectOutputScale: 1 + m_UsingShadowmask: 1 + m_BakeBackend: 1 + m_LightmapMaxSize: 1024 + m_BakeResolution: 40 + m_Padding: 2 + m_TextureCompression: 1 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAO: 0 + m_MixedBakeMode: 2 + m_LightmapsBakeMode: 1 + m_FilterMode: 1 + m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_RealtimeResolution: 2 + m_ForceWhiteAlbedo: 0 + m_ForceUpdates: 0 + m_FinalGather: 0 + m_FinalGatherRayCount: 256 + m_FinalGatherFiltering: 1 + m_PVRCulling: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_LightProbeSampleCountMultiplier: 4 + m_PVRBounces: 2 + m_PVRMinBounces: 1 + m_PVREnvironmentMIS: 1 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 +--- !u!1 &160940364 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 160940368} + - component: {fileID: 160940367} + - component: {fileID: 160940366} + - component: {fileID: 160940365} + m_Layer: 0 + m_Name: Boundary bottom left + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!135 &160940365 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160940364} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &160940366 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160940364} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &160940367 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160940364} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &160940368 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 160940364} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -10, y: -10, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &941021721 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 941021724} + - component: {fileID: 941021723} + - component: {fileID: 941021722} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &941021722 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 941021721} + m_Enabled: 1 +--- !u!20 &941021723 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 941021721} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &941021724 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 941021721} + m_LocalRotation: {x: 0.21736304, y: -0, z: -0, w: 0.97609085} + m_LocalPosition: {x: 0, y: 9.15, z: -27.5} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 25.108, y: 0, z: 0} +--- !u!1 &996484657 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 996484661} + - component: {fileID: 996484660} + - component: {fileID: 996484659} + - component: {fileID: 996484658} + m_Layer: 0 + m_Name: Boundary center + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!135 &996484658 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996484657} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &996484659 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996484657} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &996484660 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996484657} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &996484661 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996484657} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1206022453 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1206022457} + - component: {fileID: 1206022456} + - component: {fileID: 1206022455} + - component: {fileID: 1206022454} + m_Layer: 0 + m_Name: Boundary top right + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!135 &1206022454 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1206022453} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1206022455 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1206022453} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1206022456 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1206022453} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1206022457 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1206022453} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 10, y: 10, z: 10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1211923374 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1211923376} + - component: {fileID: 1211923375} + - component: {fileID: 1211923377} + - component: {fileID: 1211923378} + m_Layer: 0 + m_Name: NetworkManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1211923375 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1211923374} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 593a2fe42fa9d37498c96f9a383b6521, type: 3} + m_Name: + m_EditorClassIdentifier: + DontDestroy: 0 + RunInBackground: 1 + LogLevel: 1 + NetworkConfig: + ProtocolVersion: 0 + NetworkTransport: {fileID: 1674777073} + RegisteredScenes: + - MultiprocessTestingScene + - SampleScene + AllowRuntimeSceneChanges: 0 + PlayerPrefab: {fileID: 4700706668509470175, guid: 7eeaaf9e50c0afc4dab93584a54fb0d6, + type: 3} + NetworkPrefabs: + - Override: 0 + Prefab: {fileID: 9115731988109684252, guid: c2851feb7276442cc86a6f2d1d69ea11, + type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + ReceiveTickrate: 64 + NetworkTickIntervalSec: 0.05 + MaxReceiveEventsPerTickRate: -1 + EventTickrate: 64 + ClientConnectionBufferTimeout: 10 + ConnectionApproval: 0 + ConnectionData: + EnableTimeResync: 0 + TimeResyncInterval: 30 + EnableNetworkVariable: 1 + EnsureNetworkVariableLengthSafety: 0 + EnableSceneManagement: 1 + ForceSamePrefabs: 1 + RecycleNetworkIds: 1 + NetworkIdRecycleDelay: 120 + RpcHashSize: 0 + LoadSceneTimeOut: 120 + EnableMessageBuffering: 1 + MessageBufferTimeout: 20 + EnableNetworkLogs: 1 +--- !u!4 &1211923376 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1211923374} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1674777072} + - {fileID: 2027640072} + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1211923377 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1211923374} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 068bf11ceb1344667af4cc40950f44f4, type: 3} + m_Name: + m_EditorClassIdentifier: + referencedPrefab: {fileID: 5637023994061915634, guid: b0952a471c5a147cb92f6afcdb648f8a, + type: 3} +--- !u!114 &1211923378 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1211923374} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 55d1c75ce242745ac98f7e7aca6d2d19, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1274245423 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1274245425} + - component: {fileID: 1274245424} + - component: {fileID: 1274245426} + m_Layer: 0 + m_Name: TestCoordinator + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1274245424 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1274245423} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 2217825759 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!4 &1274245425 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1274245423} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 10, y: 10, z: 10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1274245426 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1274245423} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ef1240e0784f84eadb77fe822e2e03c7, type: 3} + m_Name: + m_EditorClassIdentifier: + isRegistering: 0 + hasRegistered: 0 +--- !u!1 &1674777071 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1674777072} + - component: {fileID: 1674777073} + m_Layer: 0 + m_Name: UNET + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1674777072 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1674777071} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1211923376} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1674777073 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1674777071} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b84c2d8dfe509a34fb59e2b81f8e1319, type: 3} + m_Name: + m_EditorClassIdentifier: + MessageBufferSize: 50000 + MaxConnections: 100 + MaxSentMessageQueueSize: 50000 + ConnectAddress: 127.0.0.1 + ConnectPort: 7777 + ServerListenPort: 7777 + ServerWebsocketListenPort: 8887 + SupportWebsocket: 0 + Channels: [] + UseMLAPIRelay: 0 + MLAPIRelayAddress: 184.72.104.138 + MLAPIRelayPort: 8888 + MessageSendMode: 0 +--- !u!1 &2027640071 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2027640072} + - component: {fileID: 2027640073} + m_Layer: 0 + m_Name: UTP + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2027640072 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2027640071} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1211923376} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2027640073 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2027640071} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fc5ef7b69296d69458910681f29471e6, type: 3} + m_Name: + m_EditorClassIdentifier: + Port: 7777 + Address: 127.0.0.1 diff --git a/testproject/Assets/Scenes/MultiprocessTestingScene.unity.meta b/testproject/Assets/Scenes/MultiprocessTestingScene.unity.meta new file mode 100644 index 0000000000..5a9d45d780 --- /dev/null +++ b/testproject/Assets/Scenes/MultiprocessTestingScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 76743cb7b342c49279327834918a9c6e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs new file mode 100644 index 0000000000..8babc0bf17 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.TestTools; + +namespace MLAPI.MultiprocessRuntimeTests +{ + public class MultiprocessTestsAttribute : CategoryAttribute + { + public const string multiprocessCategoryName = "Multiprocess"; + public MultiprocessTestsAttribute() : base(multiprocessCategoryName){} + } + + [MultiprocessTests] + public abstract class BaseMultiprocessTests + { + + protected virtual bool m_IsPerformanceTest => true; + + private bool ShouldIgnoreTests => m_IsPerformanceTest && Application.isEditor; + + protected abstract int NbWorkers { get; } + + [OneTimeSetUp] + public virtual void SetupTestFixture() + { + if (ShouldIgnoreTests) + { + Assert.Ignore("Ignoring tests that shouldn't run from unity editor. Performance tests should be run from remote test execution on device (this can be ran using the \"run selected tests (your platform)\" button"); + } + + SceneManager.LoadScene(BuildMultiprocessTestPlayer.mainSceneName, LoadSceneMode.Single); + SceneManager.sceneLoaded += OnSceneLoaded; + + for (int i = 0; i < NbWorkers; i++) + { + MultiprocessOrchestration.StartWorkerNode(); // will automatically start built player as clients + } + } + + private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) + { + SceneManager.sceneLoaded -= OnSceneLoaded; + NetworkManager.Singleton.StartHost(); + } + + [UnitySetUp] + public virtual IEnumerator Setup() + { + yield return new WaitUntil(() => NetworkManager.Singleton != null && NetworkManager.Singleton.IsServer); + + var startTime = Time.time; + while (NetworkManager.Singleton.ConnectedClients.Count <= NbWorkers) + { + yield return new WaitForSeconds(0.2f); + + if (Time.time - startTime > TestCoordinator.maxWaitTimeout) + { + throw new Exception($"waiting too long to see clients to connect, got {NetworkManager.Singleton.ConnectedClients.Count - 1} clients, but was expecting {NbWorkers}, failing"); + } + } + TestCoordinator.Instance.KeepAliveClientRpc(); + } + + [TearDown] + public virtual void Teardown() + { + if (!ShouldIgnoreTests) + { + TestCoordinator.Instance.TestRunTeardown(); + } + } + + [OneTimeTearDown] + public virtual void TeardownSuite() + { + if (!ShouldIgnoreTests) + { + TestCoordinator.Instance.CloseRemoteClientRpc(); + NetworkManager.Singleton.StopHost(); + } + } + } +} + diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs.meta new file mode 100644 index 0000000000..6b52bd9e90 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f77e60aa394b9419784b6c46618fb553 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs new file mode 100644 index 0000000000..4c22ca1d21 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace MLAPI.MultiprocessRuntimeTests +{ + [TestFixture(1)] + [TestFixture(2)] + public class TestCoordinatorTests : BaseMultiprocessTests + { + private int m_NbWorkers; + protected override int NbWorkers => m_NbWorkers; + + protected override bool m_IsPerformanceTest => false; + + public TestCoordinatorTests(int nbWorkers) + { + m_NbWorkers = nbWorkers; + } + + private static void ExecuteSimpleCoordinatorTest() + { + TestCoordinator.Instance.WriteTestResultsServerRpc(float.PositiveInfinity); + } + + private static void ExecuteWithArgs(byte[] args) + { + TestCoordinator.Instance.WriteTestResultsServerRpc(args[0]); + } + + [UnityTest] + public IEnumerator CheckTestCoordinator() + { + // Sanity check for TestCoordinator + // Call the method + TestCoordinator.Instance.InvokeFromMethodActionRpc(ExecuteSimpleCoordinatorTest); + + var nbResults = 0; + for (int i = 0; i < NbWorkers; i++) // wait and test for the two clients + { + yield return new WaitUntil(TestCoordinator.ResultIsSet()); + + var (clientId, result) = TestCoordinator.ConsumeCurrentResult().Take(1).Single(); + Assert.Greater(result, 0f); + nbResults++; + } + Assert.That(nbResults, Is.EqualTo(NbWorkers)); + } + + [UnityTest] + public IEnumerator CheckTestCoordinatorWithArgs() + { + TestCoordinator.Instance.InvokeFromMethodActionRpc(ExecuteWithArgs, 99); + var nbResults = 0; + + for (int i = 0; i < NbWorkers; i++) // wait and test for the two clients + { + yield return new WaitUntil(TestCoordinator.ResultIsSet()); + + var (clientId, result) = TestCoordinator.ConsumeCurrentResult().Take(1).Single(); + Assert.That(result, Is.EqualTo(99)); + nbResults++; + } + Assert.That(nbResults, Is.EqualTo(NbWorkers)); + } + } +} diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs.meta new file mode 100644 index 0000000000..104be914d0 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5e62651568514685a0b50d623fa8a96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef new file mode 100644 index 0000000000..43f80edd04 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef @@ -0,0 +1,25 @@ +{ + "name": "Unity.Multiplayer.MLAPI.MultiprocessRuntime", + "rootNamespace": "", + "references": [ + "Unity.Multiplayer.MLAPI.Runtime", + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "ScriptsForAutomatedTesting", + "Unity.PerformanceTesting", + "MultiprocessTestsHelpers" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef.meta new file mode 100644 index 0000000000..a06b37d08b --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/com.unity.multiplayer.mlapi.multiprocessruntime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 66273ab9e01074f7da305fe84e13da47 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From efb083cec872a82a42e5ca51e48c721ea9afced2 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 16:37:21 -0400 Subject: [PATCH 03/32] adding fixed testcoordinator --- .../MultiprocessRuntime/TestCoordinator.cs | 337 ++++++++++++++++++ .../TestCoordinator.cs.meta | 11 + 2 files changed, 348 insertions(+) create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs.meta diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs new file mode 100644 index 0000000000..6602faade7 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -0,0 +1,337 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using MLAPI; +using MLAPI.Configuration; +using MLAPI.Logging; +using MLAPI.Messaging; +using NUnit.Framework; +using NUnit.Framework.Interfaces; +using UnityEngine; +using UnityEngine.TestTools; +using Debug = UnityEngine.Debug; + +/// +/// TestCoordinator +/// Used for coordinating multiprocess end to end tests. Used to call RPCs on other nodes and gather results +/// This is needed to coordinate server and client execution steps. The current remote player test runner hardcodes test +/// to run in a bootstrap scene before launching the player and doesn't call each tests individually. There's not opportunity +/// to coordinate test execution between client and server with that model. +/// The only per tests communication already existing is to get the results per test as they are running +/// With this test coordinator, it's not possible to start a main test node with the test runner and have that server start other worker nodes +/// on which to execute client tests. We use MLAPI as both a test framework and as the target of our performance tests. +/// +[RequireComponent(typeof(NetworkObject))] +public class TestCoordinator : NetworkBehaviour +{ + public const int perTestTimeout = 5 * 60; // seconds + + public const float maxWaitTimeout = 20; + private const char k_MethodFullNameSplitChar = '@'; + + + private bool m_ShouldShutdown; + private float m_TimeSinceLastConnected; + private float m_TimeSinceLastKeepAlive; + + public static TestCoordinator Instance; + + private Dictionary> m_TestResultsLocal = new Dictionary>(); // this isn't super efficient, but since it's used for signaling around the tests, shouldn't be too bad + private Dictionary m_ClientIsFinished = new Dictionary(); + + public static Dictionary>.KeyCollection AllClientIdsWithResults => Instance.m_TestResultsLocal.Keys; + public static List AllClientIdExceptMine => NetworkManager.Singleton.ConnectedClients.Keys.ToList().FindAll(client => client != NetworkManager.Singleton.LocalClientId); + + private void Awake() + { + if (Instance != null) + { + Debug.LogError("Multiple test coordinator! destroying self"); + Destroy(gameObject); + return; + } + + Instance = this; + } + + public void Start() + { + bool isClient = Environment.GetCommandLineArgs().Any(value => value == MultiprocessOrchestration.isWorkerArg); + if (isClient) + { + Debug.Log("starting MLAPI client"); + NetworkManager.Singleton.StartClient(); + } + + NetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback; + + ExecuteStepInContext.InitializeAllSteps(); + } + + public void Update() + { + if (Time.time - m_TimeSinceLastKeepAlive > perTestTimeout) + { + QuitApplication(); + Assert.Fail("Stayed idle too long"); + } + if ((IsServer && NetworkManager.Singleton.IsListening) || (IsClient && NetworkManager.Singleton.IsConnectedClient)) + { + m_TimeSinceLastConnected = Time.time; + } + else if (Time.time - m_TimeSinceLastConnected > maxWaitTimeout || m_ShouldShutdown) + { + // Make sure we don't have zombie processes + Debug.Log($"quitting application, shouldShutdown set to {m_ShouldShutdown}, is listening {NetworkManager.Singleton.IsListening}, is connected client {NetworkManager.Singleton.IsConnectedClient}"); + if (!m_ShouldShutdown) + { + QuitApplication(); + Assert.Fail($"something wrong happened, was not connected for {Time.time - m_TimeSinceLastConnected} seconds"); + } + } + } + + private static void QuitApplication() + { +#if UNITY_EDITOR + UnityEditor.EditorApplication.isPlaying = false; +#else + Application.Quit(); +#endif + } + + public void TestRunTeardown() + { + m_TestResultsLocal.Clear(); + } + + public void OnDestroy() + { + if (NetworkObject != null && NetworkManager != null) + { + NetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback; + } + } + + private static void OnClientDisconnectCallback(ulong clientId) + { + if (clientId == NetworkManager.Singleton.ServerClientId || clientId == NetworkManager.Singleton.LocalClientId) + { + // if disconnect callback is for me or for server, quit, we're done here + Debug.Log($"received disconnect from {clientId}, quitting"); + QuitApplication(); + } + } + + private static string GetMethodInfo(Action method) + { + return $"{method.Method.DeclaringType.FullName}{k_MethodFullNameSplitChar}{method.Method.Name}"; + } + + private static string GetMethodInfo(Action method) + { + return $"{method.Method.DeclaringType.FullName}{k_MethodFullNameSplitChar}{method.Method.Name}"; + } + + public static IEnumerable<(ulong clientId, float result)> ConsumeCurrentResult() + { + foreach (var kv in Instance.m_TestResultsLocal) + { + while (kv.Value.Count > 0) + { + var toReturn = (kv.Key, kv.Value[0]); + kv.Value.RemoveAt(0); + yield return toReturn; + } + } + } + + public static IEnumerable ConsumeCurrentResult(ulong clientID) + { + var allResults = Instance.m_TestResultsLocal[clientID]; + while (allResults.Count > 0) + { + var toReturn = allResults[0]; + allResults.RemoveAt(0); + yield return toReturn; + } + } + + public static float PeekLatestResult(ulong clientId) + { + if (Instance.m_TestResultsLocal.ContainsKey(clientId) && Instance.m_TestResultsLocal[clientId].Count > 0) + { + return Instance.m_TestResultsLocal[clientId].Last(); + } + + return float.NaN; + } + + /// + /// Returns appropriate lambda according to parameters + /// Includes time check to make sure this times out + /// + /// + /// + /// + public static Func ResultIsSet(bool useTimeoutException = true) + { + var startWaitTime = Time.time; + return () => + { + if (Time.time - startWaitTime > maxWaitTimeout) + { + if (useTimeoutException) + { + throw new Exception($"timeout while waiting for results, didn't get results for {Time.time - startWaitTime} seconds"); + } + + return true; + } + + foreach (var clientIdAndTestResultList in Instance.m_TestResultsLocal) + { + if (clientIdAndTestResultList.Value.Count > 0) + { + return true; + } + } + + return false; + }; + } + + public static Func ConsumeClientIsFinished(ulong clientId, bool useTimeoutException = true) + { + var startWaitTime = Time.time; + return () => + { + if (Time.time - startWaitTime > maxWaitTimeout) + { + if (useTimeoutException) + { + throw new Exception($"timeout while waiting for client finished, didn't get results for {Time.time - startWaitTime} seconds"); + } + else + { + return true; + } + } + + if (Instance.m_ClientIsFinished.ContainsKey(clientId) && Instance.m_ClientIsFinished[clientId]) + { + Instance.m_ClientIsFinished[clientId] = false; // consume + return true; + } + + return false; + }; + } + + [ServerRpc(RequireOwnership = false)] + public void ClientFinishedServerRpc(ServerRpcParams p = default) + { + // signal from clients to the server to say the client is done with it's task + m_ClientIsFinished[p.Receive.SenderClientId] = true; + } + + public void InvokeFromMethodActionRpc(Action methodInfo, params byte[] args) + { + var methodInfoString = GetMethodInfo(methodInfo); + InvokeFromMethodNameClientRpc(methodInfoString, args, new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = AllClientIdExceptMine.ToArray() } }); + } + + public void InvokeFromMethodActionRpc(Action methodInfo) + { + var methodInfoString = GetMethodInfo(methodInfo); + InvokeFromMethodNameClientRpc(methodInfoString, null, new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = AllClientIdExceptMine.ToArray() } }); + } + + [ClientRpc] + public void TriggerActionIDClientRpc(string actionID, byte[] args, ClientRpcParams clientRpcParams = default) + { + Debug.Log($"received RPC from server, client side triggering action ID {actionID}"); + try + { + ExecuteStepInContext.allActions[actionID].Invoke(args); + } + catch (Exception e) + { + WriteErrorServerRpc(e.Message); + throw; + } + } + + [ClientRpc] + public void InvokeFromMethodNameClientRpc(string methodInfoString, byte[] args, ClientRpcParams clientRpcParams = default) + { + try + { + var split = methodInfoString.Split(k_MethodFullNameSplitChar); + var (classToExecute, staticMethodToExecute) = (split[0], split[1]); + + var foundType = Type.GetType(classToExecute); + if (foundType == null) + { + throw new Exception($"couldn't find {classToExecute}"); + } + + var foundMethod = foundType.GetMethod(staticMethodToExecute, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + if (foundMethod == null) + { + throw new Exception($"couldn't find method {staticMethodToExecute}"); + } + + foundMethod.Invoke(null, args != null ? new object[] { args } : null); + } + catch (Exception e) + { + WriteErrorServerRpc(e.Message); + throw; + } + } + + [ClientRpc] + public void CloseRemoteClientRpc() + { + try + { + NetworkManager.Singleton.StopClient(); + m_ShouldShutdown = true; // wait until isConnectedClient is false to run Application Quit in next update + Debug.Log("Quitting player cleanly"); + Application.Quit(); + } + catch (Exception e) + { + WriteErrorServerRpc(e.Message); + throw; + } + } + + [ClientRpc] + public void KeepAliveClientRpc() + { + m_TimeSinceLastKeepAlive = Time.time; + } + + [ServerRpc(RequireOwnership = false)] + public void WriteTestResultsServerRpc(float result, ServerRpcParams receiveParams = default) + { + var senderId = receiveParams.Receive.SenderClientId; + if (!m_TestResultsLocal.ContainsKey(senderId)) + { + m_TestResultsLocal[senderId] = new List(); + } + + m_TestResultsLocal[senderId].Add(result); + } + + [ServerRpc(RequireOwnership = false)] + public void WriteErrorServerRpc(string errorMessage, ServerRpcParams receiveParams = default) + { + Debug.LogError($"Got Exception client side {errorMessage}, from client {receiveParams.Receive.SenderClientId}"); + } +} diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs.meta new file mode 100644 index 0000000000..f8c2a3c472 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef1240e0784f84eadb77fe822e2e03c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 4ea4d4ca720bb0b733872f4eefd5db950a73561f Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 16:42:25 -0400 Subject: [PATCH 04/32] adding missing change --- testproject/ProjectSettings/EditorBuildSettings.asset | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testproject/ProjectSettings/EditorBuildSettings.asset b/testproject/ProjectSettings/EditorBuildSettings.asset index 0f1a066d92..da26d6d0c7 100644 --- a/testproject/ProjectSettings/EditorBuildSettings.asset +++ b/testproject/ProjectSettings/EditorBuildSettings.asset @@ -41,4 +41,7 @@ EditorBuildSettings: - enabled: 1 path: Assets/Tests/Manual/NetworkSceneManagerCallbacks/SceneWeAreSwitchingFrom.unity guid: 073bd2111475c0643be45b7abe6a97ad + - enabled: 1 + path: Assets/Scenes/MultiprocessTestingScene.unity + guid: 76743cb7b342c49279327834918a9c6e m_configObjects: {} From 5803269e30a3fb26307d851ea7d574a1b261de26 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 17:35:28 -0400 Subject: [PATCH 05/32] taking changes from wip branch --- .../Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs index 8babc0bf17..d49d2f857d 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs @@ -24,7 +24,7 @@ public abstract class BaseMultiprocessTests protected abstract int NbWorkers { get; } [OneTimeSetUp] - public virtual void SetupTestFixture() + public virtual void SetupTestSuite() { if (ShouldIgnoreTests) { From c804d641f1e8c54a986386e1c0d429597f876b68 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 18:07:28 -0400 Subject: [PATCH 06/32] commenting out ExecuteStepInContext for better PR clarity --- .../Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs index 6602faade7..92078a3c98 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -68,7 +68,7 @@ public void Start() NetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback; - ExecuteStepInContext.InitializeAllSteps(); + // ExecuteStepInContext.InitializeAllSteps(); } public void Update() @@ -256,7 +256,7 @@ public void TriggerActionIDClientRpc(string actionID, byte[] args, ClientRpcPara Debug.Log($"received RPC from server, client side triggering action ID {actionID}"); try { - ExecuteStepInContext.allActions[actionID].Invoke(args); + // ExecuteStepInContext.allActions[actionID].Invoke(args); } catch (Exception e) { From 23e435aa5d15d8b5919edd161b76fa11ed646fca Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 19:36:49 -0400 Subject: [PATCH 07/32] cleanup --- .../MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index b7917a266b..1b7d2b24e1 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -80,12 +80,11 @@ public static void DeleteBuild() /// public static bool Build(bool isDebug = false) { - // Save standalone build path to file + // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) var f = File.CreateText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.buildInfoFileName)); f.Write(buildPath); f.Close(); - // var buildPath = Application.streamingAssetsPath; // deleting so we don't end up testing on outdated builds if there's a build failure DeleteBuild(); From c38a957ecba73423c0a8088105164424f7375dd6 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Sun, 27 Jun 2021 19:41:09 -0400 Subject: [PATCH 08/32] better name --- .../MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 1b7d2b24e1..3e9d4d82d5 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -20,7 +20,7 @@ public class BuildMultiprocessTestPlayer : MonoBehaviour #if UNITY_EDITOR [MenuItem(multiprocessBaseMenuName+"/Build Test Player #t")] - public static void BuildNoExecute() + public static void BuildNoDebug() { var success = Build(); if (!success) From b1656ae5e159e447633a3ae1289d5c2ac5913a88 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Mon, 5 Jul 2021 18:30:54 -0400 Subject: [PATCH 09/32] consistent naming --- .../Helpers/BuildMultiprocessTestPlayer.cs | 27 +++++++++---------- .../Helpers/MultiprocessOrchestration.cs | 8 +++--- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 3e9d4d82d5..94bc5a7dcf 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -12,14 +12,13 @@ /// public class BuildMultiprocessTestPlayer : MonoBehaviour { - public const string multiprocessBaseMenuName = "MLAPI Multiprocess Test"; - public const string BuildAndExecuteMenuName = multiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; - public static string buildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); - public const string mainSceneName = "MultiprocessTestingScene"; - + public const string BuildAndExecuteMenuName = k_MultiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; + private const string k_MultiprocessBaseMenuName = "MLAPI Multiprocess Test"; + private const string k_MainSceneName = "MultiprocessTestingScene"; + private static string s_BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); #if UNITY_EDITOR - [MenuItem(multiprocessBaseMenuName+"/Build Test Player #t")] + [MenuItem(k_MultiprocessBaseMenuName+"/Build Test Player #t")] public static void BuildNoDebug() { var success = Build(); @@ -29,7 +28,7 @@ public static void BuildNoDebug() } } - [MenuItem(multiprocessBaseMenuName+"/Build Test Player in debug mode")] + [MenuItem(k_MultiprocessBaseMenuName+"/Build Test Player in debug mode")] public static void BuildDebug() { var success = Build(true); @@ -39,14 +38,14 @@ public static void BuildDebug() } } - [MenuItem(multiprocessBaseMenuName+"/Delete Test Build")] + [MenuItem(k_MultiprocessBaseMenuName+"/Delete Test Build")] public static void DeleteBuild() { switch (Application.platform) { case RuntimePlatform.WindowsPlayer: case RuntimePlatform.WindowsEditor: - var exePath = $"{buildPath}.exe"; + var exePath = $"{s_BuildPath}.exe"; if (File.Exists(exePath)) { File.Delete(exePath); @@ -58,7 +57,7 @@ public static void DeleteBuild() break; case RuntimePlatform.OSXPlayer: case RuntimePlatform.OSXEditor: - var toDelete = buildPath + ".app"; + var toDelete = s_BuildPath + ".app"; if (Directory.Exists(toDelete)) { Directory.Delete(toDelete, recursive: true); @@ -81,8 +80,8 @@ public static void DeleteBuild() public static bool Build(bool isDebug = false) { // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) - var f = File.CreateText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.buildInfoFileName)); - f.Write(buildPath); + var f = File.CreateText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName)); + f.Write(s_BuildPath); f.Close(); // deleting so we don't end up testing on outdated builds if there's a build failure @@ -98,7 +97,7 @@ public static bool Build(bool isDebug = false) // will have more connection permission popups when launching though } - var buildPathToUse = buildPath; + var buildPathToUse = s_BuildPath; if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) { buildPathToUse += ".exe"; @@ -106,7 +105,7 @@ public static bool Build(bool isDebug = false) buildOptions &= ~BuildOptions.AutoRunPlayer; var buildReport = BuildPipeline.BuildPlayer( - new[] { $"Assets/Scenes/{mainSceneName}.unity" }, + new[] { $"Assets/Scenes/{k_MainSceneName}.unity" }, buildPathToUse, EditorUserBuildSettings.activeBuildTarget, buildOptions); diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs index 7f9f84d82c..7977f9db57 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs @@ -8,8 +8,8 @@ public class MultiprocessOrchestration { - public const string buildInfoFileName = "buildInfo.txt"; - public const string isWorkerArg = "-isWorker"; + public const string BuildInfoFileName = "buildInfo.txt"; + public const string IsWorkerArg = "-isWorker"; public static void StartWorkerNode() { @@ -19,7 +19,7 @@ public static void StartWorkerNode() string buildInstructions = $"You probably didn't generate your build. Please make sure you build a player using the '{BuildMultiprocessTestPlayer.BuildAndExecuteMenuName}' menu"; try { - var buildInfo = File.ReadAllText(Path.Combine(Application.streamingAssetsPath, buildInfoFileName)); + var buildInfo = File.ReadAllText(Path.Combine(Application.streamingAssetsPath, BuildInfoFileName)); switch (Application.platform) { case RuntimePlatform.OSXPlayer: @@ -42,7 +42,7 @@ public static void StartWorkerNode() workerNode.StartInfo.UseShellExecute = false; workerNode.StartInfo.RedirectStandardError = true; workerNode.StartInfo.RedirectStandardOutput = true; - workerNode.StartInfo.Arguments = $"{isWorkerArg} -popupwindow -screen-width 100 -screen-height 100"; + workerNode.StartInfo.Arguments = $"{IsWorkerArg} -popupwindow -screen-width 100 -screen-height 100"; // workerNode.StartInfo.Arguments += " -deepprofiling"; // enable for deep profiling try { From 4ddcd259990a080eeef2072d0e444272c3156fdb Mon Sep 17 00:00:00 2001 From: Sam Bellomo <71790295+SamuelBellomo@users.noreply.github.com> Date: Mon, 5 Jul 2021 18:54:54 -0400 Subject: [PATCH 10/32] Apply suggestions from code review Fixed some typos Co-authored-by: Matt Walsh <69258106+mattwalsh-unity@users.noreply.github.com> --- .../Helpers/BuildMultiprocessTestPlayer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 3e9d4d82d5..f7125cbc25 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -53,7 +53,7 @@ public static void DeleteBuild() } else { - Debug.Log($"exe {exePath} doesn't exists"); + Debug.Log($"exe {exePath} doesn't exist"); } break; case RuntimePlatform.OSXPlayer: @@ -65,7 +65,7 @@ public static void DeleteBuild() } else { - Debug.Log($"directory {toDelete} doesn't exists"); + Debug.Log($"directory {toDelete} doesn't exist"); } break; default: From 55e6853dcc81ed82ef666f818554521bd1090305 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Mon, 5 Jul 2021 18:55:36 -0400 Subject: [PATCH 11/32] Applying suggestions --- .../Helpers/BuildMultiprocessTestPlayer.cs | 6 ++---- .../Helpers/MultiprocessOrchestration.cs | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 94bc5a7dcf..88918f9950 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -10,7 +10,7 @@ /// This is needed as Unity throws "An abnormal situation has occurred: the PlayerLoop internal function has been called recursively. Please contact Customer Support with a sample project so that we can reproduce the problem and troubleshoot it." /// when trying to build from Setup() steps in tests. /// -public class BuildMultiprocessTestPlayer : MonoBehaviour +public static class BuildMultiprocessTestPlayer { public const string BuildAndExecuteMenuName = k_MultiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; private const string k_MultiprocessBaseMenuName = "MLAPI Multiprocess Test"; @@ -80,9 +80,7 @@ public static void DeleteBuild() public static bool Build(bool isDebug = false) { // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) - var f = File.CreateText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName)); - f.Write(s_BuildPath); - f.Close(); + File.WriteAllText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName), s_BuildPath); // deleting so we don't end up testing on outdated builds if there's a build failure DeleteBuild(); diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs index 7977f9db57..31487b675b 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs @@ -16,6 +16,8 @@ public static void StartWorkerNode() var workerNode = new Process(); //TODO this should be replaced eventually by proper orchestration for all supported platforms + // Starting new local processes is a solution to help run perf tests locally. CI should have multi machine orchestration to + // run performance tests with more realistic conditions. string buildInstructions = $"You probably didn't generate your build. Please make sure you build a player using the '{BuildMultiprocessTestPlayer.BuildAndExecuteMenuName}' menu"; try { @@ -36,7 +38,8 @@ public static void StartWorkerNode() } catch (FileNotFoundException) { - throw new Exception($"Couldn't find build info file. {buildInstructions}"); + Debug.LogError($"Couldn't find build info file. {buildInstructions}"); + throw; } workerNode.StartInfo.UseShellExecute = false; From 17c7e7d9247ff435e7a50fe9fcf140089ffcfa36 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Mon, 5 Jul 2021 19:02:28 -0400 Subject: [PATCH 12/32] naming --- .../Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs index 92078a3c98..9b6a8de724 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -43,7 +43,7 @@ public class TestCoordinator : NetworkBehaviour private Dictionary m_ClientIsFinished = new Dictionary(); public static Dictionary>.KeyCollection AllClientIdsWithResults => Instance.m_TestResultsLocal.Keys; - public static List AllClientIdExceptMine => NetworkManager.Singleton.ConnectedClients.Keys.ToList().FindAll(client => client != NetworkManager.Singleton.LocalClientId); + public static List AllClientIdsExceptMine => NetworkManager.Singleton.ConnectedClients.Keys.ToList().FindAll(client => client != NetworkManager.Singleton.LocalClientId); private void Awake() { @@ -241,13 +241,13 @@ public void ClientFinishedServerRpc(ServerRpcParams p = default) public void InvokeFromMethodActionRpc(Action methodInfo, params byte[] args) { var methodInfoString = GetMethodInfo(methodInfo); - InvokeFromMethodNameClientRpc(methodInfoString, args, new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = AllClientIdExceptMine.ToArray() } }); + InvokeFromMethodNameClientRpc(methodInfoString, args, new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = AllClientIdsExceptMine.ToArray() } }); } public void InvokeFromMethodActionRpc(Action methodInfo) { var methodInfoString = GetMethodInfo(methodInfo); - InvokeFromMethodNameClientRpc(methodInfoString, null, new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = AllClientIdExceptMine.ToArray() } }); + InvokeFromMethodNameClientRpc(methodInfoString, null, new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = AllClientIdsExceptMine.ToArray() } }); } [ClientRpc] From 72217122102a728f54f3cafc6e24c29faf169d99 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Mon, 5 Jul 2021 19:04:41 -0400 Subject: [PATCH 13/32] should be kept public for following PR --- .../Helpers/BuildMultiprocessTestPlayer.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 4a4023870f..0c017f18d7 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -12,13 +12,13 @@ /// public static class BuildMultiprocessTestPlayer { - public const string BuildAndExecuteMenuName = k_MultiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; - private const string k_MultiprocessBaseMenuName = "MLAPI Multiprocess Test"; - private const string k_MainSceneName = "MultiprocessTestingScene"; - private static string s_BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); + public const string MultiprocessBaseMenuName = "MLAPI Multiprocess Test"; + public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; + public const string MainSceneName = "MultiprocessTestingScene"; + public static string BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); #if UNITY_EDITOR - [MenuItem(k_MultiprocessBaseMenuName+"/Build Test Player #t")] + [MenuItem(MultiprocessBaseMenuName+"/Build Test Player #t")] public static void BuildNoDebug() { var success = Build(); @@ -28,7 +28,7 @@ public static void BuildNoDebug() } } - [MenuItem(k_MultiprocessBaseMenuName+"/Build Test Player in debug mode")] + [MenuItem(MultiprocessBaseMenuName+"/Build Test Player in debug mode")] public static void BuildDebug() { var success = Build(true); @@ -38,14 +38,14 @@ public static void BuildDebug() } } - [MenuItem(k_MultiprocessBaseMenuName+"/Delete Test Build")] + [MenuItem(MultiprocessBaseMenuName+"/Delete Test Build")] public static void DeleteBuild() { switch (Application.platform) { case RuntimePlatform.WindowsPlayer: case RuntimePlatform.WindowsEditor: - var exePath = $"{s_BuildPath}.exe"; + var exePath = $"{BuildPath}.exe"; if (File.Exists(exePath)) { File.Delete(exePath); @@ -57,7 +57,7 @@ public static void DeleteBuild() break; case RuntimePlatform.OSXPlayer: case RuntimePlatform.OSXEditor: - var toDelete = s_BuildPath + ".app"; + var toDelete = BuildPath + ".app"; if (Directory.Exists(toDelete)) { Directory.Delete(toDelete, recursive: true); @@ -80,7 +80,7 @@ public static void DeleteBuild() public static bool Build(bool isDebug = false) { // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) - File.WriteAllText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName), s_BuildPath); + File.WriteAllText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName), BuildPath); // deleting so we don't end up testing on outdated builds if there's a build failure DeleteBuild(); @@ -95,7 +95,7 @@ public static bool Build(bool isDebug = false) // will have more connection permission popups when launching though } - var buildPathToUse = s_BuildPath; + var buildPathToUse = BuildPath; if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) { buildPathToUse += ".exe"; @@ -103,7 +103,7 @@ public static bool Build(bool isDebug = false) buildOptions &= ~BuildOptions.AutoRunPlayer; var buildReport = BuildPipeline.BuildPlayer( - new[] { $"Assets/Scenes/{k_MainSceneName}.unity" }, + new[] { $"Assets/Scenes/{MainSceneName}.unity" }, buildPathToUse, EditorUserBuildSettings.activeBuildTarget, buildOptions); From 4ff120694d7b6a84e363d156ac0aff4aad5da13f Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Mon, 5 Jul 2021 19:05:51 -0400 Subject: [PATCH 14/32] apply rename --- .../Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs | 2 +- .../Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs index d49d2f857d..501920e9a8 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs @@ -31,7 +31,7 @@ public virtual void SetupTestSuite() Assert.Ignore("Ignoring tests that shouldn't run from unity editor. Performance tests should be run from remote test execution on device (this can be ran using the \"run selected tests (your platform)\" button"); } - SceneManager.LoadScene(BuildMultiprocessTestPlayer.mainSceneName, LoadSceneMode.Single); + SceneManager.LoadScene(BuildMultiprocessTestPlayer.MainSceneName, LoadSceneMode.Single); SceneManager.sceneLoaded += OnSceneLoaded; for (int i = 0; i < NbWorkers; i++) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs index 9b6a8de724..221e97f2a6 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -59,7 +59,7 @@ private void Awake() public void Start() { - bool isClient = Environment.GetCommandLineArgs().Any(value => value == MultiprocessOrchestration.isWorkerArg); + bool isClient = Environment.GetCommandLineArgs().Any(value => value == MultiprocessOrchestration.IsWorkerArg); if (isClient) { Debug.Log("starting MLAPI client"); From eeae93cc098e6c4c9ebbcf1191d1edf94f9aa774 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Mon, 5 Jul 2021 19:50:27 -0400 Subject: [PATCH 15/32] using proper list --- .../Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs index 221e97f2a6..ae5bcb8518 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -42,7 +42,7 @@ public class TestCoordinator : NetworkBehaviour private Dictionary> m_TestResultsLocal = new Dictionary>(); // this isn't super efficient, but since it's used for signaling around the tests, shouldn't be too bad private Dictionary m_ClientIsFinished = new Dictionary(); - public static Dictionary>.KeyCollection AllClientIdsWithResults => Instance.m_TestResultsLocal.Keys; + public static List AllClientIdsWithResults => Instance.m_TestResultsLocal.Keys.ToList(); public static List AllClientIdsExceptMine => NetworkManager.Singleton.ConnectedClients.Keys.ToList().FindAll(client => client != NetworkManager.Singleton.LocalClientId); private void Awake() From 520c20d449fef6fd85b8b7ced6f458755a564664 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Mon, 5 Jul 2021 19:55:01 -0400 Subject: [PATCH 16/32] better exception --- .../Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs index ae5bcb8518..7cf323fb73 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -282,7 +282,7 @@ public void InvokeFromMethodNameClientRpc(string methodInfoString, byte[] args, var foundMethod = foundType.GetMethod(staticMethodToExecute, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (foundMethod == null) { - throw new Exception($"couldn't find method {staticMethodToExecute}"); + throw new MissingMethodException($"couldn't find method {staticMethodToExecute}"); } foundMethod.Invoke(null, args != null ? new object[] { args } : null); From f6309e9cf78b1c962bdc6925d1f5cb0bb7fcb7e7 Mon Sep 17 00:00:00 2001 From: "M. Fatih MAR" Date: Tue, 6 Jul 2021 15:08:22 +0100 Subject: [PATCH 17/32] fix/cleanup asmdefs again --- ...nity.multiplayer.mlapi.runtimetests.asmdef | 6 ++++-- .../Runtime/testproject.runtimetests.asmdef | 20 +++++-------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef b/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef index da062e7cb9..6f899c67cc 100644 --- a/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/com.unity.multiplayer.mlapi.runtimetests.asmdef @@ -8,6 +8,8 @@ "optionalUnityReferences": [ "TestAssemblies" ], - "includePlatforms": [], - "excludePlatforms": [] + "defineConstraints": [ + "UNITY_INCLUDE_TESTS", + "UNITY_EDITOR" + ] } \ No newline at end of file diff --git a/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef b/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef index 45c640863c..abe114e619 100644 --- a/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef +++ b/testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef @@ -1,25 +1,15 @@ { "name": "TestProject.RuntimeTests", - "rootNamespace": "", "references": [ - "Unity.Multiplayer.MLAPI.Runtime", - "Unity.Multiplayer.MLAPI.RuntimeTests", "TestProject.ManualTests", - "UnityEngine.TestRunner", - "UnityEditor.TestRunner" + "Unity.Multiplayer.MLAPI.Runtime", + "Unity.Multiplayer.MLAPI.RuntimeTests" ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": true, - "precompiledReferences": [ - "nunit.framework.dll" + "optionalUnityReferences": [ + "TestAssemblies" ], - "autoReferenced": false, "defineConstraints": [ "UNITY_INCLUDE_TESTS", "UNITY_EDITOR" - ], - "versionDefines": [], - "noEngineReferences": false + ] } \ No newline at end of file From cd809ec13ee5a3566d010b8b5963400465f589f5 Mon Sep 17 00:00:00 2001 From: Sam Bellomo <71790295+SamuelBellomo@users.noreply.github.com> Date: Tue, 6 Jul 2021 14:07:36 -0400 Subject: [PATCH 18/32] Apply suggestions from code review Co-authored-by: M. Fatih MAR --- .../MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs index 31487b675b..c5eb6f9893 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs @@ -33,7 +33,7 @@ public static void StartWorkerNode() workerNode.StartInfo.FileName = $"{buildInfo}.exe"; break; default: - throw new NotImplementedException("StartWorkerNode: Current platform not supported"); + throw new NotImplementedException($"{nameof(StartWorkerNode)}: Current platform is not supported"); } } catch (FileNotFoundException) @@ -52,7 +52,7 @@ public static void StartWorkerNode() var newProcessStarted = workerNode.Start(); if (!newProcessStarted) { - throw new Exception("Process not started!"); + throw new Exception("Failed to start process!"); } } catch (Win32Exception e) From 29e05bb500a4a1737a3ad6c6fac08d1cb462a6b0 Mon Sep 17 00:00:00 2001 From: "M. Fatih MAR" Date: Thu, 8 Jul 2021 10:06:34 +0100 Subject: [PATCH 19/32] no longer ignore '[Ss]treamingAssets/buildInfo.txt' --- testproject/.gitignore | 3 --- testproject/Assets/Scenes.meta | 8 ++++++++ testproject/Assets/Tests/Runtime/MultiprocessRuntime.meta | 8 ++++++++ .../Assets/Tests/Runtime/MultiprocessRuntime/Helpers.meta | 8 ++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 testproject/Assets/Scenes.meta create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime.meta create mode 100644 testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers.meta diff --git a/testproject/.gitignore b/testproject/.gitignore index aee9c94cdb..acbbe841e6 100644 --- a/testproject/.gitignore +++ b/testproject/.gitignore @@ -70,7 +70,4 @@ crashlytics-build.properties /[Aa]ssets/[Ss]treamingAssets/aa.meta /[Aa]ssets/[Ss]treamingAssets/aa/* -/[Aa]ssets/[Ss]treamingAssets/buildInfo.txt -/[Aa]ssets/[Ss]treamingAssets/buildInfo.txt.meta - InitTestScene* diff --git a/testproject/Assets/Scenes.meta b/testproject/Assets/Scenes.meta new file mode 100644 index 0000000000..3b475ec820 --- /dev/null +++ b/testproject/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e6274e6e608eb41f2ace27f3a117474d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime.meta new file mode 100644 index 0000000000..6e70f368f6 --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f415999c439ee4394bfb822a0fa30051 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers.meta b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers.meta new file mode 100644 index 0000000000..24050f230a --- /dev/null +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b9c9a4d019af9478d9fcebc1ba79d771 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From ed2519c1f0ff8966ba23c8d880f5e0352f5f5d98 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 10:16:10 -0400 Subject: [PATCH 20/32] PR suggestions --- .../Helpers/BuildMultiprocessTestPlayer.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 0c017f18d7..69d0323f3f 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -13,28 +13,28 @@ public static class BuildMultiprocessTestPlayer { public const string MultiprocessBaseMenuName = "MLAPI Multiprocess Test"; - public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; + public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build Test Player #t"; public const string MainSceneName = "MultiprocessTestingScene"; public static string BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); #if UNITY_EDITOR - [MenuItem(MultiprocessBaseMenuName+"/Build Test Player #t")] + [MenuItem(BuildAndExecuteMenuName)] public static void BuildNoDebug() { - var success = Build(); - if (!success) + var report = BuildPlayer(); + if (report.summary.result != BuildResult.Succeeded) { - throw new Exception("Build failed!"); + throw new Exception($"Build failed! {report.summary.totalErrors} errors, {report.summary}"); } } - [MenuItem(MultiprocessBaseMenuName+"/Build Test Player in debug mode")] + [MenuItem(MultiprocessBaseMenuName + "/Build Test Player in debug mode")] public static void BuildDebug() { - var success = Build(true); - if (!success) + var report = BuildPlayer(true); + if (report.summary.result != BuildResult.Succeeded) { - throw new Exception("Build failed!"); + throw new Exception($"Build failed! {report.summary.totalErrors} errors, {report.summary}"); } } @@ -77,7 +77,7 @@ public static void DeleteBuild() /// reporting. We only want to main node to do that, worker nodes should be dumb /// /// - public static bool Build(bool isDebug = false) + public static BuildReport BuildPlayer(bool isDebug = false) { // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) File.WriteAllText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName), BuildPath); @@ -108,7 +108,7 @@ public static bool Build(bool isDebug = false) EditorUserBuildSettings.activeBuildTarget, buildOptions); - return buildReport.summary.result == BuildResult.Succeeded; + return buildReport; } #endif } From b08561a2cef3d8c01f1f2744f42ef528ba72c5fd Mon Sep 17 00:00:00 2001 From: Sam Bellomo <71790295+SamuelBellomo@users.noreply.github.com> Date: Thu, 8 Jul 2021 11:00:24 -0400 Subject: [PATCH 21/32] changing root menu Co-authored-by: M. Fatih MAR --- .../MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 0c017f18d7..34e680c80d 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -12,7 +12,7 @@ /// public static class BuildMultiprocessTestPlayer { - public const string MultiprocessBaseMenuName = "MLAPI Multiprocess Test"; + public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; public const string MainSceneName = "MultiprocessTestingScene"; public static string BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); From 1c9fb6cd007051e935b5fa0c487f06840246e489 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 12:01:18 -0400 Subject: [PATCH 22/32] # --- .../MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 69d0323f3f..fad39655a7 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -77,7 +77,7 @@ public static void DeleteBuild() /// reporting. We only want to main node to do that, worker nodes should be dumb /// /// - public static BuildReport BuildPlayer(bool isDebug = false) + private static BuildReport BuildPlayer(bool isDebug = false) { // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) File.WriteAllText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName), BuildPath); From c6d3b4a61ad9eaae1faf28ad0d6e70d511b7bdf6 Mon Sep 17 00:00:00 2001 From: Sam Bellomo <71790295+SamuelBellomo@users.noreply.github.com> Date: Thu, 8 Jul 2021 14:27:36 -0400 Subject: [PATCH 23/32] rename test scene Co-authored-by: M. Fatih MAR --- .../MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 34e680c80d..0904a7485a 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -14,7 +14,7 @@ public static class BuildMultiprocessTestPlayer { public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build - Execute multiprocess tests #%t"; - public const string MainSceneName = "MultiprocessTestingScene"; + public const string MainSceneName = "MultiprocessTestScene"; public static string BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); #if UNITY_EDITOR From 2aa372b5d4cbe03fb0363740cfb0f0965c0e2242 Mon Sep 17 00:00:00 2001 From: Sam Bellomo <71790295+SamuelBellomo@users.noreply.github.com> Date: Thu, 8 Jul 2021 14:30:28 -0400 Subject: [PATCH 24/32] Update testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs Co-authored-by: M. Fatih MAR --- .../Helpers/BuildMultiprocessTestPlayer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 0904a7485a..365e0b3408 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -57,14 +57,14 @@ public static void DeleteBuild() break; case RuntimePlatform.OSXPlayer: case RuntimePlatform.OSXEditor: - var toDelete = BuildPath + ".app"; - if (Directory.Exists(toDelete)) + var appPath = BuildPath + ".app"; + if (Directory.Exists(appPath)) { - Directory.Delete(toDelete, recursive: true); + Directory.Delete(appPath, recursive: true); } else { - Debug.Log($"directory {toDelete} doesn't exist"); + Debug.Log($"[{nameof(BuildMultiprocessTestPlayer)}] MacOS build does not exist ({appPath})"); } break; default: From 484700f01e6b9f0490ddbe870ecc2cf19982e099 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 14:33:20 -0400 Subject: [PATCH 25/32] rename for test scene --- ...MultiprocessTestingScene.unity => MultiprocessTestScene.unity} | 0 ...ssTestingScene.unity.meta => MultiprocessTestScene.unity.meta} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename testproject/Assets/Scenes/{MultiprocessTestingScene.unity => MultiprocessTestScene.unity} (100%) rename testproject/Assets/Scenes/{MultiprocessTestingScene.unity.meta => MultiprocessTestScene.unity.meta} (100%) diff --git a/testproject/Assets/Scenes/MultiprocessTestingScene.unity b/testproject/Assets/Scenes/MultiprocessTestScene.unity similarity index 100% rename from testproject/Assets/Scenes/MultiprocessTestingScene.unity rename to testproject/Assets/Scenes/MultiprocessTestScene.unity diff --git a/testproject/Assets/Scenes/MultiprocessTestingScene.unity.meta b/testproject/Assets/Scenes/MultiprocessTestScene.unity.meta similarity index 100% rename from testproject/Assets/Scenes/MultiprocessTestingScene.unity.meta rename to testproject/Assets/Scenes/MultiprocessTestScene.unity.meta From cba7b19d11daeef64ad3a48cdc479945dbe85079 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 14:37:56 -0400 Subject: [PATCH 26/32] proper rename for scene --- testproject/Assets/Scenes/MultiprocessTestScene.unity | 2 +- testproject/ProjectSettings/EditorBuildSettings.asset | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testproject/Assets/Scenes/MultiprocessTestScene.unity b/testproject/Assets/Scenes/MultiprocessTestScene.unity index 65e0b7ee89..d4a6e985ce 100644 --- a/testproject/Assets/Scenes/MultiprocessTestScene.unity +++ b/testproject/Assets/Scenes/MultiprocessTestScene.unity @@ -683,7 +683,7 @@ MonoBehaviour: ProtocolVersion: 0 NetworkTransport: {fileID: 1674777073} RegisteredScenes: - - MultiprocessTestingScene + - MultiprocessTestScene - SampleScene AllowRuntimeSceneChanges: 0 PlayerPrefab: {fileID: 4700706668509470175, guid: 7eeaaf9e50c0afc4dab93584a54fb0d6, diff --git a/testproject/ProjectSettings/EditorBuildSettings.asset b/testproject/ProjectSettings/EditorBuildSettings.asset index c8f83681c4..0aad2d2bec 100644 --- a/testproject/ProjectSettings/EditorBuildSettings.asset +++ b/testproject/ProjectSettings/EditorBuildSettings.asset @@ -45,6 +45,6 @@ EditorBuildSettings: path: Assets/Tests/Manual/NetworkAnimatorTests/NetworkAnimatorEnhancement.unity guid: f88da8bb8d07e11418eaad6524d5cc12 - enabled: 1 - path: Assets/Scenes/MultiprocessTestingScene.unity + path: Assets/Scenes/MultiprocessTestScene.unity guid: 76743cb7b342c49279327834918a9c6e m_configObjects: {} From 90fffe4ba7edbac100c605946d09aa6070210def Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 15:00:53 -0400 Subject: [PATCH 27/32] # --- .../Helpers/BuildMultiprocessTestPlayer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 2d14b4b44e..a6c5378122 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -15,7 +15,7 @@ public static class BuildMultiprocessTestPlayer public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build Test Player #t"; public const string MainSceneName = "MultiprocessTestScene"; - public static string BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTestBuild"); + public static string BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTests/MultiprocessTestBuild"); #if UNITY_EDITOR [MenuItem(BuildAndExecuteMenuName)] @@ -24,7 +24,7 @@ public static void BuildNoDebug() var report = BuildPlayer(); if (report.summary.result != BuildResult.Succeeded) { - throw new Exception($"Build failed! {report.summary.totalErrors} errors, {report.summary}"); + throw new Exception($"Build failed! {report.summary.totalErrors} errors"); } } @@ -34,7 +34,7 @@ public static void BuildDebug() var report = BuildPlayer(true); if (report.summary.result != BuildResult.Succeeded) { - throw new Exception($"Build failed! {report.summary.totalErrors} errors, {report.summary}"); + throw new Exception($"Build failed! {report.summary.totalErrors} errors"); } } From 2c915e92a9ca644db6af7cfa94abade02529b576 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 15:16:56 -0400 Subject: [PATCH 28/32] simpler flow --- .../Helpers/BuildMultiprocessTestPlayer.cs | 38 +++++-------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index a6c5378122..a9b3d7ecf5 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -15,7 +15,8 @@ public static class BuildMultiprocessTestPlayer public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build Test Player #t"; public const string MainSceneName = "MultiprocessTestScene"; - public static string BuildPath => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTests/MultiprocessTestBuild"); + public static string BuildPathDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTests"); + public static string BuildPath => Path.Combine(BuildPathDirectory, "/MultiprocessTestBuild"); #if UNITY_EDITOR [MenuItem(BuildAndExecuteMenuName)] @@ -38,37 +39,16 @@ public static void BuildDebug() } } - [MenuItem(MultiprocessBaseMenuName+"/Delete Test Build")] + [MenuItem(MultiprocessBaseMenuName + "/Delete Test Build")] public static void DeleteBuild() { - switch (Application.platform) + if (Directory.Exists(BuildPathDirectory)) { - case RuntimePlatform.WindowsPlayer: - case RuntimePlatform.WindowsEditor: - var exePath = $"{BuildPath}.exe"; - if (File.Exists(exePath)) - { - File.Delete(exePath); - } - else - { - Debug.Log($"exe {exePath} doesn't exist"); - } - break; - case RuntimePlatform.OSXPlayer: - case RuntimePlatform.OSXEditor: - var appPath = BuildPath + ".app"; - if (Directory.Exists(appPath)) - { - Directory.Delete(appPath, recursive: true); - } - else - { - Debug.Log($"[{nameof(BuildMultiprocessTestPlayer)}] MacOS build does not exist ({appPath})"); - } - break; - default: - throw new NotImplementedException(); + Directory.Delete(BuildPathDirectory, recursive: true); + } + else + { + Debug.Log($"[{nameof(BuildMultiprocessTestPlayer)}] build directory does not exist ({BuildPathDirectory}) not deleting anything"); } } From 9a3bd9b9b698955ad47384fe09d136965d2210ae Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 15:30:03 -0400 Subject: [PATCH 29/32] fixes --- .../Helpers/BuildMultiprocessTestPlayer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index a9b3d7ecf5..3449a4d658 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -15,8 +15,8 @@ public static class BuildMultiprocessTestPlayer public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build Test Player #t"; public const string MainSceneName = "MultiprocessTestScene"; - public static string BuildPathDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds/MultiprocessTests"); - public static string BuildPath => Path.Combine(BuildPathDirectory, "/MultiprocessTestBuild"); + private static string BuildPathDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds","MultiprocessTests"); + public static string BuildPath => Path.Combine(BuildPathDirectory, "MultiprocessTestPlayer"); #if UNITY_EDITOR [MenuItem(BuildAndExecuteMenuName)] @@ -80,6 +80,7 @@ private static BuildReport BuildPlayer(bool isDebug = false) { buildPathToUse += ".exe"; } + Debug.Log($"Starting multiprocess player build using path {buildPathToUse}"); buildOptions &= ~BuildOptions.AutoRunPlayer; var buildReport = BuildPipeline.BuildPlayer( @@ -88,6 +89,7 @@ private static BuildReport BuildPlayer(bool isDebug = false) EditorUserBuildSettings.activeBuildTarget, buildOptions); + Debug.Log($"done building"); return buildReport; } #endif From 070f6afcd078bb6772b50218f341b9d606e4c2f3 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 21:58:18 -0400 Subject: [PATCH 30/32] formatting issues --- .../BaseMultiprocessTests.cs | 20 ++++++++++------- .../Helpers/BuildMultiprocessTestPlayer.cs | 2 +- .../Helpers/MultiprocessOrchestration.cs | 1 - .../MultiprocessRuntime/TestCoordinator.cs | 22 +++++++------------ .../TestCoordinatorTests.cs | 17 +++++++------- 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs index 501920e9a8..ace3f408dc 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs @@ -9,19 +9,22 @@ namespace MLAPI.MultiprocessRuntimeTests { public class MultiprocessTestsAttribute : CategoryAttribute { - public const string multiprocessCategoryName = "Multiprocess"; - public MultiprocessTestsAttribute() : base(multiprocessCategoryName){} + public const string MultiprocessCategoryName = "Multiprocess"; + public MultiprocessTestsAttribute() : base(MultiprocessCategoryName) { } } [MultiprocessTests] public abstract class BaseMultiprocessTests { - protected virtual bool m_IsPerformanceTest => true; private bool ShouldIgnoreTests => m_IsPerformanceTest && Application.isEditor; - protected abstract int NbWorkers { get; } + /// + /// Implement this to specify the amount of workers to spawn from your main test runner + /// TODO there's a good chance this will be refactored with something fancier once we start integrating with bokken + /// + protected abstract int WorkerCount { get; } [OneTimeSetUp] public virtual void SetupTestSuite() @@ -34,7 +37,7 @@ public virtual void SetupTestSuite() SceneManager.LoadScene(BuildMultiprocessTestPlayer.MainSceneName, LoadSceneMode.Single); SceneManager.sceneLoaded += OnSceneLoaded; - for (int i = 0; i < NbWorkers; i++) + for (int i = 0; i < WorkerCount; i++) { MultiprocessOrchestration.StartWorkerNode(); // will automatically start built player as clients } @@ -52,15 +55,16 @@ public virtual IEnumerator Setup() yield return new WaitUntil(() => NetworkManager.Singleton != null && NetworkManager.Singleton.IsServer); var startTime = Time.time; - while (NetworkManager.Singleton.ConnectedClients.Count <= NbWorkers) + while (NetworkManager.Singleton.ConnectedClients.Count <= WorkerCount) { yield return new WaitForSeconds(0.2f); - if (Time.time - startTime > TestCoordinator.maxWaitTimeout) + if (Time.time - startTime > TestCoordinator.MaxWaitTimeoutSec) { - throw new Exception($"waiting too long to see clients to connect, got {NetworkManager.Singleton.ConnectedClients.Count - 1} clients, but was expecting {NbWorkers}, failing"); + throw new Exception($"waiting too long to see clients to connect, got {NetworkManager.Singleton.ConnectedClients.Count - 1} clients, but was expecting {WorkerCount}, failing"); } } + TestCoordinator.Instance.KeepAliveClientRpc(); } diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs index 77f877a115..4bfc7ab20f 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/BuildMultiprocessTestPlayer.cs @@ -15,7 +15,7 @@ public static class BuildMultiprocessTestPlayer public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build Test Player #t"; public const string MainSceneName = "MultiprocessTestScene"; - private static string BuildPathDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds","MultiprocessTests"); + private static string BuildPathDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds", "MultiprocessTests"); public static string BuildPath => Path.Combine(BuildPathDirectory, "MultiprocessTestPlayer"); #if UNITY_EDITOR diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs index 18196d7954..b09ee09914 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs @@ -2,7 +2,6 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; -using UnityEditor; using UnityEngine; using Debug = UnityEngine.Debug; diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs index 7cf323fb73..61cbbbb234 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -1,17 +1,11 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Reflection; using MLAPI; -using MLAPI.Configuration; -using MLAPI.Logging; using MLAPI.Messaging; using NUnit.Framework; -using NUnit.Framework.Interfaces; using UnityEngine; -using UnityEngine.TestTools; using Debug = UnityEngine.Debug; /// @@ -27,12 +21,11 @@ [RequireComponent(typeof(NetworkObject))] public class TestCoordinator : NetworkBehaviour { - public const int perTestTimeout = 5 * 60; // seconds + public const int PerTestTimeoutSec = 5 * 60; // seconds - public const float maxWaitTimeout = 20; + public const float MaxWaitTimeoutSec = 20; private const char k_MethodFullNameSplitChar = '@'; - private bool m_ShouldShutdown; private float m_TimeSinceLastConnected; private float m_TimeSinceLastKeepAlive; @@ -49,7 +42,7 @@ private void Awake() { if (Instance != null) { - Debug.LogError("Multiple test coordinator! destroying self"); + Debug.LogError("Multiple test coordinator, destroying this instance"); Destroy(gameObject); return; } @@ -73,16 +66,17 @@ public void Start() public void Update() { - if (Time.time - m_TimeSinceLastKeepAlive > perTestTimeout) + if (Time.time - m_TimeSinceLastKeepAlive > PerTestTimeoutSec) { QuitApplication(); Assert.Fail("Stayed idle too long"); } + if ((IsServer && NetworkManager.Singleton.IsListening) || (IsClient && NetworkManager.Singleton.IsConnectedClient)) { m_TimeSinceLastConnected = Time.time; } - else if (Time.time - m_TimeSinceLastConnected > maxWaitTimeout || m_ShouldShutdown) + else if (Time.time - m_TimeSinceLastConnected > MaxWaitTimeoutSec || m_ShouldShutdown) { // Make sure we don't have zombie processes Debug.Log($"quitting application, shouldShutdown set to {m_ShouldShutdown}, is listening {NetworkManager.Singleton.IsListening}, is connected client {NetworkManager.Singleton.IsConnectedClient}"); @@ -182,7 +176,7 @@ public static Func ResultIsSet(bool useTimeoutException = true) var startWaitTime = Time.time; return () => { - if (Time.time - startWaitTime > maxWaitTimeout) + if (Time.time - startWaitTime > MaxWaitTimeoutSec) { if (useTimeoutException) { @@ -209,7 +203,7 @@ public static Func ConsumeClientIsFinished(ulong clientId, bool useTimeout var startWaitTime = Time.time; return () => { - if (Time.time - startWaitTime > maxWaitTimeout) + if (Time.time - startWaitTime > MaxWaitTimeoutSec) { if (useTimeoutException) { diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs index 4c22ca1d21..79d53ed053 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinatorTests.cs @@ -1,4 +1,3 @@ -using System; using System.Collections; using System.Linq; using NUnit.Framework; @@ -11,14 +10,14 @@ namespace MLAPI.MultiprocessRuntimeTests [TestFixture(2)] public class TestCoordinatorTests : BaseMultiprocessTests { - private int m_NbWorkers; - protected override int NbWorkers => m_NbWorkers; + private int m_WorkerCount; + protected override int WorkerCount => m_WorkerCount; protected override bool m_IsPerformanceTest => false; - public TestCoordinatorTests(int nbWorkers) + public TestCoordinatorTests(int workerCount) { - m_NbWorkers = nbWorkers; + m_WorkerCount = workerCount; } private static void ExecuteSimpleCoordinatorTest() @@ -39,7 +38,7 @@ public IEnumerator CheckTestCoordinator() TestCoordinator.Instance.InvokeFromMethodActionRpc(ExecuteSimpleCoordinatorTest); var nbResults = 0; - for (int i = 0; i < NbWorkers; i++) // wait and test for the two clients + for (int i = 0; i < WorkerCount; i++) // wait and test for the two clients { yield return new WaitUntil(TestCoordinator.ResultIsSet()); @@ -47,7 +46,7 @@ public IEnumerator CheckTestCoordinator() Assert.Greater(result, 0f); nbResults++; } - Assert.That(nbResults, Is.EqualTo(NbWorkers)); + Assert.That(nbResults, Is.EqualTo(WorkerCount)); } [UnityTest] @@ -56,7 +55,7 @@ public IEnumerator CheckTestCoordinatorWithArgs() TestCoordinator.Instance.InvokeFromMethodActionRpc(ExecuteWithArgs, 99); var nbResults = 0; - for (int i = 0; i < NbWorkers; i++) // wait and test for the two clients + for (int i = 0; i < WorkerCount; i++) // wait and test for the two clients { yield return new WaitUntil(TestCoordinator.ResultIsSet()); @@ -64,7 +63,7 @@ public IEnumerator CheckTestCoordinatorWithArgs() Assert.That(result, Is.EqualTo(99)); nbResults++; } - Assert.That(nbResults, Is.EqualTo(NbWorkers)); + Assert.That(nbResults, Is.EqualTo(WorkerCount)); } } } From e64b12e22b98c5579f0f8751e48df2ba4aece032 Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Thu, 8 Jul 2021 23:01:41 -0400 Subject: [PATCH 31/32] name fix --- .../Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs index 61cbbbb234..fc0efec2e1 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/TestCoordinator.cs @@ -250,7 +250,7 @@ public void TriggerActionIDClientRpc(string actionID, byte[] args, ClientRpcPara Debug.Log($"received RPC from server, client side triggering action ID {actionID}"); try { - // ExecuteStepInContext.allActions[actionID].Invoke(args); + //ExecuteStepInContext.AllActions[actionId].Invoke(args); } catch (Exception e) { From 50398b393a2f51ca447b52b7ae3453bfe1b16ffd Mon Sep 17 00:00:00 2001 From: Samuel Bellomo Date: Fri, 9 Jul 2021 15:22:32 -0400 Subject: [PATCH 32/32] fix for automation fail right now --- .../Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs | 2 +- .../Helpers/MultiprocessOrchestration.cs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs index ace3f408dc..f6b82d71db 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/BaseMultiprocessTests.cs @@ -18,7 +18,7 @@ public abstract class BaseMultiprocessTests { protected virtual bool m_IsPerformanceTest => true; - private bool ShouldIgnoreTests => m_IsPerformanceTest && Application.isEditor; + private bool ShouldIgnoreTests => m_IsPerformanceTest && Application.isEditor || MultiprocessOrchestration.IsUsingUTR(); // todo remove UTR check once we have proper automation /// /// Implement this to specify the amount of workers to spawn from your main test runner diff --git a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs index b09ee09914..6dec09b4cb 100644 --- a/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs +++ b/testproject/Assets/Tests/Runtime/MultiprocessRuntime/Helpers/MultiprocessOrchestration.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; +using System.Linq; using UnityEngine; using Debug = UnityEngine.Debug; @@ -60,4 +61,10 @@ public static void StartWorkerNode() throw; } } + + // todo remove this once we have proper automation + public static bool IsUsingUTR() + { + return Environment.GetCommandLineArgs().Contains("-automated"); + } }