Major upgrade
This commit is contained in:
369
Source/Program/TestStand/TestStand.ActionManager.cs
Normal file
369
Source/Program/TestStand/TestStand.ActionManager.cs
Normal file
@@ -0,0 +1,369 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using NationalInstruments.TestStand.Interop.API;
|
||||
using ProgramLib;
|
||||
using ProgramLib.GUI.View;
|
||||
|
||||
namespace TestStand
|
||||
{
|
||||
/// <summary>
|
||||
/// Provide wrapper function to call into Action classes
|
||||
/// All methods defined in this class must be called from TestStand.
|
||||
/// No other code should be calling these methods outside of TestStand.
|
||||
/// </summary>
|
||||
public static class ActionManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Reset display for steps in a loop. Call this function right after While, Do or For step
|
||||
/// </summary>
|
||||
public static void ResetDisplayForStepsInLoop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ProgramLib.Program.TestStandSeqContext != null)
|
||||
{
|
||||
int numSteps = ProgramLib.Program.TestStandSeqContext.Sequence.GetNumSteps(ProgramLib.Program.TestStandSeqContext.Step.StepGroup);
|
||||
int currentStepIndex = ProgramLib.Program.TestStandSeqContext.Step.StepIndex;
|
||||
while (++currentStepIndex < numSteps)
|
||||
{
|
||||
Step step = ProgramLib.Program.TestStandSeqContext.Sequence.GetStep(currentStepIndex, ProgramLib.Program.TestStandSeqContext.Step.StepGroup);
|
||||
if (!string.IsNullOrEmpty(step.ResultStatus))
|
||||
step.ResultStatus = "";
|
||||
}
|
||||
|
||||
ProgramLib.Program.TestStandSeqContext.Engine.PostUIMessage(ProgramLib.Program.TestStandSeqContext.Execution, ProgramLib.Program.TestStandSeqContext.Thread, UIMessageCodes.UIMsg_RefreshWindows, 0, "", null, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Power on
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void UutPowerOn()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.UutPowerOnAction();
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Power off
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void UutPowerOff()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.UutPowerOffAction();
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform Safe-to-turn-on (STTO)
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void PerformStto()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.PerformSttoAction();
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connect to UUT test port
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void UutTestPortConnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.UutTestPortConnectAction();
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect from UUT test port
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void UutTestPortDisconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.UutTestPortDisconnectAction();
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Select a MSFR test case
|
||||
/// </summary>
|
||||
/// <param name="endStepComment">Unique comment to identify the end step associated with the loop we trying to break out of</param>
|
||||
/// <returns></returns>
|
||||
public static void SelectMsfrTestCase(string endStepComment = default)
|
||||
{
|
||||
ProgramLib.GUI.Util.StandardButtons button = ProgramLib.GUI.Util.StandardButtons.NOT_SET;
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().GuiManager[ProgramGuiManager.WINDOWS.DEFAULT].Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
ProgramLib.Program.Instance().GuiManager[ProgramLib.ProgramGuiManager.WINDOWS.LIVE_DATA].Hide();
|
||||
ProgramLib.Program.Instance().GuiManager[ProgramLib.ProgramGuiManager.WINDOWS.MSFR_TEST_CASES].ShowDialog();
|
||||
ProgramLib.Program.Instance().GuiManager[ProgramLib.ProgramGuiManager.WINDOWS.LIVE_DATA].Show();
|
||||
|
||||
button = ((MsfrTestCasesWindow)ProgramLib.Program.Instance().GuiManager[ProgramLib.ProgramGuiManager.WINDOWS.MSFR_TEST_CASES]).ClickedButton;
|
||||
});
|
||||
|
||||
if (button == ProgramLib.GUI.Util.StandardButtons.CANCEL_NO && !string.IsNullOrEmpty(endStepComment))
|
||||
{
|
||||
Util.BreakOutOfLoop(endStepComment);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a confirmation message. Can use the cancel button as a mechanism to break out of loop if we're in a loop
|
||||
/// </summary>
|
||||
/// <param name="endStepComment">Unique comment to identify the end step associated with the loop we trying to break out of</param>
|
||||
/// <returns></returns>
|
||||
public static void DisplayConfirmationMessage(string message, string leftButtonText = "OK", string rightButtonText = "Cancel", string endStepComment = default)
|
||||
{
|
||||
ProgramLib.GUI.Util.StandardButtons button = ProgramLib.GUI.Util.StandardButtons.NOT_SET;
|
||||
try
|
||||
{
|
||||
ConfirmationWindow window = (ConfirmationWindow)ProgramLib.Program.Instance().GuiManager[ProgramLib.ProgramGuiManager.WINDOWS.CONFIRMATION];
|
||||
ProgramLib.Program.Instance().GuiManager[ProgramGuiManager.WINDOWS.DEFAULT].Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
ProgramLib.Program.Instance().GuiManager[ProgramLib.ProgramGuiManager.WINDOWS.LIVE_DATA].Hide();
|
||||
window.ConfirmationMessage = message;
|
||||
window.OkButtonText = leftButtonText;
|
||||
window.CancelButtonText = rightButtonText;
|
||||
window.ShowDialog();
|
||||
ProgramLib.Program.Instance().GuiManager[ProgramLib.ProgramGuiManager.WINDOWS.LIVE_DATA].Show();
|
||||
|
||||
button = window.ClickedButton;
|
||||
});
|
||||
|
||||
if (button == ProgramLib.GUI.Util.StandardButtons.CANCEL_NO && !string.IsNullOrEmpty(endStepComment))
|
||||
{
|
||||
Util.BreakOutOfLoop(endStepComment);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display wait message with countdown timer
|
||||
/// </summary>
|
||||
/// <param name="message">message to display</param>
|
||||
/// <param name="delaySec">number of seconds to wait</param>
|
||||
/// <returns></returns>
|
||||
public static void DisplayWaitMessage(string message, double delaySec)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().GuiManager.DisplayWaitMessage(message, delaySec);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send test message to UUT
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void SendTestMessageToUut(string messageName, string configSectionName = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.SendTestMessageToUutAction(messageName, configSectionName);
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Uart Handshake message to UUT
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void StartTacticalUartReadThreadAction()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.StartTacticalUartReadThreadAction();
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Uart Handshake message to UUT
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void PerformTacticalUartCommAction()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.PerformTacticalUartCommAction();
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Uart Handshake message to UUT
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void SendCoeAdnucMsgToUut(string coeDeviceName, bool continueOnError = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.SendCoeAdnucMsgToUutAction(coeDeviceName);
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex, continueOnError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Uart Handshake message to UUT
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void SendCoeUncageMsgToUut(string coeDeviceName, bool continueOnError = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.SendCoeUncageMsgToUutAction(coeDeviceName);
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex, continueOnError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Uart Handshake message to UUT
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void SendCoeBatteryGoodMsgToUut(string coeDeviceName, bool continueOnError = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.BasicAction action = new ProgramLib.SendCoeBatteryGoodMsgToUutAction(coeDeviceName);
|
||||
action.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex, continueOnError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
334
Source/Program/TestStand/TestStand.ProgramManager.cs
Normal file
334
Source/Program/TestStand/TestStand.ProgramManager.cs
Normal file
@@ -0,0 +1,334 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using NationalInstruments.TestStand.Interop.API;
|
||||
using ProgramLib;
|
||||
|
||||
namespace TestStand
|
||||
{
|
||||
internal class OriginalStepSetting
|
||||
{
|
||||
public int _stepIndex;
|
||||
public StepGroups _stepGroup;
|
||||
public string _postExpression;
|
||||
public bool _clearAdditionalResults;
|
||||
|
||||
public OriginalStepSetting(int stepIndex, StepGroups stepGroups, string postExpression, bool clearAdditionalResults = false)
|
||||
{
|
||||
_stepIndex = stepIndex;
|
||||
_stepGroup = stepGroups;
|
||||
_postExpression = postExpression;
|
||||
_clearAdditionalResults = clearAdditionalResults;
|
||||
}
|
||||
}
|
||||
|
||||
internal class StepErrorSetting
|
||||
{
|
||||
public int _stepIndex;
|
||||
public StepGroups _stepGroup;
|
||||
public string _errorMessage;
|
||||
|
||||
public StepErrorSetting(int stepIndex, StepGroups stepGroups, string errorMessage)
|
||||
{
|
||||
_stepIndex = stepIndex;
|
||||
_stepGroup = stepGroups;
|
||||
_errorMessage = errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provide wrapper function to intialize and finalize Program class
|
||||
/// All methods defined in this class must be called from TestStand.
|
||||
/// No other code should be calling these methods outside of TestStand.
|
||||
/// </summary>
|
||||
public static class ProgramManager
|
||||
{
|
||||
// keep track of all the steps that have their settings changed by this program
|
||||
private static List<OriginalStepSetting> _originalStepSettingList = new List<OriginalStepSetting>();
|
||||
|
||||
// keep track of all the steps that have errors
|
||||
private static List<StepErrorSetting> _stepErrorSettingList = new List<StepErrorSetting>();
|
||||
|
||||
/// <summary>
|
||||
/// Initialize power supply measurement manager
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializeProgram(string partNumber = "", string serialNumber = "", string testType = "", string testName = "", bool isThereHardware = true, string configSubFolderName = "Default", object testStandSeqContext = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_originalStepSettingList = new List<OriginalStepSetting>();
|
||||
_stepErrorSettingList = new List<StepErrorSetting>();
|
||||
ProgramLib.Program.Instance(partNumber, serialNumber, testType, testName, isThereHardware, configSubFolderName, testStandSeqContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize power supply measurement manager
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void FinalizeProgram(bool openTestDataFolder = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ProgramLib.Program._program != null)
|
||||
{
|
||||
// signal to all running threads to exit
|
||||
ProgramLib.Program._program.EventManager[EventManager.Events.GLOBAL_QUIT].Set();
|
||||
|
||||
BasicAction action = new UutPowerOffAction();
|
||||
action.Run();
|
||||
|
||||
// needs to kill all the support threads since they could be accessing GUI
|
||||
ProgramLib.Program._program.KillSupportThreads();
|
||||
|
||||
// must kill GUI thread before Program destructor can get called
|
||||
ProgramLib.Program._program.KillGuiThread();
|
||||
|
||||
if (ProgramLib.Program.Instance().MalMeasurementLibManager.SwitchMeasurementManager != null)
|
||||
{
|
||||
ProgramLib.Program.Instance().MalMeasurementLibManager.SwitchMeasurementManager.Dispose();
|
||||
}
|
||||
|
||||
PerformTestStandEndOfRunActivities();
|
||||
|
||||
ProgramLib.Program._program.PerformPostTestActivities();
|
||||
|
||||
if (openTestDataFolder)
|
||||
Process.Start(@$"{ProgramLib.Program._program.FileAndFolderManager.GetFolder(FileAndFolderManager.Folders.DATA_TEST)}");
|
||||
|
||||
// this starts garbage collection on this object which then in turn start garbage collection
|
||||
// on all objects it created
|
||||
ProgramLib.Program._program = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform TestStand End-of-Run activities
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static void PerformTestStandEndOfRunActivities()
|
||||
{
|
||||
if (ProgramLib.Program.TestStandSeqContext != null)
|
||||
{
|
||||
// restore original settings for steps that have been modified by this program
|
||||
foreach (OriginalStepSetting setting in _originalStepSettingList)
|
||||
{
|
||||
ProgramLib.Program.TestStandSeqContext.Sequence.GetStep(setting._stepIndex, setting._stepGroup).PostExpression = setting._postExpression;
|
||||
|
||||
if (setting._clearAdditionalResults)
|
||||
ProgramLib.Program.TestStandSeqContext.Sequence.GetStep(setting._stepIndex, setting._stepGroup).AdditionalResults.CustomResults.Clear();
|
||||
}
|
||||
|
||||
// for the first step that has an error in the Main group but is allowed to continue,
|
||||
// we want to flag it at the end of the sequence
|
||||
if (!ProgramLib.Program._terminateTestInitiated)
|
||||
{
|
||||
int numSteps = ProgramLib.Program.TestStandSeqContext.Sequence.GetNumSteps(StepGroups.StepGroup_Main);
|
||||
bool foundError = false;
|
||||
for (int i = 0; i < numSteps; i++)
|
||||
{
|
||||
foreach (StepErrorSetting setting in _stepErrorSettingList)
|
||||
{
|
||||
if (setting._stepIndex == i && setting._stepGroup == StepGroups.StepGroup_Main)
|
||||
{
|
||||
Step step = ProgramLib.Program.TestStandSeqContext.Sequence.GetStep(setting._stepIndex, setting._stepGroup);
|
||||
|
||||
if (String.Equals(step.ResultStatus, "Error"))
|
||||
{
|
||||
// tells teststand there's a exception occurred and give it the error message
|
||||
ProgramLib.Program.TestStandSeqContext.SequenceErrorMessage = setting._errorMessage + " ";
|
||||
ProgramLib.Program.TestStandSeqContext.SequenceErrorOccurred = true;
|
||||
foundError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundError)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is only meant to be called from third-party test executive such as TestStand.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static void MoveTestStandTestReportToTestFolder(string sourceTestReportFilePath, string destinationTestReportPath)
|
||||
{
|
||||
string filenameWithoutExt = Path.GetFileNameWithoutExtension(sourceTestReportFilePath);
|
||||
string pdfFilename = filenameWithoutExt + ".pdf";
|
||||
sourceTestReportFilePath = Path.Combine(Path.GetDirectoryName(sourceTestReportFilePath), pdfFilename);
|
||||
string destinationTestReportFilePath = Path.Combine(destinationTestReportPath, pdfFilename);
|
||||
|
||||
// wait until the teststand report is created
|
||||
int maxRetries = 5;
|
||||
int retries = 0;
|
||||
while (retries++ < maxRetries && !File.Exists(sourceTestReportFilePath))
|
||||
{
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
if (File.Exists(sourceTestReportFilePath) && Directory.Exists(destinationTestReportPath))
|
||||
{
|
||||
File.Move(sourceTestReportFilePath, destinationTestReportFilePath);
|
||||
|
||||
try
|
||||
{
|
||||
string reportDir = Path.GetDirectoryName(sourceTestReportFilePath);
|
||||
if (Regex.IsMatch(reportDir, @"\\report\\?$", RegexOptions.IgnoreCase))
|
||||
{
|
||||
Directory.Delete(Path.GetDirectoryName(sourceTestReportFilePath), true);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All code module should not throw exception into teststand and let teststand handle the exception
|
||||
/// We give the teststand step a nice error message and tell teststand to go to cleanup
|
||||
/// If we are not calling into code from teststand, then we throw exception as usual
|
||||
/// Call this only from code executing on the main TestStand thread
|
||||
/// </summary>
|
||||
/// <param name="ex"></param>
|
||||
/// <returns></returns>
|
||||
internal static void TerminateTestOnMainThreadError(Exception ex, bool continueOnError = false)
|
||||
{
|
||||
if (ProgramLib.Program.TestStandSeqContext != null)
|
||||
{
|
||||
string message = ProgramLib.Util.LogException(ex, ProgramLib.Program._logger);
|
||||
message = Regex.Replace(message, "[\"]+", "");
|
||||
message = Regex.Replace(message, @"\\([nrt])", @"\\$1", RegexOptions.IgnoreCase);
|
||||
|
||||
lock (ProgramLib.Program._terminateTestSyncObj)
|
||||
{
|
||||
if (!ProgramLib.Program._terminateTestInitiated)
|
||||
{
|
||||
if (!continueOnError)
|
||||
{
|
||||
ProgramLib.Program.TestStandSeqContext.Step.AsPropertyObject().SetValBoolean("Result.Error.Occurred", 0, true);
|
||||
ProgramLib.Program._terminateTestInitiated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool foundError = false;
|
||||
foreach (StepErrorSetting setting in _stepErrorSettingList)
|
||||
{
|
||||
if (setting._stepIndex == ProgramLib.Program.TestStandSeqContext.Step.StepIndex && setting._stepGroup == ProgramLib.Program.TestStandSeqContext.Step.StepGroup)
|
||||
{
|
||||
setting._errorMessage = message;
|
||||
foundError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundError)
|
||||
_stepErrorSettingList.Add(new StepErrorSetting(ProgramLib.Program.TestStandSeqContext.Step.StepIndex, ProgramLib.Program.TestStandSeqContext.Step.StepGroup, message));
|
||||
}
|
||||
|
||||
ProgramLib.Program.TestStandSeqContext.Step.AsPropertyObject().SetValString("Result.Error.Msg", 0, $"{message} ");
|
||||
ProgramLib.Program.TestStandSeqContext.Step.ResultStatus = "Error";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Check inner exception.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Support threads such as monitor threads need a way to stop the sequence if it encounters a fatal error
|
||||
/// This function is meant to be called from background threads such as FailureMonitorThread which monitors any error signaled by any
|
||||
/// other background thread.
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
internal static void TerminateTestOnSupportThreadError()
|
||||
{
|
||||
if (ProgramLib.Program.TestStandSeqContext != null)
|
||||
{
|
||||
string message = ProgramLib.Util.LogException(ProgramLib.Program._fatalFailureExceptionFromSupportThread, ProgramLib.Program._logger);
|
||||
message = Regex.Replace(message, "[\"]+", "");
|
||||
message = Regex.Replace(message, @"\\([nrt])", @"\\$1", RegexOptions.IgnoreCase);
|
||||
|
||||
lock (ProgramLib.Program._terminateTestSyncObj)
|
||||
{
|
||||
if (!ProgramLib.Program._terminateTestInitiated)
|
||||
{
|
||||
// tells teststand there's a exception occurred and give it the error message
|
||||
ProgramLib.Program.TestStandSeqContext.SequenceErrorMessage = message + " ";
|
||||
ProgramLib.Program.TestStandSeqContext.SequenceErrorOccurred = true;
|
||||
|
||||
// tells TestStand to go to clean up
|
||||
ProgramLib.Program.TestStandSeqContext.StepGroup = StepGroups.StepGroup_Cleanup;
|
||||
ProgramLib.Program.TestStandSeqContext.NextStepIndex = 0;
|
||||
|
||||
ProgramLib.Program._terminateTestInitiated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save original step settings so we can restore them.
|
||||
/// If we don't restore step settings that we change in this program, then the sequence file will be marked as unsaved
|
||||
/// </summary>
|
||||
internal static void SaveOriginalStepSetting(int stepIndex, StepGroups stepGroup, string postExpression, bool clearAdditionResults = false)
|
||||
{
|
||||
bool stepAlreadyExist = false;
|
||||
foreach (OriginalStepSetting setting in _originalStepSettingList)
|
||||
{
|
||||
if (setting._stepIndex == stepIndex && setting._stepGroup == stepGroup)
|
||||
{
|
||||
stepAlreadyExist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stepAlreadyExist)
|
||||
{
|
||||
_originalStepSettingList.Add(new OriginalStepSetting(stepIndex, stepGroup, postExpression, clearAdditionResults));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
164
Source/Program/TestStand/TestStand.SetupManager.cs
Normal file
164
Source/Program/TestStand/TestStand.SetupManager.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
using System;
|
||||
|
||||
namespace TestStand
|
||||
{
|
||||
/// <summary>
|
||||
/// Provide wrapper functions to initialize instruments, measurements, gui, support threads, etc
|
||||
/// All methods defined in this class must be called from TestStand.
|
||||
/// No other code should be calling these methods outside of TestStand.
|
||||
/// </summary>
|
||||
public static class SetupManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize power supply measurement manager
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializePowerSupplyMeasurementManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().InitializePowerSupplyMeasurementManager();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize DIO measurement manager
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializeDioMeasurementManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().InitializeDioMeasurementManager();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize switch measurement manager
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializeSwitchMeasurementManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().InitializeSwitchMeasurementManager();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize switch measurement manager
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializeCoeMeasurementManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().InitializeCoeMeasurementManager();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize serial devices
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializeSerialDevices()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().InitializeSerialDevices();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize GUI manager
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializeGuiManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().InitializeGuiManager();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start all the monitor/read threads here
|
||||
/// Call this only after ProgramGuiManager and PowerSupplyManager has been initialized since these threads could be
|
||||
/// accessing those objects
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void InitializeSupportThreads()
|
||||
{
|
||||
try
|
||||
{
|
||||
ProgramLib.Program.Instance().InitializeSupportThreads();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DO NOT THROW in this block
|
||||
// this function will handle the error accordingly since we could be calling this from third-party test executive like TestStand
|
||||
ProgramManager.TerminateTestOnMainThreadError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Source/Program/TestStand/Util.cs
Normal file
64
Source/Program/TestStand/Util.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
using NationalInstruments.TestStand.Interop.API;
|
||||
|
||||
namespace TestStand
|
||||
{
|
||||
/// <summary>
|
||||
/// TestStand utility functions
|
||||
/// </summary>
|
||||
internal static class Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Break out of while, do and for loop
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
public static void BreakOutOfLoop(string endStepComment)
|
||||
{
|
||||
if (ProgramLib.Program.TestStandSeqContext != null)
|
||||
{
|
||||
int numSteps = ProgramLib.Program.TestStandSeqContext.Sequence.GetNumSteps(ProgramLib.Program.TestStandSeqContext.Step.StepGroup);
|
||||
int currentStepIndex = ProgramLib.Program.TestStandSeqContext.Step.StepIndex;
|
||||
|
||||
while (++currentStepIndex < numSteps)
|
||||
{
|
||||
Step step = ProgramLib.Program.TestStandSeqContext.Sequence.GetStep(currentStepIndex, ProgramLib.Program.TestStandSeqContext.Step.StepGroup);
|
||||
|
||||
if (string.Equals(step.AsPropertyObject().Comment, endStepComment, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// we at the end of the Main group
|
||||
if (currentStepIndex == numSteps - 1)
|
||||
{
|
||||
// tells TestStand to go to clean up
|
||||
ProgramLib.Program.TestStandSeqContext.StepGroup = StepGroups.StepGroup_Cleanup;
|
||||
ProgramLib.Program.TestStandSeqContext.NextStepIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgramLib.Program.TestStandSeqContext.NextStepIndex = ++currentStepIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user