%UnitTest.TestProduction
Class %UnitTest.TestProduction Extends %UnitTest.TestCase [ System = 3 ]
Unit test base class specialized for testing productions.
Unit tests created based on this class are associated with one production. When the unit test is run, it automatically starts the production, allows it to run for a parameterized time, puts new event log entries in an array and passes control to a method for custom verifications, then stops the production and checks for errors.
The programmer can adjust some parameters, add code to verify results, and use callback methods to handle events before/after start/stop production.
How to use this class:
- Create a subclass of this base class, one per production. Typically there will be one directory per production, and one unit test class per directory/production, called for example Test.xml. In case one wants to run the same production with various settings there may be additional unit test classes such as Test2.xml, Test3.xml, etc.
- Override parameter PRODUCTION to contain the production class name.
- Override parameters MAXWAIT, MINRUN and IGNOREPRODUCTIONERRORS if the defaults are not adequate to the production case.
- Override method CheckResults to include your code with custom verification of the intended production results.
- Override method CheckErrors if you set IGNOREPRODUCTIONERRORS = 1 and want to check the errors yourself.
- Override methods OnBeforeProductionStart and OnAfterProductionStart with code to run before or after the production is started, for example to put files in place (before start), or to call a method that fires the test by instantiating a business service and sending a message (after start).
- Override methods OnBeforeProductionStop and OnAfterProductionStop with code to run right before or after the production is stopped, if needed.
Note: Initialization and cleanup code may go as usual into OnBeforeOneTest(), OnAfterOneTest(), etc., inherited from %UnitTest.TestCase.
There are methods to facilitate usage, such as change settings, retrieve additional records from the Interoperability event log, compare files, etc. More details are given below and in the description for each method.
General utility/helper methods available to be used in the test code:
- GetSetting: Get the current value of a setting for a production item.
- ChangeSetting: Change the value of settings for production items.
- CreateCredentials: Define credentials.
- SendRequest: Call Interoperability testing service to send a request.
- CopyFile: Copy a file from a directory to another directory.
- CompareFiles: Compare the contents of two files.
- Error: Compose a general error message as %Status with the text message provided.
- LogErrors: Generate log messages with all errors contained in a status variable.
- GetEventLog: Retrieve records from the Interoperability event log.
- SelectToString: Return a string containing select information from the Event Log.
File management utility/helper methods available to be used in the test code (all with normalized names):
- CreateMainDirTree: Initialize test directories, with subdirectories for HL7 use.
- CopyFile: Copy a file from a directory to another directory.
- CompareFiles: Compare the contents of two files.
- CleanUpDirectory: Remove all files from a directory or tree.
The following properties are available:
- MainDir
- HL7InputDir
- HL7OutputDir
- HL7ArchiveDir
- HL7WorkDir
- MachineName
- InstanceName
- DSNToSamples
- DSNToUser
Utility/helper methods to be used during test development or debugging:
- Run: Run without loading/deleting any classes.
- Debug: Run in debug mode, without loading/deleting any classes.
- Export: Export all classes in a package to a directory.
- ListSettings: List to the terminal all current settings for a given production and config item.
Parameters
PRODUCTION;
Parameter PRODUCTION;
Class name of the production. It must contain the production class name.
MAXWAIT
Parameter MAXWAIT = 10;
Maximum time in seconds to wait for the production to completely start or stop. The default is 10 seconds, override if necessary.
MINRUN
Parameter MINRUN = 10;
Minimum time to let production run before collecting event log entries of type "infouser" and check for results. The default is 10 seconds, override if necessary. This varies with the production; some productions only need to run for a little time, and some require more time.
IGNOREPRODUCTIONERRORS
Parameter IGNOREPRODUCTIONERRORS = 0;
If any errors appear in the Event Log during execution of the production, the test will fail. In many cases, errors are expected to happen. In this case, override this parameter. You may also want to check them manually by overriding the method CheckErrors.
Properties
MainDir
Property MainDir As %String;
Normalized root test directory name, which by default is directory TestAutoNNN on the same level as the InterSystems IRIS or HealthShare instance, and where NNN is the build number. To initialize the directory tree see method CreateMainDirTree.
HL7InputDir
Property HL7InputDir As %String;
Normalized directory name for HL7 input
HL7OutputDir
Property HL7OutputDir As %String;
Normalized directory name for HL7 output
HL7WorkDir
Property HL7WorkDir As %String;
Normalized directory name for HL7 work
HL7ArchiveDir
Property HL7ArchiveDir As %String;
Normalized directory name for HL7 archive
MachineName
Property MachineName As %String;
Machine name
InstanceName
Property InstanceName As %String;
Instance name
DSNToSamples
Property DSNToSamples As %String;
DSN name pointing to namespace SAMPLES
DSNToUser
Property DSNToUser As %String;
DSN name pointing to namespace USER
BaseLogId
Property BaseLogId As %Integer;
Production's first event log ID
LastLogId
Property LastLogId As %Integer;
Last event log ID retrieved for this production execution
Methods
%OnNew
Method %OnNew(initvalue) As %Status [ Internal ]
Initialize properties.
Note: Do not edit this method. If you want to change the property values, set them directly in your code.
OnBeforeProductionStart
Method OnBeforeProductionStart() As %Status
Code to run right before the production is started. This is useful to:
- Adjust settings - see method ChangeSetting.
- Create directories - see method CreateMainDirTree.
- Copy files - see method CopyFile.
- Create credentials required by the production - see method CreateCredentials.
- etc. If an error status is returned, the test will be aborted and failed. So if a non fatal error occurs, you may invoke ..LogErrors(status,"OnBeforeProductionStart()") and return $$$OK.
OnAfterProductionStart
Method OnAfterProductionStart() As %Status
Code to run right after the production is started. Used, for example, to call a method that initiates the test. If an error status is returned, the test will be aborted and failed and the production will be stopped. So if a non fatal error occurs, you may invoke ..LogErrors(status,"OnAfterProductionStart()") and return $$$OK.
OnBeforeProductionStop
Method OnBeforeProductionStop() As %Status
Code to run right before the production is stopped. If an error status is returned, the test will be failed and aborted, the production will be stopped. If a non fatal error occurs, you may invoke ..LogErrors(status,"OnBeforeProductionStop()") and return $$$OK.
OnAfterProductionStop
Method OnAfterProductionStop() As %Status
Code to run right after the production is stopped. If an error status is returned, the test is failed. If a non fatal error occurs, you may invoke ..LogErrors(status,"OnAfterProductionStop()") and return $$$OK.
CheckResults
Method CheckResults(ByRef Log As %String, New As %String) As %Status
Fill in with code to check the results for the production execution.
This method is initialized with a local array containing user created entries of type "Info" from the Event Log, not including the start production/components entries, with the following contents:
Log = last existing seq for array Log()
Log(seq, fieldname) = fieldvalue
To get other entries from the Event Log, or for more information about the array contents, see method GetEventLog.
Return $$$OK in most cases, or an error status if you want to indicate that there was a failure. Remember that failures are automatic when unit test macros are used.
CheckErrors
Method CheckErrors() As %Status
Override this method if you are going to check errors with custom code. It's automatically invoked when parameter IGNOREPRODUCTIONERRORS = 1.
GetSetting
ClassMethod GetSetting(production As %String = "", configName As %String = "", setting As %String = "", Output value As %String) As %Status
Get the current value of a setting for a production item. Value must be passed by reference. Examples:
Set s = ..GetSetting([Production], ConfigName, Setting, .Value)
Set s = ##class(%UnitTest.TestProduction).GetSetting(Production, ConfigName, Setting, .Value)
ChangeSetting
ClassMethod ChangeSetting(production As %String = "", configName As %String = "", setting As %String = "", value As %String = "", saveToProduction As %Boolean = 0) As %Status
Change the value of a setting for a production item, optionally updating the production class too. Examples:
Set s = ..ChangeSetting([Production], ConfigName, Setting, Value)
Set s = ##class(%UnitTest.TestProduction).ChangeSetting(Production, ConfigName, Setting, Value, 1)
The values are validated. Check the return for errors.
ChangeOrGetSetting
ClassMethod ChangeOrGetSetting(operation As %String = "Get", production As %String = "", configName As %String = "", setting As %String = "", ByRef value As %String = "") As %Status [ Internal, Private ]
Internal method called by GetSetting and ChangeSetting.
CreateCredentials
ClassMethod CreateCredentials(CredId As %String = "", User As %String = "", Pw As %String = "") As %Status
Define credentials. If one already exists with the same Id, it's overwritten. Examples:
Set s = ..CreateCredentials(Id, UserName, Password)
Set s = ##class(%UnitTest.TestProduction).CreateCredentials(Id, UserName, Password)
SendRequest
ClassMethod SendRequest(Name As %String = "", Req As %RegisteredObject, ByRef Resp As %RegisteredObject, GetReply As %Boolean = 0, Time As %Integer = 30) As %Status
Call Interoperability testing service to send a request to a business process or business operation. This is a way to invoke them directly without creating a dummy business service. The production needs to be enabled for testing.
If no request object type is passed, then type Ens.Request is assumed.
Example:
Set s = ..SendRequest("MyBPName", MyRequestObject, .Response, [GetReply], [Time])
GetReply=1 indicates a response is expected (default is 0).
Time indicates how long to wait for a response in case GetReply=1. Default is 30 secs.
Error
ClassMethod Error(msg As %String = "", s As %Status = "") As %Status
Compose a general error message as %Status with the text message provided. If message is the null string, this method returns $$$OK instead.
To append text to an existing error text, pass the status as a second argument.
Examples:
Set status=..Error(message, [oldstatus])
Set status=##class(%UnitTest.TestProduction).Error(message, [oldstatus])
LogErrors
Method LogErrors(s As %Status = 1, where As %String = "")
Generate log messages with all errors contained in status variable s.
GetEventLog
Method GetEventLog(type As %String = "all", name As %String = "", baseId As %Integer, ByRef v As %String, Output New As %Integer) As %Status
Retrieve records from the Interoperability event log, returning them in an array.
type = "info" or "error" or "trace" or "warning" or "alert" or "assert" or "infouser" or "startstop" or "other" name = config name to filter entries (only fetch entries associated with this config name)
Examples:
To get new user entries of type "Info":
Set s = ..GetEventLog("infouser", "", "", .Log, .New)
To get new entries of type "Trace":
Set s = ..GetEventLog("trace", "MyBP", "", .Log, .New)
where New indicates how many new entries were found.
Sample format for the returned array:
Log(1,"ConfigName")="Ens.ScheduleHandler"
Log(1,"ID")="114"
Log(1,"Job")="4768"
Log(1,"SessionId")="8"
Log(1,"SourceClass")="Ens.Director"
Log(1,"SourceMethod")="UpdateProduction"
Log(1,"Stack")=""
Log(1,"Text")="Production 'QDENS.HL7.HL7Routing.Production' is up-to-date."
Log(1,"TimeLogged")="2006-12-05 17:41:06.421"
Log(1,"Type")="Info"
SelectToString
ClassMethod SelectToString(ByRef Log As %String, Prop As %String = "", Value As %String = "", Del As %String = "^") As %String
Extract select text information from the event log returned results, and return a delimited string containing the count followed by selected values, filtering by property/index Prop equals to Value.
Run
ClassMethod Run() As %Status
Run itself without loading/deleting any classes. Example:
Do ##class(MyTestClass).Run()
See also method Debug.
Debug
ClassMethod Debug() As %Status
Run itself in debug mode, without loading/deleting any classes. If an assertion fails or if an error is encountered, execution will pause. Example:
Do ##class(MyTestClass).Debug()
See also method Run.
Export
ClassMethod Export(dir As %String = "", suite As %String = "")
Export all classes in the same package to a directory as a set of individual files.
If the directory is not specified, then ^UnitTestRoot will be used as a base and the last piece of the package name will be used as the subdirectory name.
If the suite name is not specified, then the last piece of the package name of the current class will be used.
Note that parameter suite is ignored when a directory is specified.
Examples:
Do ##class(MyTestClass).Export()
Do ##class(MyTestClass).Export("D:\Test\MyProductionTests\TempDir")
Do ##class(MyTestClass).Export(,"MySuite")
To do: In production-enabled namespaces, all rules and VDoc schemas whose names start with the package should also be exported.
To do: Think about other kinds of files such as CSP pages.
ListSettings
ClassMethod ListSettings(production As %String = "", configName As %String = "")
List all existing settings and their values for a given production and config item name. If a config name is provided, all settings for this config name are listed. Otherwise all config names are listed. Examples:
Do ##class(MyTestClass).ListSettings(, [configname])
Do ##class(%UnitTest.TestProduction).ListSettings(production, [configname])
SubMainDir
Method SubMainDir(AddDirs = "") As %String
Helper method to return the normalized directory name for the full directory path composed of the default test directory plus the additional directories, eg. sub1/sub2. The argument containing the additional directories must use slashes ( / ) as the directory delimiter, on all platforms.
CreateMainDirTree
Method CreateMainDirTree() As %Status
Create a test directory tree that is suitable for generic testing and for HL7 testing. The default root test directory is defined by property MainDir.
This method does not erase any files or directories if they are already present. To do a cleanup, see method CleanUpDirectory.
This method may be invoked in OnBeforeAllTests() or OnBeforeProductionStart() to initialize the test directory tree.
CleanUpDirectory
Method CleanUpDirectory(Dir As %String = "", Recurse As %Boolean = 0) As %Status [ Internal ]
Delete all files in a directory. If Recurse is true, also delete all subdirectories recursively, and delete the original directory selected, that is, the entire directory vanishes.
CopyFile
Method CopyFile(FileName As %String = "", SourceDir As %String = "", TargetDir As %String = "") As %Status
Copy a file from a directory to another directory. This allows for example to place files in input directories. The default origin directory SourceDir is the unit test directory. The default destination directory TargetDir is the directory name specified by HL7InputDir.
CompareFiles
Method CompareFiles(FileName1 As %String = "", FileName2 As %String = "", Dir1 As %String = "", Dir2 As %String = "") As %Status
Compare the contents of two files and return $$$OK if they are equal, or a status code otherwise.
The default for FileName2 is the same name as FileName1 concatenated with _reference before the last file extension.
Examples:
FileName1 = MyFile.txt, default FileName2 = MyFile_Reference.txt
FileName1 = HL7Message_ADTA01, default FileName2 = HL7Message_ADTA01_Reference
The default for Dir1 is the directory name specified by HL7OutputDir.
The default for Dir2 is the unit test directory.
GetFullName
ClassMethod GetFullName(Dir As %String = "", FileName As %String = "") As %String
Given a directory and a file name, return a normalized full file name.
CheckEnvironment
Method CheckEnvironment() As %Status [ CodeMode = objectgenerator, Internal, Private ]
CheckParameterPRODUCTION
Method CheckParameterPRODUCTION() As %Status [ CodeMode = objectgenerator, Internal, Private ]
Enforce mandatory parameter PRODUCTION to be filled in.
GetMacros
ClassMethod GetMacros(Output MacroVars As %String) [ CodeMode = objectgenerator, Internal, Private ]
Define an array with the macros used in this class from the definitions in the production when available.
CheckNamespace
ClassMethod CheckNamespace() As %Status
Check if namespace is Interoperability or HealthShare enabled.
StartProduction
Method StartProduction() As %Boolean [ Internal, Private ]
StopProduction
Method StopProduction() As %Boolean [ Internal, Private ]
WaitForState
Method WaitForState(pState As %String) As %Status [ Internal, Private ]
TestControl
Method TestControl() As %Status [ Internal ]
Main execution flow control.