// Copyright Keysight Technologies 2012-2019
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at http://mozilla.org/MPL/2.0/.
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace OpenTap
{
#region Data structure
///
/// A named object.
///
public interface IAttributedObject
{
///
/// Name of this object.
///
string Name { get; }
///
/// String describing this object.
///
string ObjectType { get; }
}
///
/// A named parameter.
///
public interface IParameter : IAttributedObject
{
///
/// Optional name of the group of parameters to which this parameter belongs.
///
string Group { get; }
///
/// Value of this parameter.
///
IConvertible Value { get; }
}
///
/// A list of parameters, with a string indexer.
///
public interface IParameters : IList
{
///
/// Get a parameter by name. This can be the ObjectType or Name of a parameter. e.g "OpenTap.Unit" or just "Unit".
///
/// Null if the parameter was not found
IConvertible this[string Name] { get; }
}
///
/// An object in a hierarchy with a name and some named properties.
///
public interface IData : IAttributedObject
{
///
/// Parent of this object.
///
IData Parent { get; }
///
/// All parameters that describes this object.
///
IParameters Parameters { get; }
///
/// Returns an ID that identifies this object.
///
///
long GetID();
}
///
/// Contains data that has the same table name, column names, and result data types as a .
///
public interface IResultTable : IData
{
///
/// Array containing the result columns.
///
IResultColumn[] Columns { get; }
}
///
/// Interface to store column data.
///
public interface IResultColumn : IAttributedObject
{
///
/// Data in the column.
///
Array Data { get; }
}
///
/// An "extensible Enum" that can be used to describe attachments.
///
public class AttachmentType : IEquatable
{
#region Support
private string _TypeName;
///
/// Creates an attachment type object.
///
public AttachmentType(string TypeName)
{
this._TypeName = TypeName;
}
///
/// Compares this object to another.
///
bool IEquatable.Equals(AttachmentType other)
{
return _TypeName == other._TypeName;
}
///
/// Compares this object to another.
///
public override bool Equals(object obj)
{
if (obj is AttachmentType)
return _TypeName == ((AttachmentType)obj)._TypeName;
else
return false;
}
///
/// Returns the hashcode for this object.
///
public override int GetHashCode()
{
return _TypeName.GetHashCode();
}
#endregion
///
/// A log file.
///
public static AttachmentType LogFile { get { return new AttachmentType("LogFile"); } }
///
/// A TestPlan XML file.
///
public static AttachmentType TestPlan { get { return new AttachmentType("TestPlan"); } }
}
#endregion
#region Searching
///
/// The operation for .
///
public enum ComparisonOperator
{
/// Two specified values must be the same.
Equal,
/// Two specified values must be different.
NotEqual,
/// Parameter must be less than.
Less,
/// Parameter must be less than or equal.
LessEqual,
/// Parameter must be greater than.
Greater,
/// Parameter must be greater than or equal.
GreaterEqual,
/// Parameter must be similar to the value.
/// This is guaranteed to be true if the two values are equal, but is not otherwise guaranteed to work in any specific way.
Like,
///
/// Value must exist as a parameter name or value.
///
Exists
}
///
/// Operation for .
///
public enum LogicalOperator
{
///
/// Specifies that both conditions must be satisfied.
///
And,
///
/// Specifies that at least one of the two conditions must be satisfied.
///
Or
}
///
/// The basic search operand from which the other search operands are derived.
///
public abstract class SearchOperand
{
}
/// Matches all children of the specified parents.
public class SearchChildrenOf : SearchOperand
{
///
/// The list of elements to match the children of.
///
public List Parents { get; set; }
/// Matches all children of the specified parents.
///
public SearchChildrenOf(List parents)
{
Parents = parents;
}
}
///
/// Matches the last test plan run.
///
public class SearchLastRun : SearchOperand
{
///
/// Number of the last runs to select.
///
public int Count { get; }
///
/// Matches the last test plan run.
///
public SearchLastRun(int count = 1)
{
Count = count;
}
}
/// A binary operation between two other operations.
public class SearchCombinator : SearchOperand
{
///
/// Left-side operand.
///
public SearchOperand A { get; }
///
/// Operation to perform.
///
public LogicalOperator Operator { get; }
///
/// Right-side operand.
///
public SearchOperand B { get; }
/// A binary operation between two other operations.
public SearchCombinator(SearchOperand a, LogicalOperator logicalOperator, SearchOperand b)
{
A = a;
Operator = logicalOperator;
B = b;
}
}
///
/// Comparison between a named parameter and a value.
///
public class SearchParameterValue : SearchOperand
{
///
/// Scope of the parameter to match ("", "plan", or "step").
///
public string Scope { get; }
///
/// GroupName of the parameter to match (leave empty to match any group).
///
public string Group { get;}
///
/// Name of the parameter to match.
///
public string Parameter { get;}
///
/// Operation to perform.
///
public ComparisonOperator CompareOperator { get;}
///
/// Value to compare against the right-side value.
///
public IConvertible Value { get; }
/// Comparison between a named parameter and a value.
///
///
///
///
///
public SearchParameterValue(string parameter, ComparisonOperator compareOperator, IConvertible value, string group = "", string scope = "")
{
Parameter = parameter;
CompareOperator = compareOperator;
Value = value;
Group = group;
Scope = scope;
}
}
///
/// Comparison between a named parameter and a value.
///
public class SearchRange : SearchOperand
{
///
/// The scope of the parameter to match. Could be "plan" or "step".
///
public string Scope { get; set; }
///
/// The name of the parameter to match.
///
public string Parameter { get; set; }
///
/// The value to compare against as the right-hand side.
///
public ICombinedNumberSequence Value { get; set; }
}
///
/// The conditions for what to search for.
///
public class SearchCondition
{
///
/// When true, specifies that any matched tree nodes automatically match all parents of that element.
///
public bool GetParents { get; set; }
///
/// When true, specifies that a matched tree root node automatically matches all children of that given element.
///
public bool GetChildren { get; set; }
///
/// The tree of conditions to match for.
///
public SearchOperand Operation { get; set; }
///
/// Condition that will match all elements in the result store.
///
///
public static SearchCondition All()
{
return new SearchCondition { GetChildren = true, GetParents = true, Operation = null };
}
///
/// Condition that will match any elements in a list as well as all children of those elements.
///
///
public static SearchCondition ChildrenOf(IEnumerable testPlanRunIds)
{
return new SearchCondition { Operation = new SearchChildrenOf(testPlanRunIds.ToList()), GetChildren = true, GetParents = false };
}
///
/// Condition that will match all elements in the result store.
///
///
public static SearchCondition LastRun()
{
return new SearchCondition { GetChildren = true, GetParents = true, Operation = new SearchLastRun() };
}
}
#endregion
///
/// A structure containing limit set data.
///
public class LimitSet
{
///
/// The friendly name of the limit set.
///
public string Name { get; private set; }
///
/// The limits in this limit set.
///
public List Limits { get; set; }
///
/// Initializes a new instance of the class.
///
///
public LimitSet(string name)
{
Name = name;
Limits = new List();
}
}
///
/// A single limit from a limit set.
///
public class Limit : ValidatingObject
{
///
/// The result name to match.
///
[Display("Result Name", Description: "The name of the result to match.", Order: -10)]
public string ResultName { get; set; }
///
/// The result column to which the limits are applied.
///
[Display("Column Name", Description: "The name of the result column to apply limit to.", Order: -9)]
public string ColumnName { get; set; }
///
/// The lower limit to apply to the result.
///
[Display("Lower Limit", Description: "The lower limit. To pass the column value must be above this.", Order: -8)]
public double LowerLimit { get; set; }
///
/// The upper limit to apply to the result.
///
[Display("Upper Limit", Description: "The upper limit. To pass the column value must be below this.", Order: -7)]
public double UpperLimit { get; set; }
///
/// The conditions that have to apply for this limit.
///
[Display("Conditions", Description: "Additional conditions that apply for this limit. All conditions must evaluate to true for this limit to be used.", Order: -6)]
public List Conditions { get; set; }
///
/// Initializes a new instance of the class.
///
public Limit()
{
Rules.Add(() => !string.IsNullOrWhiteSpace(ResultName), "Result Name must be valid.", "ResultName");
Rules.Add(() => !string.IsNullOrWhiteSpace(ColumnName), "Column Name must be valid.", "ColumnName");
Conditions = new List();
ResultName = "";
ColumnName = "";
}
}
///
/// A condition for a specific limit that must be satisfied for the limit to apply.
///
public class LimitCondition : ValidatingObject
{
///
/// The result column name that this condition applies to.
///
[Display("When Column", Description: "The condition value tested comes from the result column with this name.", Order: -3)]
public string ColumnName { get; set; }
///
/// The lower limit for this condition.
///
[Display("Greater Than", Description: "The condition value must be above this value.", Order: -2)]
public double LowerLimit { get; set; }
///
/// The upper limit for this condition.
///
[Display("Less Than", Description: "The condition value must be below this value.", Order: -1)]
public double UpperLimit { get; set; }
///
/// Returns a string describing this object.
///
///
public override string ToString()
{
return String.Format("{0} < {1} < {2}", LowerLimit, ColumnName, UpperLimit);
}
///
/// Initializes a new instance of the class.
///
public LimitCondition()
{
Rules.Add(() => !string.IsNullOrWhiteSpace(ColumnName), "Column Name must be valid.", "ColumnName");
}
}
///
/// Interface to results storage plugins.
///
public interface IResultStore : IResource, ITapPlugin
{
///
/// Get list of properties on entries in the database which starts with a given string.
/// The returned properties should be ordered by their frequency of use in the dataset.
///
/// Only consider parameters from this scope. Could be "plan" or "step", or empty to consider all scopes.
/// Only consider parameters from this parameter group. Can be empty to match any group.
///
///
List GetProperties(string scope, string group, string startsWith, int limit);
///
/// Gets all elements which match a given search condition.
///
///
///
///
IEnumerable GetEntries(SearchCondition cond, List limitsets, bool withResults);
///
/// Tries to delete the given entries and all sub entries.
///
/// Entries to delete.
bool DeleteEntries(IEnumerable entries);
///
/// Returns all registered limit sets.
///
List GetLimitSets();
///
/// Adds a limit set to the results store.
///
///
void AddLimitSet(LimitSet limitSet);
///
/// Deletes a limit set from the database.
///
/// The name of the limit set to delete.
void DeleteLimitSet(string Name);
///
/// Returns the binary data for the given objects attachment, or null if it could not be found.
///
///
///
byte[] GetAttachment(IData entry, AttachmentType attachmentType);
///
/// Gets a list of attachments on the given object.
///
///
List GetValidAttachments(IData entry);
///
/// Returns the average duration of the last step runs with similar settings.
///
///
///
TimeSpan? GetAverageDuration(TestStepRun step, int averageCount);
///
/// Returns the average duration of the last PlanRuns runs with a similar plan.
///
///
///
TimeSpan? GetAverageDuration(TestPlanRun plan, int averageCount);
}
///
/// IResultStore that supports attachment streams.
///
public interface IAttachmentStream : IResultStore
{
///
/// Returns a stream that can read a given attachment entry. The returned stream must be disposed.
///
///
///
Stream GetAttachmentStream(IData entry, AttachmentType attachmentType);
}
///
/// Interface to support result tagging in the OpenTAP Results Viewer.
///
public interface IResultTagging : IResultStore
{
///
/// Add a TestPlan parameter to a number of TestPlans.
///
void AddTestPlanRunParameter(IEnumerable PlanRunIDs, string Group, string ParameterName, IConvertible Value);
///
/// Delete a TestPlan parameter from a number of TestPlans.
///
void DeleteTestPlanRunParameter(IEnumerable PlanRunIDs, string Group, string ParameterName, IConvertible Value);
///
/// Get distinct TestPlan parameter values ordered by popularity (number of uses). Optionally limited to Limit values, scope and group.
///
IEnumerable GetTestPlanRunParameterValues(string ParameterName, string Scope = "", string Group = "", int Limit = -1);
}
///
/// Delegate that triggers notification updates when results are added to the store.
///
public delegate void ResultUpdateEvent(object Sender);
///
/// Interface to add notifications when the Results Viewer gets new data.
///
public interface IResultStoreNotification : IResultStore
{
///
/// Event triggered when results are added to the store.
///
event ResultUpdateEvent ResultUpdated;
///
/// Event triggered when TestPlan or TestStep runs are added to the store.
///
event ResultUpdateEvent RunsUpdated;
///
/// Enables the Updated events.
///
void EnableUpdateEvents();
///
/// Disables the Updated events.
///
void DisableUpdateEvents();
}
///
/// When implemented along with , this interface allows files with a given extension to be opened using your .
/// It also can be used to allow the export of results to a file.
///
public interface IFileResultStore
{
///
/// Gets or sets the currently chosen file.
///
string FilePath { set; get; }
///
/// Default extension without the dot (.) that files must match in order to load a file's results to Results Viewer (e.g. TapResults, not .TapResults).
///
string DefaultExtension { get; }
}
}