예제 #1
0
        /// <summary>
        /// Execute the TestPlan as specified.
        /// </summary>
        /// <param name="resultListeners">ResultListeners for result outputs.</param>
        /// <param name="metaDataParameters">Optional metadata parameters.</param>
        /// <param name="stepsOverride">Sub-section of test plan to be executed. Note this might include child steps of disabled parent steps.</param>
        /// <param name="cancellationToken">Cancellation token to abort the testplan</param>
        /// <returns>TestPlanRun results, no StepResults.</returns>
        public Task <TestPlanRun> ExecuteAsync(IEnumerable <IResultListener> resultListeners, IEnumerable <ResultParameter> metaDataParameters, HashSet <ITestStep> stepsOverride, CancellationToken cancellationToken)
        {
            Task <TestPlanRun> result = Task.Run(() =>
            {
                var sem = new SemaphoreSlim(0);
                TestPlanRun testPlanRun = null;
                TapThread.Start(() =>
                {
                    try
                    {
                        cancellationToken.Register(TapThread.Current.Abort);
                        testPlanRun = Execute(resultListeners, metaDataParameters, stepsOverride);
                    }
                    finally
                    {
                        sem.Release();
                    }
                }, "Plan Thread");
                sem.Wait();

                return(testPlanRun);
            });

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Execute the TestPlan as specified. Blocking.
        /// </summary>
        /// <param name="resultListeners">ResultListeners for result outputs.</param>
        /// <param name="metaDataParameters">Optional metadata parameters.</param>
        /// <param name="stepsOverride">Sub-section of test plan to be executed. Note this might include child steps of disabled parent steps.</param>
        /// <returns>TestPlanRun results, no StepResults.</returns>
        public TestPlanRun Execute(IEnumerable <IResultListener> resultListeners, IEnumerable <ResultParameter> metaDataParameters = null, HashSet <ITestStep> stepsOverride = null)
        {
            TestPlanRun run = null;

            TapThread.WithNewContext(() => run = this.DoExecute(resultListeners, metaDataParameters, stepsOverride));
            return(run);
        }
예제 #3
0
        /// <summary>
        /// Opens all resources referenced in this TestPlan (Instruments/DUTs/ResultListeners).
        /// This can be called before <see cref="TestPlan.Execute()"/> to manually control the opening/closing of the resources.
        /// </summary>
        public void Open(IEnumerable <IResultListener> listeners)
        {
            if (listeners == null)
            {
                throw new ArgumentNullException("listeners");
            }
            if (PrintTestPlanRunSummary)
            {
                listeners = listeners.Concat(new IResultListener[] { summaryListener });
            }

            if (currentExecutionState != null)
            {
                throw new InvalidOperationException("Open has already been called.");
            }
            if (IsRunning)
            {
                throw new InvalidOperationException("This TestPlan is already running.");
            }

            try
            {
                var allSteps = Utils.FlattenHeirarchy(Steps.Where(x => x.Enabled), step => step.GetEnabledChildSteps()).ToList();

                Stopwatch timer = Stopwatch.StartNew();
                currentExecutionState = new TestPlanRun(this, listeners.ToList(), DateTime.Now, Stopwatch.GetTimestamp(), true);
                OpenInternal(currentExecutionState, false, listeners.Cast <IResource>().ToList(), allSteps);
                try
                {
                    currentExecutionState.ResourceManager.WaitUntilAllResourcesOpened(TapThread.Current.AbortToken);
                }
                catch
                {
                    Log.Warning("Caught error while opening resources! See error message for details.");
                    throw;
                }

                Log.Debug(timer, "TestPlan opened.");
            }
            catch
            {
                // If there is an error, reset the state to allow calling open again later
                // when the user has fixed the error.
                if (currentExecutionState != null)
                {
                    currentExecutionState.ResourceManager.EndStep(this, TestPlanExecutionStage.Open);
                }

                if (monitors != null)
                {
                    foreach (var item in monitors)
                    {
                        item.ExitTestPlanRun(currentExecutionState);
                    }
                }

                currentExecutionState = null;
                throw;
            }
        }
예제 #4
0
        /// <summary>
        /// Signals that an action is beginning.
        /// </summary>
        /// <param name="planRun">The planrun for the currently executing testplan.</param>
        /// <param name="item">The item affected by the current action. This can be either a testplan or a teststep.</param>
        /// <param name="stage">The stage that is beginning.</param>
        /// <param name="cancellationToken">Used to cancel the step early.</param>
        public void BeginStep(TestPlanRun planRun, ITestStepParent item, TestPlanExecutionStage stage, CancellationToken cancellationToken)
        {
            switch (stage)
            {
            case TestPlanExecutionStage.Execute:
                if (item is TestPlan testPlan)
                {
                    var resources = ResourceManagerUtils.GetResourceNodes(StaticResources.Cast <object>().Concat(EnabledSteps));

                    // Proceed to open resources in case they have been changed or closed since last opening/executing the testplan.
                    // In case any are null, we need to do this before the resource prompt to allow a ILockManager implementation to
                    // set the resource first.
                    if (resources.Any(r => r.Resource == null))
                    {
                        beginOpenResoureces(resources, cancellationToken);
                    }

                    testPlan.StartResourcePromptAsync(planRun, resources.Select(res => res.Resource));

                    if (resources.Any(r => openTasks.ContainsKey(r.Resource) == false))
                    {
                        beginOpenResoureces(resources, cancellationToken);
                    }
                }
                break;

            case TestPlanExecutionStage.Open:
                if (item is TestPlan)
                {
                    var resources = ResourceManagerUtils.GetResourceNodes(StaticResources.Cast <object>().Concat(EnabledSteps));
                    beginOpenResoureces(resources, cancellationToken);
                }
                break;

            case TestPlanExecutionStage.Run:
            case TestPlanExecutionStage.PrePlanRun:
            {
                bool openCompletedWithSuccess = openTasks.Values.All(x => x.Status == TaskStatus.RanToCompletion);
                if (!openCompletedWithSuccess)
                {           // open did not complete or threw an exception.
                    using (TimeoutOperation.Create(() => TestPlan.PrintWaitingMessage(Resources)))
                        WaitUntilAllResourcesOpened(cancellationToken);
                }
                break;
            }

            case TestPlanExecutionStage.PostPlanRun: break;
            }
        }
예제 #5
0
 public override void OnTestPlanRunCompleted(TestPlanRun planRun, Stream log)
 {
     foreach (IResultSink sink in currentSinks)
     {
         try
         {
             sink.OnTestPlanRunCompleted(planRun);
         }
         catch (Exception ex)
         {
             Log.Error($"{TypeData.GetTypeData(sink).Name} caused an error.");
             Log.Debug(ex);
         }
     }
 }
예제 #6
0
        /// <summary>
        /// On test plan run completed the previously temporary file is moved to the location expanded by the macro path.
        /// </summary>
        /// <param name="planRun"></param>
        /// <param name="logStream"></param>
        public override void OnTestPlanRunCompleted(TestPlanRun planRun, Stream logStream)
        {
            if (logStream == null)
            {
                throw new ArgumentNullException("logStream");
            }
            base.OnTestPlanRunCompleted(planRun, logStream);
            OnActivity();


            string     outpath = "";
            FileStream fstr;

            lock (filereadlocker)
            {
                string realPath = FilePath.Expand(planRun);
                if (Path.GetDirectoryName(realPath) != "")
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(realPath));
                }

                int fileid = 1;
                outpath = realPath;
                while (File.Exists(outpath))
                {
                    var extension = Path.GetExtension(realPath);
                    outpath = Path.ChangeExtension(realPath, string.Format(".{0}", fileid++) + extension);
                }
                fstr = new FileStream(outpath, FileMode.Create);
            }

            if (useFilter())
            {
                filterCopyStream(logStream, fstr);
            }
            else
            {
                logStream.CopyTo(fstr);
            }
            fstr.Close();
        }
예제 #7
0
        private void OpenInternal(TestPlanRun run, bool isOpen, List <IResource> resources, List <ITestStep> steps)
        {
            monitors = TestPlanRunMonitors.GetCurrent();
            try
            {
                // Enter monitors
                foreach (var item in monitors)
                {
                    item.EnterTestPlanRun(run);
                }
            }
            finally   // We need to make sure OpenAllAsync is always called (even when CheckResources throws an exception).
            {         // Otherwise we risk that e.g. ResourceManager.WaitUntilAllResourcesOpened() will hang forever.
                run.ResourceManager.EnabledSteps    = steps;
                run.ResourceManager.StaticResources = resources;

                if (!isOpen)
                {
                    run.ResourceManager.BeginStep(run, this, TestPlanExecutionStage.Open, TapThread.Current.AbortToken);
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Closes all resources referenced in this TestPlan (Instruments/DUTs/ResultListeners).
        /// This should be called if <see cref="TestPlan.Open()"/> was called earlier to manually close the resources again.
        /// </summary>
        public void Close()
        {
            if (IsRunning)
            {
                throw new InvalidOperationException("Cannot close TestPlan while it is running.");
            }
            if (currentExecutionState == null)
            {
                throw new InvalidOperationException("Call open first.");
            }

            Stopwatch timer = Stopwatch.StartNew();

            currentExecutionState.ResourceManager.EndStep(this, TestPlanExecutionStage.Open);

            // If we locked the setup earlier, unlock it now that all recourses has been closed:
            foreach (var item in monitors)
            {
                item.ExitTestPlanRun(currentExecutionState);
            }

            currentExecutionState = null;
            Log.Debug(timer, "TestPlan closed.");
        }
예제 #9
0
        bool runPrePlanRunMethods(IEnumerable <ITestStep> steps, TestPlanRun planRun)
        {
            Stopwatch preTimer = Stopwatch.StartNew(); // try to avoid calling Stopwatch.StartNew too often.
            TimeSpan  elaps    = preTimer.Elapsed;

            foreach (ITestStep step in steps)
            {
                if (step.Enabled == false)
                {
                    continue;
                }
                bool runPre = true;
                if (step is TestStep s)
                {
                    runPre = s.PrePostPlanRunUsed;
                }
                planRun.StepsWithPrePlanRun.Add(step);
                try
                {
                    if (runPre)
                    {
                        planRun.AddTestStepStateUpdate(step.Id, null, StepState.PrePlanRun);
                        try
                        {
                            step.PlanRun = planRun;
                            planRun.ResourceManager.BeginStep(planRun, step, TestPlanExecutionStage.PrePlanRun, TapThread.Current.AbortToken);
                            try
                            {
                                step.PrePlanRun();
                            }
                            finally
                            {
                                planRun.ResourceManager.EndStep(step, TestPlanExecutionStage.PrePlanRun);
                                step.PlanRun = null;
                            }
                        }
                        finally
                        {
                            planRun.AddTestStepStateUpdate(step.Id, null, StepState.Idle);
                        }
                    }

                    if (!runPrePlanRunMethods(step.ChildTestSteps, planRun))
                    {
                        return(false);
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(String.Format("PrePlanRun of '{0}' failed with message '{1}'.",
                                            step.Name, ex.Message));
                    Log.Debug(ex);
                    Log.Error("Aborting TestPlan.");
                    return(false);
                }
                finally
                {
                    if (runPre)
                    {
                        var newelaps = preTimer.Elapsed;

                        Log.Debug(newelaps - elaps, "{0} PrePlanRun completed.", step.GetStepPath());
                        elaps = newelaps;
                    }
                }
            }
            return(true);
        }
예제 #10
0
        private TestPlanRun DoExecute(IEnumerable <IResultListener> resultListeners, IEnumerable <ResultParameter> metaDataParameters, HashSet <ITestStep> stepsOverride)
        {
            if (resultListeners == null)
            {
                throw new ArgumentNullException("resultListeners");
            }

            if (PrintTestPlanRunSummary && !resultListeners.Contains(summaryListener))
            {
                resultListeners = resultListeners.Concat(new IResultListener[] { summaryListener });
            }
            resultListeners = resultListeners.Where(r => r is IEnabledResource ? ((IEnabledResource)r).IsEnabled : true);
            IList <ITestStep> steps;

            if (stepsOverride == null)
            {
                steps = Steps;
            }
            else
            {
                // Remove steps that are already included via their parent steps.
                foreach (var step in stepsOverride)
                {
                    if (step == null)
                    {
                        throw new ArgumentException("stepsOverride may not contain null", "stepsOverride");
                    }

                    var p = step.GetParent <ITestStep>();
                    while (p != null)
                    {
                        if (stepsOverride.Contains(p))
                        {
                            throw new ArgumentException("stepsOverride may not contain steps and their parents.", "stepsOverride");
                        }
                        p = p.GetParent <ITestStep>();
                    }
                }
                steps = Utils.FlattenHeirarchy(Steps, step => step.ChildTestSteps).Where(stepsOverride.Contains).ToList();
            }

            long initTimeStamp = Stopwatch.GetTimestamp();
            var  initTime      = DateTime.Now;

            Log.Info("-----------------------------------------------------------------");

            var fileStreamFile = FileSystemHelper.CreateTempFile();
            var logStream      = new HybridStream(fileStreamFile, 1024 * 1024);

            var planRunLog = new FileTraceListener(logStream)
            {
                IsRelative = true
            };

            OpenTap.Log.AddListener(planRunLog);

            var allSteps        = Utils.FlattenHeirarchy(steps, step => step.ChildTestSteps);
            var allEnabledSteps = Utils.FlattenHeirarchy(steps.Where(x => x.Enabled), step => step.GetEnabledChildSteps());

            var enabledSinks = new HashSet <IResultSink>();

            TestStepExtensions.GetObjectSettings <IResultSink, ITestStep, IResultSink>(allEnabledSteps, true, null, enabledSinks);
            if (enabledSinks.Count > 0)
            {
                var sinkListener = new ResultSinkListener(enabledSinks);
                resultListeners = resultListeners.Append(sinkListener);
            }

            Log.Info("Starting TestPlan '{0}' on {1}, {2} of {3} TestSteps enabled.", Name, initTime, allEnabledSteps.Count, allSteps.Count);

            // Reset step verdict.
            foreach (var step in allSteps)
            {
                if (step.Verdict != Verdict.NotSet)
                {
                    step.Verdict = Verdict.NotSet;
                    step.OnPropertyChanged("Verdict");
                }
            }

            if (currentExecutionState != null)
            {
                // load result listeners that are _not_ used in the previous runs.
                // otherwise they wont get opened later.
                foreach (var rl in resultListeners)
                {
                    if (!currentExecutionState.ResultListeners.Contains(rl))
                    {
                        currentExecutionState.ResultListeners.Add(rl);
                    }
                }
            }

            var currentListeners = currentExecutionState != null ? currentExecutionState.ResultListeners : resultListeners;

            TestPlanRun execStage;
            bool        continuedExecutionState = false;

            if (currentExecutionState != null)
            {
                execStage = new TestPlanRun(currentExecutionState, initTime, initTimeStamp);

                continuedExecutionState = true;
            }
            else
            {
                execStage = new TestPlanRun(this, resultListeners.ToList(), initTime, initTimeStamp);

                execStage.Parameters.AddRange(PluginManager.GetPluginVersions(allEnabledSteps));
                execStage.ResourceManager.ResourceOpened += r =>
                {
                    execStage.Parameters.AddRange(PluginManager.GetPluginVersions(new List <object> {
                        r
                    }));
                };
            }


            if (metaDataParameters != null)
            {
                execStage.Parameters.AddRange(metaDataParameters);
            }

            var prevExecutingPlanRun = executingPlanRun.LocalValue;

            executingPlanRun.LocalValue = execStage;
            CurrentRun = execStage;

            failState runWentOk = failState.StartFail;

            // ReSharper disable once InconsistentNaming
            var preRun_Run_PostRunTimer = Stopwatch.StartNew();

            try
            {
                execStage.FailedToStart = true; // Set it here in case OpenInternal throws an exception. Could happen if a step is missing an instrument

                OpenInternal(execStage, continuedExecutionState, currentListeners.Cast <IResource>().ToList(), allEnabledSteps);

                execStage.WaitForSerialization();
                execStage.ResourceManager.BeginStep(execStage, this, TestPlanExecutionStage.Execute, TapThread.Current.AbortToken);

                if (continuedExecutionState)
                {  // Since resources are not opened, getting metadata cannot be done in the wait for resources continuation
                   // like shown in TestPlanRun. Instead we do it here.
                    foreach (var res in execStage.ResourceManager.Resources)
                    {
                        execStage.Parameters.AddRange(ResultParameters.GetMetadataFromObject(res));
                    }
                }

                runWentOk = failState.ExecFail; //important if test plan is aborted and runWentOk is never returned.
                runWentOk = execTestPlan(execStage, steps);
            }
            catch (Exception e)
            {
                if (e is OperationCanceledException && execStage.MainThread.AbortToken.IsCancellationRequested)
                {
                    Log.Warning(String.Format("TestPlan aborted. ({0})", e.Message));
                    execStage.UpgradeVerdict(Verdict.Aborted);
                }
                else if (e is ThreadAbortException)
                {
                    // It seems this actually never happens.
                    Log.Warning("TestPlan aborted.");
                    execStage.UpgradeVerdict(Verdict.Aborted);
                    //Avoid entering the finally clause.
                    Thread.Sleep(500);
                }
                else if (e is System.ComponentModel.LicenseException)
                {
                    Log.Error(e.Message);
                    execStage.UpgradeVerdict(Verdict.Error);
                }
                else
                {
                    Log.Warning("TestPlan aborted.");
                    Log.Error(e.Message);
                    Log.Debug(e);
                    execStage.UpgradeVerdict(Verdict.Error);
                }
            }
            finally
            {
                execStage.FailedToStart = (runWentOk == failState.StartFail);

                try
                {
                    finishTestPlanRun(execStage, preRun_Run_PostRunTimer, runWentOk, planRunLog, logStream);
                }
                catch (Exception ex)
                {
                    Log.Error("Error while finishing TestPlan.");
                    Log.Debug(ex);
                }

                OpenTap.Log.RemoveListener(planRunLog);
                planRunLog.Dispose();

                logStream.Dispose();
                File.Delete(fileStreamFile);

                // Clean all test steps StepRun, otherwise the next test plan execution will be stuck at TestStep.DoRun at steps that does not have a cleared StepRun.
                foreach (var step in allSteps)
                {
                    step.StepRun = null;
                }

                executingPlanRun.LocalValue = prevExecutingPlanRun;
                CurrentRun = prevExecutingPlanRun;
            }
            return(execStage);
        }
예제 #11
0
 /// <summary>Clears the memory.</summary>
 /// <param name="planRun"></param>
 public override void OnTestPlanRunStart(TestPlanRun planRun)
 {
     stepRuns     = new Dictionary <Guid, TestStepRun>();
     this.planRun = planRun;
 }
예제 #12
0
 /// <summary> Cleans up after this instance </summary>
 public void OnTestPlanRunCompleted(TestPlanRun run)
 {
     ItemsInQueue.Dispose();
 }
예제 #13
0
 /// <summary> Initializes this instance. </summary>
 public void OnTestPlanRunStart(TestPlanRun run)
 {
     ItemsInQueue = new ManualResetEvent(false);
 }
예제 #14
0
        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);
                    }
                }
            }
        }
예제 #15
0
        /// <summary>
        /// Calls the PromptForDutMetadata delegate for all referenced DUTs.
        /// </summary>
        internal void StartResourcePromptAsync(TestPlanRun planRun, IEnumerable <IResource> _resources)
        {
            var resources = _resources.Where(x => x != null).ToArray();

            List <Type> componentSettingsWithMetaData = new List <Type>();
            var         componentSettings             = PluginManager.GetPlugins <ComponentSettings>();
            bool        AnyMetaData = false;

            planRun.PromptWaitHandle.Reset();

            try
            {
                foreach (var setting in componentSettings)
                {
                    foreach (var member in setting.GetMembers())
                    {
                        var attr = member.GetAttribute <MetaDataAttribute>();
                        if (attr != null && attr.PromptUser)
                        {
                            AnyMetaData = true;
                            componentSettingsWithMetaData.Add(setting);
                        }
                    }
                }

                foreach (var resource in resources)
                {
                    var type = TypeData.GetTypeData(resource);
                    foreach (var __prop in type.GetMembers())
                    {
                        IMemberData prop = __prop;
                        var         attr = prop.GetAttribute <MetaDataAttribute>();
                        if (attr != null && attr.PromptUser)
                        {
                            AnyMetaData = true;
                        }
                    }
                }
            }
            catch
            {
                // this is just a defensive catch to make sure that the waithandle is not left unset (and we risk waiting for it indefinitely)
                planRun.PromptWaitHandle.Set();
                throw;
            }

            if (AnyMetaData && EngineSettings.Current.PromptForMetaData)
            {
                TapThread.Start(() =>
                {
                    try
                    {
                        List <object> objects = new List <object>();
                        objects.AddRange(componentSettingsWithMetaData.Select(ComponentSettings.GetCurrent));
                        objects.AddRange(resources);

                        planRun.PromptedResources = resources;
                        var obj = new MetadataPromptObject {
                            Resources = objects
                        };
                        UserInput.Request(obj, false);
                        if (obj.Response == MetadataPromptObject.PromptResponse.Abort)
                        {
                            planRun.MainThread.Abort();
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Debug(e);
                        planRun.MainThread.Abort("Error occured while executing platform requests. Metadata prompt can be disabled from the Engine settings menu.");
                    }
                    finally
                    {
                        planRun.PromptWaitHandle.Set();
                    }
                }, name: "Request Metadata");
            }
            else
            {
                planRun.PromptWaitHandle.Set();
            }
        }
예제 #16
0
        /// <summary>
        /// Signals that an action is beginning.
        /// </summary>
        /// <param name="planRun">The planrun for the currently executing testplan.</param>
        /// <param name="item">The item affected by the current action. This can be either a testplan or a teststep.</param>
        /// <param name="stage">The stage that is beginning.</param>
        /// <param name="cancellationToken">Used to cancel the step early.</param>
        public void BeginStep(TestPlanRun planRun, ITestStepParent item, TestPlanExecutionStage stage, CancellationToken cancellationToken)
        {
            switch (stage)
            {
            case TestPlanExecutionStage.Open:
            case TestPlanExecutionStage.Execute:
            {
                var resources = ResourceManagerUtils.GetResourceNodes(StaticResources);

                if (item is TestPlan plan && stage == TestPlanExecutionStage.Execute)
                {
                    // Prompt for metadata for all resources, not only static ones.
                    var testPlanResources = ResourceManagerUtils.GetResourceNodes(EnabledSteps);
                    plan.StartResourcePromptAsync(planRun, resources.Concat(testPlanResources).Select(res => res.Resource));
                }

                if (resources.All(r => r.Resource?.IsConnected ?? false))
                {
                    return;
                }

                // Call ILockManagers before checking for null
                try
                {
                    lockManager.BeforeOpen(resources, cancellationToken);
                }
                finally
                {
                    lock (resourceWithBeforeOpenCalled)
                    {
                        resourceWithBeforeOpenCalled.AddRange(resources);
                    }
                }

                try
                {
                    // Check null resources
                    if (resources.Any(res => res.Resource == null))
                    {
                        // Now check resources since we know one of them should have a null resource
                        resources.ForEach(res =>
                            {
                                if (res.StrongDependencies.Contains(null) || res.WeakDependencies.Contains(null))
                                {
                                    throw new Exception(String.Format("Resource property not set on resource {0}. Please configure resource.", res.Resource));
                                }
                            });
                    }
                }
                finally
                {
                    OpenResources(resources, cancellationToken);
                }
                break;
            }

            case TestPlanExecutionStage.Run:
                if (item is ITestStep step)
                {
                    var resources = ResourceManagerUtils.GetResourceNodes(new List <object> {
                        step
                    });
                    if (resources.Any())
                    {
                        // Call ILockManagers before checking for null
                        try
                        {
                            lockManager.BeforeOpen(resources, cancellationToken);
                        }
                        finally
                        {
                            lock (resourceWithBeforeOpenCalled)
                            {
                                resourceWithBeforeOpenCalled.AddRange(resources);
                            }
                        }

                        try
                        {
                            // Check null resources
                            if (resources.Any(res => res.Resource == null))
                            {
                                step.CheckResources();

                                // Now check resources since we know one of them should have a null resource
                                resources.ForEach(res =>
                                {
                                    if (res.StrongDependencies.Contains(null) || res.WeakDependencies.Contains(null))
                                    {
                                        throw new Exception(String.Format("Resource property not set on resource {0}. Please configure resource.", res.Resource));
                                    }
                                });
                            }
                        }
                        finally
                        {
                            lock (resourceLock)
                            {
                                resourceDependencies[step] = resources.Select(x => x.Resource).ToList();
                                foreach (ResourceNode n in resources)
                                {
                                    if (n.Resource is IResource resource)
                                    {
                                        if (!resourceReferenceCount.ContainsKey(resource))
                                        {
                                            resourceReferenceCount[resource] = 0;
                                        }
                                        resourceReferenceCount[resource] += 1;
                                    }
                                }
                            }

                            OpenResources(resources, cancellationToken);
                        }
                        WaitHandle.WaitAny(new[] { planRun.PromptWaitHandle, planRun.MainThread.AbortToken.WaitHandle });
                    }
                }
                break;
            }
        }
예제 #17
0
        failState execTestPlan(TestPlanRun execStage, IList <ITestStep> steps)
        {
            WaitHandle.WaitAny(new[] { execStage.PromptWaitHandle, TapThread.Current.AbortToken.WaitHandle });
            bool resultListenerError = false;

            execStage.ScheduleInResultProcessingThread <IResultListener>(resultListener =>
            {
                try
                {
                    using (TimeoutOperation.Create(() => PrintWaitingMessage(new List <IResource>()
                    {
                        resultListener
                    })))
                        execStage.ResourceManager.WaitUntilResourcesOpened(TapThread.Current.AbortToken, resultListener);
                    try
                    {
                        // some resources might set metadata in the Open methods.
                        // this information needs to be propagated to result listeners as well.
                        // this returns quickly if its a lazy resource manager.
                        using (TimeoutOperation.Create(
                                   () => PrintWaitingMessage(new List <IResource>()
                        {
                            resultListener
                        })))
                            execStage.ResourceManager.WaitUntilAllResourcesOpened(TapThread.Current.AbortToken);
                    }
                    catch // this error will also be handled somewhere else.
                    {
                    }

                    execStage.WaitForSerialization();
                    foreach (var res in execStage.PromptedResources)
                    {
                        execStage.Parameters.AddRange(ResultParameters.GetMetadataFromObject(res));
                    }
                    resultListener.OnTestPlanRunStart(execStage);
                }
                catch (OperationCanceledException) when(execStage.MainThread.AbortToken.IsCancellationRequested)
                {
                    // test plan thread was aborted, this is OK.
                }
                catch (Exception ex)
                {
                    Log.Error("Error in OnTestPlanRunStart for '{0}': '{1}'", resultListener, ex.Message);
                    Log.Debug(ex);
                    resultListenerError = true;
                }
            }, true);

            if (resultListenerError)
            {
                return(failState.StartFail);
            }

            var sw = Stopwatch.StartNew();

            try
            {
                execStage.StepsWithPrePlanRun.Clear();
                if (!runPrePlanRunMethods(steps, execStage))
                {
                    return(failState.StartFail);
                }
            }
            catch (Exception e)
            {
                Log.Error(e.GetInnerMostExceptionMessage());
                Log.Debug(e);
                return(failState.StartFail);
            }
            finally{
                {
                    Log.Debug(sw, "PrePlanRun Methods completed");
                }
            }

            Stopwatch planRunOnlyTimer = Stopwatch.StartNew();
            var       runs             = new List <TestStepRun>();

            try
            {
                for (int i = 0; i < steps.Count; i++)
                {
                    var step = steps[i];
                    if (step.Enabled == false)
                    {
                        continue;
                    }
                    var run = step.DoRun(execStage, execStage);
                    if (!run.Skipped)
                    {
                        runs.Add(run);
                    }
                    run.CheckBreakCondition();

                    // note: The following is copied inside TestStep.cs
                    if (run.SuggestedNextStep is Guid id)
                    {
                        int nextindex = steps.IndexWhen(x => x.Id == id);
                        if (nextindex >= 0)
                        {
                            i = nextindex - 1;
                        }
                        // if skip to next step, dont add it to the wait queue.
                    }
                }
            }
            catch (TestStepBreakException breakEx)
            {
                Log.Info("{0}", breakEx.Message);
            }
            finally
            {
                // Now wait for them to actually complete. They might defer internally.
                foreach (var run in runs)
                {
                    run.WaitForCompletion();
                    execStage.UpgradeVerdict(run.Verdict);
                }
            }



            Log.Debug(planRunOnlyTimer, "Test step runs finished.");

            return(failState.Ok);
        }
예제 #18
0
 /// <summary>
 /// Creates a new ResultProxy. Done for each test step run.
 /// </summary>
 /// <param name="stepRun">TestStepRun that this result proxy is proxy for.</param>
 /// <param name="planRun">TestPlanRun that this result proxy is proxy for.</param>
 public ResultSource(TestStepRun stepRun, TestPlanRun planRun)
 {
     this.stepRun = stepRun;
     this.planRun = planRun;
 }
예제 #19
0
파일: MacroPath.cs 프로젝트: ZHJEE/OpenTAP
        /// <summary> Expands the text. Macros are harvested from the optional TestPlanRun or the test step.</summary>
        /// <param name="run">A place to find additional metadata for macro expansion.</param>
        /// <param name="date">If no date was found in the metadata, this date will be used. If date is not supplied, DateTime.Now will be used.</param>
        /// <param name="testPlanDir">If no TestPlanDir was found in the metata, this TestPlanDir will be used.</param>
        /// <param name="replacements">Overrides other macro parameters.</param>
        /// <returns>The expanded string.</returns>
        public string Expand(TestPlanRun run, DateTime?date, string testPlanDir, Dictionary <string, object> replacements)
        {
            ITestStepParent context = Context;

            IEnumerable <(string, object)> getMacro()
            {
                // note: macros are case-insensitive.

                if (testPlanDir != null)
                {
                    yield return("TestPlanDir", testPlanDir);
                }

                if (date != null)
                {
                    yield return("date", date);
                }

                if (replacements != null)
                {
                    foreach (var elem in replacements)
                    {
                        yield return(elem.Key, elem.Value);
                    }
                }

                if (run != null)
                {
                    var runparams = run.Parameters.Concat(ResultParameters.GetMetadataFromObject(run)).Where(y => y.IsMetaData);

                    foreach (var v in runparams)
                    {
                        var path = v.Value;
                        yield return(v.Name, path);

                        yield return(v.MacroName, path);
                    }
                }

                ITestStepParent ctx = context;

                while (ctx != null)
                {
                    var p = ResultParameters.GetMetadataFromObject(ctx);
                    foreach (var v in p)
                    {
                        if (v.IsMetaData == false)
                        {
                            continue;
                        }
                        var path = v.Value;
                        yield return(v.Name, path);

                        yield return(v.MacroName, path);
                    }
                    ctx = ctx.Parent;
                }
                yield return("date", DateTime.Now);

                yield return("Verdict", Verdict.NotSet);

                var met = ResultParameters.GetComponentSettingsMetadataLazy(false);

                foreach (var ps in met)
                {
                    foreach (var v in ps)
                    {
                        if (v.IsMetaData == false)
                        {
                            continue;
                        }

                        var path = v.Value;
                        yield return(v.Name, path);

                        yield return(v.MacroName, path);
                    }
                }
            }

            return(ReplaceMacros(Text, getMacro().Select(x => (x.Item1, StringConvertProvider.GetString(x.Item2)))));
        }
예제 #20
0
파일: MacroPath.cs 프로젝트: ZHJEE/OpenTAP
 /// <summary> Expands the text. Macros are harvested from the optional TestPlanRun or the test step.</summary>
 /// <param name="run">A place to find additional metadata for macro expansion.</param>
 /// <param name="date">If no date was found in the metadata, this date will be used. If date is not supplied, DateTime.Now will be used.</param>
 /// <param name="testPlanDir">If no TestPlanDir was found in the metata, this TestPlanDir will be used.</param>
 /// <returns>The expanded string.</returns>
 public string Expand(TestPlanRun run = null, DateTime?date = null, string testPlanDir = null)
 {
     return(Expand(run, date, testPlanDir, null));
 }