void finishTestPlanRun(TestPlanRun run, Stopwatch testPlanTimer, failState runWentOk, TraceListener Logger, HybridStream logStream) { try { if (run != null) { if (runWentOk == failState.StartFail) { if (PrintTestPlanRunSummary) { summaryListener.OnTestPlanRunStart(run); // Call this to ensure that the correct planrun is being summarized } if (run.Verdict < Verdict.Aborted) { run.Verdict = Verdict.Error; } } for (int i = run.StepsWithPrePlanRun.Count - 1; i >= 0; i--) { Stopwatch postTimer = Stopwatch.StartNew(); String stepPath = string.Empty; try { ITestStep step = run.StepsWithPrePlanRun[i]; if ((step as TestStep)?.PrePostPlanRunUsed ?? true) { stepPath = step.GetStepPath(); run.AddTestStepStateUpdate(step.Id, null, StepState.PostPlanRun); try { run.ResourceManager.BeginStep(run, step, TestPlanExecutionStage.PostPlanRun, TapThread.Current.AbortToken); step.PlanRun = run; try { step.PostPlanRun(); } finally { run.ResourceManager.EndStep(step, TestPlanExecutionStage.PostPlanRun); step.PlanRun = null; } } finally { run.AddTestStepStateUpdate(step.Id, null, StepState.Idle); } Log.Debug(postTimer, "{0} PostPlanRun completed.", stepPath); } } catch (Exception ex) { Log.Warning("Error during post plan run of {0}.", stepPath); Log.Debug(ex); } } run.Duration = testPlanTimer.Elapsed; } if (run != null) { try { // The open resource threads might throw exceptions. If they do we must // Wait() for them to catch the exception. // If the run was aborted after the open resource threads were started but // before we wait for them (e.g. by an error in PrePlanRun), then we do it // here. run.ResourceManager.WaitUntilAllResourcesOpened(TapThread.Current.AbortToken); } catch (OperationCanceledException) { // Ignore this because this typically means that the wait was cancelled before. // Just to be sure also upgrade verdict to aborted. run.UpgradeVerdict(Verdict.Aborted); } catch (AggregateException e) { if (e.InnerExceptions.Count == 1) { Log.Error("Failed to open resource ({0})", e.GetInnerMostExceptionMessage()); Log.Debug(e); } else { Log.Error("Errors while opening resources:", e.GetInnerMostExceptionMessage()); foreach (Exception ie in e.InnerExceptions) { Log.Error(" {0}", ie.GetInnerMostExceptionMessage()); Log.Debug(ie); } } } if (PrintTestPlanRunSummary) { // wait for the summaryListener so the summary appears in the log file. run.WaitForResultListener(summaryListener); summaryListener.PrintSummary(); } OpenTap.Log.Flush(); Logger.Flush(); logStream.Flush(); run.AddTestPlanCompleted(logStream, runWentOk != failState.StartFail); run.ResourceManager.EndStep(this, TestPlanExecutionStage.Execute); if (!run.IsCompositeRun) { run.ResourceManager.EndStep(this, TestPlanExecutionStage.Open); } } } finally { if (monitors != null) { foreach (var item in monitors) { item.ExitTestPlanRun(run); } } } }