using LabViewHelper;
|
using NationalInstruments.LabVIEW.Interop;
|
using OpenTap;
|
using OpenTap.Addin.Annotation;
|
using OpenTap.Addin.Util;
|
using System;
|
using System.Collections.Concurrent;
|
using System.Collections.ObjectModel;
|
using System.IO;
|
using System.Linq;
|
using System.Xml.Serialization;
|
using ViHelper;
|
|
namespace AddInPlugin
|
{
|
public class LvlibpData
|
{
|
public string path { get; set; }
|
public DateTime lastUpdateTime { get; set; }
|
|
public string[] names { get; private set; }
|
|
private ConcurrentDictionary<string, ViVariable[]> inCache = new ConcurrentDictionary<string, ViVariable[]>();
|
private ConcurrentDictionary<string, ViVariable[]> outCache = new ConcurrentDictionary<string, ViVariable[]>();
|
|
public LvlibpData(DateTime lastUpdateTime, string[] names)
|
{
|
this.lastUpdateTime = lastUpdateTime;
|
this.names = names;
|
}
|
|
public void GetIO(string viName, out ViVariable[] inVars, out ViVariable[] outVars)
|
{
|
if (!inCache.ContainsKey(viName) || !outCache.ContainsKey(viName))
|
{
|
LabViHelper.GetIOTypeByLvlibp(path, viName, out inVars, out outVars);
|
inCache[viName] = inVars;
|
outCache[viName] = outVars;
|
}
|
else
|
{
|
inVars = inCache[viName];
|
outVars = outCache[viName];
|
}
|
}
|
}
|
|
public class LvlibpLoader
|
{
|
static readonly ConcurrentDictionary<string, LvlibpData> Cache = new ConcurrentDictionary<string, LvlibpData>();
|
|
public static void PreLoad()
|
{
|
try
|
{
|
LvlibpLoader.GetLibpNames("test.lvlibp", out _);
|
}
|
catch
|
{
|
|
}
|
}
|
|
private static LvlibpData GetCache(string path)
|
{
|
path = path.ToLower();
|
//if (!File.Exists(path))
|
//{
|
// return null;
|
//}
|
DateTime updateTime = File.GetLastWriteTime(path);
|
|
if (!Cache.ContainsKey(path) || Cache[path].lastUpdateTime != updateTime)
|
{
|
LabViewRunner.GetLibpNames(new LVPath(path), out var names, out ErrorCluster error);
|
Cache[path] = new LvlibpData(updateTime, names) { path = path };
|
}
|
return Cache[path];
|
}
|
|
public static void GetLibpNames(string path, out string[] names)
|
{
|
var cache = GetCache(path);
|
names = cache?.names;
|
}
|
|
public static void GetViIO(string path, string viName, out ViVariable[] inVars, out ViVariable[] outVars)
|
{
|
inVars = new ViVariable[0];
|
outVars = new ViVariable[0];
|
var cache = GetCache(path);
|
cache?.GetIO(viName, out inVars, out outVars);
|
}
|
}
|
|
[Prototype]
|
[Display("LvlibpStep", Description: "ÔËÐÐlvlibp")]
|
|
public class LvlibpStep : VariableTestStep
|
{
|
#region Settings
|
private string filePath;
|
|
[Obsolete]
|
// [Display("·¾¶", Order: 0.0, Description: "¾ø¶Ô·¾¶.")]
|
[FilePath(FilePathAttribute.BehaviorChoice.Open, fileExtension: "Labview|*.lvlibp")]
|
public string FilePath
|
{
|
get => filePath;
|
set
|
{
|
Set(ref filePath, value);
|
}
|
}
|
|
private LocationString fileLocation = new LocationString();
|
[Display("·¾¶", Order: 0.0, Description: "¾ø¶Ô·¾¶.")]
|
[FilePath(FilePathAttribute.BehaviorChoice.Open, fileExtension: "Labview|*.lvlibp")]
|
public LocationString FileLocation
|
{
|
get => fileLocation;
|
set
|
{
|
Set(ref fileLocation, value);
|
}
|
}
|
|
protected override void OnRootChanged(TestPlan old, TestPlan plan)
|
{
|
try
|
{
|
if (!string.IsNullOrEmpty(FilePath))
|
{
|
FileLocation.AbsoluteLocation = FilePath;
|
FilePath = null;
|
}
|
FileLocation.Refresh(Root.Path);
|
FileLocation.PropertyChanged += FileLocation_PropertyChanged;
|
if (!FileLocation.GetLocation(Root.Path, out string path))
|
{
|
return;
|
}
|
//LabViewRunner.GetIO(new LVPath(ViPath), 0, out Cluster[] inputs, out Cluster[] outputs, out type[] iTypes, out type[] oTypes, out var viError);
|
//LabViewRunner.GetLibpNames(new LVPath(path), out string[] names, out ErrorCluster error);
|
LvlibpLoader.GetLibpNames(path, out string[] names);
|
|
NameDatasource = new ObservableCollection<string>(names);
|
LoadVi();
|
LoadException = null;
|
}
|
catch (Exception ex)
|
{
|
LoadException = ex;
|
//Log.Error("ViStep load vi error. {0}", ex);
|
}
|
}
|
|
private ObservableCollection<string> nameDatasource;
|
[XmlIgnore]
|
public ObservableCollection<string> NameDatasource
|
{
|
get => nameDatasource;
|
set
|
{
|
Set(ref nameDatasource, value);
|
}
|
}
|
|
private string viName;
|
|
[Display("VI", Order: 0.0, Description: "VIÃû³Æ.")]
|
[DynamicSelect(nameof(NameDatasource))]
|
public string ViName
|
{
|
get => viName;
|
set
|
{
|
Set(ref viName, value);
|
LoadVi();
|
}
|
}
|
|
|
private bool showWindow;
|
|
[Display("ÏÔʾ´°¿Ú", Order: 0.0)]
|
public bool ShowWindow
|
{
|
get => showWindow;
|
set
|
{
|
Set(ref showWindow, value);
|
}
|
}
|
|
#endregion
|
|
private Exception loadException;
|
|
[XmlIgnore]
|
public Exception LoadException
|
{
|
get => loadException;
|
set
|
{
|
Set(ref loadException, value);
|
}
|
}
|
|
public LvlibpStep()
|
{
|
// ToDo: Set default values for properties / settings.
|
//Rules.Add(() => !string.IsNullOrWhiteSpace(FilePath), "·¾¶²»ÄÜΪ¿Õ", FilePath);
|
Rules.Add(() => FileLocation.GetLocation(Root.Path, out _), "Îļþ¼ÓÔØÊ§°Ü", nameof(FileLocation));
|
Rules.Add(() => LoadException == null, () => $"VI¼ÓÔØÊ§°Ü:{LoadException}", nameof(FileLocation));
|
}
|
|
private void FileLocation_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
{
|
Load();
|
}
|
|
private void ConcatVariable(MethodVariable mv, MethodVariable[] source)
|
{
|
MethodVariables.Add(mv);
|
var preview = source?.FirstOrDefault(v => v.Name == mv.Name && !string.IsNullOrEmpty(v.ValueStr));
|
if (preview != null)
|
{
|
mv.ValueStr = preview.ValueStr;
|
}
|
}
|
|
private void LoadVi()
|
{
|
try
|
{
|
if (!FileLocation.GetLocation(Root?.Path, out string path))
|
{
|
return;
|
}
|
//LabViewRunner.GetIO(new LVPath(ViPath), 0, out Cluster[] inputs, out Cluster[] outputs, out type[] iTypes, out type[] oTypes, out var viError);
|
//LabViHelper.GetIOTypeByLvlibp(path, ViName, out var inVariables, out var outVariables);
|
|
LvlibpLoader.GetViIO(path, viName, out var inVariables, out var outVariables);
|
|
var last = MethodVariables?.ToArray();
|
MethodVariables.Clear();
|
foreach (var inv in inVariables)
|
{
|
var newOne = new MethodVariable
|
{
|
Name = inv.Name,
|
Type = inv.Type,
|
TypeName = inv.Type.ToString(),
|
Direction = VariableDirection.In,
|
ValueStr = inv.Type == typeof(string) ? $"\"{inv.Data?.ToString()}\"" : inv.Data?.ToString()
|
};
|
ConcatVariable(newOne, last);
|
}
|
|
foreach (var onv in outVariables)
|
{
|
var newOne = new MethodVariable
|
{
|
Name = onv.Name,
|
Type = onv.Type,
|
TypeName = onv.Type.ToString(),
|
Direction = VariableDirection.Out
|
};
|
ConcatVariable(newOne, last);
|
}
|
LoadException = null;
|
}
|
catch (Exception ex)
|
{
|
LoadException = ex;
|
//Log.Error("ViStep load vi error. {0}", ex);
|
}
|
}
|
|
private void Load()
|
{
|
try
|
{
|
if (!FileLocation.GetLocation(Root?.Path, out string path))
|
{
|
return;
|
}
|
//LabViewRunner.GetIO(new LVPath(ViPath), 0, out Cluster[] inputs, out Cluster[] outputs, out type[] iTypes, out type[] oTypes, out var viError);
|
|
LabViewRunner.GetLibpNames(new LVPath(path), out string[] names, out var outVariables);
|
NameDatasource = new ObservableCollection<string>(names);
|
|
LoadException = null;
|
}
|
catch (Exception ex)
|
{
|
LoadException = ex;
|
//Log.Error("ViStep load vi error. {0}", ex);
|
}
|
}
|
|
public override void PrePlanRun()
|
{
|
// ToDo: Optionally add any setup code this step needs to run before the testplan starts
|
base.PrePlanRun();
|
}
|
|
/// <summary>
|
/// ת»»²ÎÊý
|
/// </summary>
|
private void ResolveVariables()
|
{
|
foreach (var m in MethodVariables)
|
{
|
m.Value = PlanRun.Resolve(this, m.ValueStr, m.Type);
|
}
|
}
|
|
/// <summary>
|
/// ÔËÐк¯Êý
|
/// </summary>
|
private void RunMethod()
|
{
|
if (!FileLocation.GetLocation(Root?.Path, out string path))
|
{
|
return;
|
}
|
ResolveVariables();
|
|
var ins = MethodVariables.Where(m => m.Direction == VariableDirection.In && m.Value != null)
|
.Select(m => new LabViewHelper.Cluster { name = m.Name, variant__32Data = new LVVariant(m.Value) }).ToArray();
|
|
|
LabViewRunner.RunLibpByName2(new LVPath(path), ViName, 0, ShowWindow, ins, out var outs, out ErrorCluster err);
|
if (err.status)
|
{
|
Verdict = Verdict.Error;
|
return;
|
}
|
|
foreach (var ov in outs)
|
{
|
foreach (var m in MethodVariables)
|
{
|
if (ov.name == m.Name)
|
{
|
m.Value = ov.variant__32Data.value;
|
break;
|
}
|
}
|
}
|
}
|
|
protected override void RunDetail()
|
{
|
try
|
{
|
// ToDo: Add test case code here
|
//RunChildSteps(); //If step has child steps.
|
RunMethod();
|
|
UpdateVariableToRuntime();
|
this.Verdict = Verdict.Pass;
|
}
|
catch (Exception ex)
|
{
|
Log.Error("ViStep Run error. {0}", ex);
|
this.Verdict = Verdict.Error;
|
}
|
}
|
|
public override void PostPlanRun()
|
{
|
// ToDo: Optionally add any cleanup code this step needs to run after the entire testplan has finished
|
base.PostPlanRun();
|
}
|
}
|
}
|