private void StartTests(IUnitTestRun run, TaskCompletionSource <bool> tcs, Lifetime taskLifetime) { myLogger.Trace("RunUnitTestLaunch.Start."); var rdTask = myBackendUnityHost.BackendUnityModel.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 (myBackendUnityHost.BackendUnityModel.Value.UnitTestLaunch.Value.TestMode == TestMode.Play) { if (!myPackageValidator.CanRunPlayModeTests(out var playMessage)) { defaultMessage = $"{defaultMessage} {playMessage}"; } }
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)); } }); }); } });
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)); } });