public void Cancel(IUnitTestRun run) { mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "CancellingUnitTests", () => { var launchProperty = myEditorProtocol.UnityModel.Value?.UnitTestLaunch; if (launchProperty != null && launchProperty.HasValue()) { launchProperty.Value?.Abort.Start(Unit.Instance); } run.GetData(ourCompletionSourceKey).NotNull().SetCanceled(); }); }
private void RefreshAndRunTask(IUnitTestRun run, TaskCompletionSource <bool> tcs, Lifetime taskLifetime) { var cancellationTs = run.GetData(ourCancellationTokenSourceKey); var cancellationToken = cancellationTs.NotNull().Token; myLogger.Trace("Before calling Refresh."); Refresh(run.Lifetime, tcs, cancellationToken).ContinueWith(__ => { if (tcs.Task.IsCanceled || tcs.Task.IsFaulted) // Refresh failed or was stopped { return; } myLogger.Trace("Refresh. OnCompleted."); // KS: Can't use run.Lifetime for ExecuteOrQueueEx here and in all similar places: run.Lifetime is terminated when // Unit Test Session is closed from UI without cancelling the run. This will leave task completion source in running state forever. mySolution.Locks.ExecuteOrQueueEx(myLifetime, "Check compilation", () => { if (!run.Lifetime.IsAlive || cancellationTs.IsCancellationRequested) { tcs.TrySetCanceled(); return; } if (myBackendUnityHost.BackendUnityModel.Value == null) { tcs.SetException(new Exception("Unity Editor connection unavailable.")); return; } var filters = GetFilters(run); UnitTestLaunchClientControllerInfo unityClientControllerInfo = null; var clientControllerInfo = run.HostController.GetClientControllerInfo(run); if (clientControllerInfo != null) { unityClientControllerInfo = new UnitTestLaunchClientControllerInfo( clientControllerInfo.AssemblyLocation, clientControllerInfo.ExtraDependencies?.ToList(), clientControllerInfo.TypeName); } var frontendBackendModel = mySolution.GetProtocolSolution().GetFrontendBackendModel(); myUsageStatistics.TrackActivity("UnityUnitTestPreference", frontendBackendModel.UnitTestPreference.Value.ToString()); var mode = TestMode.Edit; if (frontendBackendModel.UnitTestPreference.Value == UnitTestLaunchPreference.PlayMode) { mode = TestMode.Play; } var launch = new UnitTestLaunch(run.Launch.Session.Id, filters, mode, unityClientControllerInfo); myBackendUnityHost.BackendUnityModel.ViewNotNull(taskLifetime, (lt, model) => { // recreate UnitTestLaunch in case of AppDomain.Reload, which is the case with PlayMode tests myLogger.Trace("UnitTestLaunch.SetValue."); if (frontendBackendModel.UnitTestPreference.Value == UnitTestLaunchPreference.Both) { model.UnitTestLaunch.SetValue(launch); SubscribeResults(run, lt, launch); launch.RunResult.Advise(lt, result => { if (launch.TestMode == TestMode.Play) { tcs.SetResult(result.Passed); } else { launch = new UnitTestLaunch(launch.SessionId, launch.TestFilters, TestMode.Play, launch.ClientControllerInfo); model.UnitTestLaunch.SetValue(launch); SubscribeResults(run, lt, launch); StartTests(run, tcs, lt); } }); } else { model.UnitTestLaunch.SetValue(launch); SubscribeResults(run, lt, launch); launch.RunResult.Advise(lt, result => { tcs.SetResult(result.Passed); }); } }); StartTests(run, tcs, taskLifetime); // set results for explicit tests foreach (var element in run.Elements.OfType <NUnitElementBase>().Where(a => a.RunState == RunState.Explicit && !run.Launch.Criterion.Explicit.Contains(a))) { myUnitTestResultManager.TestFinishing(element, run.Launch.Session, "Test should be run explicitly", UnitTestStatus.Ignored); } }); }, cancellationToken); }
private void RefreshAndRunTask(IUnitTestRun run, TaskCompletionSource <bool> tcs, Lifetime taskLifetime) { var cancellationTs = run.GetData(ourCancellationTokenSourceKey); myLogger.Verbose("Before calling Refresh."); Refresh(run.Lifetime, cancellationTs.NotNull().Token).GetAwaiter().OnCompleted(() => { // KS: Can't use run.Lifetime for ExecuteOrQueueEx here and in all similar places: run.Lifetime is terminated when // Unit Test Session is closed from UI without cancelling the run. This will leave task completion source in running state forever. mySolution.Locks.ExecuteOrQueueEx(myLifetime, "Check compilation", () => { if (!run.Lifetime.IsAlive || cancellationTs.IsCancellationRequested) { tcs.SetCanceled(); return; } if (myEditorProtocol.UnityModel.Value == null) { myLogger.Verbose("Unity Editor connection unavailable."); tcs.SetException(new Exception("Unity Editor connection unavailable.")); return; } var task = myEditorProtocol.UnityModel.Value.GetCompilationResult.Start(Unit.Instance); task.Result.AdviseNotNull(myLifetime, result => { if (!run.Lifetime.IsAlive || cancellationTs.IsCancellationRequested) { tcs.SetCanceled(); } else if (!result.Result) { tcs.SetException(new Exception("There are errors during compilation in Unity.")); mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "RunViaUnityEditorStrategy compilation failed", () => { var notification = new NotificationModel("Compilation failed", "Script compilation in Unity failed, so tests were not started.", true, RdNotificationEntryType.INFO); myNotificationsModel.Notification(notification); }); myUnityHost.PerformModelAction(model => model.ActivateUnityLogView()); } else { var launch = SetupLaunch(run); mySolution.Locks.ExecuteOrQueueEx(myLifetime, "ExecuteRunUT", () => { if (!run.Lifetime.IsAlive || cancellationTs.IsCancellationRequested) { tcs.SetCanceled(); return; } if (myEditorProtocol.UnityModel.Value == null) { tcs.SetException(new Exception("Unity Editor connection unavailable.")); return; } myEditorProtocol.UnityModel.ViewNotNull(taskLifetime, (lt, model) => { // recreate UnitTestLaunch in case of AppDomain.Reload, which is the case with PlayMode tests model.UnitTestLaunch.SetValue(launch); SubscribeResults(run, lt, tcs, launch); }); myUnityProcessId.When(taskLifetime, (int?)null, _ => tcs.TrySetException(new Exception("Unity Editor has been closed."))); var rdTask = myEditorProtocol.UnityModel.Value.RunUnitTestLaunch.Start(Unit.Instance); rdTask?.Result.Advise(taskLifetime, res => { myLogger.Trace($"RunUnitTestLaunch result = {res.Result}"); if (!res.Result) { var defaultMessage = "Failed to start tests in Unity."; var isCoverage = run.HostController.HostId != WellKnownHostProvidersIds.DebugProviderId && run.HostController.HostId != WellKnownHostProvidersIds.RunProviderId; if (myPackageValidator.HasNonCompatiblePackagesCombination(isCoverage, out var message)) { defaultMessage = $"{defaultMessage} {message}"; } if (myEditorProtocol.UnityModel.Value.UnitTestLaunch.Value.TestMode == TestMode.Play) { if (!myPackageValidator.CanRunPlayModeTests(out var playMessage)) { defaultMessage = $"{defaultMessage} {playMessage}"; } } tcs.TrySetException(new Exception(defaultMessage)); } }); }); } });
public void Abort(IUnitTestRun run) { // TODO: cancel tests in Unity Editor run.GetData(ourCompletionSourceKey).NotNull().SetCanceled(); }
public void Cancel(IUnitTestRun run) => run.GetData(ourLifetimeDefinitionKey)?.Terminate();
private void RefreshAndRunTask(IUnitTestRun run, TaskCompletionSource <bool> tcs, Lifetime taskLifetime) { var cancellationTs = run.GetData(ourCancellationTokenSourceKey); var cancellationToken = cancellationTs.NotNull().Token; myLogger.Trace("Before calling Refresh."); Refresh(run.Lifetime, tcs, cancellationToken).ContinueWith(__ => { if (tcs.Task.IsCanceled || tcs.Task.IsFaulted) // Refresh failed or was stopped { return; } myLogger.Trace("Refresh. OnCompleted."); // KS: Can't use run.Lifetime for ExecuteOrQueueEx here and in all similar places: run.Lifetime is terminated when // Unit Test Session is closed from UI without cancelling the run. This will leave task completion source in running state forever. mySolution.Locks.ExecuteOrQueueEx(myLifetime, "Check compilation", () => { if (!run.Lifetime.IsAlive || cancellationTs.IsCancellationRequested) { tcs.TrySetCanceled(); return; } var launch = SetupLaunch(run); if (myEditorProtocol.UnityModel.Value == null) { tcs.SetException(new Exception("Unity Editor connection unavailable.")); return; } myEditorProtocol.UnityModel.ViewNotNull(taskLifetime, (lt, model) => { // recreate UnitTestLaunch in case of AppDomain.Reload, which is the case with PlayMode tests myLogger.Trace("UnitTestLaunch.SetValue."); model.UnitTestLaunch.SetValue(launch); SubscribeResults(run, lt, tcs, launch); }); myLogger.Trace("RunUnitTestLaunch.Start."); var rdTask = myEditorProtocol.UnityModel.Value.RunUnitTestLaunch.Start(Unit.Instance); rdTask?.Result.Advise(taskLifetime, res => { myLogger.Trace($"RunUnitTestLaunch result = {res.Result}"); if (!res.Result) { var defaultMessage = "Failed to start tests in Unity."; var isCoverage = run.HostController.HostId != WellKnownHostProvidersIds.DebugProviderId && run.HostController.HostId != WellKnownHostProvidersIds.RunProviderId; if (myPackageValidator.HasNonCompatiblePackagesCombination(isCoverage, out var message)) { defaultMessage = $"{defaultMessage} {message}"; } if (myEditorProtocol.UnityModel.Value.UnitTestLaunch.Value.TestMode == TestMode.Play) { if (!myPackageValidator.CanRunPlayModeTests(out var playMessage)) { defaultMessage = $"{defaultMessage} {playMessage}"; } } tcs.TrySetException(new Exception(defaultMessage)); } });
public void Abort(IUnitTestRun run) { myUnityEditorProtocol.UnityModel.Value?.UnitTestLaunch.Value?.Abort.Start(RdVoid.Instance); run.GetData(ourCompletionSourceKey).NotNull().SetCanceled(); }
private static void CancelPrepareForRun(IUnitTestRun run) => run.GetData(ourLifetimeDefinitionKey)?.Terminate();