################################################################################
# TSL-LIBRARY: EMOS_FRM_stp_lib
################################################################################
# Copyright (C) 2000 EMOS Computer Consulting GmbH
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# For further information please contact:
#
# Dean Rajovic
# EMOS Computer Consulting GmbH
# Oskar-Messter-Straße 25
# 85737 Ismaning
# Germany
# tel.: +49 89 608 765-0
# mailto:drajovic@emos.de
# http://www.emos.de
################################################################################
# $Revision: 1.6 $
# $Author: drajovic $
# $Date: 2005/01/27 08:53:54 $
# $Source: C:/Archive/FRAMEWORK/EMOS_GPL/FRM/emos_frm_stp_lib/script,v $
# $NoKeywords: $
################################################################################
#/***
#* Defines an interface for efficient creation of test cases unsing the FRM
#* data tables.<p>
#* A typical FRM test case defines its test data across columns. This is the
#* plain oposite of the approach taken by Mercury and many other testers. The
#* benefit of defining test data column-wise is the ability to define many,
#* very many (up to 64k) test entries which makes very complex tests possible
#* (accross rows the limit is 256) which are comparatively easy to maintain
#* (no ugly right-left scrolling, you can see much more test data at once).
#* Additionally, you can (hypothetically) "pack" up to 254 of such complex tests
#* in a single Excel-file wich can greatly reduce the mess on your hard drive.<p>
#* A single test case contains three important parts:
#* <ul>
#* <li><code>name</code> content of the cell in the first row</li>
#* <li><code>sequence</code> a single cell containing the list of test steps
#* which are to be executed in a sequence</li>
#* <li><code>step(s)</code> an indexed block of rows containing test data</li>
#* </ul>
#* To keep things simple imagine a part of some application with two windows.
#* First window contains the list of user names and three buttons: New, Edit, Delete.
#* Imagine a table "User1.xls" with the following content:
#* <table border>
#* <tr> <th>IDX</th> <th>Name</th><th>1</th><th>2</th><th>3</th> </tr>
#* <tr> <td>x</td> <th>Testsequence</th> <td><pre>select_user
#*user_data</pre></td> <td><pre>select_user
#*user_data</pre></td> <td>select_user</td> </tr>
#* <tr> <td>x</td> <th>select_user</th> <th> </th> <th> </th> <th> </th> </tr>
#* <tr> <td> </td> <td>user list</td> <td></td> <td>dean</td> <td>dean</td> </tr>
#* <tr> <td> </td> <td>New/Edit/Delete</td> <td>New</td> <td>Edit</td> <td>Delete</td> </tr>
#* <tr> <td> </td> <td>delete? (OK/Cancel)</td> <td> </td> <td> </td> <td>OK</td> </tr>
#* <tr> <td>x</td> <th>user_data</th> <th> </th> <th>CHK</th> <th> </th> </tr>
#* <tr> <td> </td> <td>first name</td> <td>dean</td> <td>dean</td> <td> </td> </tr>
#* <tr> <td> </td> <td>last name</td> <td>rajovic</td> <td>rajovic</td> <td> </td> </tr>
#* <tr> <td> </td> <td>OK/Cancel</td> <td>OK</td> <td>Cancel</td> <td> </td> </tr>
#* </table>
#* This table contains three independent test cases named 1, 2 and 3.
#* Test 1 creates a new user....
#*/
static const COUNT = 0;
static const NEXT = 1;
static const IDX = 2;
static const DEFAULT_IDX_NAME = "Testvorgang";
# Dreidimensional: steps[ table, test, vorgang ]
static steps[];
#Dreidimensional: info[ table, test, info_type ]
static info[];
public __evalRC; # public variable used to communicate returne code for eval statements
#/**
#* Initialises the step iterator.
#* @param tid (in) table ID
#* @param test (in) column name
#* @param idx (in) (optional) index (i.e. table row) containing test steps [default: "Testvorgang"]
#* @return
#* E_OK: success
#* E_NOT_FOUND: no steps found (idx missing)
#* else: other error
#*/
public function FRM_STP_init_steps ( in tid, in test, in idx )
{
auto rc, val, count, arr[], i, msg;
if ( idx == "" )
idx = DEFAULT_IDX_NAME;
rc = FRM_get_cell( tid, test, idx, val );
if ( rc != E_OK )
{
msg = sprintf( "Teststeps cannot be determined; idx=[%s] rc=[%s]", idx, rc );
tl_step( "FRM_STP_init_steps", rc, msg );
return rc;
}
FRM_STP_clear_steps ( tid, test );
info[ tid, test, IDX ] = idx;
info[ tid, test, COUNT ] = 0;
info[ tid, test, NEXT ] = 1;
FRM_STP_load_steps( tid,test, idx, val );
# since 04/2001: load up to 99 additional test step cells
for( i=1; i<100; i++ )
{
if ( FRM_get_cell( tid, test, idx&i, val ) != E_OK )
break;
FRM_STP_load_steps( tid, test, idx&i, val );
}
return (info[ tid, test, COUNT ]==0) ? E_NOT_FOUND : E_OK;
}
#/**
#* Loads the content of a single table cell (steps separated by newline char)
#* into the internal step table.
#*/
static function FRM_STP_load_steps ( in tid, in test, in idx, in val )
{
auto arr[], count, i;
auto count2 =info[ tid, test, COUNT ];
count = split( val, arr, "\n" );
for( i=1; i<=count; i++ )
{
steps[ tid, test, count2+i ] = arr[i];
info[ tid, test, COUNT ] = count2+i;
}
}
#/**
#* Frees all references to the specified test.
#* @param tid (in) table ID
#* @param test (in) column name
#*/
public function FRM_STP_clear_steps ( in tid, in test )
{
auto i, idx = tid & ARRSEP & test;
for ( i in steps )
if ( match (i, idx) == 1 )
delete steps[i];
for ( i in info )
if ( match (i, idx) == 1 )
delete info[i];
}
#/**
#* Indicates whether there are steps to execute.
#* @param tid (in) table ID
#* @param test (in) column name
#* @return
#* TRUE: there are more steps; use FRM_STP_get_next_step() to get the next one
#* FALSE: all steps have been retrieved
#*/
public function FRM_STP_has_more_steps ( in tid, in test )
{
if ( ((tid, test, COUNT) in info) && ((tid, test, NEXT) in info) )
return ( info[tid, test, NEXT] <= info[tid, test, COUNT] );
return FALSE;
}
#/**
#* Returns the next step. Note that the <b>implicit steps</b> are never returned
#* with this command. They are simply executed by this function. The implicit
#* steps are:
#* <ul>
#* <li><code>LINK</code> executes a test in this or some other data table,
#* the test is atomatically loaded if necessary</li>
#* <li><code>LINA</code> same as LINK while loading ALL tests from the specified
#* table (sometimes impoves the overal performance)</li>
#* <li><code>LINX</code> executes a specified test from an inverted data table
#* (table in which tests are organised/indexed horizontally)</li>
#* <li><code>CALL</code> invokes an arbitrary WinRunner main test</li>
#* <li><code>EVAL</code> invokes an arbitrary WinRunner function</li>
#* <li><code>EXEC</code> evaluates a block of WinRunner functions</li>
#* <li><code>#</code> any step starting with # is treated as a comment</li>
#* <li>obsolete syntax is still valid</li>
#* <li><code><b>LNK:</b>script_name</code> links this test with another one
#* (loading only the specified tests)</li>
#* <li><code><b>LNA:</b>script_name</code> links this test with another one
#* (loading all tests in the referenced table)</li>
#* <li><code><b>EXE:</b>test step</code> exectutes all rows in the specified test block</li>
#* <li><code><b>###:</b>test step</code> comments out the given test step</li>
#* <li><code><<PAUSE>></code> pauses the test execution in interactive mode</li>
#* </ul>
#* @param tid (in) table ID
#* @param test (in) column name
#* @param step (out) name (idx) of the test step
#* @param mode (out) mode to be applied ( FRM_SET_MODE/FRM_CHK_MODE/FRM_GEN_MODE )
#* @return
#* E_OK: success; test step defined
#* E_FILE_EOF: no steps to be retreived
#* else: failure
#*/
public function FRM_STP_get_next_step ( in tid, in test, out step, out mode )
{
auto val, stp, nxt, hdr;
auto formatted, sep, arr[], count, i;
auto cmd, drv, tbl, tst;
auto rc = E_OK;
while ( 1 )
{
if ( !FRM_STP_has_more_steps ( tid, test ) )
return E_FILE_EOF;
nxt = info[ tid, test, NEXT ];
stp = strip_both( steps[tid, test, nxt ] );
# empty step or comment
if ( stp == "" || substr( stp,1,1 ) == "#" )
{
info[ tid, test, NEXT ] = nxt+1;
continue;
}
hdr = toupper( substr( stp,1,4 ) );
# look for keywords
switch ( hdr )
{
# shortcuts for SET/CHK/ATR/GEN modes
case "SET:":
case "CHK:":
case "ATR:":
case "GEN:":
# call to another FRM test
case "LINK":
case "LINA":
case "LINX":
# call to an arbitrary test script
case "CALL":
# executes an arbtrary WinRunner command
case "EVAL":
# executes a block of WinRunner commands
case "EXEC":
# old-fashined links (still supported)
case "LNK:":
case "LNA:":
# old-fashioned EXEC
case "EXE:":
formatted = (length(stp) > 4 ? TRUE : FALSE);
break;
default:
formatted = FALSE;
break;
}
info[ tid, test, NEXT ] = nxt+1;
if ( !formatted )
{
step = stp;
if ( FRM_STP_is_internal_step( step, tid ) )
continue;
wrlog_block_start ( stp );
if ( FRM_STP_is_dummy_step_mode() )
{
wrlog_block_stop ( stp, 0 );
continue;
}
break;
}
switch ( hdr )
{
case "SET:":
mode = FRM_SET_MODE;
step = substr( stp, 5 );
wrlog_block_start ( step );
if ( FRM_STP_is_dummy_step_mode() )
{
wrlog_block_stop ( step, 0 );
continue;
}
break;
case "CHK:":
mode = FRM_CHK_MODE;
step = substr( stp, 5 );
wrlog_block_start ( step );
if ( FRM_STP_is_dummy_step_mode() )
{
wrlog_block_stop ( step, 0 );
continue;
}
break;
case "ATR:":
mode = FRM_ATR_MODE;
step = substr( stp, 5 );
wrlog_block_start ( step );
if ( FRM_STP_is_dummy_step_mode() )
{
wrlog_block_stop ( step, 0 );
continue;
}
break;
case "GEN:":
mode = FRM_GEN_MODE;
step = substr( stp, 5 );
wrlog_block_start ( step );
if ( FRM_STP_is_dummy_step_mode() )
{
wrlog_block_stop ( step, 0 );
continue;
}
break;
case "LINK":
case "LINA":
case "LINX":
wrlog_block_start ( stp );
rc = FRM_STP_parse_link( stp, tid, drv, tbl, tst );
wrlog_block_stop ( stp, rc );
if ( rc != E_OK ) break;
wrlog_test_start ( tst, tbl, drv );
rc = FRM_STP_eval_link( hdr, tid, drv, tbl, tst );
wrlog_test_stop ( stp, rc );
if ( rc != E_OK ) break;
continue;
case "CALL":
wrlog_block_start ( stp );
if ( !FRM_STP_is_dummy_step_mode() )
rc = FRM_STP_eval_call( stp );
wrlog_block_stop ( stp, rc );
if ( rc != E_OK ) break;
continue;
case "EVAL":
wrlog_block_start ( stp );
if ( !FRM_STP_is_dummy_step_mode() )
rc = FRM_STP_eval( substr( stp, 6 ) );
wrlog_block_stop ( stp, rc );
continue;
case "EXEC":
mode = FRM_SET_MODE;
step = substr( stp, 6 );
wrlog_block_start ( stp );
if ( !FRM_STP_is_dummy_step_mode() )
rc = FRM_STP_exec( tid, test, step, mode );
wrlog_block_stop ( stp, rc );
if ( rc != E_OK ) break;
continue;
# KEPT ONLY FOR THE SAKE OF COMPATIBILITY WITH THE OLD DATA TABLES
# use LINK and/or LINA instead!
case "LNK:":
case "LNA:":
mode = FRM_SET_MODE;
step = substr( stp, 5 );
wrlog_block_start ( stp );
wrlog_block_stop ( stp, 0 );
if ( hdr == "LNK:" )
rc = FRM_STP_link( tid, test, step, mode, FALSE );
else
rc = FRM_STP_link( tid, test, step, mode, TRUE );
# propagate errors up the call chain
if ( rc != E_OK ) break;
continue;
case "EXE:":
mode = FRM_SET_MODE;
step = substr( stp, 5 );
wrlog_block_start ( stp );
if ( !FRM_STP_is_dummy_step_mode() )
rc = FRM_STP_exec( tid, test, step, mode );
wrlog_block_stop ( stp, rc );
if ( rc != E_OK ) break;
continue;
default:
# internal error if you land here
rc = E_GENERAL_ERROR;
break;
}
tl_step( "STEP", rc, sprintf( "[%s] failed returning [rc=%s]", stp, rc ) );
return rc;
}
}
#/**
#* Parses the call to another FRM test, i.e. call driver( table, test ).
#* SYNTAX:
#* <code>LINK<SEP>[driver]<SEP>[table]<SEP>test</code>
#* or
#* <code>LINA<SEP>[driver]<SEP>[table]<SEP>test</code>
#*/
static function FRM_STP_parse_link ( in line, in curr_tid, out drv, out tbl, out tst )
{
auto sep, arr[], count, i;
auto dir, file;
sep = substr( line, 5, 1 );
count = split( line, arr, sep );
if ( count != 4 )
return E_ILLEGAL_PARAMETER;
# driver is optional if new driver logic is used
drv = strip_both( arr[2] );
if ( drv == "" && !FRM_DRV_is_new_test_driver() )
return E_ILLEGAL_PARAMETER;
# test name must be specified
tst = strip_both( arr[4] );
if ( tst == "" )
return E_ILLEGAL_PARAMETER;
tbl = strip_both( arr[3] );
# table name is optional (default: current table)
# if we don't return tbl, then curr_tid should be used by the caller
if ( tbl == "" )
return E_OK;
# if table only contains the sheet name (i.e. starts with name sep),
# then substitute the full path of the current table
if ( substr(tbl, 1, 1) == ddt_get_name_sep() )
{
split_path( FRM_get_filename(curr_tid), dir, file, "\\" );
tbl = join_path( dir, file, "\\" ) & tbl;
return E_OK;
}
# otherwise if table name supplied (eventually with sheet name),
# then table name MUST be absolute and backslash-separated
tbl = replace(tbl, "/", "\\");
if ( match( tbl, " *[A-Za-z]:" ) != 1 && substr( tbl, 1, 1 ) != "\\" )
{
split_path( FRM_get_name(curr_tid), dir, file, "\\" );
tbl = join_path( dir, tbl, "\\" );
}
return E_OK;
}
#/**
#* Executes the link call.
#* SYNTAX:
#* <code>LINK<SEP>[driver]<SEP>[table]<SEP>test</code>
#* or
#* <code>LINA<SEP>[driver]<SEP>[table]<SEP>test</code>
#*/
static function FRM_STP_eval_link( in typ, in curr_tid, in drv, in tbl, in tst )
{
auto rc, tid, cmd;
rc = E_OK;
switch ( typ )
{
# loads only the required column (if not loaded yet)
# and executes the test with that column
case "LINK":
if ( tbl == "" )
{
tid = curr_tid;
rc = FRM_load_test( tid, tst );
break;
}
if ( FRM_is_table_open( tbl, tid ) )
{
rc = FRM_load_test( tid, tst );
break;
}
rc = FRM_open( tbl, tst, tid );
break;
# loads all columns if required column not loaded yet
# and executes the test with specified column
case "LINA":
if ( tbl == "" )
{
tid = curr_tid;
rc = FRM_is_parameter( tid, tst );
if ( rc != E_OK )
{
rc = FRM_close( tid );
rc = FRM_open( tbl, "<<ALL>>", tid );
}
break;
}
if ( FRM_is_table_open( tbl, tid ) )
{
rc = FRM_is_parameter( tid, tst );
if ( rc != E_OK )
{
rc = FRM_close( tid );
rc = FRM_open( tbl, "<<ALL>>", tid );
}
break;
}
rc = FRM_open( tbl, "<<ALL>>", tid );
break;
# loads all columns if table not loaded yet
# and executes the test assuming the tests are spread across rows
case "LINX":
if ( tbl == "" )
{
tid = curr_tid;
break;
}
if ( FRM_is_table_open( tbl, tid ) )
{
break;
}
rc = FRM_open( tbl, "<<ALL>>", tid );
break;
default:
# should never happen
rc = E_GENERAL_ERROR;
}
if ( rc != E_OK )
return rc;
if ( FRM_DRV_is_new_test_driver() )
{
return FRM_DRV_test_driver( drv, tid, tst );
}
else
{
cmd = sprintf( "treturn call_close \"%s\" ( \"%s\", \"%s\" );", drv, tid, tst );
debug_msg( sprintf( "%s: %s ...", typ, cmd ) );
rc = eval( cmd );
cmd = sprintf( "treturn call_close \"%s\" ( \"%s\", \"%s\" );", drv, tid, tst );
debug_msg( sprintf( "%s: %s [rc=%s]", typ, cmd, rc ) );
# we always return E_OK because test driver that was called
# sould have handled the error anyway, if we had returned the rc,
# we would cause all other recursive calls of (i.e. links to) the
# same test diver to fail even if they run fine
return E_OK;
}
}
#/**
#* Parses the call to an arbitrary test, i.e. call test ( [param]* )
#* SYNTAX:
#* <code>CALL<SEP>test[<SEP>arg]*</code>
#*/
static function FRM_STP_eval_call ( in line )
{
auto rc, sep, cmd;
auto arr[], count, i;
sep = substr( line, 5, 1 );
count = split( line, arr, sep );
if ( count < 2 )
return E_ILLEGAL_PARAMETER;
cmd = sprintf( "treturn call_close \"%s\" (", arr[2] );
for ( i=3; i<=count; i++ )
{
cmd = sprintf( "%s%s \"%s\"", cmd, (i>3 ? "," : ""), arr[i] );
}
cmd = cmd & " );";
debug_msg( sprintf( "CALL: %s; ...", cmd ) );
rc = eval( cmd );
debug_msg( sprintf( "CALL: %s; [rc=%s]", cmd, rc ) );
return rc;
}
#/**
#* Executes a block of TSL-statements defined in the given block.
#*/
static function FRM_STP_exec ( in tid, in test, in idx, in mode )
{
auto rc, obj, val, row;
rc = FRM_init_block( tid, test, idx, mode );
if ( rc != E_OK )
return rc;
rc = FRM_get_current_row( tid, row );
while ( rc == E_OK || rc == E_FRM_SKIP )
{
row++;
rc = FRM_get( tid, FRM_COL_NAME, obj, row );
if ( rc != E_OK && rc != E_FRM_SKIP ) break;
if ( match( obj, "<<[eE][nN][dD][eE]*>>" ) ) break;
rc = FRM_get( tid, test, val, row );
# if ( rc == E_FRM_SKIP ) continue;
if ( rc != E_OK ) break;
FRM_STP_eval( val );
}
return (rc==E_FRM_SKIP)? E_OK : rc;
}
#/**
#* Evaluates an arbitrary command. You can specify multiple commands by separating them
#* with semicolins. The outcome of the eval statement is expected to be passed by the
#* global variable __evalRC (the assignment has to be done by the evalueated code.
#* For example use code like this "__evalRc = some_function();" in order to let
#* framework evaluate your return code. If you don't assign any value to __evalRC,
#* then eval will erturn E_OK.
#* @param cmd (in) command(s) to be executed (it is not necessary to place the
#* semicolon at the end of the last command but you must separate multiple
#* commands with the semicolon, though).
#*/
static function FRM_STP_eval ( in cmd )
{
extern __evalRC;
debug_msg( sprintf( "EVAL: %s; ...", cmd ) );
__evalRC = E_OK;
eval( cmd & ";" );
debug_msg( sprintf( "EVAL: %s; [done]", cmd ) );
return FRM_rc2( __evalRC, cmd );
}
static function FRM_STP_eval_old ( in cmd )
{
auto count, arr[], i;
count = split( cmd, arr, ";" );
for( i=1; i<=count; i++ )
{
debug_msg( sprintf( "EVAL: %s; ...", arr[i] ) );
eval( arr[i] & ";" );
debug_msg( sprintf( "EVAL: %s; [done]", arr[i] ) );
}
}
#/**
#* OBSOLETE: KEPT ONLY FOR THE SAKE OF COMPATIBILITY WITH THE OLD DATA TABLES.
#* Indicates an internal step (step containg special command).
#* @param step (in) the step to be evaluated
#* @param tid (in) id of the active test table
#* @return
#* TRUE: internal
#* FALSE: "ordinary" step
#* @deprecated
#*/
static function FRM_STP_is_internal_step( in step, in tid )
{
switch ( toupper( step ) )
{
case "<<PAUSE>>":
wrlog_block_start ( step );
if ( !FRM_STP_is_dummy_step_mode() )
pause( "Test interrupted due to <<PAUSE>>" );
wrlog_block_stop ( step, 0 );
break;
default:
return FALSE;
}
return TRUE;
}
#/**
#* OBSOLETE: KEPT ONLY FOR THE SAKE OF COMPATIBILITY WITH THE OLD DATA TABLES.
#* Executes another test(s) in the same or some other table(s) running the same
#* or some other tsl script.
#*@deprecated
#*/
static function FRM_STP_link ( in tid, in test, in idx, in mode, in load_all )
{
auto rc, row, nam, val, obj, table2, tid2, dir, file, cmd;
auto no_table, no_test;
auto p1, p2;
if ( load_all == "" )
load_all = FALSE;
rc = FRM_init_block( tid, test, idx, mode );
if ( rc != E_OK )
return rc;
rc = FRM_get_current_row( tid, row );
while ( rc == E_OK || rc == E_FRM_SKIP )
{
row++;
rc = FRM_get( tid, FRM_COL_NAME, obj, row );
if ( rc != E_OK ) break;
if ( match( obj, "<<[eE][nN][dD][eE]*>>" ) ) break;
rc = FRM_get( tid, test, val, row );
if ( rc == E_FRM_SKIP ) continue;
if ( rc != E_OK ) break;
no_table = ( match( obj, "<.*>" ) )? TRUE : FALSE;
no_test = ( match( val, "<.*>" ) )? TRUE : FALSE;
if ( no_table || no_test )
{
p1 = substr( obj, 2, length(obj)-2 );
p2 = substr( val, 2, length(val)-2 );
if ( p1 == "" && p2 == "" )
cmd = "treturn call_close \"" & idx & "\" ();";
if ( p1 == "" && p2 != "" )
cmd = "treturn call_close \"" & idx & "\" (\"\",\"" & p2 & "\");";
if ( p1 != "" && p2 == "" )
cmd = "treturn call_close \"" & idx & "\" (\"" & p1 & "\");";
if ( p1 != "" && p2 != "" )
cmd = "treturn call_close \"" & idx & "\" (\"" & p1 & "\",\"" & p2 & "\");";
wrlog_block_start ( cmd );
rc = eval( cmd );
wrlog_block_stop ( cmd, rc );
continue;
}
#relative Pfade werden absolut
if ( !match( obj, "[A-Za-z]:" ) && substr( obj, 1, 1 ) != "\\" )
{
split_path( replace(FRM_get_name(tid), "/", "\\"), dir, file, "\\" );
table2 = join_path( dir, obj, "\\" );
}
else
{
table2 = obj;
}
if ( load_all )
{
if ( FRM_is_open( table2 ) )
{
tid2 = FRM_get_tid( table2 );
rc = FRM_is_parameter( tid2, val );
if ( rc != E_OK )
{
rc = FRM_close( tid2 );
rc = FRM_open( table2, "<<ALL>>", tid2 );
}
}
else
{
rc = FRM_open( table2, "<<ALL>>", tid2 );
}
}
else
{
if ( FRM_is_open( table2 ) )
rc = FRM_load_test( FRM_get_tid(table2), val );
else
rc = FRM_open( table2, val, tid2 );
}
if ( rc != E_OK )
{
tl_step( "FRM_STP_link", rc, "table=["&table2&"], RC=["&rc&"]" );
break;
}
if ( FRM_DRV_is_new_test_driver() )
{
return FRM_DRV_test_driver( idx, tid2, val );
}
else
{
cmd = "treturn call_close \"" & idx & "\" ( \""&tid2&"\", \""&val&"\" );";
wrlog_test_start ( val, table2, idx );
rc = eval( cmd );
wrlog_test_stop ( val, rc );
}
}
return rc;
}
#/**
#* Flag for dummy step mode. This mode can be used for the purpose of documenting
#* the test suite. With this mode EMOS Framework only pretends to execute the test
#* suite. It navigates through all test cases all the way to the individual
#* test block but it does not execute them.
#*/
static emos_dummy_step_mode = FALSE;
#/**
#* Turns dummy test mode on/off.
#* @param mode (in) true/false
#* @return the sam as the input parameter mode
#*/
public function FRM_STP_set_dummy_step_mode( in mode )
{
return emos_dummy_step_mode = mode;
}
#/**
#* Indicates the dummy test mode.
#* @return TRUE: dummy mode on, FALSE: dummy mode off
#*/
public function FRM_STP_is_dummy_step_mode( )
{
return emos_dummy_step_mode;
}