// 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 OpenTap.Plugins.BasicSteps;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.IO;
namespace OpenTap.Engine.UnitTests
{
[TestFixture]
public class SweepStepTest
{
public class IsOpenedDut : Dut
{
public bool IsOpened = false;
public bool IsClosed = false;
public bool IsUsed = false;
public override void Open()
{
base.Open();
IsOpened = true;
}
public override void Close()
{
base.Close();
IsClosed = true;
}
public void Use()
{
IsUsed = true;
}
}
public class IsOpenUsedTestStep : TestStep
{
public IsOpenedDut Resource { get; set; }
[ResourceOpen(ResourceOpenBehavior.Ignore)]
public IsOpenedDut Resource2 { get; set; }
[ResourceOpen(ResourceOpenBehavior.Ignore)]
public IsOpenedDut[] Resource3 { get; set; }
public override void Run()
{
Assert.IsTrue(Resource.IsConnected);
if(Resource2 != Resource)
Assert.IsFalse(Resource2.IsConnected);
foreach(var res in Resource3)
if(res != Resource)
Assert.IsFalse(res.IsConnected);
Resource.Use();
}
}
///
/// Tests that instruments/resources are opened when indirectly referenced from SweepLoop.
///
[Test]
public void TestResourceReference()
{
// Loop seems to provoke a race condition in test plan execution
for (int i = 0; i < 10; i++)
{
EngineSettings.Current.ToString();
var step = new OpenTap.Plugins.BasicSteps.SweepLoop();
var theDuts = Enumerable.Range(0, 10).Select(number => new IsOpenedDut()).ToArray();
var otherdut = new IsOpenedDut();
step.ChildTestSteps.Add(new IsOpenUsedTestStep() { Resource = new IsOpenedDut(), Resource2 = otherdut, Resource3 = new []{new IsOpenedDut() }});
step.SweepParameters.Add(new OpenTap.Plugins.BasicSteps.SweepParam(new IMemberData[] { TypeData.FromType(typeof(IsOpenUsedTestStep)).GetMember("Resource") }, theDuts));
var plan = new TestPlan();
plan.PrintTestPlanRunSummary = true;
plan.ChildTestSteps.Add(step);
var rlistener = new PlanRunCollectorListener();
var planRun = plan.Execute(new IResultListener[] { rlistener });
Assert.AreEqual(theDuts.Length + 1, rlistener.StepRuns.Count);
Assert.IsTrue(planRun.Verdict == Verdict.NotSet);
Assert.IsTrue(theDuts.All(dut => dut.IsClosed && dut.IsOpened && dut.IsUsed));
}
}
public class SweepTestStep : TestStep
{
[Display(" abc ")]
public int SweepProp { get; set; }
public int Value { get; private set; }
public override void Run()
{
Value += SweepProp;
Results.Publish("ABC", new List { "abc" }, SweepProp);
}
}
[Test]
[Pairwise]
public void RunSweep([Values(true,false)] bool acrossRuns, [Values(true, false)]bool allEnabled)
{
var tp = new TestPlan();
var sl = new SweepLoop()
{
CrossPlan = acrossRuns ? SweepLoop.SweepBehaviour.Across_Runs : SweepLoop.SweepBehaviour.Within_Run
};
var ds = new SweepTestStep();
sl.ChildTestSteps.Add(ds);
sl.SweepParameters.Add(new SweepParam(new[] { TypeData.GetTypeData(ds).GetMember("SweepProp") }, 2,3,5,7));
sl.EnabledRows = new bool[] { true, allEnabled, true, true };
tp.ChildTestSteps.Add(sl);
using (var st = new MemoryStream())
{
tp.Save(st);
st.Seek(0, 0);
tp = TestPlan.Load(st, tp.Path);
}
ds = tp.ChildTestSteps[0].ChildTestSteps[0] as SweepTestStep;
if (acrossRuns)
{
foreach(var rowEnabled in sl.EnabledRows)
{
if (rowEnabled)
{
var pr = tp.Execute();
Assert.IsFalse(pr.FailedToStart);
Assert.AreEqual(Verdict.NotSet, pr.Verdict);
}
}
}
else
{
var pr = tp.Execute();
Assert.IsFalse(pr.FailedToStart);
}
if(allEnabled)
Assert.AreEqual(17, ds.Value);
else
Assert.AreEqual(14, ds.Value);
}
[Test]
public void SweepPropertiesUpdateTest()
{
var savestream = new MemoryStream();
var tp = new TestPlan();
{
var range = new SweepLoopRange()
{
SweepPoints = 3,
SweepStart = 1,
SweepEnd = 2
};
tp.ChildTestSteps.Add(range);
tp.Save(savestream);
}
savestream.Seek(0, SeekOrigin.Begin);
// Verify that the removal event is triggered both on new and serialized sweep ranges
var plans = new[] { tp, TestPlan.Load(savestream, Path.GetTempFileName()) };
foreach (var plan in plans)
{
var sweep = plan.ChildTestSteps[0] as SweepLoopRange;
CollectionAssert.IsEmpty(sweep.SweepProperties);
var delay1 = new DelayStep();
var delay2 = new DelayStep();
sweep.ChildTestSteps.Add(delay1);
sweep.ChildTestSteps.Add(delay2);
sweep.SweepProperties = new List() { TypeData.FromType(typeof(DelayStep)).GetMember(nameof(DelayStep.DelaySecs)) };
// Verify that the sweep property was added
Assert.AreEqual(1, sweep.SweepProperties.Count);
// Removing the first delay should do nothing
sweep.ChildTestSteps.Remove(delay1);
Assert.AreEqual(1, sweep.SweepProperties.Count);
// Removing the final delay should remove the property
sweep.ChildTestSteps.Remove(delay2);
CollectionAssert.IsEmpty(sweep.SweepProperties);
}
}
[Test]
public void SerializeNestedSweepLoopRange()
{
var tp = new TestPlan();
var s1 = new SweepLoopRange();
var s2 = new SweepLoopRange();
var s3 = new DelayStep() { DelaySecs = 0 };
tp.ChildTestSteps.Add(s1);
s1.ChildTestSteps.Add(s2);
s2.ChildTestSteps.Add(s3);
s1.SweepProperties = new List() { TypeData.FromType(typeof(DelayStep)).GetMember(nameof(DelayStep.DelaySecs)) };
s2.SweepProperties = new List() { TypeData.FromType(typeof(DelayStep)).GetMember(nameof(DelayStep.DelaySecs)) };
using (var st = new System.IO.MemoryStream())
{
tp.Save(st);
st.Seek(0, 0);
tp = TestPlan.Load(st, tp.Path);
}
s1 = tp.ChildTestSteps[0] as SweepLoopRange;
s2 = s1.ChildTestSteps[0] as SweepLoopRange;
Assert.AreEqual(1, s1.SweepProperties.Count);
Assert.AreEqual(1, s2.SweepProperties.Count);
Assert.AreEqual(s1.SweepPropertyName, s2.SweepPropertyName);
}
[Ignore("This is very unstable on CI runners")]
[TestCase(true)]
[TestCase(false)]
public void RunSweepWithInterruptions(bool loopRange)
{
IEnumerable check;
var tp = new TestPlan();
TestStep sweep;
if (loopRange)
{
var sweepRange = new SweepLoopRange();
sweepRange.SweepStart = 10;
sweepRange.SweepEnd = 30;
sweepRange.SweepStep = 1;
sweepRange.SweepProperties = new List() { TypeData.FromType(typeof(SweepTestStep)).GetMember("SweepProp") };
sweep = sweepRange;
check = Enumerable.Range(10, (int)(sweepRange.SweepEnd - sweepRange.SweepStart + 1));
}
else
{
check = Enumerable.Range(10, 20);
var sweepRange = new SweepLoop();
var lst = new List();
lst.Add(new SweepParam(new[] { TypeData.FromType(typeof(SweepTestStep)).GetMember("SweepProp") }, check.Cast