Code Examples
- Working with Images and starting Sessions based on Images
- Simple session creation based on Runner installation
- Create and execute a test plan
- Load and execute a test plan
- Receiving results, logs and events from a Session
- How to work with component settings
- Configuring a Runner for default execution and using stored test plans on the Runner
Image creation
For this example we have a Runner started which has the ID: HKZ6QN3
// Create connection
var options = ConnectionFactory.GetDefaultOptions();
options.Servers = new string[] { "nats://127.0.0.1:20111" };
IConnection connection = new ConnectionFactory().CreateConnection(options);
RunnerClient runner = new RunnerClient(connection.ServerInfo.ServerName, connection);
// Specify image to use for the session
Image image = new Image();
image.Packages = new List<PackageSpecifier>
{
new PackageSpecifier() { Name = "Demonstration" },
new PackageSpecifier() { Name = "HTTP", Version = "1.0.0" },
// We can even specify a different runner version for the session
new PackageSpecifier() { Name = "Runner", Version = "1.2.1" }
};
image.Repositories = new List<string>() { "https://packages.opentap.io" };
// Ask the Runner to resolve the image. Resolution will check if the image can be created and download any missing packages.
Image resolvedImage = runner.ResolveImage(new List<Image>() { image });
// Start a new session with the resolved image
SessionClient newSession = runner.StartImageSession(resolvedImage);
// Use the session for test automation
// Shutdown the session
runner.ShutdownSession(newSession.Id);
In this example, we successfully resolved an image, started and stopped a session based on the image. This can be verified in the Runner
logs:
Session creation
Although the Image approach offers flexibility, some use-cases can be kept simple by just using a Runner Session
based on the Runner
installation.
// Create connection
var options = ConnectionFactory.GetDefaultOptions();
options.Servers = new string[] { "nats://127.0.0.1:20111" };
IConnection connection = new ConnectionFactory().CreateConnection(options);
RunnerClient runner = new RunnerClient(connection.ServerInfo.ServerName, connection);
// Start a new session based on Runner installation
SessionClient newSession = runner.StartSession();
// Use the session for test automation. Plugins available in this session comes from the packages installed in the Runner.
// Shutdown the session
runner.ShutdownSession(newSession.Id);
Create and Run Test Plan
In this example, we use the simple session from the Session creation example above, but before shutting down the session, we setup and run a simple test plan.
// Create connection
var options = ConnectionFactory.GetDefaultOptions();
options.Servers = new string[] { "nats://127.0.0.1:20111" };
IConnection connection = new ConnectionFactory().CreateConnection(options);
RunnerClient runner = new RunnerClient(connection.ServerInfo.ServerName, connection);
// Start a new session based on Runner installation
SessionClient newSession = runner.StartSession();
var types = newSession.GetStepTypes();
var plan = newSession.GetTestPlan(null);
plan.ChildTestSteps.Clear();
plan.ChildTestSteps.Add(types.FirstOrDefault(s => s.TypeName.Contains("Delay")));
plan = newSession.SetTestPlan(plan);
var delayStepSettings = newSession.GetSettings(plan.ChildTestSteps[0].Id);
if (delayStepSettings.FirstOrDefault(s => s.PropertyName == "DelaySecs") is TextBoxControl textBox)
textBox.StringValue = "3 s";
delayStepSettings = newSession.SetSettings(plan.ChildTestSteps[0].Id, delayStepSettings);
var status = newSession.RunTestPlan(new List<Parameter>());
while (status.ExecutionState != ExecutionState.Idle)
{
await Task.Delay(1000);
status = newSession.GetStatus();
}
Console.WriteLine(status.Verdict.ToString());
// Shutdown the session
runner.ShutdownSession(newSession.Id);
In this example, we retrieved the available test step types using GetStepTypes
and chose a Delay
step and inserted into the Test Plan using SetTestPlan
.
Afterwards, we retrieved the Delay
step settings and modified the Time Delay
to be 3 s
.
Lastly, we ran the Test Plan and contiunually asked for the status until the ExecutionState
turned back to Idle
. The Verdict of the Test Plan was logged and the output of this program would be NotSet
.
Load and Run Test Plan
In this example, we use the simple session from the Session creation example above, but before shutting down the session, we load and run a Test Plan locally stored on the disk.
// Create connection
var options = ConnectionFactory.GetDefaultOptions();
options.Servers = new string[] { "nats://127.0.0.1:20111" };
IConnection connection = new ConnectionFactory().CreateConnection(options);
RunnerClient runner = new RunnerClient(connection.ServerInfo.ServerName, connection);
// Start a new session based on Runner installation
SessionClient newSession = runner.StartSession();
newSession.SetTestPlanXML(File.ReadAllText("MyTestPlan.TapPlan"));
var status = newSession.RunTestPlan(new List<Parameter>());
while (status.ExecutionState != ExecutionState.Idle)
{
await Task.Delay(1000);
status = newSession.GetStatus();
}
Console.WriteLine(status.Verdict.ToString());
// Shutdown the session
runner.ShutdownSession(newSession.Id);
Results, Logs and Events
In this example, we use the simple session from the Create and Run Test Plan section above, but with results, logs and events logged.
// Create connection
var options = ConnectionFactory.GetDefaultOptions();
options.Servers = new string[] { "nats://127.0.0.1:20111" };
IConnection connection = new ConnectionFactory().CreateConnection(options);
RunnerClient runner = new RunnerClient(connection.ServerInfo.ServerName, connection);
// Start a new session based on Runner installation
SessionClient newSession = runner.StartSession();
// Connect to the session logs
newSession.ConnectSessionLogs(logHandler);
void logHandler(LogList list)
{
foreach(var log in list.Logs)
Console.WriteLine($"{log.Source,-12}: {log.Message}");
}
// Connect to the session results
newSession.ConnectSessionResults(resultHandler, runHandler);
void resultHandler(Result result)
{
Console.WriteLine($"Result: {result.Status}");
}
void runHandler(TestRun run)
{
Console.WriteLine($"Run: {run.Status}");
}
// Connect to the session events
newSession.ConnectSessionEvents(eventHandler);
void eventHandler(SessionEvent evt)
{
Console.WriteLine($"Event: {evt.EventType}");
}
var types = newSession.GetStepTypes();
var plan = newSession.GetTestPlan(null);
plan.ChildTestSteps.Clear();
plan.ChildTestSteps.Add(types.FirstOrDefault(s => s.TypeName.Contains("Delay")));
plan = newSession.SetTestPlan(plan);
var delayStepSettings = newSession.GetSettings(plan.ChildTestSteps[0].Id);
if (delayStepSettings.FirstOrDefault(s => s.PropertyName == "DelaySecs") is TextBoxControl textBox)
textBox.StringValue = "3 s";
delayStepSettings = newSession.SetSettings(plan.ChildTestSteps[0].Id, delayStepSettings);
var status = newSession.RunTestPlan(new List<Parameter>());
while (status.ExecutionState != ExecutionState.Idle)
{
await Task.Delay(1000);
status = newSession.GetStatus();
}
Console.WriteLine(status.Verdict.ToString());
// Shutdown the session
runner.ShutdownSession(newSession.Id);
This code should produce the following output, where events, runs and results are prepended with “Event: “, “Run: “, and “Result: “.
Working with ComponentSettings
// Create connection
var options = ConnectionFactory.GetDefaultOptions();
options.Servers = new string[] { "nats://127.0.0.1:20111" };
IConnection connection = new ConnectionFactory().CreateConnection(options);
RunnerClient runner = new RunnerClient(connection.ServerInfo.ServerName, connection);
// Create a new session client
SessionClient newSession = runner.StartSession();
try
{
// Let's get the overview of component settings available in the session
var componentSettings = newSession.GetComponentSettingsOverview();
foreach (var componentSetting in componentSettings)
Console.WriteLine($"Component Setting: {componentSetting.Name} ({componentSetting.GroupName})");
// Outputs:
// Component Setting: DUTs(Bench)
// Component Setting: Engine(-)
// Component Setting: Instruments(Bench)
// Component Setting: Connections(Bench)
// Component Setting: Results(-)
// Component Setting: Editor(-)
// Component Setting: Cloud Drive(-)
// Let's check the instruments component settings
var intrumentIdentifier = componentSettings.FirstOrDefault(s => s.Name == "Instruments" && s.GroupName == "Bench");
// Let's assume the session has Demonstration plugin installed and list the available instrument types
var instrumentTypes = newSession.GetComponentSettingsListAvailableTypes(intrumentIdentifier.GroupName, intrumentIdentifier.Name);
foreach (var instrumentType in instrumentTypes)
Console.WriteLine($"Instrument Type: {string.Join("/", instrumentType.TypeDisplay.Group)}/{instrumentType.TypeDisplay.Name}");
// Outputs:
// Instrument Type: / Generic SCPI Instrument
// Instrument Type: Demo / Battery Test / Power Analyzer
// Instrument Type: Demo / Battery Test / Temperature Chamber
// Instrument Type: Demo / Results And Timing/ Timing Instrument
// Let's list the configured instruments
var instruments = newSession.GetComponentSettings(intrumentIdentifier.GroupName, intrumentIdentifier.Name);
if (instruments is ComponentSettingsList list)
{
foreach (var instrument in list.Items)
Console.WriteLine($"Instrument: {instrument.Name}");
}
// Outputs:
// Instrument: SCPI
// Instrument: PSU
// Instrument: TEMP
// Let's assume we want to create a new instrument of type "Demo / Battery Test / Power Analyzer"
instruments = newSession.AddComponentSettingsListItem(intrumentIdentifier.GroupName, intrumentIdentifier.Name, instrumentTypes.FirstOrDefault(s => s.TypeDisplay.Name == "Power Analyzer").TypeName);
// Let's list the available instruments again
if (instruments is ComponentSettingsList list2)
{
foreach (var instrument in list2.Items)
Console.WriteLine($"Instrument: {instrument.Name}");
}
// Outputs:
// Instrument: SCPI
// Instrument: PSU
// Instrument: TEMP
// Instrument: PSU (1)
// Let's check the settings of the new instrument "PSU (1)"
foreach (var setting in (instruments as ComponentSettingsList).Items[3].Settings)
{
Console.WriteLine($"Setting: {setting.Display.Name}");
if (setting is TextBoxControl textBox)
{
Console.WriteLine(textBox.StringValue);
}
}
// Outputs:
// Setting: Cell Size Factor
// 0.005
}
finally
{
runner.ShutdownSession(newSession.Id);
}
Default Endpoints
Default endpoints are endpoints that affect each other. They are:
- SetDefaultImage: Sets a default image in the Runner environment. The image includes essential packages.
- GetDefaultImage: Retrieves the currently set default image.
- SetDefaultSettings: Applies default settings for the Runner. Settings might have various package dependencies.
- GetDefaultSettings: Retrieves the current settings from the Runner.
- StartDefaultSession: Starts a session using the default settings and image.
- StartDefaultSessionOverrideImage: Begins a session with an overridden image for specific use cases.
- SetTestPlans: Sets a list of test plans to be used in the Runner.
- AddTestPlan: Adds a single test plan to the current list in the Runner.
- GetTestPlans: Retrieves the list of test plans stored in the Runner.
A Session’s plugin configuration depends on:
- The dependencies of the TestPlan.
- The dependencies of the Settings.
- The packages defined in a “default image”.
- Optionally, the packages defined in an “image override”.
The following example demonstrates how to use the RunnerClient for managing test plans in a Runner session.
public static void DefaultTestPlanShowcase(RunnerClient runnerClient)
{
// Set the base image. This includes basic packages that are not dependencies of the TestPlans or SettingsPackage
Image baseImage = new Image()
{
Packages = new List<PackageSpecifier>()
{
new PackageSpecifier() { Name = "Runner", Version = "1.7.0" }
},
Repositories = new List<string>()
{
"https://packages.opentap.io"
}
};
runnerClient.Default.SetImage(baseImage); // Apply the base image configuration
// Define and set the Settings Package
RepositoryPackageReference settingsPackageReference = new RepositoryPackageReference()
{
Repository = "https://test-automation.pw.keysight.com/api/packages",
Path = "/users/dennis.rasmussen@keysight.com/BatterySettings.TapPackage",
Version = "0.2.0"
};
runnerClient.Default.SetSettings(settingsPackageReference); // Apply settings package
// Define and add Default TestPlans to be stored in the Runner
List<RepositoryPackageReference> testPlans = new List<RepositoryPackageReference>()
{
// Define individual test plans
new RepositoryPackageReference
{
Repository = "https://test-automation.pw.keysight.com/api/packages",
Path = "/users/dennis.rasmussen@keysight.com/BatteryPlan.TapPlan",
Version = "0.1.0-Draft.5"
},
new RepositoryPackageReference
{
Repository = "https://test-automation.pw.keysight.com/api/packages",
Path = "/users/dennis.rasmussen@keysight.com/Demonstration.TapPlan",
Version = "0.1.0-Draft.4"
},
new RepositoryPackageReference
{
Repository = "https://test-automation.pw.keysight.com/api/packages",
Path = "/users/dennis.rasmussen@keysight.com/Calibration.TapPlan",
Version = "0.1.0-Draft.1"
}
};
// Add and set the test plans in the Runner
runnerClient.Default.AddTestPlan(testPlans[0]);
runnerClient.Default.SetTestPlans(testPlans); // Set multiple test plans at once
// Fetch and run the stored TestPlans
foreach (var plan in runnerClient.Default.GetTestPlans())
{
Console.WriteLine($"TestPlan: {plan.Path} {plan.Version}");
// Start a session for each test plan
// The Session will have the Packages needed required from the BaseImage, Settings dependencies & TestPlan dependencies
// The Session will also already have the Settings and the TestPlan loaded
var session = runnerClient.Default.StartSession(plan);
try
{
// Run the TestPlan and monitor its execution
var status = session.RunTestPlan(new List<Parameter>());
while (status.ExecutionState != ExecutionState.Idle)
{
status = session.GetStatus(); // Continuously check the status
Thread.Sleep(1000); // Delay to avoid overloading
}
Console.WriteLine($"TestPlan: {plan.Path} {plan.Version} - Verdict {status.Verdict}");
}
finally
{
runnerClient.ShutdownSession(session.Id); // Ensure session is properly closed
}
}
}
Future code examples:
- Editing Step and TestPlan settings
- Load from and save to Repository