unity/EditorPlugin/UnitTesting/UnityEditorTestLauncher.cs (118 lines of code) (raw):

using System; using System.Linq; using System.Reflection; using JetBrains.Collections.Viewable; using JetBrains.Diagnostics; using JetBrains.Rd.Tasks; using JetBrains.Rider.Model.Unity.BackendUnity; namespace JetBrains.Rider.Unity.Editor.UnitTesting { internal class UnityEditorTestLauncher { private readonly UnitTestLaunch myLaunch; private static readonly ILog ourLogger = Log.GetLog("RiderPlugin"); public UnityEditorTestLauncher(UnitTestLaunch launch) { myLaunch = launch; } public bool TryLaunchUnitTests() { var success = TryLaunchUnitTestsInternal(); if (success) return true; return false; } private bool TryLaunchUnitTestsInternal() { try { var riderPackageAssembly = RiderPackageInterop.GetAssembly(); var launcherType = riderPackageAssembly?.GetType("Packages.Rider.Editor.UnitTesting.RiderTestRunner"); if (launcherType == null) return false; var assemblyNames = myLaunch.TestFilters.Select(a => a.AssemblyName).ToArray(); var testNames = myLaunch.TestFilters.SelectMany(a => a.TestNames).ToArray(); var groupNames = myLaunch.TestFilters.SelectMany(a => a.GroupNames).ToArray(); var categoryNames = myLaunch.TestFilters.SelectMany(a => a.TestCategories).ToArray(); var mode = (int) myLaunch.TestMode; // 0 for Both, 1 for Edit, 2 for Play MethodInfo runTestsMethod; object[] args; if (myLaunch.ClientControllerInfo != null) { ourLogger.Verbose($"ClientController specified (SessionId={myLaunch.SessionId}): {myLaunch.ClientControllerInfo.TypeName}, {myLaunch.ClientControllerInfo.CodeBase}"); runTestsMethod = launcherType.GetMethod("RunTestsWithSyncCallbacks"); if (runTestsMethod == null) { ourLogger.Verbose($"Method 'RunTestsWithSyncCallbacks' not found in type '{launcherType.AssemblyQualifiedName}'"); return false; } args = new object[] {myLaunch.SessionId.ToString(), mode, assemblyNames, testNames, categoryNames, groupNames, null, myLaunch.ClientControllerInfo.CodeBase, myLaunch.ClientControllerInfo.TypeName, myLaunch.ClientControllerInfo.CodeBaseDependencies?.ToArray() }; } else { runTestsMethod = launcherType.GetMethod("RunTests"); if (runTestsMethod == null) { ourLogger.Verbose($"Method 'RunTests' not found in type '{launcherType.AssemblyQualifiedName}'"); return false; } args = new object[] {mode, assemblyNames, testNames, categoryNames, groupNames, null}; } runTestsMethod.Invoke(null, args); return true; } catch (Exception e) { ourLogger.Error(e, "Exception while TryLaunchUnitTestsInternal."); } return false; } internal static void SupportAbortNew(UnitTestLaunch launch) { try { var riderPackageAssembly = RiderPackageInterop.GetAssembly(); var apiType = riderPackageAssembly?.GetType("Packages.Rider.Editor.UnitTesting.RiderTestRunner"); if (apiType == null) { ourLogger.Verbose($"Could not find RiderTestRunner in the {riderPackageAssembly}."); return; }; var methodName = "CancelTestRun"; var stopRunMethod = apiType.GetMethod(methodName); if (stopRunMethod == null) stopRunMethod = apiType.GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic); if (stopRunMethod == null) ourLogger.Verbose($"Could not find {methodName} in the {apiType.Name}."); launch.Abort.Set((lifetime, _) => { var task = new RdTask<bool>(); if (stopRunMethod != null) { ourLogger.Verbose($"Call {methodName} method via reflection."); try { stopRunMethod.Invoke(null, null); task.Set(true); if (!launch.RunStarted.HasTrueValue()) // if RunStarted never happened launch.RunResult(new RunResult(false)); } catch (Exception) { ourLogger.Verbose($"Call {methodName} method failed."); task.Set(false); } } else task.Set(false); return task; }); } catch (Exception e) { ourLogger.Error(e, "Unexpected exception in SupportAbortNew"); } } } }