Task IUnitTestRunStrategy.Run(IUnitTestRun run) { var key = run.Launch.GetData(ourLaunchedInUnityKey); if (key != null) { return(Task.FromResult(false)); } var tcs = new TaskCompletionSource <bool>(); run.Launch.PutData(ourLaunchedInUnityKey, "smth"); run.PutData(ourCompletionSourceKey, tcs); mySolution.Locks.ExecuteOrQueueEx(mySolution.GetLifetime(), "ExecuteRunUT", () => { if (myUnityEditorProtocol.UnityModel.Value == null) { return; } var currentConnectionLifetime = Lifetimes.Define(mySolution.GetLifetime()); myUnityEditorProtocol.UnityModel.Change.Advise_NoAcknowledgement(currentConnectionLifetime.Lifetime, (args) => { if (args.HasNew && args.New == null) { currentConnectionLifetime.Terminate(); } }); RunInternal(run, currentConnectionLifetime.Lifetime, myUnityEditorProtocol.UnityModel.Value, tcs); }); return(tcs.Task); }
public async Task PrepareForRun(IUnitTestRun run) { var lifetimeDef = Lifetime.Define(); run.PutData(ourLifetimeDefinitionKey, lifetimeDef); await myInnerHostController.PrepareForRun(run).ConfigureAwait(false); if (!myUnityController.IsUnityEditorUnitTestRunStrategy(run.RunStrategy)) { return; } lock (myStartUnitySync) { myStartUnityTask = myStartUnityTask.ContinueWith(_ => { var unityEditorProcessId = myUnityController.TryGetUnityProcessId(); return(unityEditorProcessId.HasValue ? Task.CompletedTask : myShellLocks.Tasks.StartNew(lifetimeDef.Lifetime, Scheduling.FreeThreaded, () => StartUnityIfNeed(lifetimeDef.Lifetime))); }, lifetimeDef.Lifetime, TaskContinuationOptions.None, myShellLocks.Tasks.GuardedMainThreadScheduler).Unwrap(); } await myStartUnityTask.ConfigureAwait(false); }
Task IUnitTestRunStrategy.Run(IUnitTestRun run) { lock (myCurrentLaunchesTaskAccess) { var cancellationTs = new CancellationTokenSource(); run.Lifetime.OnTermination(cancellationTs.Cancel); run.PutData(ourCancellationTokenSourceKey, cancellationTs); var newLaunchTask = myCurrentLaunchesTask.ContinueWith(_ => Run(run), cancellationTs.Token).Unwrap(); myCurrentLaunchesTask = Task.WhenAll(myCurrentLaunchesTask, newLaunchTask); return(newLaunchTask); } }
public Task PrepareForRun(IUnitTestRun run, ITaskRunnerHostController next) { var lifetimeDef = myLifetime.CreateNested(); run.PutData(ourLifetimeDefinitionKey, lifetimeDef); lock (myStartUnitySync) { WrapStartUnityTask(() => PrepareForRunInternal(lifetimeDef.Lifetime, run)); WrapStartUnityTask(() => next.PrepareForRun(run)); return(myStartUnityTask); } }
Task IUnitTestRunStrategy.Run(IUnitTestRun run) { var key = run.Launch.GetData(ourLaunchedInUnityKey); if (key != null) { return(Task.FromResult(false)); } var tcs = new TaskCompletionSource <bool>(); run.Launch.PutData(ourLaunchedInUnityKey, "smth"); run.PutData(ourCompletionSourceKey, tcs); var hostId = run.HostController.HostId; switch (hostId) { case WellKnownHostProvidersIds.DebugProviderId: mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "AttachDebuggerToUnityEditor", () => { var task = myUnityHost.GetValue(model => model.AttachDebuggerToUnityEditor.Start(Unit.Instance)); task.Result.AdviseNotNull(run.Lifetime, result => { if (!result.Result) { tcs.SetException(new Exception("Unable to attach debugger.")); } else { RefreshAndRunTask(run, tcs); } }); }); break; case WellKnownHostProvidersIds.RunProviderId: RefreshAndRunTask(run, tcs); break; default: run.Launch.Output.Error( $"Starting Unity tests from '{hostId}' is currently unsupported. Please use `Run`."); return(Task.FromResult(false)); } return(tcs.Task); }
Task IUnitTestRunStrategy.Run(IUnitTestRun run) { var key = run.Launch.GetData(ourLaunchedInUnityKey); if (key != null) { return(Task.FromResult(false)); } var hostId = run.HostController.HostId; if (hostId == WellKnownHostProvidersIds.DebugProviderId) { run.Launch.Output.Error("Starting Unity tests from 'Debug' is currently unsupported. Please attach to editor and use 'Run'."); return(Task.FromResult(false)); } if (hostId != WellKnownHostProvidersIds.RunProviderId) { run.Launch.Output.Error($"Starting Unity tests from '{hostId}' is currently unsupported. Please use `Run`."); return(Task.FromResult(false)); } var tcs = new TaskCompletionSource <bool>(); run.Launch.PutData(ourLaunchedInUnityKey, "smth"); run.PutData(ourCompletionSourceKey, tcs); mySolution.Locks.ExecuteOrQueueEx(mySolution.GetLifetime(), "ExecuteRunUT", () => { if (myUnityEditorProtocol.UnityModel.Value == null) { return; } var currentConnectionLifetime = Lifetimes.Define(mySolution.GetLifetime()); myUnityEditorProtocol.UnityModel.Change.Advise_NoAcknowledgement(currentConnectionLifetime.Lifetime, (args) => { if (args.HasNew && args.New == null) { currentConnectionLifetime.Terminate(); } }); RunInternal(run, currentConnectionLifetime.Lifetime, myUnityEditorProtocol.UnityModel.Value, tcs); }); return(tcs.Task); }
Task IUnitTestRunStrategy.Run(IUnitTestRun run) { lock (myCurrentLaunchesTaskAccess) { var key = run.Launch.GetData(ourLaunchedInUnityKey); if (key != null) { return(Task.FromResult(false)); } run.Launch.PutData(ourLaunchedInUnityKey, "smth"); var cancellationTs = new CancellationTokenSource(); run.Lifetime.OnTermination(cancellationTs.Cancel); run.PutData(ourCancellationTokenSourceKey, cancellationTs); var newLaunchTask = myCurrentLaunchesTask.ContinueWith(_ => Run(run), cancellationTs.Token).Unwrap(); myCurrentLaunchesTask = Task.WhenAll(myCurrentLaunchesTask, newLaunchTask); return(newLaunchTask); } }
Task IUnitTestRunStrategy.Run(IUnitTestRun run) { var key = run.Launch.GetData(ourLaunchedInUnityKey); if (key != null) { return(Task.FromResult(false)); } var hostId = run.HostController.HostId; if (hostId == WellKnownHostProvidersIds.DebugProviderId) { run.Launch.Output.Error( "Starting Unity tests from 'Debug' is currently unsupported. Please attach to editor and use 'Run'."); return(Task.FromResult(false)); } if (hostId != WellKnownHostProvidersIds.RunProviderId) { run.Launch.Output.Error( $"Starting Unity tests from '{hostId}' is currently unsupported. Please use `Run`."); return(Task.FromResult(false)); } var tcs = new TaskCompletionSource <bool>(); run.Launch.PutData(ourLaunchedInUnityKey, "smth"); run.PutData(ourCompletionSourceKey, tcs); myLogger.Verbose("Before calling Refresh."); Refresh(mySolution.Locks, run.Lifetime).GetAwaiter().OnCompleted(() => { mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "Check compilation", () => { 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(run.Lifetime, result => { 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(run.Lifetime, "ExecuteRunUT", () => { if (myEditorProtocol.UnityModel.Value == null) { tcs.SetException(new Exception("Unity Editor connection unavailable.")); return; } myEditorProtocol.UnityModel.ViewNotNull(run.Lifetime, (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); }); myEditorProtocol.UnityModel.Value.RunUnitTestLaunch(); }); } }); }); }); return(tcs.Task); }
Task IUnitTestRunStrategy.Run(IUnitTestRun run) { var key = run.Launch.GetData(ourLaunchedInUnityKey); if (key != null) { return(Task.FromResult(false)); } var hostId = run.HostController.HostId; if (hostId == WellKnownHostProvidersIds.DebugProviderId) { run.Launch.Output.Error("Starting Unity tests from 'Debug' is currently unsupported. Please attach to editor and use 'Run'."); return(Task.FromResult(false)); } if (hostId != WellKnownHostProvidersIds.RunProviderId) { run.Launch.Output.Error($"Starting Unity tests from '{hostId}' is currently unsupported. Please use `Run`."); return(Task.FromResult(false)); } var tcs = new TaskCompletionSource <bool>(); run.Launch.PutData(ourLaunchedInUnityKey, "smth"); run.PutData(ourCompletionSourceKey, tcs); // todo: Refresh Assets DB before running tests #558 // You can check EditorApplication.isCompiling after the refresh and if it is true, then a refresh will happen if there are no compile errors. // You can also hook into these event, this will tell you when compilation of assemblies started/finished. // https://docs.unity3d.com/ScriptReference/Compilation.CompilationPipeline-assemblyCompilationFinished.html // https://docs.unity3d.com/ScriptReference/Compilation.CompilationPipeline-assemblyCompilationStarted.html // Note that those events are only available for Unity 5.6+ // mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "RefreshBeforeUT", () => // { // myRiderSolutionSaver.Save(run.Lifetime, mySolution, async () => // { // await myUnityRefresher.Refresh(true); // }); // }); mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "ExecuteRunUT", () => { if (myUnityEditorProtocol.UnityModel.Value == null) { tcs.SetException(new Exception("Unity Editor connection unavailable.")); return; } var currentConnectionLifetime = Lifetimes.Define(run.Lifetime); myUnityEditorProtocol.UnityModel.Change.Advise_NoAcknowledgement(currentConnectionLifetime.Lifetime, args => { if (args.HasNew && args.New == null) { currentConnectionLifetime.Terminate(); } }); RunInternal(run, currentConnectionLifetime.Lifetime, myUnityEditorProtocol.UnityModel.Value, tcs); }); return(tcs.Task); }
Task IUnitTestRunStrategy.Run(IUnitTestRun run) { var key = run.Launch.GetData(ourLaunchedInUnityKey); if (key != null) { return(Task.FromResult(false)); } var hostId = run.HostController.HostId; if (hostId == WellKnownHostProvidersIds.DebugProviderId) { run.Launch.Output.Error( "Starting Unity tests from 'Debug' is currently unsupported. Please attach to editor and use 'Run'."); return(Task.FromResult(false)); } if (hostId != WellKnownHostProvidersIds.RunProviderId) { run.Launch.Output.Error( $"Starting Unity tests from '{hostId}' is currently unsupported. Please use `Run`."); return(Task.FromResult(false)); } var tcs = new TaskCompletionSource <bool>(); run.Launch.PutData(ourLaunchedInUnityKey, "smth"); run.PutData(ourCompletionSourceKey, tcs); // todo: Refresh Assets DB before running tests #558 // You can check EditorApplication.isCompiling after the refresh and if it is true, then a refresh will happen if there are no compile errors. // You can also hook into these event, this will tell you when compilation of assemblies started/finished. // https://docs.unity3d.com/ScriptReference/Compilation.CompilationPipeline-assemblyCompilationFinished.html // https://docs.unity3d.com/ScriptReference/Compilation.CompilationPipeline-assemblyCompilationStarted.html // Note that those events are only available for Unity 5.6+ myLogger.Verbose("Before calling Refresh."); Refresh(mySolution.Locks, run.Lifetime).GetAwaiter().OnCompleted(() => { mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "Check compilation", () => { 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(RdVoid.Instance); task.Result.AdviseNotNull(run.Lifetime, result => { 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 RdNotificationEntry("Compilation failed", "Script compilation in Unity failed, so tests were not started.", true, RdNotificationEntryType.INFO); myNotificationsModel.Notification.Fire(notification); }); myUnityHost.PerformModelAction(model => model.ActivateUnityLogView.Fire()); } else { var launch = SetupLaunch(run); mySolution.Locks.ExecuteOrQueueEx(run.Lifetime, "ExecuteRunUT", () => { if (myEditorProtocol.UnityModel.Value == null) { tcs.SetException(new Exception("Unity Editor connection unavailable.")); return; } myEditorProtocol.UnityModel.ViewNotNull(run.Lifetime, (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); }); myEditorProtocol.UnityModel.Value.RunUnitTestLaunch.Fire(RdVoid.Instance); }); } }); }); }); return(tcs.Task); }