/// <summary> Returns true if a member is enabled. </summary> public static bool IsEnabled(IMemberData property, object instance, out IMemberData dependentProp, out IComparable dependentValue, out bool hidden) { if (property == null) { throw new ArgumentNullException(nameof(property)); } if (instance == null) { throw new ArgumentNullException(nameof(instance)); } ITypeData instanceType = TypeData.GetTypeData(instance); var dependencyAttrs = property.GetAttributes <EnabledIfAttribute>(); dependentProp = null; dependentValue = 0; hidden = false; bool enabled = true; foreach (var at in dependencyAttrs) { bool newEnabled = true; dependentProp = instanceType.GetMember(at.PropertyName); if (dependentProp == null) { // We cannot be sure that the step developer has used this attribute correctly // (could just be a typo in the (weakly typed) property name), thus we need to // provide a good error message that leads the developer to where the error is. log.Warning("Could not find property '{0}' on '{1}'. EnabledIfAttribute can only refer to properties of the same class as the property it is decorating.", at.PropertyName, instanceType.Name); enabled = false; return(false); } var depValue = dependentProp.GetValue(instance); try { newEnabled = calcEnabled(at, depValue); } catch (ArgumentException) { // CompareTo throws ArgumentException when obj is not the same type as this instance. newEnabled = false; } if (!newEnabled && at.HideIfDisabled) { hidden = true; } enabled &= newEnabled; } return(enabled); }
/// <summary> /// Renames a previously initialized temporary log file. /// </summary> public static void Rename(string path) { try { rename(path); } catch (UnauthorizedAccessException e) { log.Warning("Unable to rename log file to {0} as permissions was denied.", path); log.Debug(e); }catch (IOException e) { // This could also be an error the the user does not have permissions. E.g OpenTAP installed in C:\\ log.Warning("Unable to rename log file to {0} as the file could not be created.", path); log.Debug(e); } }
/// <summary> /// Searches the files in fileNames for dlls implementing <see cref="ITapPlugin"/> /// and puts the implementation in the appropriate list. /// </summary> /// <param name="_fileNames">List of files to search.</param> static PluginSearcher SearchAndAddToStore(IEnumerable <string> _fileNames) { var fileNames = _fileNames.ToList(); Stopwatch timer = Stopwatch.StartNew(); PluginSearcher searcher = new PluginSearcher(); try { var w2 = Stopwatch.StartNew(); IEnumerable <TypeData> foundPluginTypes = searcher.Search(fileNames); IEnumerable <AssemblyData> foundAssemblies = foundPluginTypes.Select(p => p.Assembly).Distinct(); log.Debug(w2, "Found {0} plugin assemblies containing {1} plugin types.", foundAssemblies.Count(), foundPluginTypes.Count()); foreach (AssemblyData asm in foundAssemblies) { assemblyResolver.AddAssembly(asm.Name, asm.Location); if (asm.Location.Contains(AppDomain.CurrentDomain.BaseDirectory)) { log.Debug("Found version {0,-16} of {1}", asm.SemanticVersion?.ToString() ?? asm.Version?.ToString(), Path.GetFileName(asm.Location)); } else { // log full path of assembly if it was loaded with --search from another directory. log.Debug("Found version {0,-16} of {1} from {2}", asm.SemanticVersion?.ToString() ?? asm.Version?.ToString(), Path.GetFileName(asm.Location), asm.Location); } } } catch (Exception ex) { log.Error("Plugin search failed for: " + String.Join(", ", fileNames)); log.Debug(ex); } log.Debug(timer, "Searched {0} Assemblies.", fileNames.Count); if (GetPlugins(searcher, typeof(IInstrument).FullName).Count == 0) { log.Warning("No instruments found."); } if (GetPlugins(searcher, typeof(ITestStep).FullName).Count == 0) { log.Warning("No TestSteps found."); } return(searcher); }
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. } }
void Propagate(IResultListener rt, ResultTable result) { try { rt.OnResultPublished(stepRun.Id, result); } catch (Exception e) { log.Warning("Caught exception in result handling task."); log.Debug(e); planRun.RemoveFaultyResultListener(rt); } }
/// <summary> /// Prints the warning + Line information. /// </summary> /// <param name="log"></param> /// <param name="node"></param> /// <param name="message"></param> /// <param name="args"></param> public static void Warning(this TraceSource log, XElement node, string message, params object[] args) { var lineinfo = ((System.Xml.IXmlLineInfo)node); log.Warning("XML line {0} column {1}: {2}", lineinfo.LineNumber, lineinfo.LinePosition, string.Format(message, args)); }
/// <summary> /// Prints the summary. /// </summary> public void PrintSummary() { if (planRun == null) { return; //Something very wrong happened. In this case the use will be informed of an error anyway. } bool hasOtherVerdict = planRun.Verdict != Verdict.Pass && planRun.Verdict != Verdict.NotSet; ILookup <Guid, TestStepRun> parentLookup = null; int maxIndent = 0; if (stepRuns != null) { parentLookup = stepRuns.Values.ToLookup(v => v.Parent); Func <Guid, int> getMaxIndent = null; getMaxIndent = guid => 1 + parentLookup[guid].Select(step => getMaxIndent(step.Id)).DefaultIfEmpty(0).Max(); maxIndent = getMaxIndent(planRun.Id); } int maxVerdictLength = hasOtherVerdict ? planRun.Verdict.ToString().Length : 0; if (stepRuns != null) { foreach (TestStepRun run in parentLookup[planRun.Id]) { int max = getMaxVerdictLength(run, maxVerdictLength, parentLookup); if (max > maxVerdictLength) { maxVerdictLength = max; } } } int addPadLength = maxIndent + (int)Math.Round(maxVerdictLength / 2.0); int maxLength = -1; Func <string, int, string> formatSummaryHeader = (message, indentLength) => { string indent = new String('-', indentLength + 3); StringBuilder sb = new StringBuilder(indent); sb.Append(message); sb.Append(indent); maxLength = sb.Length; return(sb.ToString()); }; Func <string, string> formatSummary = (message) => { int fillLength = (int)Math.Floor((maxLength - message.Length) / 2.0); StringBuilder sb = new StringBuilder(new string('-', fillLength)); sb.Append(message); sb.Append('-', maxLength - sb.Length); return(sb.ToString()); }; summaryLog.Info(formatSummaryHeader(String.Format(" Summary of test plan started {0} ", planRun.StartTime), addPadLength)); if (stepRuns != null) { int idx = 0; foreach (TestStepRun run in parentLookup[planRun.Id]) { printSummary(run, maxIndent, idx, parentLookup); } } else { summaryLog.Warning("Test plan summary skipped. Summary contains too many steps ({0}).", stepRunLimit); } summaryLog.Info(formatSummary(separator)); if (!hasOtherVerdict) { summaryLog.Info(formatSummary(String.Format(" Test plan completed successfully in {0,6} ", ShortTimeSpan.FromSeconds(planRun.Duration.TotalSeconds).ToString()))); } else { summaryLog.Info(formatSummary(String.Format(" Test plan completed with verdict {1} in {0,6} ", ShortTimeSpan.FromSeconds(planRun.Duration.TotalSeconds).ToString(), planRun.Verdict))); } }