Just returning to the software for Parallel dynamic testplans - Technical - OpenTAP Community Forum after some time working on other aspects of the project.
I was hoping to use a ResultListener to synchronize some unit tests of the concurrent runs, but Session.Create()
doesn’t seem to clone the ResultSettings in the way I was expecting.
I’ve got a ResultListener
defined in my test project as follows
class SyncListener : ResultListener
{
private readonly SyncMessageStore messageStore;
private string dut;
public SyncListener(SyncMessageStore syncMessageColletor)
{
this.messageStore = syncMessageColletor;
}
public override void OnTestPlanRunStart(TestPlanRun planRun)
{
base.OnTestPlanRunStart(planRun);
dut = (new MacroString { Text = "<DUT>" }).Expand(planRun);
}
public override void OnTestStepRunStart(TestStepRun stepRun)
{
base.OnTestStepRunStart(stepRun);
messageStore.ActiveTestName.AddOrUpdate(dut, stepRun.TestStepName, (key, oldVal) => stepRun.TestStepName);
}
public override void OnTestPlanRunCompleted(TestPlanRun planRun, Stream logStream)
{
base.OnTestPlanRunCompleted(planRun, logStream);
messageStore.Complete.AddOrUpdate(dut, true, (key, oldVal) => true);
}
}
An object to store the bits I want to capture from each test run, at the moment just the name of the test that’s running and if the run’s complete.
class SyncMessageStore
{
public ConcurrentDictionary<string, bool> Complete { get; } = new();
public ConcurrentDictionary<string, string> ActiveTestName { get; } = new();
}
My test code (stripped down for brevity ) is something like this
SyncMessageStore messageStore = new();
ResultSettings.Current.Add(new SyncListener(messageStore));
scanTargetSelecter.SelectScanTarget(Position.P01);
serialNumberProvider.SendSerialNumber("000000001"); // This kicks off the first test run
scanTargetSelecter.SelectScanTarget(Position.P02);
serialNumberProvider.SendSerialNumber("000000002"); // This kicks off the second test run
while (!messageStore.ActiveTestName.All(x => x.Value == "Wait")) { }
Thread.Sleep(50);
Assert.Equal("Waiting", singleViews[0].StatusText);
Assert.Equal("Waiting", singleViews[1].StatusText);
I have a test manager which deals with getting test plans, and starting runs etc.
using (Session.Create(SessionOptions.RedirectLogging | SessionOptions.OverlayComponentSettings))
{
TestPlan = testPlanProvider.GetTestPlanFromMaterialNumber(MaterialInfo.MaterialNumber);
TestPlan.BreakOffered += TestPlan_BreakOffered;
List<ResultListener> resultListeners = new(ResultSettings.Current.Cast<ResultListener>())
{
new SimpleListener(this),
new LogResultListener() { FilePath = new MacroString() { Text = "TestRunLogs\\<Serial> <Date>.txt", Context = TestPlan } },
};
List<ResultParameter> metaDataParameters = new()
{
new("", "DUT", TestPosition, "DUT"),
new("", "Serial", SerialNumber, "Serial")
};
CurrentRun = TestPlan.ExecuteAsync(resultListeners, metaDataParameters, null, CancellationToken.None);
}
I was expecting that using OverlayComponentSettings
would give me a new instance of for ResultSettings.Current based off the one set up in the test but that doesn’t seem to be the case.
The API docs say about OverlayComponentSettings
, “Component settings are cloned for the sake of this session. Instrument, DUT etc instances are cloned. When this is used, test plans should be reloaded in the new context.” Do ResultListeners not fall under “Instrument, DUT etc”?