Using SAFS Flow Control Commands

Doc Release: 10.14.2010

Goto:Exit Commands, Branching Commands, Error Recovery and Control

Note that a BlockID is the name given a particular record that is a BlockID record in a test table.  It identifies a location in a test table and NOT truly a block of associated code.  These BlockID records have the Record Type "B" in their first field. The second field is the name or BlockID for that record and is used as the target for these Flow Control Commands.

It is important to note the way in which SAFS drivers seek a named Block Id.

When a Driver is instructed to branch to a specific BlockID--whether it be a custom Driver, or the SAFSINPUT service--it searches first from the current record and towards the END of the file.  It does NOT search forward from the current record towards the start of the file.

If the target BlockID is not found when the End Of File is reached, the search will then continue from the first line of the file and thru subsequent lines until the BlockID is found, or until the test record that initiated the request to branch is reached.

Below is an example, for clarity:
# RTCOMMAND PARAM PARAM PARAM
1 B Continue      
2 T Do Something      
3 C OnLessThanGotoBlockID Continue ^Value1 ^Value2
4 C GotoBlockID Finished    
5 B Continue      
6 T Do Something      
7 C OnLessThanGotoBlockID Continue ^Value1 ^Value2
8          
9 B Loop      
10 T Do Something      
11 C OnLessThanGotoBlockID Loop ^Value1 ^Value2
12 C GotoBlockID Continue    
13 B Finished     

Goto:Branching Commands, Error Recovery and Control, Back to Top

Exit/Abort Commands
ExitTable Exit the current Step, Suite, or Cycle table.
ExitSuite Exit the current Step table AND the current Suite.
ExitCycle Exit the current Step table AND the Suite AND Cycle.

Examples
C, ExitTable Exit the current Step, Suite, or Cycle table.
C, ExitSuite Exit the current Step AND abort the Suite.
C, ExitCycle Exit the current Step and/or Suite AND abort the Cycle.

The Exit commands are used to force an exit of the current table. They help bypass records or tests that we do not wish to execute. Such is the case when we separate the table into separate blocks with BlockID references. In some of these situations, we do not want the drivers to continue into the next block. Instead, we can use these commands to exit the test table. They have no parameters.

ExitTable will cause the table containing the command to immediately exit. This is valid for any Step, Suite, or Cycle table. If a BlockID was set with SetExitTableBlock for the current test level, then execution will transfer to that block prior to the actual exit. This allows us to perform any required cleanup we wish to do upon exiting the test table.

ExitSuite will cause the Step or Suite table containing the command to immediately exit. This command is not really valid inside a Cycle level test table. In a Suite table this is no different than issuing an ExitTable command. However, in a Step table this command allows us to not only exit the current Step table, but also to exit/abort the Suite that called the Step table. With this we can abort a larger test or process that we know just isn't going to work.

As with the ExitTable command, any BlockID set with SetExitTableBlock will be executed at both the Step and Suite levels.

ExitCycle will cause the Step, Suite, or Cycle table containing the command to immediately exit. In a Cycle table this is no different than issuing an ExitTable command. However, in a Step table this command allows us to not only exit the current Step table, but also to exit/abort the current Suite and Cycle. With this we can abort the entire test or Cycle process if necessary.

As with the ExitTable command, any BlockID set with SetExitTableBlock will be executed at the Step, Suite, and Cycle levels.


Goto:Exit Commands, Error Recovery and Control, Back to Top

Branching Commands
GotoBlockID Jump to a specific BlockID record.
OnEqualGotoBlockID Jump to a specific BlockID record if two values are equal.

Examples
C, GotoBlockID, ABlockID Jump to the BlockID record named "ABlockID".
C, OnEqualGotoBlockID, ABlockID, Value1, Value2 Jump to a specific BlockID record if two text values are equal.
C, OnEqualGotoBlockID, ABlockID, ^AVariable, Value2 Jump to a specific BlockID record if a variable value matches a text value.
C, OnEqualGotoBlockID, ABlockID, ^AVariable, ^AnotherOne Jump to a specific BlockID record if two variable values match.

GotoBlockID forces a jump to the blockID specified. A blockID is a record in the table with a RecordType of "B"--a BlockID record. The second field in that BlockID record contains the name assigned to that record in the table and acts as a target blockID for these flow control commands.

OnEqualGotoBlockID allows a simple comparison to cause a jump to occur if two values match. These can be two literal text values, or literal text compared against the value of a DDVariable, or a comparison of two DDVariable values. Like most all other fields in our test tables, the fields used for the comparison are extracted as Trimmed Quoted strings. That means that leading and trailing whitespace is removed unless enclosed by double-quote marks. Outermost double-quote marks are also removed. Thus, if leading or trailing whitespace is not significant, the double-quote marks are optional. Of course, DDVariables will not be found inside double-quote marks. Inside the quotes they would be treated as literal text.

When used in conjunction with an AssignPropertyVariable test record in GenericMasterFunctions we can extract an object's property value into a DDVariable and then perform a branch based on the success or failure of the comparison. Note, however, this comparison is NOT a test comparison and will not generate a test failure. Use a VerifyProperty test record to perform a comparison that records a test result.

Other possibilities include branching based on DDVariable values that were assigned by prior tests, or by variable value changes caused by scripts. For example, a Cycle could call a Suite which performs different processing based on DDVariable values set by the Cycle.


Goto:Exit Commands, Branching Commands, Back to Top

Error Recovery and Control Commands
SetExitTableBlock Set or Clear the BlockID to execute when ExitTable is executed.
SetGeneralScriptFailureBlock Set or Clear the BlockID to execute when a General Failure occurs.
SetScriptWarningBlock Set or Clear the BlockID to execute when a Warning occurs.
SetInvalidFileIOBlock Set or Clear the BlockID to execute when an File IO error occurs.
SetScriptNotExecutedBlock Set or Clear the BlockID to execute when a "ScriptNotExecuted" error occurs.
SetNoScriptFailureBlock Set or Clear the BlockID to execute if no error is encountered.

Note, these error conditions are the status conditions defined in SAFS sourcecode. While many of these contain the substring "Script" in them, these conditions are generally not strictly associated with the execution of a tool script, per se. "Script" and "test record" or "test table" are interchangeable in this regard.

Examples
C, SetExitTableBlock, AExitHandler Set the block named AExitHandler to execute if/when ExitTable is executed.
C, SetExitTableBlock, "" Reset so no special handler is invoked if/when ExitTable is executed.

These commands are used to identify error handler blocks within the test tables. When a command has set an error handler block, that block is executed if/when that status condition is satisfied. The check for that status condition is performed at the end of processing for each record. Not just test records, but ALL valid record types. Comments and blank lines are not considered valid records. The syntax for setting and resetting for each command is the same as the example shown.

Each test level maintains its own settings. So a Set command performed at the Suite level does not affect any settings done for the Cycle or Step levels.

With the exception of SetNoScriptFailureBlock, these settings are NOT automatically reset on exiting any given table. This allows the test developer to implement a standard set of test table templates that share common error recovery handlers. If this is not the case, you can implement an exit handler block that performs cleanup when exiting the table. Use SetExitTableBlock to set the exit handler blockID to enable that processing. If necessary, remember to clear or reset that blockID to nothing within the exit handler itself so that subsequent tables don't attempt to invoke a handler they might not contain. This may apply to all of the error recovery settings you might make within any given table.

The SetNoScriptFailureBlock setting is reset immediately upon its first invocation. After all, we expect most of our records to execute with no failure. So, the command is best used immediately before the record you expect to have an issue with.

The SetInvalidFileIOBlock setting is used to handle File IO errors that may have occurred somewhere in the processing of a record, or test, or script. It does not generally respond to File IO errors with the table itself because that means the table is not getting processed and the block could never get executed. Instead, it reacts to File IO errors that occur external to the test table that is being processed.

ScriptNotExecuted is generally encountered when an error occurs that prevents the normal execution of a record. For example, a Script Command Failure that prevents a Driver Command or Component Function from executing. Or, the failed invocation of SuiteDriver or StepDriver from a higher test level. It is not intended to be an indication of a failure of a tool script invoked from a CallScript command.

For the average low-level test developer, the most commonly used error recovery and control commands would be handling GeneralScriptFailure and ExitTable processing.

Goto:Exit Commands, Branching Commands, Error Recovery and Control, Back to Top