Beispiel #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);
        }
Beispiel #2
0
        public void Run2()
        {
            var steps = EnabledChildSteps.ToArray();

            SemaphoreSlim sem = new SemaphoreSlim(0);
            var           trd = TapThread.Current;

            Log.Info("Starting {0} child steps in separate threads.", steps.Length);
            foreach (var _step in steps)
            {
                var step = _step;
                TapThread.Start(() =>
                {
                    try
                    {
                        RunChildStep(step);
                    }
                    catch
                    {
                        // no need to do anything. This thread will end now.
                        TapThread.WithNewContext(trd.Abort, null);
                    }
                    finally
                    {
                        sem.Release();
                    }
                });
            }

            for (int waits = 0; waits < steps.Length; waits++)
            {
                sem.Wait();
            }
        }
Beispiel #3
0
 /// <summary>
 /// Start a search task that finds plugins to the platform.
 /// This call is not blocking, some other calls to PluginManager will automatically
 /// wait for this task to finish (or even start it if it hasn't been already). These calls
 /// include <see cref="GetAllPlugins"/>, <see cref="GetPlugins{BaseType}"/>,
 /// <see cref="GetPlugins(Type)"/>, <see cref="LocateType(string)"/> and <see cref="LocateTypeData(string)"/>
 /// </summary>
 public static Task SearchAsync()
 {
     searchTask.Reset();
     searcher = null;
     ChangeID++;
     TapThread.Start(Search);
     return(Task.Run(() => GetSearcher()));
 }
Beispiel #4
0
 private void MonitorPackageChange()
 {
     if (!IsMonitoringPackageChange)
     {
         IsMonitoringPackageChange = true;
         TapThread.Start(() =>
         {
             while (true)
             {
                 ChangeId.WaitForChangeBlocking();
                 PackageChanged();
             }
         });
     }
 }
Beispiel #5
0
        public void TestThreadField()
        {
            tf.Value  = 100;
            tf2.Value = 200;
            object    value = null;
            Semaphore sem   = new Semaphore(0, 1);

            TapThread.Start(() =>
            {
                value = tf.Value;
                sem.Release();
            });
            sem.WaitOne();
            Assert.AreEqual(100, value);
        }
Beispiel #6
0
        public void TestValuesExtremes()
        {
            var prev = UserInput.GetInterface();

            try
            {
                CliUserInputInterface.Load();
                TestObject obj = new TestObject();
                var        sem = new SemaphoreSlim(0);
                bool       exceptionHappened = false;
                try
                {
                    UserInput.Request(obj, TimeSpan.Zero, true); // should return immediately.
                    Assert.Fail("Timeout exception should have been thrown");
                }
                catch (TimeoutException)
                {
                }
                var trd = TapThread.Start(() =>
                {
                    try
                    {
                        UserInput.Request(obj, TimeSpan.MaxValue, true);
                    }
                    catch (OperationCanceledException)
                    {
                        exceptionHappened = true;
                    }

                    sem.Release();
                });
                trd.Abort();
                if (!sem.Wait(1000) || exceptionHappened == false)
                {
                    Assert.Fail("Should have been canceled by thread");
                }
            }
            finally
            {
                UserInput.SetInterface(prev);
            }
        }
Beispiel #7
0
        public static TapProcessContainer StartFromArgs(string args, TimeSpan timeOutAfter)
        {
            Process proc = new Process();

            var container = new TapProcessContainer {
                TapProcess = proc
            };


            var file  = Path.GetDirectoryName(typeof(PluginManager).Assembly.Location);
            var files = new[] { Path.Combine(file, "tap.exe"), Path.Combine(file, "tap"), Path.Combine(file, "tap.dll") };

            global::OpenTap.Log.CreateSource("test").Debug($"location: {file}");
            var program = files.First(File.Exists);

            if (program.Contains(".dll"))
            {
                program = "dotnet";
                args    = $"\"{file}/tap.dll\" " + args;
            }

            proc.StartInfo = new ProcessStartInfo(program, args)
            {
                UseShellExecute        = true,
                RedirectStandardOutput = true,
                RedirectStandardInput  = true,
                RedirectStandardError  = true,
                CreateNoWindow         = true,
            };
            proc.StartInfo.UseShellExecute = false;

            container.go();
            TapThread.Start(() =>
            {
                TapThread.Sleep(timeOutAfter);
                proc.Kill();
            });
            return(container);
        }
Beispiel #8
0
        public void TimeoutOperationTest()
        {
            var sem = new System.Threading.Semaphore(0, 1);

            TapThread.Start(() => sem.Release());
            sem.WaitOne();
            {
                bool calledAction = false;
                var  operation    = TimeoutOperation.Create(TimeSpan.FromMilliseconds(1), () =>
                {
                    calledAction = true;
                    sem.Release();
                });
                sem.WaitOne();
                Assert.IsTrue(calledAction);
            }
            {
                bool calledAction = false;
                var  operation    = TimeoutOperation.Create(TimeSpan.FromMilliseconds(50), () => calledAction = true);
                operation.Dispose();
                Assert.IsFalse(calledAction);
            }
            {
                bool calledAction = false;
                var  operation    = TimeoutOperation.Create(TimeSpan.FromMilliseconds(1), () =>
                {
                    calledAction = true;
                });
                operation.Dispose();
                Assert.IsFalse(calledAction);
            }
            {
                bool calledAction = false;
                var  operation    = TimeoutOperation.Create(TimeSpan.FromMilliseconds(1), () => calledAction = true);
                Assert.IsFalse(calledAction);
                operation.Dispose();
            }
        }
Beispiel #9
0
        public void SweepRaceBug()
        {
            // test that validation rules can be checked while the test plan is running
            // without causing an error. The validation rules does not need to do actual validation
            // but since SweepLoop and SweepLoopRange modifies its child steps this could cause an error
            // as shown by SweepRaceBugCheckStep and SweepRaceBugStep.
            var plan   = new TestPlan();
            var repeat = new RepeatStep {
                Count = 10, Action = RepeatStep.RepeatStepAction.Fixed_Count
            };
            var loop = new SweepLoop();

            repeat.ChildTestSteps.Add(loop);
            loop.ChildTestSteps.Add(new SweepRaceBugStep()
            {
            });
            loop.ChildTestSteps.Add(new SweepRaceBugCheckStep()
            {
            });
            var steptype = TypeData.FromType(typeof(SweepRaceBugStep));
            var member   = steptype.GetMember(nameof(SweepRaceBugStep.Frequency));
            var member2  = TypeData.FromType(typeof(SweepRaceBugCheckStep)).GetMember(nameof(SweepRaceBugCheckStep.Frequency2));

            var lst = new List <SweepParam>();

            double[] values = new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            lst.Add(new SweepParam(new[] { member }, values.Cast <object>().ToArray()));
            lst.Add(new SweepParam(new[] { member2 }, values.Cast <object>().ToArray()));
            loop.SweepParameters = lst;

            var loopRange = new SweepLoopRange();

            loopRange.SweepStart  = 1;
            loopRange.SweepEnd    = 10;
            loopRange.SweepPoints = 10;
            loopRange.ChildTestSteps.Add(new SweepRaceBugStep()
            {
            });
            loopRange.ChildTestSteps.Add(new SweepRaceBugCheckStep()
            {
            });
            loopRange.SweepProperties = new List <IMemberData> {
                member, member2
            };
            var repeat2 = new RepeatStep {
                Count = 10, Action = RepeatStep.RepeatStepAction.Fixed_Count
            };

            repeat2.ChildTestSteps.Add(loopRange);
            var parallel = new ParallelStep();

            plan.ChildTestSteps.Add(parallel);
            parallel.ChildTestSteps.Add(repeat);
            parallel.ChildTestSteps.Add(repeat2);

            TestPlanRun run = null;

            TapThread.Start(() => run = plan.Execute());
            TapThread.Start(() =>
            {
                while (run == null)
                {
                    loopRange.Error.ToList();
                }
            });
            while (run == null)
            {
                loop.Error.ToList();
            }

            Assert.AreEqual(Verdict.NotSet, run.Verdict);
        }
Beispiel #10
0
        public override void Run()
        {
            Int32 timeout = Timeout <= 0 ? Int32.MaxValue : Timeout;

            prepend = string.IsNullOrEmpty(LogHeader) ? "" : LogHeader + " ";

            var process = new Process();

            process.StartInfo.FileName               = Application;
            process.StartInfo.Arguments              = Arguments;
            process.StartInfo.WorkingDirectory       = Path.GetFullPath(WorkingDirectory);
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError  = true;
            process.StartInfo.CreateNoWindow         = true;
            var abortRegistration = TapThread.Current.AbortToken.Register(() =>
            {
                Log.Debug("Ending process '{0}'.", Application);
                process.Kill();
            });

            if (WaitForEnd)
            {
                output = new StringBuilder();

                using (outputWaitHandle = new ManualResetEvent(false))
                    using (errorWaitHandle = new ManualResetEvent(false))
                        using (process)
                            using (abortRegistration)
                            {
                                process.OutputDataReceived += OutputDataRecv;
                                process.ErrorDataReceived  += ErrorDataRecv;

                                Log.Debug("Starting process {0} with arguments \"{1}\"", Application, Arguments);
                                process.Start();

                                process.BeginOutputReadLine();
                                process.BeginErrorReadLine();
                                var newlineArray = new [] { Environment.NewLine };

                                if (process.WaitForExit(timeout) &&
                                    outputWaitHandle.WaitOne(timeout) &&
                                    errorWaitHandle.WaitOne(timeout))
                                {
                                    var resultData = output.ToString();

                                    ProcessOutput(resultData);
                                    if (CheckExitCode)
                                    {
                                        if (process.ExitCode != 0)
                                        {
                                            UpgradeVerdict(Verdict.Fail);
                                        }
                                        else
                                        {
                                            UpgradeVerdict(Verdict.Pass);
                                        }
                                    }
                                }
                                else
                                {
                                    process.OutputDataReceived -= OutputDataRecv;
                                    process.ErrorDataReceived  -= ErrorDataRecv;

                                    var resultData = output.ToString();

                                    if (AddToLog)
                                    {
                                        foreach (var line in resultData.Split(newlineArray, StringSplitOptions.None))
                                        {
                                            Log.Info("{0}{1}", prepend, line);
                                        }
                                    }

                                    ProcessOutput(resultData);

                                    Log.Error("Timed out while waiting for application. Trying to kill process...");

                                    process.Kill();
                                    UpgradeVerdict(Verdict.Fail);
                                }
                            }
            }
            else
            {
                TapThread.Start(() =>
                {
                    using (process)
                        using (abortRegistration)
                        {
                            process.Start();
                            process.WaitForExit();
                            abortRegistration.Dispose();
                        }
                });
            }
        }
Beispiel #11
0
        void IUserInputInterface.RequestUserInput(object dataObject, TimeSpan Timeout, bool modal)
        {
            if (readerThread == null)
            {
                lock (readerLock)
                {
                    if (readerThread == null)
                    {
                        readerThread = TapThread.Start(() =>
                        {
                            while (true)
                            {
                                lines.Add(Console.ReadLine());
                            }
                        }, "Console Reader");
                    }
                }
            }
            DateTime TimeoutTime;

            if (Timeout == TimeSpan.MaxValue)
            {
                TimeoutTime = DateTime.MaxValue;
            }
            else
            {
                TimeoutTime = DateTime.Now + Timeout;
            }

            if (Timeout >= new TimeSpan(0, 0, 0, 0, int.MaxValue))
            {
                Timeout = new TimeSpan(0, 0, 0, 0, -1);
            }
            do
            {
                if (platforDialogMutex.WaitOne(Timeout))
                {
                    break;
                }
                if (DateTime.Now >= TimeoutTime)
                {
                    throw new TimeoutException("Request User Input timed out");
                }
            } while (true);

            try
            {
                Log.Flush();
                var a    = AnnotationCollection.Annotate(dataObject);
                var mems = a.Get <IMembersAnnotation>()?.Members;

                if (mems == null)
                {
                    return;
                }
                mems = mems.Concat(a.Get <IForwardedAnnotations>()?.Forwarded ?? Array.Empty <AnnotationCollection>());
                var title = TypeData.GetTypeData(dataObject)?.GetMember("Name")?.GetValue(dataObject) as string;
                if (string.IsNullOrWhiteSpace(title) == false)
                {
                    Console.WriteLine(title);
                }
                bool isBrowsable(IMemberData m)
                {
                    var browsable = m.GetAttribute <System.ComponentModel.BrowsableAttribute>();

                    // Browsable overrides everything
                    if (browsable != null)
                    {
                        return(browsable.Browsable);
                    }

                    if (m is IMemberData mem)
                    {
                        if (m.HasAttribute <OutputAttribute>())
                        {
                            return(true);
                        }
                        if (!mem.Writable || !mem.Readable)
                        {
                            return(false);
                        }
                        return(true);
                    }
                    return(false);
                }
                foreach (var _message in mems)
                {
                    var mem = _message.Get <IMemberAnnotation>()?.Member;
                    if (mem != null)
                    {
                        if (!isBrowsable(mem))
                        {
                            continue;
                        }
                    }
                    log.Flush();
                    var str = _message.Get <IStringValueAnnotation>();
                    if (str == null)
                    {
                        continue;
                    }
                    var name = _message.Get <DisplayAttribute>()?.Name;

start:
                    var isVisible = _message.Get <IAccessAnnotation>()?.IsVisible ?? true;
                    if (!isVisible)
                    {
                        continue;
                    }


                    var isReadOnly = _message.Get <IAccessAnnotation>()?.IsReadOnly ?? false;
                    if (isReadOnly)
                    {
                        Console.WriteLine($"{str.Value}");
                        continue;
                    }

                    var           proxy       = _message.Get <IAvailableValuesAnnotationProxy>();
                    List <string> options     = null;
                    bool          pleaseEnter = true;
                    if (proxy != null)
                    {
                        pleaseEnter = false;
                        options     = new List <string>();

                        int index         = 0;
                        var current_value = proxy.SelectedValue;
                        foreach (var value in proxy.AvailableValues)
                        {
                            var v = value.Get <IStringValueAnnotation>();
                            if (v != null)
                            {
                                Console.Write("{1}: '{0}'", v.Value, index);
                                if (value == current_value)
                                {
                                    Console.WriteLine(" (default)");
                                }
                                else
                                {
                                    Console.WriteLine();
                                }
                            }
                            options.Add(v?.Value);
                            index++;
                        }
                        Console.Write("Please enter a number or name ");
                    }

                    var  layout   = _message.Get <IMemberAnnotation>()?.Member.GetAttribute <LayoutAttribute>();
                    bool showName = layout?.Mode.HasFlag(LayoutMode.FullRow) == true ? false : true;
                    if (pleaseEnter)
                    {
                        Console.Write("Please enter ");
                    }
                    if (showName)
                    {
                        Console.Write($"{name} ({str.Value}): ");
                    }
                    else
                    {
                        Console.Write($"({str.Value}): ");
                    }


                    var read = (awaitReadLine(TimeoutTime) ?? "").Trim();
                    if (read == "")
                    {
                        // accept the default value.
                        continue;
                    }
                    try
                    {
                        if (options != null && int.TryParse(read, out int result))
                        {
                            if (result < options.Count)
                            {
                                read = options[result];
                            }
                            else
                            {
                                goto start;
                            }
                        }
                        str.Value = read;

                        var err = a.Get <IErrorAnnotation>();
                        IEnumerable <string> errors = err?.Errors;

                        _message.Write();
                        if (errors?.Any() == true)
                        {
                            Console.WriteLine("Unable to parse value {0}", read);
                            goto start;
                        }
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Unable to parse '{0}'", read);
                        goto start;
                    }
                }
                a.Write();
            }
            finally
            {
                platforDialogMutex.ReleaseMutex();
            }
        }
Beispiel #12
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();
            }
        }
Beispiel #13
0
        /// <summary> Enqueue a new piece of work to be handled in the future. </summary>
        /// <param name="f"></param>
        public void EnqueueWork(Action f)
        {
            void threadGo()
            {
                try
                {
                    var awaitArray = new WaitHandle[] { addSemaphore.AvailableWaitHandle, cancel.Token.WaitHandle };
                    while (true)
                    {
retry:
                        awaitArray[1] = cancel.Token.WaitHandle;
                        int thing = 0;
                        if (longRunning)
                        {
                            thing = WaitHandle.WaitAny(awaitArray);
                        }
                        else
                        {
                            thing = WaitHandle.WaitAny(awaitArray, Timeout);
                        }
                        if (thing == 0 && !addSemaphore.Wait(0))
                        {
                            goto retry;
                        }
                        bool ok = thing == 0;

                        if (!ok)
                        {
                            if (cancel.IsCancellationRequested == false && longRunning)
                            {
                                continue;
                            }
                            lock (threadCreationLock)
                            {
                                if (workItems.Count > 0)
                                {
                                    goto retry;
                                }
                                break;
                            }
                        }


                        Action run = null;
                        while (!workItems.TryDequeue(out run))
                        {
                            Thread.Yield();
                        }
                        if (average != null)
                        {
                            var sw = Stopwatch.StartNew();
                            run();
                            average.PushTimeSpan(sw.Elapsed);
                        }
                        else
                        {
                            run();
                        }
                        Interlocked.Decrement(ref countdown);
                    }
                }
                finally
                {
                    lock (threadCreationLock)
                    {
                        threadCount--;
                    }
                }
            }

            while (addSemaphore.CurrentCount >= semaphoreMaxCount - 10)
            {
                // #4246: this is incredibly rare, but can happen if millions of results are pushed at once.
                //        the solution is to just slow a bit down when it happens.
                //        100 ms sleep is OK, because it needs to do around 1M things before it's idle.
                TapThread.Sleep(100);
            }
            Interlocked.Increment(ref countdown);
            workItems.Enqueue(f);
            addSemaphore.Release();

            if (threadCount == 0)
            {
                lock (threadCreationLock)
                {
                    if (threadCount == 0)
                    {
                        TapThread.Start(threadGo, Name);
                        threadCount++;
                    }
                }
            }
        }