Beispiel #1
0
        public override void Run()
        {
            // There are four levels of log messages Info, Warning, Error, Debug.
            MyLog.Info("Info from Run");
            for (int i = 0; i < 10; i++)
            {
                MyLog.Debug("Debug {0} from Run", i); // MyLog.X works like string.Format with regards to arguments.
            }
            MyLog.Warning("Warning from Run");
            MyLog.Error("Error from Run");

            // The Log can accept a Stopwatch Object to be used for timing analysis.
            Stopwatch sw1 = Stopwatch.StartNew();

            TapThread.Sleep(100);
            MyLog.Info(sw1, "Info from Run");

            Stopwatch sw2 = Stopwatch.StartNew();

            TapThread.Sleep(200);
            MyLog.Error(sw2, "Error from step");

            // Tracebar can be used to show results in the MyLog.
            var traceBar = new TraceBar();

            traceBar.LowerLimit = -3.0;
            for (var i = -2; i < 11; i++)
            {
                traceBar.UpperLimit = i < 5 ? 3 : 15;
                // GetBar returns a string with value, low limit, a dashed line
                // indicating magnitude, the upper limit, and (if failing), a fail indicator.
                string temp = traceBar.GetBar(i);
                MyLog.Info("MyResult: " + temp);
                TapThread.Sleep(200);
            }
            // Sample output shown below.
            //   MyResult: 2.00 - 3-------------------------|-----  3
            //   MyResult: 3.00 - 3------------------------------ | 3
            //   MyResult: 4.00 - 3------------------------------ > 3  Fail
            //   MyResult: 5.00 - 3------------ -| -----------------15
            //   MyResult: 6.00 - 3-------------- -| ---------------15

            // TraceBar remembers if any results failed, so it can be used for the verdict.
            UpgradeVerdict(traceBar.CombinedVerdict);

            // The log also supports showing stack traces.
            // Useful for debugging.
            try
            {
                throw new Exception("My exception");
            }
            catch (Exception e)
            {
                MyLog.Error("Caught exception: '{0}'", e.Message);
                MyLog.Debug(e); // Prints the stack trace to the MyLog.
            }
        }
Beispiel #2
0
 ///<summary>Searches for plugins.</summary>
 public static void Search()
 {
     searchTask.Reset();
     searcher = null;
     assemblyResolver.Invalidate(DirectoriesToSearch);
     ChangeID++;
     try
     {
         IEnumerable <string> fileNames = assemblyResolver.GetAssembliesToSearch();
         searcher = SearchAndAddToStore(fileNames);
     }
     catch (Exception e)
     {
         log.Error("Caught exception while searching for plugins: '{0}'", e.Message);
         log.Debug(e);
         searcher = null;
     }
     finally
     {
         searchTask.Set();
     }
 }
Beispiel #3
0
 /// <summary>
 /// Run an action as the final step after the last deferred action
 /// </summary>
 /// <param name="action"></param>
 void IResultSource.Finally(Action <Task> action)
 {
     if (deferCount == 0)
     {
         action(Finished);
         DeferWorker?.Dispose();
     }
     else
     {
         DeferWorker.EnqueueWork(() =>
         {
             try
             {
                 if (deferExceptions.Count == 1)
                 {
                     action(Task.FromException(deferExceptions[0]));
                 }
                 else if (deferExceptions.Count > 1)
                 {
                     action(Task.FromException(new AggregateException(deferExceptions.ToArray())));
                 }
                 else
                 {
                     action(Finished);
                 }
                 DeferWorker.Dispose();
             }
             catch (OperationCanceledException)
             {
             }
             catch (Exception e)
             {
                 log.Error("Caught error while finalizing test step run. {0}", e.Message);
                 log.Debug(e);
             }
         });
     }
 }
        /// <summary>
        /// Finds all IResource properties on a list of references. The references can be any class derived from ITapPlugin, such as ITestStep or IResource.
        /// If a reference supplied in the <paramref name="references"/> list is a IResource itself it will be added to the resulting list.
        /// </summary>
        internal List <ResourceNode> GetAllResources(object[] references, out bool errorDetected)
        {
            errorDetected = false;

            ResourceDep[] stepResources = getManyResources(references);
            var           resourceDeps  = new List <ResourceDep>(stepResources);

            foreach (var reference in references)
            {
                if (reference is IResource res)
                {
                    resourceDeps.Add(new ResourceDep(res));
                }
            }
            List <ResourceNode> tree = GetResourceTree(resourceDeps);

            ExpandTree(tree);

            // Check that no resources have direct references to itself.
            foreach (var scc in tree.Where(x => x.StrongDependencies.Any(dep => dep == x.Resource)))
            {
                foreach (var dep in scc.StrongDependencies)
                {
                    if (dep == scc.Resource)
                    {
                        errorDetected = true;
                        Log.Error("Resource is referencing itself: {0}", scc.Resource);
                        break;
                    }
                }
            }

            // Figure out if all resources has their resource properties set
            foreach (var leaf in tree)
            {
                if (leaf.StrongDependencies.Any(s => s is null))
                {
                    errorDetected = true;
                    Log.Error($"Resource setting not set on resource {leaf.Resource}. Please configure or disable the resource.");
                }
            }

            if (errorDetected) // If any resources has resource properties which is not set, let's return early, because FindStronglyConntectedComponents method below will throw a confusing error in this case.
            {
                return(tree);
            }

            // Figure out if there are circular references, and list the circular references in an exception each.
            var sccs = FindStronglyConnectedComponents(tree);

            if (sccs.Count > 0)
            {
                errorDetected = true;

                foreach (var scc in sccs)
                {
                    Log.Error(string.Format("Circular references between resources: {0}", string.Join(",", scc.Select(res => res.Name))));
                }
            }

            //Add users of resources
            foreach (var r in references)
            {
                TestStepExtensions.GetObjectSettings <IResource, object, ResourceNode>(r, true, (res, prop) =>
                {
                    var nodes = tree.Where(n => n.Resource == res);
                    if (nodes.Count() > 1)
                    {
                        // Normally we would expect that the tree only contains one node representing each resource.
                        // In case of null resources however, we want one node per property, such that ILockManager.BeforeOpen()
                        // has a chance to set each property to a different resource instance.
                        if (res != null)
                        {
                            throw new Exception($"Duplicate entry for Resource '{res.Name}' in tree.");
                        }
                        nodes = nodes.Where(n => n.Depender == prop);
                    }
                    var nodeRepresentingResource = nodes.FirstOrDefault();
                    if (nodeRepresentingResource != null)
                    {
                        nodeRepresentingResource.References.Add(new ResourceReference(r, prop));
                    }
                    return(nodeRepresentingResource);
                }, new HashSet <ResourceNode>());
            }
            return(tree);
        }
Beispiel #5
0
        /// <summary>
        /// Blocks the thread while closing all resources in parallel.
        /// </summary>
        private void CloseAllResources()
        {
            Dictionary <IResource, List <IResource> > dependencies = openedResources.ToDictionary(r => r.Resource, r => new List <IResource>()); // this dictionary will hold resources with dependencies (keys) and what resources depend on them (values)

            foreach (var n in openedResources)
            {
                foreach (var dep in n.StrongDependencies)
                {
                    dependencies[dep].Add(n.Resource);
                }
            }

            Dictionary <IResource, Task> closeTasks = new Dictionary <IResource, Task>();

            foreach (var r in openedResources)
            {
                closeTasks[r.Resource] = new Task(o =>
                {
                    ResourceNode res = (ResourceNode)o;

                    // Wait for the resource to open to open before closing it.
                    // in rare cases, another instrument failing open will cause close to be called.
                    try
                    {
                        openTasks[res.Resource].Wait();
                    }
                    catch
                    {
                    }

                    // wait for resources that depend on this resource (res) to close before closing this
                    Task.WaitAll(dependencies[res.Resource].Select(x => closeTasks[x]).ToArray());
                    var reslog      = GetLogSource(res.Resource);
                    Stopwatch timer = Stopwatch.StartNew();
                    try
                    {
                        res.Resource.Close();
                    }
                    catch (Exception e)
                    {
                        log.Error("Error while closing \"{0}\": {1}", res.Resource.Name, e.Message);
                        log.Debug(e);
                    }
                    if (reslog != null)
                    {
                        reslog.Info(timer, "Resource \"{0}\" closed.", res.Resource);
                    }
                }, r);
            }

            closeTasks.Values.ToList().ForEach(t => t.Start());

            void complainAboutWait()
            {
                log.Debug("Waiting for resources to close:");
                foreach (var res in openTasks.Keys)
                {
                    if (res.IsConnected)
                    {
                        log.Debug(" - {0}", res);
                    }
                }
            }

            using (TimeoutOperation.Create(complainAboutWait))
                Task.WaitAll(closeTasks.Values.ToArray());
        }