//Copyright 2012-2019 Keysight Technologies // //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. //You may obtain a copy of the License at // //http://www.apache.org/licenses/LICENSE-2.0 // //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Xml.Serialization; using OpenTap; /// /// This example contains a TAP plugin with simulated instrument and DUT. It shows /// the basic interaction between Test Steps, DUTs, and Instruments. More detail /// on the features found in the example can be found in the PluginDevelopment directory. /// The project includes a SIMULATED: /// - GeneratorInstrument (TAP Instrument). /// - LowPassFilterDut (TAP DUT). /// MeasurePeakAmplitudeTestStep (this file) is a TAP Test Step that: /// 1. Programs the generator. /// 2. Configures the low pass filter. /// 3. Collects the results from the low pass filter. /// 4. Publishes results to any configured result listeners. /// namespace OpenTap.Plugins.ExamplePlugin { // The display attribute defines the grouping, name and description of settings in the Add New Step window. [Display(Groups: new[] { "Examples", "Example Plugin" }, Name: "Measure Peak Amplitude", Description: "Checks the maximum value of a waveform after passing through a low pass filter.")] // All Test Steps inherit from the TestStep base class. public class MeasurePeakAmplitudeTestStep : TestStep { #region Settings // Public properties with a getter and a setter will be shown in the TAP GUI. // Non public properties are not shown in the GUI. public double[] InputData { get; set; } // The display attribute can be used to define how Step Settings (Properties) appear // in the Step Settings panel. [Display(Group: "Generator Settings", Name: "Generator", Order: 1.1)] // Instruments are associated with a Test Step by adding a property of the desired instrument type. // This can be an exact type, an interface, or base type such as ScpiInstrument, or Instrument. public GeneratorInstrument MyGenerator { get; set; } // DUT associations are added the same way as Instruments. [Display(Group: "Filter (DUT) Settings", Name: "Filter", Order: 2.1)] public LowPassFilterDut MyFilter { get; set; } // Order is used to sort items within a group [Display(Group: "Filter (DUT) Settings", Name: "Window Size", Order: 2.2, Description: "Defines the size of the moving average window.")] public int WindowSize { get; set; } // Public properties are serialized upon loading/saving the TestPlan. // The XmlIgnore attribute indicates that the data should not be serialized. // This can be used when the user is required to specify a value, and there is no default value. [XmlIgnore] // Properties with private setters are not shown in the GUI. However, you may wish // to have a "read only" view of a property. To achieve that, use the Browsable(true) // attribute, and keep the setter private, as shown below. [Browsable(true)] [Display(Group: "Scope Settings", Name: "Output Data", Order: 3.1)] public double[] ReadOnlyOutputData { get; private set; } // Limit checking is usually done by creating Limit Settings, and then comparing the limits // to the result values in the Run method (see below). [Display(Group: "Limit Checking", Name: "Limit Check Enabled", Order: 4.1)] public bool LimitCheckEnabled { get; set; } [Display(Group: "Limit Checking", Name: "Max Amplitude", Order: 4.2, Description: "The maximum amplitude allowed. If exceeded, the test will be marked as failed.")] // The EnabledIf attribute allows for disabling/hiding elements based on the value of other items. // Here the MaxAmplitude editor is disable if the LimitCheckEnabled property is true. // You can find more examples in the Plugin Development\TestSteps\Attributes section. [EnabledIf("LimitCheckEnabled", true, HideIfDisabled = true)] public double MaxAmplitude { get; set; } #endregion public MeasurePeakAmplitudeTestStep() { // Default values for settings should be defined in the constructor. LimitCheckEnabled = true; MaxAmplitude = 50; InputData = new double[] {0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0}; WindowSize = 3; // Validation Rules can be defined in the constructor to restrict the user inputs. Rules.Add(() => WindowSize > 0, "Window size must be greater than zero", "WindowSize"); Rules.Add(SizesAreAppropriate, "Input Data must be larger than window size", "WindowSize", "InputData"); } //public override void PrePlanRun() //{ // // This method is called on all TestSteps at the START of TestPlan execution. // // If no setup code is needed, this method can be removed. // base.PrePlanRun(); //} public override void Run() { // The Run method is where the main execution logic of a TestStep exists. // This is a required method. try { // Setup instrument. MyGenerator.SetInputData(InputData); // Setup DUT. MyFilter.WindowSize = WindowSize; // Execute logic for DUT and handle data from DUT. ReadOnlyOutputData = MyFilter.CalcMovingAverage(InputData); // Check to see if limit checking is enabled. If so, Upgrade the verdict. if (LimitCheckEnabled) { // The Verdict is used by TAP to convey the general execution result of a Test Step. UpgradeVerdict(ReadOnlyOutputData.Max() >= MaxAmplitude ? Verdict.Fail : Verdict.Pass); } else { // All Test Steps have a standard Log object (inherited from the base class) // that can be used to write messages to the run log and the session log. Log.Debug("Limit checking was not enabled. This is why the verdict is inconclusive."); UpgradeVerdict(Verdict.Inconclusive); } // Different log message types can be used based on what is being written. Log.Info("The DUT comment is {0}", MyFilter.Comment); // All Test Steps also contain a Results object. Results are store by calling Publish or PublishTable. Results.PublishTable("Inputs Versus Moving Average", new List() {"Input Values", "Output Values"}, InputData, ReadOnlyOutputData); } catch (Exception ex) { Log.Error(ex.Message); // The verdict can be set more than once in a Test Step. // UpgradeVerdict sets the current verdict to the more serious verdict. // If the new Verdict is not more severe, the original setting will be kept. UpgradeVerdict(Verdict.Error); } } //public override void PostPlanRun() //{ // // This method is called on all TestSteps at the END of TestPlan execution. // // If no shutdown code is needed, this method can be removed. // base.PostPlanRun(); //} // Additional methods can be added to Test Step classes. private bool SizesAreAppropriate() { return InputData.Length > WindowSize; } } }