LTP GCOV extension - code coverage report
Current view: directory - src/services/scripter_module - min_scripter_if.c
Test: min.info
Date: 2009-06-18 Instrumented lines: 1448
Code covered: 64.1 % Executed lines: 928

       1                 : /*
       2                 :  * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
       3                 :  * and/or its subsidiary(-ies).
       4                 :  * Contact: Konrad Marek Zapalowicz
       5                 :  * Contact e-mail: DG.MIN-Support@nokia.com
       6                 :  * 
       7                 :  * This program is free software: you can redistribute it and/or modify it 
       8                 :  * under the terms of the GNU General Public License as published by the Free 
       9                 :  * Software Foundation, version 2 of the License. 
      10                 :  * 
      11                 :  * This program is distributed in the hope that it will be useful, but WITHOUT 
      12                 :  * ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or 
      13                 :  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General  Public License for
      14                 :  * more details. You should have received a copy of the GNU General Public 
      15                 :  * License along with this program. If not,  see 
      16                 :  * <http://www.gnu.org/licenses/>.
      17                 :  */
      18                 : 
      19                 : 
      20                 : /**
      21                 :  *  @file       min_scripter_if.c
      22                 :  *  @version    0.1
      23                 :  *  @brief      This file contains implementation of MIN Scripter interface.
      24                 :  */
      25                 : 
      26                 : /* ------------------------------------------------------------------------- */
      27                 : /* INCLUDE FILES */
      28                 : #include <sched.h>
      29                 : #include <ctype.h>
      30                 : 
      31                 : #include <dllist.h>
      32                 : #include <min_lego_interface.h>
      33                 : #include <min_scripter_if.h>
      34                 : #include <scripter_plugin.h>
      35                 : #include <scripter_common.h>
      36                 : #include <test_module_api.h>
      37                 : #include <min_test_interference.h>
      38                 : /* ------------------------------------------------------------------------- */
      39                 : /* EXTERNAL DATA STRUCTURES */
      40                 : /* None */
      41                 : 
      42                 : /* ------------------------------------------------------------------------- */
      43                 : /* EXTERNAL GLOBAL VARIABLES */
      44                 : 
      45                 : /* ------------------------------------------------------------------------- */
      46                 : /* EXTERNAL FUNCTION PROTOTYPES */
      47                 : /* ------------------------------------------------------------------------- */
      48                 : extern int      scripter_init (minScripterIf * scripter_if);
      49                 : /* ------------------------------------------------------------------------- */
      50                 : /* GLOBAL VARIABLES */
      51                 : /* ------------------------------------------------------------------------- */
      52                 : TSBool          stprun = ESFalse; /**< exit flag for scripted test process */
      53                 : TSBool          ctprun = ESFalse; /**< exit flag for combined test process */
      54                 : struct scripter_mod_ scripter_mod;
      55                 : DLList         *tp_handlers = INITPTR;  /**< handles to tmapi fctions from TC*/
      56                 : DLList         *allowedresults = INITPTR; /**< Allowed  result codes. */
      57                 : DLList         *allowederrors = INITPTR;  /**< Allowed error codes. */
      58                 : DLList         *defines = INITPTR;  /**< Contains defintions            */
      59                 : DLList         *variables = INITPTR;/**< Contains scripter variables */
      60                 : DLList         *interference_handles = INITPTR;/**<test interference "instances"*/
      61                 : /* ------------------------------------------------------------------------- */
      62                 : /* CONSTANTS */
      63                 : /* None */
      64                 : 
      65                 : /* ------------------------------------------------------------------------- */
      66                 : /* MACROS */
      67                 : /** Reports scripter run time error with one argumen 
      68                 :  * @param __errstr__ the error string
      69                 :  * @param __errarg__ error argument string
      70                 :  */
      71                 : #define SCRIPTER_RTERR_ARG(__errstr__,__errarg__) \
      72                 : do {                                                                       \
      73                 :         MIN_ERROR (__errstr__,__errarg__);                                 \
      74                 :         snprintf (scripter_mod.script_tcr.desc_, MaxTestResultDescription, \
      75                 :                   "%s:%s:%d - %s [%s]",        __FILE__,__FUNCTION__, __LINE__,  \
      76                 :                   __errstr__, __errarg__);                                 \
      77                 :         scripter_mod.error_occured = ESTrue;                               \
      78                 :         scripter_mod.script_tcr.result_ = TP_CRASHED;                      \
      79                 : } while (0)
      80                 : 
      81                 : /** Reports scripter run time error
      82                 :  * @param __errstr__ the error string
      83                 :  */
      84                 : #define SCRIPTER_RTERR(__errstr__) \
      85                 : do {                                                                       \
      86                 :         MIN_ERROR (__errstr__);                            \
      87                 :         snprintf (scripter_mod.script_tcr.desc_, MaxTestResultDescription, \
      88                 :                   "%s:%s:%d - %s",__FILE__, __FUNCTION__, __LINE__,        \
      89                 :                   __errstr__);                                             \
      90                 :         scripter_mod.error_occured = ESTrue;                               \
      91                 :         scripter_mod.script_tcr.result_ = TP_CRASHED;                      \
      92                 : } while (0)
      93                 : 
      94                 : /* ------------------------------------------------------------------------- */
      95                 : /* LOCAL GLOBAL VARIABLES */
      96                 : /* None */
      97                 : 
      98                 : /* ------------------------------------------------------------------------- */
      99                 : /* LOCAL CONSTANTS AND MACROS */
     100                 : /* None */
     101                 : 
     102                 : /* ------------------------------------------------------------------------- */
     103                 : /* MODULE DATA STRUCTURES */
     104                 : /* ------------------------------------------------------------------------- */
     105                 : struct scripter_mod_ {
     106                 :         minScripterIf  min_scripter_if;/**< Interface to parser plugin     */
     107                 :         DLList         *req_events;      /**< Local requested events.        */
     108                 :         DLList         *tp_details;      /**< Global list of loaded modules. */
     109                 :         int             mqid;            /**< Message Queue Id               */
     110                 :         TSBool          script_finished; /**< Set when script end  noticed   */
     111                 :         TSBool          tclass_exec;     /**< Set while class func running   */
     112                 :         TSBool          paused;          /**< Set when paused from the cui   */
     113                 :         TSBool          extif_pending;   /**< Waiting resp to ext cont. msg  */
     114                 :         TSBool          event_pending;   /**< Waiting for event ind          */
     115                 :         TSBool          error_occured;   /**< Run time error flag            */
     116                 :         unsigned int    extif_remote;    /**< number of remote test cases    */
     117                 :         char           *testcomplete;    /**< Complete test flag             */
     118                 :         TSBool          canceliferror;   /**< Cancels script if error in test*/
     119                 :         unsigned long   sleep;           /**< Sleep enabled flag if this > 0 */
     120                 :         struct timeval  time;            /**< Used for sleep realization     */
     121                 :         TestCaseResult  script_tcr;      /**< Scripted test case result      */
     122                 :         char           *expected_var;    /**< Variable we are expecting      */
     123                 :         int             shm_id;          /**< Shared segment ID              */
     124                 : };
     125                 : 
     126                 : typedef struct {
     127                 :         char           *name_;
     128                 :         TSBool          initialized_;
     129                 :         char           *value_;
     130                 : } ScriptVar;
     131                 : 
     132                 : typedef struct {
     133                 :         char                    name_[32];
     134                 :         testInterference        *instance_;
     135                 : } InterfHandle;
     136                 : 
     137                 : /* ------------------------------------------------------------------------- */
     138                 : /* LOCAL FUNCTION PROTOTYPES */
     139                 : /* ------------------------------------------------------------------------- */
     140                 : /** Used for finding class name on list. */
     141                 : LOCAL int       _findclass (const void *a, const void *b);
     142                 : /* ------------------------------------------------------------------------- */
     143                 : /** Used for finding test process of specified pid. */
     144                 : LOCAL int       _findpid (const void *a, const void *b);
     145                 : /* ------------------------------------------------------------------------- */
     146                 : /** Used for finding test process of specified status. */
     147                 : LOCAL int       _findstatus (const void *a, const void *b);
     148                 : /* ------------------------------------------------------------------------- */
     149                 : /** Used for finding test process of specified testid. */
     150                 : LOCAL int       _findid (const void *a, const void *b);
     151                 : /* ------------------------------------------------------------------------- */
     152                 : /** Used for finding specified allowed result and also allowed error code */
     153                 : LOCAL int       _findallowedresult (const void *a, const void *b);
     154                 : /* ------------------------------------------------------------------------- */
     155                 : /** Fetches pointer to run_method from library and stores it in safe place.
     156                 :  *  @param dllname [in] name of the library from which pointer is fetched.
     157                 :  *  @param classname [in] mnemonic for that library.
     158                 :  */
     159                 : LOCAL void      fetch_ptr2run (const char *dllname, const char *classname);
     160                 : /* ------------------------------------------------------------------------- */
     161                 : /** Reads possible optional parameter for the RUN keyword. 
     162                 :  *  @param mip [in] line with possible parameters. 
     163                 :  *  @param ep [out] structure that contains extra parameters */
     164                 : LOCAL void      read_optional_run_params (MinItemParser * mip,
     165                 :                                           ExtraParams * ep);
     166                 : /* ------------------------------------------------------------------------- */
     167                 : /** Message handling function. Calls appropiate message handler.
     168                 :  *  @param mqid [in] message queue id.
     169                 :  *  @param msg [in] buffer that contains message to be handled.
     170                 :  */
     171                 : LOCAL void      uengine_handle_message (int mqid, const MsgBuffer * msg);
     172                 : /* ------------------------------------------------------------------------- */
     173                 : /** Handles MSG_RET
     174                 :  *  @param mqid [in] message queue id.
     175                 :  *  @param param [in] test result code.
     176                 :  *  @param message [in] description of the test result.
     177                 :  */
     178                 : LOCAL void      uengine_handle_ret (int mqid, int param, const char *message,
     179                 :                                     long sender);
     180                 : /* ------------------------------------------------------------------------- */
     181                 : /** Handles indication event.
     182                 :  *  @param mqid [in] message queue id.
     183                 :  *  @param msg [in] buffer that contains message to be handled.
     184                 :  */
     185                 : LOCAL void      uengine_handle_event_ind (int mqid, const MsgBuffer * msg);
     186                 : /* ------------------------------------------------------------------------- */
     187                 : /** Handles MSG_SNDRCV
     188                 :  *  @param mqid [in] message queue id.
     189                 :  *  @param msg [in] buffer that contains message to be handled.
     190                 :  */
     191                 : LOCAL void      uengine_handle_sndrcv (int mqid, const MsgBuffer * msg);
     192                 : /* ------------------------------------------------------------------------- */
     193                 : /** Handles MSG_END message.
     194                 :  *  @param mqid [in] message queue id.
     195                 :  *  @param msg [in] buffer that contains message to be handled.
     196                 :  */
     197                 : LOCAL void      uengine_handle_end (int mqid, const MsgBuffer * msg);
     198                 : /* ------------------------------------------------------------------------- */
     199                 : /** Handles MSG_PAUSE message.
     200                 :  *  @param mqid [in] message queue id.
     201                 :  *  @param msg [in] buffer that contains message to be handled.
     202                 :  */
     203                 : LOCAL void      uengine_handle_pause (int mqid, const MsgBuffer * msg);
     204                 : /* ------------------------------------------------------------------------- */
     205                 : /** Handles MSG_RESUME message.
     206                 :  *  @param mqid [in] message queue id.
     207                 :  *  @param msg [in] buffer that contains message to be handled.
     208                 :  */
     209                 : LOCAL void      uengine_handle_resume (int mqid, const MsgBuffer * msg);
     210                 : /* ------------------------------------------------------------------------- */
     211                 : /** Handles abort message.
     212                 :  *  @param mqid [in] message queue id.
     213                 :  *  @param msg [in] buffer that contains message to be handled.
     214                 :  */
     215                 : LOCAL void      uengine_handle_stop (int mqid, const MsgBuffer * msg);
     216                 : /* ------------------------------------------------------------------------- */
     217                 : /** Handles external controller message.
     218                 :  *  @param mqid [in] message queue id.
     219                 :  *  @param msg [in] buffer that contains message to be handled.
     220                 :  */
     221                 : LOCAL void      uengine_handle_extif (int mqid, const MsgBuffer * msg);
     222                 : /* ------------------------------------------------------------------------- */
     223                 : /** handles external controller message type EResponseSlave
     224                 :  *  @param result [in] the result of the operation: 1 = Ok, 0 = Error 
     225                 :  *  @param caseid [in] the test case id, if caseid > 0
     226                 :  */
     227                 : LOCAL void      uengine_handle_extif_response (int result, int caseid);
     228                 : /* ------------------------------------------------------------------------- */
     229                 : /** handles external controller message type ERemoteSlaveResponse
     230                 :  *  @param testresult [in] test case result. 
     231                 :  *  @param caseid [in] the test case id, if caseid > 0
     232                 :  */
     233                 : LOCAL void      uengine_handle_extif_remote_response (int testresult,
     234                 :                                                       int caseid);
     235                 : /* ------------------------------------------------------------------------- */
     236                 : /** Handler for SIGCHLD
     237                 :  *  @param sig signal numnber
     238                 :  */
     239                 : /*LOCAL void scripter_sigchld_handler( int sig );*/
     240                 : /* ------------------------------------------------------------------------- */
     241                 : /** Handler for SIGALRM
     242                 :  *  @param sig signal numnber
     243                 :  */
     244                 : LOCAL void      scripter_sigalrm_handler (int sig);
     245                 : /* ------------------------------------------------------------------------- */
     246                 : /** Checks a few global flags to see if next line in script should be executed
     247                 :  */
     248                 : LOCAL TSBool    _execute_script (void);
     249                 : /* ------------------------------------------------------------------------- */
     250                 : /** Checks if there are test cases running 
     251                 :  */
     252                 : LOCAL TSBool    _pending_tests (void);
     253                 : /* ------------------------------------------------------------------------- */
     254                 : /** List find compare function
     255                 :  *  @param a comparison lvalue
     256                 :  *  @param b comparison rvalue
     257                 :  */
     258                 : LOCAL int       _look4event (const void *a, const void *b);
     259                 : /* ------------------------------------------------------------------------- */
     260                 : /** Searches for event registration from a local list
     261                 :  *  @param eventname name of the envent
     262                 :  */
     263                 : LOCAL minEventIf *find_event_reqistration (char *eventname);
     264                 : /* ------------------------------------------------------------------------- */
     265                 : /** Translates literal category to the enum representation.
     266                 :  *  @param str [in] literal category to be translated
     267                 :  *  @return enumerator value that correstonds to str @see TTestCategory
     268                 :  */
     269                 : LOCAL TTestCategory get_result_category (const char *str);
     270                 : /* ------------------------------------------------------------------------- */
     271                 : /** Assigns a value to script variable
     272                 :  *  @param varname [in] variable name
     273                 :  *  @param varval [in] variable value
     274                 :  */
     275                 : LOCAL void var_assign (const char *varname, const char *varval);
     276                 : /* ------------------------------------------------------------------------- */
     277                 : /** Updates the scriter internal variables 
     278                 :  *  @param res [in] Test Process result
     279                 :  */
     280                 : LOCAL void update_variables (TPResult res);
     281                 : /* ------------------------------------------------------------------------- */
     282                 : /** Used for declaring scripter interal variables
     283                 :  *  @param varname [in] variable name
     284                 :  */
     285                 : LOCAL int declare_internal_var (const char *varname);
     286                 : /* ------------------------------------------------------------------------- */
     287                 : /** Interpretes the variable value as integer and increments by one
     288                 :  *  @param varname [in] variable name
     289                 :  */
     290                 : LOCAL void var_increment (const char *varname);
     291                 : /* ------------------------------------------------------------------------- */
     292                 : /** Sends scripter variables to test class
     293                 :  */
     294                 : LOCAL void send_variables ();
     295                 : /* ------------------------------------------------------------------------- */
     296                 : /** Receives scripter variables from test class
     297                 :  */
     298                 : LOCAL void receive_variables ();
     299                 : /* ------------------------------------------------------------------------- */
     300                 : /** Inspects all the results of the method, combiner calls made from the script
     301                 :  *  and decides if the scripted test case is PASSED or FAILED
     302                 :  *  @param tp_details [in] list of method / combiner calls
     303                 :  *  @param tcr [in/out] the final result
     304                 :  */
     305                 : LOCAL void      scripter_final_verdict (DLList * tp_details,
     306                 :                                         TestCaseResult * tcr);
     307                 : 
     308                 : /* FORWARD DECLARATIONS */
     309                 : /* None */
     310                 : 
     311                 : /* ------------------------------------------------------------------------- */
     312                 : /* ==================== LOCAL FUNCTIONS ==================================== */
     313                 : /* ------------------------------------------------------------------------- */
     314                 : /* ------------------------------------------------------------------------- */
     315                 : LOCAL int _findclass (const void *a, const void *b)
     316              39 : {
     317              39 :         ScriptedTestProcessDetails *stpd = (ScriptedTestProcessDetails *) a;
     318              39 :         return strcmp (stpd->testclass_, (char *)b);
     319                 : }
     320                 : 
     321                 : /* ------------------------------------------------------------------------- */
     322                 : LOCAL int _findpid (const void *a, const void *b)
     323              37 : {
     324              37 :         ScriptedTestProcessDetails *stpd = (ScriptedTestProcessDetails *) a;
     325              37 :         if (stpd->pid_ == *(long *)b)
     326              33 :                 return 0;
     327                 :         else
     328               4 :                 return 1;
     329                 : }
     330                 : 
     331                 : /* ------------------------------------------------------------------------- */
     332                 : LOCAL int _findstatus (const void *a, const void *b)
     333              46 : {
     334              46 :         ScriptedTestProcessDetails *stpd = (ScriptedTestProcessDetails *) a;
     335              46 :         if (stpd->status_ == *(int *)b)
     336              12 :                 return 0;
     337                 :         else
     338              34 :                 return 1;
     339                 : }
     340                 : 
     341                 : /* ------------------------------------------------------------------------- */
     342                 : LOCAL int _findid (const void *a, const void *b)
     343               6 : {
     344               6 :         ScriptedTestProcessDetails *stpd = (ScriptedTestProcessDetails *) a;
     345               6 :         return strcmp (stpd->options_.testid_, (char *)b);
     346                 : }
     347                 : 
     348                 : /* ------------------------------------------------------------------------- */
     349                 : LOCAL int _findallowedresult (const void *a, const void *b)
     350              27 : {
     351              27 :         if (*(int *)a == *(int *)b)
     352              27 :                 return 0;
     353                 :         else
     354               0 :                 return 1;
     355                 : }
     356                 : 
     357                 : /* ------------------------------------------------------------------------- */
     358                 : LOCAL TSBool _pending_tests ()
     359              36 : {
     360              36 :         DLListIterator  it = DLListNULLIterator;
     361              36 :         int             desiredstatus = TP_RUNNING;
     362                 : 
     363              36 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
     364                 :                            , dl_list_tail (scripter_mod.tp_details)
     365                 :                            , _findstatus, &desiredstatus);
     366                 : 
     367              36 :         if (it != DLListNULLIterator)
     368              10 :                 return ESTrue;
     369                 : 
     370              26 :         desiredstatus = TP_PAUSED;
     371              26 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
     372                 :                            , dl_list_tail (scripter_mod.tp_details)
     373                 :                            , _findstatus, &desiredstatus);
     374                 : 
     375              26 :         if (it != DLListNULLIterator)
     376               2 :                 return ESTrue;
     377                 : 
     378              24 :         if (scripter_mod.tclass_exec)
     379               0 :                 return ESTrue;
     380                 : 
     381              24 :         if (scripter_mod.extif_remote > 0)
     382               0 :                 return ESTrue;
     383                 : 
     384              24 :         return ESFalse;
     385                 : }
     386                 : 
     387                 : /* ------------------------------------------------------------------------- */
     388                 : LOCAL TSBool _execute_script ()
     389            2760 : {
     390                 :         struct timeval  res;
     391                 :         struct timeval  now;
     392            2760 :         unsigned long   elapsed = 0;    /* in [ms] */
     393                 : 
     394                 :         /* If an error has occured do not investigate further,
     395                 :          * otherwise we might get stuck (e.g. remote run + event)
     396                 :          */
     397            2760 :         if (scripter_mod.error_occured)
     398               0 :                 return ESTrue;
     399                 :         
     400                 :         /* Execute script only if its not finished */
     401            2760 :         if (scripter_mod.script_finished)
     402              12 :                 return ESFalse;
     403                 : 
     404                 :         /* ...and if a blocking method is not running */
     405            2748 :         if (scripter_mod.tclass_exec)
     406              33 :                 return ESFalse;
     407                 : 
     408                 :         /* ...and if we are not paused from the cui */
     409            2715 :         if (scripter_mod.paused)
     410               0 :                 return ESFalse;
     411                 : 
     412                 :         /* ...and if we  are not waiting for the 
     413                 :          * a response to external controller message */
     414            2715 :         if (scripter_mod.extif_pending)
     415            1039 :                 return ESFalse;
     416                 : 
     417                 :         /* ...and if we are not waiting for the test to be completed */
     418            1676 :         if (scripter_mod.testcomplete != INITPTR)
     419               0 :                 return ESFalse;
     420                 : 
     421                 :         /* ...and we are not sleeping */
     422            1676 :         if (scripter_mod.sleep > 0) {
     423                 : 
     424            1283 :                 gettimeofday (&now, NULL);
     425            1283 :                 substract_timeval (&res, &now, &scripter_mod.time);
     426                 : 
     427            1283 :                 elapsed = (unsigned long)res.tv_sec * (unsigned long)1000;
     428            1283 :                 elapsed += (unsigned long)res.tv_usec / (unsigned long)1000;
     429                 : 
     430            1283 :                 if (elapsed >= scripter_mod.sleep) {
     431              10 :                         scripter_mod.sleep = 0;
     432                 :                 } else {
     433            1273 :                         return ESFalse;
     434                 :                 }
     435                 :         }
     436                 : 
     437                 :         /* ...and we are not waiting EVENT_IND */
     438             403 :         if (scripter_mod.event_pending)
     439              44 :                 return ESFalse;
     440                 : 
     441             359 :         return ESTrue;
     442                 : }
     443                 : 
     444                 : /* ------------------------------------------------------------------------- */
     445                 : LOCAL void fetch_ptr2run (const char *dllname, const char *classname)
     446               6 : {
     447               6 :         TestClassDetails *tcd = INITPTR;
     448               6 :         int               clen = 0;
     449                 :         char             *tmp;
     450                 : 
     451               6 :         if (dllname == INITPTR) {
     452               0 :                 errno = EINVAL;
     453               0 :                 SCRIPTER_RTERR ("library name missing");
     454               0 :                 goto EXIT;
     455                 :         }
     456               6 :         if (strlen (dllname) == 0) {
     457               0 :                 errno = EINVAL;
     458               0 :                 SCRIPTER_RTERR ("library name has 0 length");
     459               0 :                 goto EXIT;
     460                 :         }
     461                 : 
     462                 :         /* 0) Initialize some data */
     463               6 :         tcd = NEW (TestClassDetails);
     464                 : 
     465                 :         /* 1) Load dll library */
     466               6 :         tcd->dllhandle_ = tl_open_tc (dllname);
     467               6 :         if (tcd->dllhandle_ == INITPTR) {
     468               0 :                 tmp = NEW2 (char, 
     469                 :                             strlen ("Unable to load library ") + 
     470                 :                             strlen (dllname) + 1);
     471               0 :                 sprintf (tmp, "Unable to load library %s", dllname);
     472               0 :                 SCRIPTER_RTERR_ARG (tmp, dlerror());
     473               0 :                 DELETE (tmp);
     474               0 :                 MIN_WARN ("Unable to load library [%s] because: %s",
     475                 :                              dllname, dlerror ());
     476               0 :                 DELETE (tcd);
     477               0 :                 goto EXIT;
     478                 :         }
     479                 : 
     480                 :         /* 2) Fetch pointer to the run function */
     481               6 :         tcd->runtc_ = dlsym (tcd->dllhandle_, "ts_run_method");
     482               6 :         if (tcd->runtc_ == NULL) {
     483               0 :                 SCRIPTER_RTERR_ARG ("Unable to resolve ts_run_method",
     484                 :                                     dlerror ());
     485               0 :                 MIN_ERROR ("Unable to resolve ts_run_method: %s",
     486                 :                              dlerror ());
     487               0 :                 DELETE (tcd);
     488               0 :                 goto EXIT;
     489                 :         }
     490                 : 
     491                 :         /* 3) Store mnemonic for that library */
     492               6 :         clen = strlen (classname);
     493               6 :         tcd->classname_ = NEW2 (char, clen + 1);
     494               6 :         memset (tcd->classname_, 0x0, clen + 1);
     495               6 :         STRCPY (tcd->classname_, classname, clen + 1);
     496                 : 
     497                 :         /* 4) Save data on the list */
     498               6 :         dl_list_add (tp_handlers, tcd);
     499               6 : EXIT:
     500                 :         return;
     501                 : }
     502                 : 
     503                 : /* ------------------------------------------------------------------------- */
     504                 : LOCAL void read_optional_run_params (MinItemParser * mip, ExtraParams * ep)
     505              14 : {
     506              14 :         char           *token = INITPTR;
     507              14 :         int             token2 = 0;
     508              14 :         char           *parsing_position = INITPTR;
     509              14 :         int             tmp = 0;
     510              14 :         TParsingType    parsing = ENormalParsing;
     511                 : 
     512              14 :         if (mip == INITPTR) {
     513               0 :                 SCRIPTER_RTERR ("Item parser argument is missing");
     514               0 :                 goto EXIT;
     515                 :         }
     516              14 :         if (ep == INITPTR) {
     517               0 :                 SCRIPTER_RTERR ("Extra params argument is missing");
     518               0 :                 goto EXIT;
     519                 :         }
     520                 : 
     521                 :         /* expect parameter */
     522              14 :         parsing_position = mip->item_skip_and_mark_pos_;
     523              14 :         tmp = mip_get_next_tagged_int (mip, "expect", &token2);
     524              14 :         if (tmp == ENOERR) {
     525               0 :                 ep->expect_ = token2;
     526               0 :                 token2 = 0;
     527                 :         } else {
     528              14 :                 ep->expect_ = ENOERR;
     529                 :         }
     530                 : 
     531                 :         /* testid parameter */
     532              14 :         mip->item_skip_and_mark_pos_ = parsing_position;
     533              14 :         tmp = mip_get_next_tagged_string (mip, "testid", &token);
     534              14 :         if (tmp == ENOERR) {
     535               5 :                 if (token != INITPTR) {
     536               5 :                         STRCPY (ep->testid_, token, 128);
     537               5 :                         DELETE (token);
     538               5 :                         token = INITPTR;
     539                 :                 }
     540                 :         } else {
     541               9 :                 STRCPY (ep->testid_, "\0", 128);
     542                 :         }
     543                 : 
     544                 :         /* ini parameter */
     545              14 :         mip->item_skip_and_mark_pos_ = parsing_position;
     546              14 :         tmp = mip_get_next_tagged_string (mip, "ini", &token);
     547              14 :         if (tmp == ENOERR) {
     548               0 :                 if (token != INITPTR) {
     549               0 :                         STRCPY (ep->ini_, token, 512);
     550               0 :                         DELETE (token);
     551               0 :                         token = INITPTR;
     552                 :                 }
     553                 :         } else {
     554              14 :                 STRCPY (ep->ini_, "\0", 512);
     555                 :         }
     556                 : 
     557                 :         /* category parameter */
     558              14 :         mip->item_skip_and_mark_pos_ = parsing_position;
     559              14 :         tmp = mip_get_next_tagged_string (mip, "category", &token);
     560              14 :         if (tmp == ENOERR) {
     561               0 :                 ep->category_ = get_result_category (token);
     562               0 :                 DELETE (token);
     563               0 :                 token = INITPTR;
     564                 :         }
     565                 : 
     566                 :         /* timeout parameter */
     567              14 :         mip->item_skip_and_mark_pos_ = parsing_position;
     568              14 :         tmp = mip_get_next_tagged_string (mip, "timeout", &token);
     569              14 :         if (tmp == ENOERR) {
     570               0 :                 ep->timeout_ = 0;
     571               0 :                 DELETE (token);
     572               0 :                 token = INITPTR;
     573                 :         }
     574                 : 
     575                 :         /* title parameter */
     576              14 :         parsing = mip_get_parsing_type (mip);
     577              14 :         mip_set_parsing_type (mip, EQuoteStyleParsing);
     578              14 :         mip->item_skip_and_mark_pos_ = parsing_position;
     579              14 :         tmp = mip_get_next_tagged_string (mip, "title", &token);
     580              14 :         if (tmp == ENOERR) {
     581               7 :                 if (token != INITPTR) {
     582               7 :                         STRCPY (ep->title_, token, 128);
     583               7 :                         DELETE (token);
     584               7 :                         token = INITPTR;
     585                 :                 }
     586                 :         } else {
     587               7 :                 STRCPY (ep->title_, "\0", 128);
     588                 :         }
     589              14 :         mip_set_parsing_type (mip, parsing);
     590              14 :       EXIT:
     591                 :         return;
     592                 : }
     593                 : 
     594                 : /* ------------------------------------------------------------------------- */
     595                 : LOCAL void uengine_read_message (int mqid, MsgBuffer * input_buffer)
     596              61 : {
     597              61 :         int             retval = 0;
     598                 : 
     599              61 :         retval = mq_read_message (mqid, getpid ()
     600                 :                                   , input_buffer);
     601              61 :         if (retval == -1) {
     602               0 :                 switch (errno) {
     603                 :                 case EINTR:
     604               0 :                         MIN_DEBUG ("Reading MQ interrupted by signal");
     605               0 :                         break;
     606                 : 
     607                 :                 case EIDRM:
     608               0 :                         SCRIPTER_RTERR("MQ id removed from the system");
     609               0 :                         MIN_FATAL ("MQ id removed from the system");
     610               0 :                         break;
     611                 : 
     612                 :                 case E2BIG:
     613               0 :                         MIN_WARN ("Recieved message too big");
     614               0 :                         break;
     615                 : 
     616                 :                 case EINVAL:
     617               0 :                         SCRIPTER_RTERR("Invalid value: mq_read_message");
     618               0 :                         MIN_ERROR ("Invalid value: mq_read_message");
     619                 :                         break;
     620                 :                 }
     621              61 :         } else if (retval < 8) {
     622                 :                 /*ignore too short messages */
     623               0 :                 MIN_NOTICE ("Recieved message is too small");
     624                 :         }
     625                 : 
     626              61 : }
     627                 : 
     628                 : /* ------------------------------------------------------------------------- */
     629                 : LOCAL void uengine_handle_message (int mqid, const MsgBuffer * msg)
     630              61 : {
     631                 :         MsgBuffer       out;
     632                 : 
     633              61 :         switch (msg->type_) {
     634                 :         case MSG_RET:
     635              33 :                 MIN_DEBUG ("Recieved MSG_RET");
     636              33 :                 uengine_handle_ret (mqid, msg->param_, msg->message_,
     637                 :                                     msg->sender_);
     638              33 :                 break;
     639                 :         case MSG_USR:
     640              12 :                 MIN_DEBUG ("Recieved MSG_USR");
     641                 :                 /* Forward message to upper level */
     642              12 :                 memcpy (&out, msg, sizeof (MsgBuffer));
     643              12 :                 out.sender_ = getpid ();
     644              12 :                 out.receiver_ = getppid ();
     645              12 :                 mq_send_message (mqid, &out);
     646                 : 
     647                 :                 /*  */
     648              12 :                 sched_yield ();
     649                 : 
     650              12 :                 break;
     651                 :         case MSG_EVENT:
     652               0 :                 MIN_DEBUG ("Recieved MSG_EVENT");
     653               0 :                 memcpy (&out, msg, sizeof (MsgBuffer));
     654               0 :                 out.sender_ = getpid ();
     655               0 :                 out.receiver_ = getppid ();
     656               0 :                 mq_send_message (mqid, &out);
     657               0 :                 break;
     658                 :         case MSG_EVENT_IND:
     659               5 :                 MIN_DEBUG ("Recieved MSG_EVENT_IND");
     660               5 :                 uengine_handle_event_ind (mqid, msg);
     661               5 :                 break;
     662                 :         case MSG_END:
     663               0 :                 MIN_DEBUG ("Recieved MSG_END");
     664               0 :                 uengine_handle_end (mqid, msg);
     665               0 :                 break;
     666                 :         case MSG_PAUSE:
     667               0 :                 MIN_DEBUG ("Recieved MSG_PAUSE");
     668               0 :                 uengine_handle_pause (mqid, msg);
     669               0 :                 break;
     670                 :         case MSG_RESUME:
     671               0 :                 MIN_DEBUG ("Recieved MSG_RESUME");
     672               0 :                 uengine_handle_resume (mqid, msg);
     673               0 :                 break;
     674                 :         case MSG_STOP:
     675               0 :                 MIN_DEBUG ("Recieved MSG_STOP");
     676               0 :                 uengine_handle_stop (mqid, msg);
     677               0 :                 break;
     678                 :         case MSG_EXTIF:
     679              10 :                 MIN_DEBUG ("Recieved MSG_EXTIF");
     680              10 :                 uengine_handle_extif (mqid, msg);
     681              10 :                 break;
     682                 :         case MSG_SNDRCV:
     683               1 :                 MIN_DEBUG ("Recieved MSG_SNDRCV");
     684               1 :                 uengine_handle_sndrcv (mqid, msg);
     685               1 :                 break;
     686                 :         default:
     687               0 :                 MIN_WARN ("Unhandled message from %d: to %d, type: %d",
     688                 :                              msg->sender_, msg->receiver_, msg->type_);
     689                 :         }
     690                 : 
     691                 : 
     692              61 : }
     693                 : 
     694                 : /* ------------------------------------------------------------------------- */
     695                 : LOCAL void uengine_handle_ret (int mqid, int param, const char *message,
     696                 :                                long sender)
     697              33 : {
     698              33 :         DLListIterator  it = DLListNULLIterator;
     699              33 :         DLListIterator  it2 = DLListNULLIterator;
     700              33 :         int             desiredstatus = TP_RUNNING;
     701              33 :         ScriptedTestProcessDetails *stpd = INITPTR;
     702              33 :         int            *tmp = INITPTR;
     703                 :         int             status;
     704                 :         TestCaseResult *tcr;
     705                 :         char            tmp2[12];
     706              33 :         TSBool          complete_used=ESFalse;
     707                 : 
     708              33 :         if (message == INITPTR) {
     709               0 :                 errno = EINVAL;
     710               0 :                 SCRIPTER_RTERR ("empty message");
     711               0 :                 goto EXIT;
     712                 :         }
     713                 : 
     714              33 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
     715                 :                            , dl_list_tail (scripter_mod.tp_details)
     716                 :                            , _findpid, &sender);
     717              33 :         if (it == DLListNULLIterator) {
     718               0 :                 sprintf (tmp2, "%lu", sender);
     719               0 :                 SCRIPTER_RTERR_ARG  ("No test of given pid", tmp2);
     720               0 :                 MIN_WARN ("There is no test of given pid [%d]", sender);
     721               0 :                 goto EXIT;
     722                 :         }
     723              33 :         stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
     724                 : 
     725              33 :         if (stpd->mod_type_ == EDLLTypeNormal) {
     726                 :                 /* We have TP created by RUN keyword (Combiner) 
     727                 :                  * let go back to previous idea and send
     728                 :                  * test result to the upper level 
     729                 :                  */
     730                 : 
     731                 :                 /* Check if we are waiting for this test to complete 
     732                 :                  * if so then restart script execution. */
     733               6 :                 if (scripter_mod.testcomplete != INITPTR &&
     734                 :                     !strcmp (scripter_mod.testcomplete,
     735                 :                              stpd->options_.testid_)) {
     736               0 :                         complete_used=ESTrue;
     737               0 :                         DELETE (scripter_mod.testcomplete);
     738               0 :                         scripter_mod.testcomplete = INITPTR;
     739                 :                 } 
     740                 :                 
     741                 :                 /* set status */
     742               6 :                 stpd->status_ = TP_ENDED;
     743                 :                 
     744               6 :                 if(complete_used==ESTrue){
     745               0 :                         test_complete(stpd->options_.testid_);
     746                 :                 }
     747                 :                 
     748                 :                 /* kill TP :) */
     749               6 :                 kill (sender, SIGUSR2);
     750               6 :                 waitpid (sender, &status, 0);
     751                 : 
     752                 :                 /* set test result test result is checked 
     753                 :                  * against expected optional parameter */
     754               6 :                 tcr = NEW (TestCaseResult);
     755               6 :                 if (param == stpd->options_.expect_) {
     756               6 :                         tcr->result_ = TP_PASSED;
     757                 :                 } else {
     758               0 :                         tcr->result_ = TP_FAILED;
     759                 :                 }
     760               6 :                 update_variables (tcr->result_);
     761                 : 
     762               6 :                 STRCPY (tcr->desc_, message, MaxTestResultDescription);
     763               6 :                 dl_list_add (stpd->tcr_list_, tcr);
     764                 : 
     765                 :                 /* Check test result and canceliferror flag */
     766               6 :                 if (param == TP_FAILED
     767                 :                     && scripter_mod.canceliferror == ESTrue) {
     768               0 :                         MIN_DEBUG ("Test Failed, canceliferror ON");
     769               0 :                         stpd->status_ = TP_CANCELED;
     770               0 :                         update_variables (TP_NC);
     771               0 :                         scripter_mod.script_finished = ESTrue;
     772                 :                         /* Now we have to 'end' rest of the tests */
     773               0 :                         it2 = dl_list_head (scripter_mod.tp_details);
     774                 :                         do {
     775               0 :                                 it = dl_list_find (it2,
     776                 :                                                    dl_list_tail (scripter_mod.
     777                 :                                                                  tp_details)
     778                 :                                                    , _findstatus,
     779                 :                                                    &desiredstatus);
     780                 : 
     781               0 :                                 if (it == DLListNULLIterator) {
     782               0 :                                         break;
     783                 :                                 }
     784                 : 
     785                 :                                 /* set status to cancelled */
     786               0 :                                 stpd = (ScriptedTestProcessDetails *)
     787                 :                                     dl_list_data (it);
     788               0 :                                 stpd->status_ = TP_CANCELED;
     789               0 :                                 update_variables (TP_NC);
     790                 :                                 /* kill test process */
     791               0 :                                 kill (stpd->pid_, SIGUSR2);
     792               0 :                                 waitpid (stpd->pid_, &status, 0);
     793                 : 
     794                 :                                 /* cause searching is in range [] */
     795               0 :                                 it = dl_list_next (it);
     796               0 :                                 it2 = it;
     797                 : 
     798               0 :                         } while (it != DLListNULLIterator);
     799                 :                 }
     800                 : 
     801                 :         } else {
     802                 :                 /* We have TP created by callfunc keyword (Scripter) */
     803                 : 
     804                 :                 /* check if the test class has modified scripter variables */
     805              27 :                 if (dl_list_size (variables) > 0) {
     806              27 :                         receive_variables();
     807                 :                 }
     808                 :                 /* Check result against allowed test result */
     809              27 :                 it = dl_list_find (dl_list_head (stpd->allowed_results_)
     810                 :                                    , dl_list_tail (stpd->allowed_results_)
     811                 :                                    , _findallowedresult,
     812                 :                                    (const void *)&param);
     813              27 :                 if (it == DLListNULLIterator) {
     814               0 :                         param = TP_FAILED;
     815                 :                 } else {
     816              27 :                         param = TP_PASSED;
     817                 :                 }
     818              27 :                 update_variables (param);
     819                 :                 /* Now we can destroy the list. No need to keep allowed
     820                 :                  * result any more. */
     821              27 :                 it = dl_list_head (stpd->allowed_results_);
     822              81 :                 while (it != DLListNULLIterator) {
     823              27 :                         tmp = (int *)dl_list_data (it);
     824              27 :                         DELETE (tmp);
     825              27 :                         dl_list_remove_it (it);
     826              27 :                         it = dl_list_head (stpd->allowed_results_);
     827                 :                 }
     828              27 :                 dl_list_free (&stpd->allowed_results_);
     829                 : 
     830              27 :                 scripter_mod.tclass_exec = 0;
     831                 : 
     832                 :                 /* Do result reporting stuff */
     833              27 :                 tcr = NEW (TestCaseResult);
     834              27 :                 tcr->result_ = param;
     835              27 :                 STRCPY (tcr->desc_, message, MaxTestResultDescription);
     836                 : 
     837              27 :                 dl_list_add (stpd->tcr_list_, tcr);
     838                 :         }
     839              33 :       EXIT:
     840                 :         return;
     841                 : }
     842                 : 
     843                 : /* ------------------------------------------------------------------------- */
     844                 : LOCAL void uengine_handle_end (int mqid, const MsgBuffer * msg)
     845               0 : {
     846                 :         /* Not needed on this sprint */
     847               0 : }
     848                 : 
     849                 : /* ------------------------------------------------------------------------- */
     850                 : LOCAL void uengine_handle_pause (int mqid, const MsgBuffer * msg)
     851               0 : {
     852                 :         /* Not needed on this sprint */
     853               0 : }
     854                 : 
     855                 : /* ------------------------------------------------------------------------- */
     856                 : LOCAL void uengine_handle_resume (int mqid, const MsgBuffer * msg)
     857               0 : {
     858                 :         /* Not needed on this sprint */
     859               0 : }
     860                 : 
     861                 : /* ------------------------------------------------------------------------- */
     862                 : LOCAL void uengine_handle_stop (int mqid, const MsgBuffer * msg)
     863               0 : {
     864                 :         /* Not needed on this sprint */
     865               0 : }
     866                 : 
     867                 : /* ------------------------------------------------------------------------- */
     868                 : LOCAL void uengine_handle_extif (int mqid, const MsgBuffer * msg)
     869              10 : {
     870              10 :         switch (msg->extif_msg_type_) {
     871                 :         case EResponseSlave:
     872               8 :                 MIN_DEBUG ("EResponseSlave");
     873               8 :                 uengine_handle_extif_response (msg->param_, msg->special_);
     874               8 :                 break;
     875                 :         case ERemoteSlaveResponse:
     876               2 :                 MIN_DEBUG ("ERemoteSlaveResponse");
     877               2 :                 uengine_handle_extif_remote_response (msg->param_,
     878                 :                                                       msg->special_);
     879               2 :                 break;
     880                 :         default:
     881               0 :                 MIN_WARN ("Unknown EXTIF command response: [%d]",
     882                 :                              msg->param_);
     883                 :         }
     884                 :         return;
     885                 : }
     886                 : 
     887                 : /* ------------------------------------------------------------------------- */
     888                 : LOCAL void uengine_handle_extif_response (int result, int caseid)
     889               8 : {
     890               8 :         ScriptedTestProcessDetails *stpd = INITPTR;
     891               8 :         int            *tmp = INITPTR;
     892                 :         /* check if na error occured - if there is an error then
     893                 :          * break script execution, if not then resume it. */
     894               8 :         if (result != ENOERR) {
     895               0 :                 MIN_WARN ("remote run error: %d", result); 
     896               0 :                 SCRIPTER_RTERR ("Remote run error");
     897               0 :                 scripter_mod.extif_pending = ESFalse;
     898                 : 
     899               0 :                 goto EXIT;
     900                 :         }
     901                 : 
     902                 :         /* special field can carry an test id - if > 0 
     903                 :          * caseid is > 0 only when response is for REMOTE RUN */
     904               8 :         if (caseid > 0) {
     905                 : 
     906               2 :                 scripter_mod.extif_remote++;
     907               2 :                 MIN_DEBUG ("scripter_mod.extif_remote=%d",
     908                 :                            scripter_mod.extif_remote);
     909                 :                            
     910               2 :                 stpd = NEW (ScriptedTestProcessDetails);
     911               2 :                 stpd->tcr_list_ = dl_list_create ();
     912               2 :                 STRCPY (stpd->testclass_, "", 1);
     913               2 :                 stpd->pid_ = 0;
     914               2 :                 STRCPY (stpd->dllname_, "", 1);
     915               2 :                 STRCPY (stpd->cfgfile_, "", 1);
     916               2 :                 stpd->mod_type_ = EDLLTypeNormal;
     917               2 :                 stpd->options_.expect_ = ENOERR;
     918               2 :                 sprintf (stpd->options_.testid_, "%d", caseid); /* caseid */
     919               2 :                 STRCPY (stpd->options_.ini_, "", 1);
     920               2 :                 stpd->options_.category_ = ECategoryNormal;
     921               2 :                 stpd->options_.timeout_ = 0;
     922               2 :                 STRCPY (stpd->options_.title_, "", 1);
     923               2 :                 stpd->status_ = TP_RUNNING;
     924                 : 
     925                 :                 /* Handle result allowing. */
     926               2 :                 if (allowedresults == INITPTR) {
     927               2 :                         stpd->allowed_results_ = dl_list_create ();
     928               2 :                         tmp = NEW (int);
     929               2 :                         *tmp = ENOERR;
     930               2 :                         dl_list_add (stpd->allowed_results_, (void *)tmp);
     931                 :                 } else {
     932               0 :                         stpd->allowed_results_ = allowedresults;
     933               0 :                         allowedresults = INITPTR;
     934                 :                 }
     935                 : 
     936               2 :                 dl_list_add (scripter_mod.tp_details, (void *)stpd);
     937                 :         }
     938                 : 
     939                 :         /* resume execution */
     940               8 :         scripter_mod.extif_pending = ESFalse;
     941               8 :       EXIT:
     942                 :         return;
     943                 : }
     944                 : 
     945                 : /* ------------------------------------------------------------------------- */
     946                 : LOCAL void uengine_handle_extif_remote_response (int testresult, int caseid)
     947               2 : {
     948               2 :         DLListIterator  it = DLListNULLIterator;
     949                 :         char            id[128];
     950               2 :         ScriptedTestProcessDetails *stpd = INITPTR;
     951                 :         TestCaseResult *tcr;
     952               2 :         scripter_mod.extif_remote--;
     953               2 :         MIN_DEBUG ("scripter_mod.extif_remote=%d",
     954                 :                    scripter_mod.extif_remote);
     955                 : 
     956               2 :         sprintf (id, "%d", caseid);
     957                 : 
     958               2 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
     959                 :                            , dl_list_tail (scripter_mod.tp_details)
     960                 :                            , _findid, id);
     961                 : 
     962               2 :         if (it == DLListNULLIterator) {
     963               0 :                 SCRIPTER_RTERR_ARG ("No test of specified caseid", id);
     964               0 :                 MIN_WARN ("There is no test of specified caseid [%d]", caseid);
     965               0 :                 goto EXIT;
     966                 :         }
     967                 :         
     968               2 :         update_variables (testresult);
     969                 : 
     970               2 :         stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
     971                 : 
     972                 :         /* set status */
     973               2 :         stpd->status_ = TP_ENDED;
     974                 :         
     975                 :         /* set test result */
     976               2 :         tcr = NEW (TestCaseResult);
     977               2 :         tcr->result_ = testresult;
     978               2 :         STRCPY (tcr->desc_, "", MaxTestResultDescription);
     979               2 :         dl_list_add (stpd->tcr_list_, tcr);
     980                 : 
     981                 : 
     982                 : 
     983               2 :       EXIT:
     984                 :         return;
     985                 : }
     986                 : 
     987                 : /* ------------------------------------------------------------------------- */
     988                 : LOCAL void uengine_handle_event_ind (int mqid, const MsgBuffer * msg)
     989               5 : {
     990               5 :         scripter_mod.event_pending = ESFalse;
     991                 :                 
     992               5 :         if (msg->param_ != EventStatOK) {
     993               0 :                 SCRIPTER_RTERR ("Event error");
     994               0 :                 MIN_ERROR ("Event error occured");
     995                 :         }
     996               5 : }
     997                 : 
     998                 : /* ------------------------------------------------------------------------- */
     999                 : LOCAL void uengine_handle_sndrcv (int mqid, const MsgBuffer * msg)
    1000               1 : {
    1001                 : 
    1002               1 :         if (!strcmp (scripter_mod.expected_var, msg->message_)) {
    1003               1 :                 scripter_mod.extif_pending = ESFalse;
    1004               1 :                 var_assign (msg->message_, msg->desc_);
    1005                 :         } else {
    1006               0 :                 SCRIPTER_RTERR_ARG ("Received unexpected  variable",
    1007                 :                                     msg->message_);
    1008               0 :                 MIN_ERROR ("Expecting variable "
    1009                 :                             "%s, received %s",
    1010                 :                             scripter_mod.expected_var, msg->message_);
    1011                 :         }
    1012                 :         return;
    1013                 : }
    1014                 : 
    1015                 : /* ------------------------------------------------------------------------- */
    1016                 : LOCAL void update_variables (TPResult res)
    1017              36 : {
    1018              36 :         switch (res) {
    1019                 :         case TP_CRASHED:
    1020               0 :                 var_increment ("CRASH_COUNT");
    1021               0 :                 var_increment ("ERROR_COUNT");
    1022               0 :                 break;
    1023                 :         case TP_TIMEOUTED:
    1024               0 :                 var_increment ("TOUT_COUNT");
    1025               0 :                 var_increment ("ERROR_COUNT");
    1026               0 :                 break;
    1027                 :         case TP_PASSED:
    1028              35 :                 break;
    1029                 :         case TP_FAILED:
    1030               0 :                 var_increment ("FAIL_COUNT");
    1031               0 :                 var_increment ("ERROR_COUNT");
    1032               0 :                 break;
    1033                 :         case TP_NC:
    1034                 :         case TP_LEAVE:
    1035               1 :                 var_increment ("ABORT_COUNT");
    1036               1 :                 var_increment ("ERROR_COUNT");
    1037               1 :                 break;
    1038                 :         default:
    1039               0 :                 SCRIPTER_RTERR ("Unexpected result");
    1040                 :                 break;
    1041                 :         }
    1042              36 :         var_increment ("TOTAL_COUNT");
    1043              36 : }
    1044                 : 
    1045                 : /* ------------------------------------------------------------------------- */
    1046                 : /*LOCAL void scripter_sigchld_handler( int sig )
    1047                 : {
    1048                 :         min_info("Scripter Test process received SIGCHLD");
    1049                 : }*/
    1050                 : /* ------------------------------------------------------------------------- */
    1051                 : LOCAL void scripter_sigalrm_handler (int sig)
    1052               0 : {
    1053               0 :         DLListIterator  it = DLListNULLIterator;
    1054               0 :         DLListIterator  it2 = DLListNULLIterator;
    1055               0 :         int             desired = TP_RUNNING;
    1056               0 :         int             status = 0;
    1057               0 :         ScriptedTestProcessDetails *stpd = INITPTR;
    1058                 : 
    1059                 :         /* Timeout! Stop execution and end all ongoing tests */
    1060               0 :         it2 = dl_list_head (scripter_mod.tp_details);
    1061                 :         do {
    1062                 :                 /* find running test */
    1063               0 :                 it = dl_list_find (it2, dl_list_tail (scripter_mod.tp_details)
    1064                 :                                    , _findstatus, &desired);
    1065                 : 
    1066               0 :                 if (it == DLListNULLIterator) {
    1067               0 :                         break;
    1068                 :                 }
    1069                 : 
    1070                 :                 /* set status to timeout */
    1071               0 :                 stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
    1072               0 :                 stpd->status_ = TP_TIMEOUT;
    1073                 : 
    1074                 :                 /* kill test process */
    1075               0 :                 kill (stpd->pid_, SIGUSR2);
    1076               0 :                 waitpid (stpd->pid_, &status, 0);
    1077                 : 
    1078                 :                 /* cause searching is in range [] */
    1079               0 :                 it = dl_list_next (it);
    1080               0 :                 it2 = it;
    1081               0 :         } while (it != DLListNULLIterator);
    1082               0 : }
    1083                 : 
    1084                 : /* ------------------------------------------------------------------------- */
    1085                 : LOCAL int _look4event (const void *a, const void *b)
    1086               2 : {
    1087               2 :         minEventIf    *e = (minEventIf *) a;
    1088               2 :         return strcmp (e->Name (e), (char *)b);
    1089                 : }
    1090                 : 
    1091                 : /* ------------------------------------------------------------------------- */
    1092                 : LOCAL minEventIf *find_event_reqistration (char *eventname)
    1093               3 : {
    1094               3 :         DLListIterator  it = DLListNULLIterator;
    1095               3 :         it = dl_list_find (dl_list_head (scripter_mod.req_events)
    1096                 :                            , dl_list_tail (scripter_mod.req_events)
    1097                 :                            , _look4event, eventname);
    1098                 : 
    1099               3 :         if (it == DLListNULLIterator) {
    1100               1 :                 MIN_WARN ("There is no event of given name: [%s]",eventname);
    1101               1 :                 return INITPTR;
    1102                 :         }
    1103               2 :         return (minEventIf *) dl_list_data (it);
    1104                 : }
    1105                 : 
    1106                 : /* ------------------------------------------------------------------------- */
    1107                 : LOCAL TTestCategory get_result_category (const char *str)
    1108               0 : {
    1109               0 :         TTestCategory   retval = ECategoryUnknown;
    1110                 : 
    1111               0 :         if (str == INITPTR) {
    1112               0 :                 errno = EINVAL;
    1113               0 :                 SCRIPTER_RTERR("no string");
    1114               0 :                 goto EXIT;
    1115                 :         }
    1116                 : 
    1117               0 :         if (strcmp ("normal", str) == 0) {
    1118               0 :                 retval = ECategoryNormal;
    1119               0 :         } else if (strcmp ("leave", str) == 0) {
    1120               0 :                 retval = ECategoryLeave;
    1121               0 :         } else if (strcmp ("panic", str) == 0) {
    1122               0 :                 retval = ECategoryPanic;
    1123               0 :         } else if (strcmp ("exception", str) == 0) {
    1124               0 :                 retval = ECategoryException;
    1125               0 :         } else if (strcmp ("timeout", str) == 0) {
    1126               0 :                 retval = ECategoryTimeout;
    1127                 :         }
    1128               0 :       EXIT:
    1129               0 :         return retval;
    1130                 : }
    1131                 : 
    1132                 : /* ------------------------------------------------------------------------- */
    1133                 : LOCAL ScriptVar *var_find (const char *varname)
    1134            1221 : {
    1135                 :         DLListIterator  it;
    1136                 :         ScriptVar      *var;
    1137                 : 
    1138            1221 :         it = dl_list_head (variables);
    1139            6593 :         while (it != INITPTR) {
    1140            4387 :                 var = dl_list_data (it);
    1141            4387 :                 if (!strcmp (var->name_, varname)) {
    1142             236 :                         return var;
    1143                 :                 }
    1144            4151 :                 it = dl_list_next (it);
    1145                 :         }
    1146             985 :         return INITPTR;
    1147                 : }
    1148                 : 
    1149                 : /* ------------------------------------------------------------------------- */
    1150                 : LOCAL const char *var_value (const char *varname)
    1151             234 : {
    1152                 :         ScriptVar      *var;
    1153                 : 
    1154             234 :         var = var_find (varname);
    1155             234 :         if (var != INITPTR) {
    1156              13 :                 if (var->initialized_ == ESFalse) {
    1157               0 :                         MIN_WARN ("variable %s not initialized", varname);
    1158               0 :                         return "UNINITIALIZED";
    1159                 :                 }
    1160              13 :                 return var->value_;
    1161                 :         }
    1162                 : 
    1163             221 :         return varname;
    1164                 : }
    1165                 : 
    1166                 : /* ------------------------------------------------------------------------- */
    1167                 : LOCAL void var_assign (const char *varname, const char *varval)
    1168             184 : {
    1169                 :         ScriptVar      *var;
    1170                 : 
    1171             184 :         var = var_find (varname);
    1172             184 :         if (var != INITPTR) {
    1173             184 :                 var->initialized_ = ESTrue;
    1174             184 :                 if (var->value_ != INITPTR)
    1175             184 :                         DELETE (var->value_);
    1176             184 :                 var->value_ = NEW2 (char, strlen (varval) + 1);
    1177             184 :                 STRCPY (var->value_, varval, strlen (varval) + 1);
    1178             184 :                 MIN_DEBUG ("%s=%s", varname, varval);
    1179                 :         } else {
    1180               0 :                 SCRIPTER_RTERR_ARG ("Trying to assign undeclared variable",
    1181                 :                                     varname);
    1182               0 :                 MIN_WARN ("Trying to assign undeclared variable %s",
    1183                 :                            varname);
    1184                 :         }
    1185                 : 
    1186                 :         return;
    1187                 : }
    1188                 : 
    1189                 : /* ------------------------------------------------------------------------- */
    1190                 : LOCAL void var_increment (const char *varname)
    1191              38 : {
    1192                 :         ScriptVar      *var;
    1193                 :         long           intval;
    1194                 : 
    1195              38 :         var = var_find (varname);
    1196              38 :         if (var == INITPTR || var->initialized_ == ESFalse) {
    1197               0 :                 SCRIPTER_RTERR_ARG ("Trying to increment undeclared variable",
    1198                 :                                     varname);
    1199                 :                 
    1200                 :         }
    1201              38 :         intval = strtol (var->value_, NULL, 10);
    1202              38 :         DELETE (var->value_);
    1203              38 :         intval ++;
    1204              38 :         var->value_ = NEW2 (char, 32);
    1205              38 :         sprintf (var->value_, "%ld", intval);
    1206                 : 
    1207                 :         return;
    1208                 : }
    1209                 : 
    1210                 : 
    1211                 : /* ------------------------------------------------------------------------- */
    1212                 : LOCAL void send_variables ()
    1213              27 : {
    1214                 :         DLListIterator   it;
    1215                 :         ScriptVar       *var;
    1216                 :         Text            *vars;
    1217              27 :         void            *sh_mem_handle = NULL, *tmp;
    1218                 : 
    1219              27 :         vars = tx_create (INITPTR);
    1220                 : 
    1221             236 :         for (it = dl_list_head(variables); it != INITPTR; 
    1222             182 :              it = dl_list_next(it)) {
    1223             182 :                 var = dl_list_data (it);
    1224             182 :                 tx_c_append (vars, var->name_);
    1225             182 :                 if (var->initialized_) {
    1226             182 :                         tx_c_append (vars, "=");
    1227             182 :                         tx_c_append (vars, var->value_);
    1228                 :                 }
    1229             182 :                 tx_c_append (vars, " ");
    1230                 :         }
    1231                 : 
    1232              27 :         sh_mem_handle = sm_attach (scripter_mod.shm_id);
    1233                 :         
    1234              27 :         if ((vars->size_ + sizeof (unsigned int)) >  
    1235                 :             sm_get_segsz (scripter_mod.shm_id)) {
    1236               0 :                 SCRIPTER_RTERR ("Variables do not fit into SHM");
    1237               0 :                 tx_destroy (&vars);
    1238               0 :                 return;
    1239                 :         }
    1240                 :         
    1241              27 :         sm_write (sh_mem_handle,
    1242                 :                   (void *)&vars->size_,
    1243                 :                   sizeof (unsigned int));
    1244              27 :         tmp = sh_mem_handle + sizeof (unsigned int);
    1245              27 :         sm_write (tmp,
    1246                 :                   (void *)(tx_share_buf (vars)),
    1247                 :                   vars->size_);
    1248                 : 
    1249              27 :         MIN_DEBUG ("SENT VARIABLES: %s", tx_share_buf(vars));
    1250              27 :         sm_detach (sh_mem_handle);
    1251                 :         
    1252              27 :         tx_destroy (&vars);
    1253                 : }
    1254                 : /* ------------------------------------------------------------------------- */
    1255                 : LOCAL void receive_variables ()
    1256              27 : {
    1257                 :         void *shmaddr;
    1258                 :         unsigned int size;
    1259              27 :         char *var_buff = INITPTR, *variable_str, *p;
    1260                 :         MinItemParser *mip;
    1261                 : 
    1262              27 :         shmaddr = sm_attach (scripter_mod.shm_id);
    1263              27 :         if (shmaddr == INITPTR) {
    1264               0 :                 SCRIPTER_RTERR ("Could not attach to shared memory segment");
    1265               0 :                 return;
    1266                 :         }
    1267                 : 
    1268              27 :         if ( sm_read (shmaddr, &size, sizeof (unsigned int)) != ENOERR) {
    1269               0 :                 SCRIPTER_RTERR ("Read from shared memory segment failed");
    1270               0 :                 goto exit;
    1271              27 :         } else if (size == 0) {
    1272               0 :                 goto exit;
    1273                 :         }
    1274                 :         /*
    1275                 :         ** Read the variable buffer from shared memory
    1276                 :         */
    1277              27 :         var_buff = NEW2 (char, size + 1);
    1278              27 :         sm_read (shmaddr + sizeof (unsigned int), var_buff, size); 
    1279              27 :         var_buff [size] = '\0';
    1280              27 :         MIN_DEBUG ("RECEIVED from test class: %s", var_buff);
    1281                 :         /*
    1282                 :         ** Create Item Parser for variable parsing
    1283                 :         */
    1284              27 :         mip = mip_create (var_buff, 0, size);
    1285              27 :         if (mip == INITPTR) {
    1286               0 :                 SCRIPTER_RTERR ("Failed to create item parser from variables");
    1287               0 :                 goto exit;
    1288                 :         }
    1289                 :         /*
    1290                 :         ** Parse the variables and save them to variable list
    1291                 :         */
    1292              27 :         mip_get_string (mip, INITPTR, &variable_str);
    1293             209 :         while (variable_str != INITPTR) {
    1294             182 :                 if ((p =  strrchr (variable_str, '=')) == NULL) {  
    1295               0 :                         if (var_find (variable_str) == INITPTR) {
    1296               0 :                                 SCRIPTER_RTERR_ARG ("Undeclared variable from"
    1297                 :                                             "testclass", variable_str);
    1298               0 :                                 DELETE (variable_str);
    1299               0 :                                 goto exit;
    1300                 :                         }
    1301                 :                 } else {
    1302                 :                         /* 
    1303                 :                         ** test class may have set the variable
    1304                 :                         */
    1305             182 :                         *p = '\0';
    1306             182 :                         p++;
    1307                 :                         
    1308             182 :                         if (strlen (p) > 0) {
    1309                 :                                 /*
    1310                 :                                 ** try to assign the new value
    1311                 :                                 */
    1312             182 :                                 var_assign (variable_str, p);
    1313             182 :                                 DELETE (variable_str);
    1314               0 :                         } else if (var_find (variable_str) == INITPTR) {
    1315                 :                                 /*
    1316                 :                                 ** Check that the variable is declared
    1317                 :                                 */
    1318               0 :                                 SCRIPTER_RTERR_ARG ("undeclared variable from "
    1319                 :                                                     "testclass", variable_str);
    1320               0 :                                 DELETE (variable_str);
    1321               0 :                                 goto exit;
    1322                 :                         
    1323                 :                         }
    1324                 :                 }
    1325             182 :                 if (mip_get_next_string (mip, &variable_str) != ENOERR)
    1326              27 :                         break;
    1327                 :         } 
    1328                 : 
    1329              27 : exit:
    1330              27 :         if (mip != INITPTR)
    1331              27 :                 mip_destroy (&mip);
    1332              27 :         if (var_buff != INITPTR)
    1333              27 :                 DELETE (var_buff);
    1334                 : 
    1335              27 :         sm_detach (shmaddr);
    1336                 : 
    1337              27 :         return;
    1338                 : }
    1339                 : 
    1340                 : /* ------------------------------------------------------------------------- */
    1341                 : LOCAL void scripter_final_verdict (DLList * tp_details, TestCaseResult * tcr)
    1342              24 : {
    1343                 :         ScriptedTestProcessDetails *stpd;
    1344                 :         DLListIterator  tpit, reit;
    1345                 :         TestCaseResult *res;
    1346                 :         int             num_fail, num_ok, cancelled;
    1347              24 :         num_fail = num_ok = cancelled = 0;
    1348                 :         char *result_str [] = {"CRASHED",
    1349                 :                                "TIMEOUTED",
    1350                 :                                "TP_PASSED",
    1351                 :                                "FAILED",
    1352                 :                                "NOT COMPLETE",
    1353              24 :                                "LEFT"};
    1354                 :         
    1355              24 :         for (tpit = dl_list_head (tp_details);
    1356              39 :              tpit != DLListNULLIterator; tpit = dl_list_next (tpit)) {
    1357              15 :                 stpd = dl_list_data (tpit);
    1358              15 :                 switch (stpd->status_) {
    1359                 :                 case TP_ENDED:
    1360                 :                 case TP_ABORTED:
    1361                 :                         break;
    1362                 :                 case TP_CANCELED:
    1363               0 :                         snprintf (tcr->desc_, 
    1364                 :                                   MaxTestResultDescription - 1, 
    1365                 :                                   "Run %s(%d) cancelled  ",
    1366                 :                                   stpd->dllname_,
    1367                 :                                   stpd->tc_id_
    1368                 :                                 );
    1369               0 :                         cancelled = 1;
    1370               0 :                         continue;
    1371                 :                 default:
    1372               0 :                         MIN_WARN ("Unexpected status of scripter "
    1373                 :                                   "test case %d", stpd->status_);
    1374               0 :                         snprintf (tcr->desc_, 
    1375                 :                                   MaxTestResultDescription - 1,
    1376                 :                                   "Unexpected status (%d) of scripter"
    1377                 :                                   "test case", stpd->status_);
    1378                 :                                   
    1379               0 :                         num_fail++;
    1380               0 :                         continue;
    1381                 :                         
    1382                 :                 }
    1383              15 :                 for (reit = dl_list_head (stpd->tcr_list_);
    1384              50 :                      reit != DLListNULLIterator; reit = dl_list_next (reit)) {
    1385              35 :                         res = dl_list_data (reit);
    1386              35 :                         switch (res->result_) {
    1387                 :                         case TP_CRASHED:
    1388                 :                         case TP_FAILED:
    1389                 :                         case TP_TIMEOUTED:
    1390                 :                         case TP_LEAVE:
    1391               0 :                                 num_fail++;
    1392               0 :                                 if (strlen (tcr->desc_) > 0) 
    1393               0 :                                         break;
    1394               0 :                                 if (stpd->mod_type_ == EDLLTypeClass)
    1395               0 :                                         snprintf (tcr->desc_, 
    1396                 :                                                   MaxTestResultDescription - 1,
    1397                 :                                                   "Test Method call \"%s.%s\""
    1398                 :                                                   "  %s",
    1399                 :                                                   stpd->testclass_, 
    1400                 :                                                   res->desc_,
    1401                 :                                                   result_str 
    1402                 :                                                   [res->result_ + 2]);
    1403                 :                                 else {
    1404               0 :                                         snprintf (tcr->desc_,
    1405                 :                                                   MaxTestResultDescription - 1, 
    1406                 :                                                   "Run %s(%d) %s: %s ",
    1407                 :                                                   stpd->dllname_,
    1408                 :                                                   stpd->tc_id_,
    1409                 :                                                   result_str 
    1410                 :                                                   [res->result_ + 2],
    1411                 :                                                   res->desc_
    1412                 :                                                 );
    1413                 :                                 }
    1414               0 :                                 break;
    1415                 :                         case TP_PASSED:
    1416              35 :                                 num_ok++;
    1417              35 :                                 break;
    1418                 :                         case TP_NC:
    1419               0 :                                 MIN_DEBUG ("TP_NC .. unxepected result code");
    1420               0 :                                 break;
    1421                 :                                 num_fail++;
    1422                 :                                 break;
    1423                 :                         default:
    1424               0 :                                 MIN_DEBUG ("unknown result code %d",
    1425                 :                                              tcr->result_);
    1426                 :                                 break;
    1427                 :                         }
    1428                 :                 }
    1429                 :         }
    1430                 : 
    1431              24 :         if (cancelled) {
    1432               0 :                 tcr->result_ = TP_NC;
    1433              24 :         } else if (num_fail > 0) {
    1434               0 :                 if (num_fail > 1)
    1435               0 :                         sprintf (tcr->desc_, "%s (%d other errors/failures)",
    1436                 :                                  tcr->desc_, num_fail - 1);
    1437               0 :                 tcr->result_ = TP_FAILED;
    1438                 :         } else {
    1439              24 :                 tcr->result_ = TP_PASSED;
    1440              24 :                 sprintf (tcr->desc_, "Scripted test case passed");
    1441                 :         }
    1442              24 :         MIN_DEBUG ("returning from scripter with desc %s",
    1443                 :                    tcr->desc_);
    1444                 :         
    1445              24 : }
    1446                 : 
    1447                 : 
    1448                 : /* ------------------------------------------------------------------------- */
    1449                 : /* ======================== FUNCTIONS ====================================== */
    1450                 : /* ------------------------------------------------------------------------- */
    1451                 : int substract_timeval (struct timeval *result, struct timeval *x,
    1452                 :                        struct timeval *y)
    1453            1283 : {
    1454                 :         /* Perform the carry for the later subtraction by updating y. */
    1455            1283 :         if (x->tv_usec < y->tv_usec) {
    1456                 :                 int             nsec =
    1457              19 :                     (y->tv_usec - x->tv_usec) / 1000000 + 1;
    1458              19 :                 y->tv_usec -= 1000000 * nsec;
    1459              19 :                 y->tv_sec += nsec;
    1460                 :         }
    1461            1283 :         if (x->tv_usec - y->tv_usec > 1000000) {
    1462              19 :                 int             nsec = (x->tv_usec - y->tv_usec) / 1000000;
    1463              19 :                 y->tv_usec += 1000000 * nsec;
    1464              19 :                 y->tv_sec -= nsec;
    1465                 :         }
    1466                 : 
    1467                 :         /* Compute the time remaining to wait.
    1468                 :          * tv_usec is certainly positive. */
    1469            1283 :         result->tv_sec = x->tv_sec - y->tv_sec;
    1470            1283 :         result->tv_usec = x->tv_usec - y->tv_usec;
    1471                 : 
    1472                 :         /* Return 1 if result is negative. */
    1473            1283 :         return x->tv_sec < y->tv_sec;
    1474                 : }
    1475                 : 
    1476                 : /* ------------------------------------------------------------------------- */
    1477                 : int add_timeval (struct timeval *result, struct timeval *x, struct timeval *y)
    1478               0 : {
    1479                 :         /* add it */
    1480               0 :         result->tv_usec = x->tv_usec + y->tv_usec;
    1481               0 :         result->tv_sec = x->tv_sec + y->tv_sec;
    1482                 : 
    1483                 :         /* round it */
    1484               0 :         while (result->tv_usec < 1000000) {
    1485               0 :                 result->tv_usec -= 1000000;
    1486               0 :                 result->tv_sec++;
    1487                 :         }
    1488                 : 
    1489                 : 
    1490               0 :         return 1;
    1491                 : }
    1492                 : 
    1493                 : /* ------------------------------------------------------------------------- */
    1494                 : int testclass_create (filename_t dllName, char *className)
    1495              15 : {
    1496              15 :         int             retval = ENOERR;
    1497              15 :         pid_t           pid = -1;
    1498              15 :         char           *dllpath = NEW2 (char, strlen (dllName) + 3 + 1);
    1499              15 :         ScriptedTestProcessDetails *stpd = INITPTR;
    1500                 :         MsgBuffer       input_buffer;
    1501                 : 
    1502              15 :         if (strlen (dllName) == 0) {
    1503               0 :                 errno = EINVAL;
    1504               0 :                 retval = -1;
    1505               0 :                 SCRIPTER_RTERR ("Library is 0 lenght");
    1506               0 :                 goto EXIT;
    1507                 :         }
    1508              15 :         if (className == INITPTR) {
    1509               0 :                 errno = EINVAL;
    1510               0 :                 SCRIPTER_RTERR ("class name missing");
    1511               0 :                 retval = -1;
    1512               0 :                 goto EXIT;
    1513                 :         }
    1514                 : 
    1515              15 :         STRCPY (dllpath, dllName, strlen (dllName));
    1516              15 :         STRCPY (&dllpath[strlen (dllName)], ".so", 4);
    1517                 : 
    1518              15 :         pid = fork ();
    1519              15 :         if (pid == 0) {
    1520                 :                 /* Child process, lets enter event loop */
    1521               6 :                 stprun = ESTrue;
    1522               6 :                 sched_yield ();
    1523               6 :                 min_log_open ("ScriptedTP", 3);
    1524               6 :                 mq_init_buffer ();
    1525               6 :                 signal (SIGUSR2, stp_handle_sigusr2);
    1526                 :                 
    1527               6 :                 fetch_ptr2run (dllpath, className);
    1528                 : 
    1529             240 :                 while (stprun) {
    1530             228 :                         if (mq_peek_message (scripter_mod.mqid, getpid())) {
    1531              27 :                                 retval = mq_read_message (scripter_mod.mqid,
    1532                 :                                                           getpid ()
    1533                 :                                                           , &input_buffer);
    1534              27 :                                 stp_handle_message (&input_buffer);
    1535                 :                         }
    1536             228 :                         usleep (10000);
    1537                 :                 }
    1538               6 :                 stp_exit();
    1539               9 :         } else if (pid > 0) {
    1540                 :                 /* TestProcess details are stored on the list */
    1541               9 :                 MIN_INFO ("Scripted Test Process created, pid: %d",getpid());
    1542               9 :                 stpd = NEW (ScriptedTestProcessDetails);
    1543               9 :                 stpd->tcr_list_ = dl_list_create ();
    1544               9 :                 stpd->pid_ = pid;
    1545               9 :                 stpd->mod_type_ = EDLLTypeClass;
    1546               9 :                 stpd->status_ = TP_NONE;
    1547               9 :                 STRCPY (stpd->testclass_, className, 128);
    1548               9 :                 STRCPY (stpd->dllname_, dllpath, MaxFileName);
    1549               9 :                 dl_list_add (scripter_mod.tp_details, (void *)stpd);
    1550                 :         } else {
    1551                 :                 /* Error */
    1552               0 :                 SCRIPTER_RTERR ("Cannot create Scripted Test Process!");
    1553               0 :                 MIN_ERROR ("Cannot create Scripted Test Process!");
    1554                 :         }
    1555               9 :         DELETE (dllpath);
    1556               9 :       EXIT:
    1557               9 :         return retval;
    1558                 : }
    1559                 : 
    1560                 : /* ------------------------------------------------------------------------- */
    1561                 : int testclass_call_function (char *className, MinItemParser * mip)
    1562              27 : {
    1563              27 :         int             retval = ENOERR;
    1564              27 :         int            *tmp = INITPTR;
    1565              27 :         DLListIterator  it = DLListNULLIterator;
    1566              27 :         ScriptedTestProcessDetails *stpd = INITPTR;
    1567                 :         MsgBuffer       msg;
    1568              27 :         char           *token = INITPTR;
    1569                 : 
    1570              27 :         memset(&msg, 0x0, sizeof(MsgBuffer));
    1571                 : 
    1572              27 :         if (className == INITPTR || strlen (className) == 0) {
    1573               0 :                 errno = EINVAL;
    1574               0 :                 SCRIPTER_RTERR ("class name missing");
    1575               0 :                 retval = -1;
    1576               0 :                 goto EXIT;
    1577                 :         }
    1578                 : 
    1579                 :         /* 1)  look for classname on list */
    1580                 : 
    1581              27 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
    1582                 :                            , dl_list_tail (scripter_mod.tp_details)
    1583                 :                            , _findclass, (void *)className);
    1584                 : 
    1585              27 :         if (it == DLListNULLIterator) {
    1586               0 :                 errno = ENODATA;
    1587               0 :                 retval = -1;
    1588               0 :                 SCRIPTER_RTERR_ARG ("Class not found on list", className);
    1589               0 :                 MIN_ERROR ("Class not found on list [%s]", className);
    1590               0 :                 goto EXIT;
    1591                 :         }
    1592                 : 
    1593              27 :         stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
    1594                 : 
    1595                 :         /* 2) Fill msg structure with data */
    1596              27 :         msg.receiver_ = stpd->pid_;
    1597              27 :         msg.sender_ = getpid ();
    1598              27 :         msg.type_ = MSG_RUN;
    1599              27 :         msg.param_ = 0;
    1600                 : 
    1601              27 :         msg.desc_[0] = '\0';
    1602              27 :         if (dl_list_size (variables) == 0) {
    1603               0 :                 STRCPY (msg.desc_, mip->item_skip_and_mark_pos_, MaxDescSize);
    1604               0 :                 if (msg.desc_ [MaxDescSize - 1] != '\0' &&
    1605                 :                     msg.desc_ [MaxDescSize - 1] != 0x0){
    1606               0 :                         SCRIPTER_RTERR_ARG ("Method call too long", className);
    1607               0 :                         msg.desc_[MaxDescSize-1] = '\0';
    1608                 :                 }
    1609                 :         } else {
    1610              97 :                 while (mip_get_next_string (mip, &token) == ENOERR) {
    1611              43 :                         if (strlen (msg.desc_) + strlen (var_value (token)) 
    1612                 :                             >= MaxDescSize) {
    1613               0 :                                 SCRIPTER_RTERR_ARG ("Method call too long", 
    1614                 :                                                     className);
    1615               0 :                                 msg.desc_[MaxDescSize-1] = '\0';
    1616                 :                         
    1617                 :                         } else
    1618              43 :                                 sprintf (msg.desc_, "%s %s", msg.desc_,
    1619                 :                                          var_value (token));
    1620                 :                 }
    1621              27 :                 DELETE (token);
    1622              27 :                 send_variables ();
    1623              27 :                 msg.special_ = scripter_mod.shm_id;
    1624                 :         }
    1625                 : 
    1626              27 :         STRCPY (msg.message_, className, MaxMsgSize);
    1627              27 :         msg.special_ = 0;
    1628                 :         /* 3) Handle result allowing. */
    1629              27 :         if (allowedresults == INITPTR) {
    1630              27 :                 stpd->allowed_results_ = dl_list_create ();
    1631              27 :                 tmp = NEW (int);
    1632              27 :                 *tmp = ENOERR;
    1633              27 :                 dl_list_add (stpd->allowed_results_, (void *)tmp);
    1634                 :         } else {
    1635               0 :                 stpd->allowed_results_ = allowedresults;
    1636               0 :                 allowedresults = INITPTR;
    1637                 :         }
    1638                 : 
    1639                 :         /* 4) send MSG_RUN command */
    1640              27 :         mq_send_message (scripter_mod.mqid, &msg);
    1641                 : 
    1642                 :         /* 5) Block the script execution until we get result back */
    1643              27 :         scripter_mod.tclass_exec = 1;
    1644              27 :       EXIT:
    1645              27 :         return retval;
    1646                 : }
    1647                 : 
    1648                 : /* ------------------------------------------------------------------------- */
    1649                 : int test_run (const char *modulename, const char *configfile, unsigned int id,
    1650                 :               MinItemParser * mip)
    1651              14 : {
    1652              14 :         ScriptedTestProcessDetails *stpd = INITPTR;
    1653              14 :         int             retval = ENOERR;
    1654              14 :         int             tmp = 0;
    1655                 :         test_libl_t     testlib;
    1656              14 :         DLList         *cases = INITPTR;
    1657              14 :         DLListIterator  it = DLListNULLIterator;
    1658                 :         struct sigaction pause_action;
    1659                 : 
    1660              14 :         TestCaseInfo   *tci = INITPTR;
    1661                 :         TestCaseResult  tcr;
    1662              14 :         if (modulename == INITPTR) {
    1663               0 :                 errno = EINVAL;
    1664               0 :                 retval = -1;
    1665               0 :                 goto EXIT;
    1666                 :         }
    1667              14 :         if (configfile == INITPTR) {
    1668               0 :                 errno = EINVAL;
    1669               0 :                 retval = -1;
    1670               0 :                 goto EXIT;
    1671                 :         }
    1672              14 :         if (mip == INITPTR) {
    1673               0 :                 errno = EINVAL;
    1674               0 :                 retval = -1;
    1675               0 :                 goto EXIT;
    1676                 :         }
    1677                 : 
    1678              14 :         stpd = NEW (ScriptedTestProcessDetails);
    1679              14 :         stpd->tcr_list_ = dl_list_create ();
    1680                 : 
    1681                 :         /* 1) Fetch possible optional parameters. */
    1682              14 :         read_optional_run_params (mip, &stpd->options_);
    1683                 : 
    1684              14 :         testlib.test_library_ = tl_open_tc (modulename);
    1685              14 :         strncpy (testlib.fname_, modulename, 255);
    1686              14 :         testlib.get_cases_fun_ = (ptr2case) dlsym (testlib.test_library_,
    1687                 :                                                    "tm_get_test_cases");
    1688              14 :         testlib.run_case_fun_ = (ptr2run) dlsym (testlib.test_library_,
    1689                 :                                                  "tm_run_test_case");
    1690                 : 
    1691              14 :         if (tl_is_ok (&testlib) == 0) {
    1692               0 :                 retval = -1;
    1693               0 :                 SCRIPTER_RTERR_ARG ("Error opening", modulename);
    1694               0 :                 goto EXIT;
    1695                 :         }
    1696                 :         /* Now we can execute a test. If test case title is
    1697                 :          * specified then we have to use it, otherwise the 
    1698                 :          * id can be used */
    1699              14 :         if (strlen (stpd->options_.title_) > 0) {
    1700                 :                 /* Use title, so first we have to find out
    1701                 :                  * what is the id of the case of given name. */
    1702               7 :                 cases = dl_list_create ();
    1703               7 :                 testlib.get_cases_fun_ (configfile, &cases);
    1704               7 :                 it = dl_list_head (cases);
    1705               7 :                 id = 1;
    1706              21 :                 while (it != DLListNULLIterator) {
    1707              14 :                         tci = (TestCaseInfo *) dl_list_data (it);
    1708              14 :                         tmp = strcmp (tci->name_, stpd->options_.title_);
    1709              14 :                         if (tmp == 0) {
    1710               7 :                                 break;
    1711                 :                         }
    1712               7 :                         it = dl_list_next (it);
    1713               7 :                         id++;
    1714                 :                 }
    1715               7 :                 dl_list_free_data (&cases);
    1716               7 :                 dl_list_free (&cases);
    1717                 :         }
    1718                 : 
    1719                 :         /* 3) Run a test */
    1720              14 :         stpd->pid_ = fork ();
    1721              14 :         if (stpd->pid_ > 0) {
    1722                 :                 /* Parent */
    1723               8 :                 STRCPY (stpd->testclass_, "\0", 1);
    1724               8 :                 STRCPY (stpd->dllname_, modulename, MaxFileName);
    1725               8 :                 STRCPY (stpd->cfgfile_, configfile, MaxFileName);
    1726               8 :                 stpd->tc_id_ = id;
    1727               8 :                 stpd->mod_type_ = EDLLTypeNormal;
    1728               8 :                 stpd->status_ = TP_RUNNING;
    1729               8 :                 scripter_mod.testcomplete = INITPTR;
    1730               8 :                 dl_list_add (scripter_mod.tp_details, (void *)stpd);
    1731               6 :         } else if (stpd->pid_ == 0) {
    1732                 :                 /* Child */
    1733               6 :                 ctprun = ESTrue;
    1734               6 :                 min_log_open ("Combined Test Process", 3);
    1735               6 :                 MIN_INFO ("Combined Test Process created, pid: %d",getpid());
    1736               6 :                 mq_init_buffer ();
    1737               6 :                 sched_yield ();
    1738               6 :                 signal (SIGUSR2, ctp_handle_sigusr2);
    1739                 : 
    1740               6 :                 pause_action.sa_sigaction = ctp_hande_sigtstp;
    1741               6 :                 sigfillset (&pause_action.sa_mask);
    1742               6 :                 pause_action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
    1743               6 :                 sigaction (SIGTSTP, &pause_action, NULL);
    1744               6 :                 testlib.run_case_fun_ (id, configfile, &tcr);
    1745               6 :                 mq_send_message2 (scripter_mod.mqid, getppid ()
    1746                 :                                   , MSG_RET, tcr.result_, tcr.desc_);
    1747              27 :                 while (ctprun) {
    1748              15 :                         usleep (10000);
    1749                 :                 }               /* Wait for death */
    1750                 :                 /* resend buffered, flush message buffer */
    1751               6 :                 mq_resend_buffered ();
    1752               6 :                 mq_flush_msg_buffer ();
    1753                 :                 /* At the end exit gracefully. */
    1754               6 :                 exit (TP_EXIT_SUCCESS);
    1755                 :         } else {
    1756               0 :                 SCRIPTER_RTERR ("Test Process NOT created");
    1757               0 :                 MIN_ERROR ("Combined Test Process NOT created");
    1758               0 :                 goto EXIT;
    1759                 :         }
    1760                 : 
    1761               8 :       EXIT:
    1762               8 :         return retval;
    1763                 : }
    1764                 : 
    1765                 : /* ------------------------------------------------------------------------- */
    1766                 : int testclass_destroy (char *className)
    1767               6 : {
    1768                 :         DLListIterator  it;
    1769               6 :         int             retval = ENOERR;
    1770               6 :         ScriptedTestProcessDetails *stpd = INITPTR;
    1771                 : 
    1772               6 :         if (className == INITPTR) {
    1773               0 :                 errno = EINVAL;
    1774               0 :                 SCRIPTER_RTERR ("No class name");
    1775               0 :                 goto EXIT;
    1776                 :         }
    1777               6 :         if (strlen (className) == 0) {
    1778               0 :                 errno = EINVAL;
    1779               0 :                 SCRIPTER_RTERR ("Class name has 0 lenght");
    1780               0 :                 retval = -1;
    1781               0 :                 goto EXIT;
    1782                 :         }
    1783                 : 
    1784                 :         /* clean-up code */
    1785               6 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
    1786                 :                            , dl_list_tail (scripter_mod.tp_details)
    1787                 :                            , _findclass, (void *)className);
    1788               6 :         if (it == DLListNULLIterator) {
    1789               0 :                 errno = ENODATA;
    1790               0 :                 retval = -1;
    1791               0 :                 SCRIPTER_RTERR_ARG("Class not found on list]", className);
    1792               0 :                 MIN_ERROR ("Class not found on list");
    1793               0 :                 goto EXIT;
    1794                 :         }
    1795                 : 
    1796               6 :         stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
    1797                 : 
    1798               6 :         stpd->status_ = TP_ENDED;
    1799               6 :         retval = kill (stpd->pid_, SIGUSR2);
    1800               6 :         if (retval == -1)
    1801               0 :                 MIN_WARN ("Cannot kill %d", stpd->pid_);
    1802                 :         else
    1803               6 :                 MIN_DEBUG ("Killed %d", stpd->pid_);
    1804               6 :         sleep (1);
    1805                 : 
    1806               6 :       EXIT:
    1807               6 :         return retval;
    1808                 : }
    1809                 : 
    1810                 : /* ------------------------------------------------------------------------- */
    1811                 : int event_request (char *eventname, int is_state)
    1812               1 : {
    1813               1 :         int             retval = ENOERR;
    1814                 :         minEventIf    *event;
    1815                 : 
    1816                 :         /*
    1817                 :          ** We can't be registered for the same event more than once 
    1818                 :          */
    1819               1 :         event = find_event_reqistration (eventname);
    1820               1 :         if (event != INITPTR) {
    1821               0 :                 SCRIPTER_RTERR_ARG ("Process already registered for event",
    1822                 :                                     eventname);
    1823               0 :                 MIN_NOTICE ("Process already registered for event %s",
    1824                 :                              eventname);
    1825               0 :                 return -1;
    1826                 :         }
    1827                 : 
    1828                 :         /*
    1829                 :          ** Create and request the event
    1830                 :          */
    1831               1 :         event =
    1832                 :             min_event_create (eventname, is_state ? EState : EIndication);
    1833               1 :         event->dont_block_ = ESTrue;
    1834               1 :         scripter_mod.event_pending = ESTrue;
    1835               1 :         event->SetType (event, EReqEvent);
    1836               1 :         Event (event);
    1837                 : 
    1838                 :         /*
    1839                 :          ** Add event to the local list of requested event or destroy
    1840                 :          */
    1841               1 :         dl_list_add (scripter_mod.req_events, event);
    1842               1 :         retval = ENOERR;
    1843                 : 
    1844               1 :         return retval;
    1845                 : }
    1846                 : 
    1847                 : /* ------------------------------------------------------------------------- */
    1848                 : int event_wait (char *eventname)
    1849               1 : {
    1850               1 :         int             retval = ENOERR;
    1851                 :         minEventIf    *event;
    1852                 : 
    1853                 :         /*
    1854                 :          ** We must be registered for the event in order to wait
    1855                 :          */
    1856               1 :         event = find_event_reqistration (eventname);
    1857               1 :         if (event == INITPTR) {
    1858               0 :                 SCRIPTER_RTERR_ARG ("No registration for event", eventname);
    1859               0 :                 MIN_WARN ("No registarion for event %s", eventname);
    1860               0 :                 return -1;
    1861                 :         }
    1862                 : 
    1863                 :         /*
    1864                 :          ** Wait for the event
    1865                 :          */
    1866               1 :         event->SetType (event, EWaitEvent);
    1867               1 :         scripter_mod.event_pending = ESTrue;
    1868               1 :         Event (event);
    1869                 : 
    1870               1 :         if (event->event_status_ == EventStatOK) {
    1871               1 :                 retval = ENOERR;
    1872                 :         } else {
    1873               0 :                 SCRIPTER_RTERR_ARG ("Event() returned with error", eventname);
    1874               0 :                 MIN_WARN ("Event():%s returned with error", eventname);
    1875               0 :                 retval = -1;
    1876                 :         }
    1877               1 :         return retval;
    1878                 : }
    1879                 : 
    1880                 : /* ------------------------------------------------------------------------- */
    1881                 : int event_release (char *eventname)
    1882               1 : {
    1883               1 :         int             retval = ENOERR;
    1884                 :         minEventIf    *event;
    1885                 : 
    1886                 :         /*
    1887                 :          ** We must be registered for the event in order release it
    1888                 :          */
    1889               1 :         event = find_event_reqistration (eventname);
    1890               1 :         if (event == INITPTR) {
    1891               0 :                 SCRIPTER_RTERR_ARG ("No registration for event %s", eventname);
    1892               0 :                 MIN_WARN ("No registration for event %s", eventname);
    1893               0 :                 return -1;
    1894                 :         }
    1895                 : 
    1896                 :         /*
    1897                 :          ** Release the event
    1898                 :          */
    1899               1 :         event->SetType (event, ERelEvent);
    1900               1 :         scripter_mod.event_pending = ESTrue;
    1901               1 :         Event (event);
    1902                 : 
    1903               1 :         if (event->event_status_ == EventStatOK) {
    1904               1 :                 retval = ENOERR;
    1905                 :         } else {
    1906               0 :                 SCRIPTER_RTERR_ARG ("Event() returned with error", eventname);
    1907               0 :                 MIN_WARN (" Event():%s returned with error", eventname);
    1908               0 :                 retval = -1;
    1909                 :         }
    1910                 : 
    1911               1 :         return retval;
    1912                 : }
    1913                 : 
    1914                 : /* ------------------------------------------------------------------------- */
    1915                 : int event_set (char *eventname, int is_state)
    1916               1 : {
    1917               1 :         int             retval = ENOERR;
    1918                 :         minEventIf    *event;
    1919               1 :         event =
    1920                 :             min_event_create (eventname, is_state ? EState : EIndication);
    1921               1 :         event->dont_block_ = ESTrue;
    1922               1 :         event->SetType (event, ESetEvent);
    1923               1 :         scripter_mod.event_pending = ESTrue;
    1924               1 :         Event (event);
    1925               1 :         if (event->event_status_ == EventStatOK) {
    1926               1 :                 retval = ENOERR;
    1927                 :         } else {
    1928               0 :                 SCRIPTER_RTERR_ARG ("Event() returned with error", eventname);
    1929               0 :                 MIN_WARN ("Event():%s returned with error", eventname);
    1930               0 :                 retval = -1;
    1931                 :         }
    1932                 : 
    1933               1 :         min_event_destroy (event);
    1934                 : 
    1935               1 :         return retval;
    1936                 : }
    1937                 : 
    1938                 : /* ------------------------------------------------------------------------- */
    1939                 : int event_unset (char *eventname)
    1940               1 : {
    1941               1 :         int             retval = ENOERR;
    1942                 :         minEventIf    *event;
    1943                 : 
    1944               1 :         event = min_event_create (eventname, EState);
    1945               1 :         event->dont_block_ = ESTrue;
    1946               1 :         event->SetType (event, EUnsetEvent);
    1947               1 :         scripter_mod.event_pending = ESTrue;
    1948               1 :         Event (event);
    1949               1 :         if (event->event_status_ == EventStatOK) {
    1950               1 :                 retval = ENOERR;
    1951                 :         } else {
    1952               0 :                 SCRIPTER_RTERR_ARG ("Event() returned with error", eventname);
    1953               0 :                 MIN_WARN ("Event():%s returned with error", eventname);
    1954               0 :                 retval = -1;
    1955                 :         }
    1956                 : 
    1957               1 :         min_event_destroy (event);
    1958                 : 
    1959               1 :         return retval;
    1960                 : }
    1961                 : 
    1962                 : /* ------------------------------------------------------------------------- */
    1963                 : int script_finish (void)
    1964              24 : {
    1965              24 :         int             retval = ENOERR;
    1966              24 :         scripter_mod.script_finished = 1;
    1967              24 :         return retval;
    1968                 : }
    1969                 : 
    1970                 : /* ------------------------------------------------------------------------- */
    1971                 : int tm_run_test_case (unsigned int id, const char *cfg_file,
    1972                 :                       TestCaseResult * result)
    1973              39 : {
    1974              39 :         int             retval = ENOERR;
    1975              39 :         MinParser      *sp = INITPTR;
    1976              39 :         DLListIterator  prev_it, it = DLListNULLIterator;
    1977              39 :         MinSectionParser *msp = INITPTR;
    1978              39 :         TSBool          msg_pending = ESFalse;
    1979              39 :         pid_t           pid = getpid ();
    1980              39 :         char           *path = INITPTR;
    1981              39 :         char           *c = INITPTR;
    1982                 :         MsgBuffer       input_buffer;
    1983                 :         ScriptVar      *var;
    1984                 :         ScriptedTestProcessDetails *stpd;
    1985                 :         Text           *cfgdefault;
    1986              39 :         char *dir = INITPTR;
    1987              39 :         char *file = INITPTR;
    1988                 : 
    1989              39 :         if (cfg_file == INITPTR) {
    1990               0 :                 errno = EINVAL;
    1991               0 :                 retval = -1;
    1992               0 :                 SCRIPTER_RTERR("config file missing");
    1993               0 :                 goto EXIT;
    1994                 :         }
    1995              39 :         if (result == INITPTR) {
    1996               0 :                 errno = EINVAL;
    1997               0 :                 SCRIPTER_RTERR("result argument missing");
    1998               0 :                 retval = -1;
    1999               0 :                 goto EXIT;
    2000                 :         }
    2001              39 :         if (id < 1) {
    2002               0 :                 errno = EINVAL;
    2003               0 :                 SCRIPTER_RTERR("invalid test case id");
    2004               0 :                 retval = -1;
    2005               0 :                 goto EXIT;
    2006                 :         }
    2007                 : 
    2008                 :         /* This function is called by TMC just after fork, so it is good
    2009                 :          * place to initialize scripter internal structures so that they
    2010                 :          * can be independent. */
    2011                 : 
    2012                 :         /* 1) Initialize Parser */
    2013              39 :         path = NEW2 (char, strlen (cfg_file) + 1);
    2014              39 :         STRCPY (path, cfg_file, strlen (cfg_file) + 1);
    2015              39 :         c = strrchr (path, '/');
    2016              39 :         if (c == NULL) {
    2017               0 :                 cfgdefault = tx_create(getenv("HOME"));
    2018               0 :                 tx_c_append(cfgdefault,"/.min");
    2019               0 :                 c = tx_share_buf(cfgdefault);
    2020               0 :                 dir = c;
    2021               0 :                 file=path;
    2022                 :         }
    2023                 :         else {
    2024              39 :                 *c = '\0';
    2025              39 :                 c++;
    2026              39 :                 dir=path;
    2027              39 :                 file=c;
    2028                 :         }
    2029                 : 
    2030              39 :         sp = mp_create (dir, file, ENoComments);
    2031              39 :         if (sp == INITPTR) {
    2032               0 :                 SCRIPTER_RTERR_ARG("Min Parser failed to create", c);
    2033               0 :                 MIN_ERROR ("Min Parser failed to initialize, params: [%s][%s]",
    2034                 :                             path, c);
    2035               0 :                 retval = -1;
    2036               0 :                 goto EXIT;
    2037                 :         }
    2038                 : 
    2039              39 :         msp = mp_section (sp, "[Test]", "[Endtest]", id);
    2040              39 :         if (msp == INITPTR) {
    2041               0 :                 SCRIPTER_RTERR("Min Parser failed to create");
    2042               0 :                 MIN_ERROR ("Min Section Parser failed to initialize,"
    2043                 :                             " params: [%s][%s]",path, c);
    2044               0 :                 retval = -1;
    2045               0 :                 goto EXIT;
    2046                 :         }
    2047                 : 
    2048                 :         /* 2) Create Lego Snake */
    2049              39 :         mli_create (msp);
    2050                 : 
    2051                 :         /* 3) Initialize scripter and events stuff and shm */
    2052              39 :         scripter_mod.tp_details = dl_list_create ();
    2053              39 :         if (scripter_mod.tp_details == INITPTR) {
    2054               0 :                 retval = -1;
    2055               0 :                 SCRIPTER_RTERR("list creation failed");
    2056               0 :                 goto EXIT;
    2057                 :         }
    2058                 : 
    2059              39 :         scripter_mod.req_events = dl_list_create ();
    2060              39 :         scripter_mod.mqid = mq_open_queue ('a');
    2061              39 :         scripter_mod.script_finished = 0;
    2062              39 :         scripter_mod.tclass_exec = 0;
    2063              39 :         scripter_mod.extif_pending = ESFalse;
    2064              39 :         scripter_mod.extif_remote = 0;
    2065              39 :         scripter_mod.testcomplete = INITPTR;
    2066              39 :         scripter_mod.canceliferror = ESFalse;
    2067              39 :         scripter_mod.error_occured = ESFalse;
    2068              39 :         scripter_mod.sleep = 0;
    2069              39 :         scripter_mod.expected_var = INITPTR;
    2070              39 :         scripter_mod.shm_id = shmget (getpid(), 4096, 
    2071                 :                                       IPC_CREAT | 0660);
    2072                 : 
    2073              39 :         if (scripter_mod.shm_id < 0) {
    2074               0 :                 MIN_ERROR ("Failed to create shared mem segment: %s",
    2075                 :                           strerror (errno));
    2076               0 :                 goto EXIT;
    2077                 :         }
    2078              39 :         MIN_DEBUG ("shmid = %d", scripter_mod.shm_id); 
    2079                 :         /* 4) Initialize scripter (the callbacks) */
    2080              39 :         scripter_init (&scripter_mod.min_scripter_if);
    2081                 : 
    2082                 :         /* 5) Set test result to default (Not Complete) */
    2083              39 :         scripter_mod.script_tcr.result_ = TP_NC;
    2084              39 :         memset (scripter_mod.script_tcr.desc_, 0x0, MaxTestResultDescription);
    2085                 : 
    2086                 :         /* 6) Set SIGCHLD and SIGALRM signal handlers */
    2087                 :         /* signal (SIGCHLD, scripter_sigchld_handler); */
    2088              39 :         signal (SIGCHLD, SIG_IGN);
    2089                 :         /* 7) The uEngine main loop */
    2090            2823 :         while (!scripter_mod.script_finished || _pending_tests ()) {
    2091                 : 
    2092                 :                 /* Check if any messages to us. */
    2093            2760 :                 msg_pending = mq_peek_message (scripter_mod.mqid, pid);
    2094                 : 
    2095                 :                 /* If message is waiting then read it and handle. */
    2096            2760 :                 if (msg_pending || scripter_mod.script_finished) {
    2097                 : 
    2098              61 :                         uengine_read_message (scripter_mod.mqid,
    2099                 :                                               &input_buffer);
    2100              61 :                         uengine_handle_message (scripter_mod.mqid,
    2101                 :                                                 &input_buffer);
    2102                 :                 }
    2103                 : 
    2104                 :                 /* Execute line of a script. */
    2105            2760 :                 if (_execute_script ()) {
    2106             359 :                         interpreter_next ();
    2107                 :                 } else {
    2108                 :                         /*sleep to avoid eating up too much cpu time
    2109                 :                           smaller usleep times are known to cause
    2110                 :                           problems in some hardwares*/
    2111            2401 :                         usleep(10000);
    2112                 :                 }
    2113                 : 
    2114                 :         }
    2115                 : 
    2116                 :         /* 8) Set test case result */
    2117              24 :         if (!scripter_mod.error_occured)
    2118              24 :                 scripter_final_verdict (scripter_mod.tp_details,
    2119                 :                                         &scripter_mod.script_tcr);
    2120              24 :       EXIT:
    2121                 :         /* set test case result, default is passed. */
    2122              24 :         *result = scripter_mod.script_tcr;
    2123                 : 
    2124                 :         /* Do some cleanup */
    2125                 : 
    2126              24 :         if (scripter_mod.expected_var != INITPTR) {
    2127               1 :                 DELETE (scripter_mod.expected_var);
    2128                 :         }
    2129                 : 
    2130              24 :         it = dl_list_tail (defines);
    2131              48 :         while (it != DLListNULLIterator) {
    2132               0 :                 free (dl_list_data (it));
    2133               0 :                 prev_it = dl_list_prev (it);
    2134               0 :                 dl_list_remove_it (it);
    2135               0 :                 it = prev_it;
    2136                 :         }
    2137                 : 
    2138              24 :         it = dl_list_tail (variables);
    2139             195 :         while (it != DLListNULLIterator) {
    2140             147 :                 var = dl_list_data (it);
    2141             147 :                 DELETE (var->name_);
    2142             147 :                 if (var->value_ != INITPTR)
    2143             147 :                         DELETE (var->value_);
    2144             147 :                 DELETE (var);
    2145             147 :                 prev_it = dl_list_prev (it);
    2146             147 :                 dl_list_remove_it (it);
    2147             147 :                 it = prev_it;
    2148                 :         }
    2149                 : 
    2150              24 :         mli_destroy ();
    2151                 : 
    2152              24 :         it = dl_list_tail (scripter_mod.tp_details);
    2153              63 :         while (it != DLListNULLIterator) {
    2154              15 :                 stpd = dl_list_data (it);
    2155              15 :                 dl_list_foreach (dl_list_head (stpd->tcr_list_),
    2156                 :                                  dl_list_tail (stpd->tcr_list_), free);
    2157              15 :                 dl_list_free (&stpd->tcr_list_);
    2158              15 :                 DELETE (stpd);
    2159              15 :                 prev_it = dl_list_prev (it);
    2160              15 :                 dl_list_remove_it (it);
    2161              15 :                 it = prev_it;
    2162                 :         }
    2163                 : 
    2164              24 :         if (sp != INITPTR) {
    2165              24 :                 mp_destroy (&sp);
    2166                 :         }
    2167              24 :         if (msp != INITPTR) {
    2168              24 :                 mmp_destroy (&msp);
    2169                 :         }
    2170              24 :         DELETE (path);
    2171                 : 
    2172              24 :         if (scripter_mod.shm_id > 0)
    2173              24 :             sm_destroy (scripter_mod.shm_id);
    2174                 : 
    2175              24 :         return retval;
    2176                 : }
    2177                 : 
    2178                 : /* ------------------------------------------------------------------------- */
    2179                 : int tm_get_test_cases (const char *cfg_file, DLList ** cases)
    2180              63 : {
    2181              63 :         int             retval = ENOERR;
    2182              63 :         MinParser     *sp = INITPTR;
    2183              63 :         MinSectionParser *msp = INITPTR;
    2184              63 :         char           *cfg_file_backup = INITPTR;
    2185              63 :         char           *c = INITPTR;
    2186              63 :         unsigned int    section_number = 1;
    2187              63 :         char           *test_case_name = INITPTR, *tmp;
    2188              63 :         Text *homemindir = INITPTR;
    2189              63 :         char *dir = INITPTR;
    2190              63 :         char *file = INITPTR;
    2191                 :        
    2192                 :         /* 0) First call initializes global list of libraries and ptrs
    2193                 :          *    to api functions from them. Deallocating of this list is
    2194                 :          *    unfortunatelly quite problematical.
    2195                 :          */
    2196              63 :         if (tp_handlers == INITPTR) {
    2197              63 :                 tp_handlers = dl_list_create ();
    2198                 :         }
    2199                 : 
    2200                 : 
    2201              63 :         if (defines == INITPTR) {
    2202              63 :                 defines = dl_list_create ();
    2203                 :         }
    2204                 : 
    2205                 : 
    2206              63 :         if (variables == INITPTR) {
    2207              63 :                 variables = dl_list_create ();
    2208              63 :                 declare_internal_var ("FAIL_COUNT");
    2209              63 :                 declare_internal_var ("CRASH_COUNT");
    2210              63 :                 declare_internal_var ("TOUT_COUNT");
    2211              63 :                 declare_internal_var ("ABORT_COUNT");
    2212              63 :                 declare_internal_var ("ERROR_COUNT");
    2213              63 :                 declare_internal_var ("TOTAL_COUNT");
    2214                 :         }
    2215                 : 
    2216                 : 
    2217                 :         /* 1) Perform POST */
    2218              63 :         if (cfg_file == INITPTR) {
    2219               0 :                 retval = -1;
    2220               0 :                 errno = EINVAL;
    2221               0 :                 SCRIPTER_RTERR ("Configuration file missing");
    2222               0 :                 goto EXIT;
    2223                 :         }
    2224              63 :         if (*cases == INITPTR) {
    2225               0 :                 retval = -1;
    2226               0 :                 errno = EINVAL;
    2227               0 :                 SCRIPTER_RTERR ("Cases list missing");
    2228               0 :                 goto EXIT;
    2229                 :         }
    2230                 : 
    2231                 :         /* 2) Initialize the scripter plugin */
    2232              63 :         scripter_init (&scripter_mod.min_scripter_if);
    2233                 : 
    2234                 :         /* 3) Validate script syntax.
    2235                 :          *    This is connected to returning test cases. If test case is
    2236                 :          *    valid then its title is added to the *cases list, if not then
    2237                 :          *    title is not added and warning is logged */
    2238                 : 
    2239              63 :         cfg_file_backup = NEW2 (char, strlen (cfg_file) + 1);
    2240              63 :         STRCPY (cfg_file_backup, cfg_file, strlen (cfg_file) + 1);
    2241                 : 
    2242              63 :         c = strrchr (cfg_file_backup, '/');
    2243              63 :         if (c == NULL) {
    2244               0 :                 c = getenv("HOME");
    2245               0 :                 if (c) {
    2246               0 :                         homemindir = tx_create("");
    2247               0 :                         tx_c_append (homemindir,c);
    2248               0 :                         tx_c_append (homemindir,"/.min");
    2249               0 :                         dir = tx_share_buf(homemindir);
    2250               0 :                         file = cfg_file_backup;
    2251               0 :                 } else c = cfg_file_backup;
    2252                 :         } else {
    2253              63 :                 *c = '\0';
    2254              63 :                 c++;
    2255              63 :                 dir = cfg_file_backup;
    2256              63 :                 file = c;
    2257                 :         }
    2258                 : 
    2259              63 :         sp = mp_create (dir, file, ENoComments);
    2260                 : 
    2261              63 :         if (sp == INITPTR) {
    2262               0 :                 tmp = NEW2 (char, strlen (cfg_file_backup) + strlen (c) + 
    2263                 :                             strlen ("MinParser not created with "
    2264                 :                                     "params:[%s][%s]") +1 );
    2265               0 :                 sprintf (tmp, "MinParser not created with params:"
    2266                 :                          "[%s][%s]", cfg_file_backup, c);
    2267               0 :                 SCRIPTER_RTERR_ARG(tmp, strerror (errno));
    2268               0 :                 DELETE (tmp);
    2269               0 :                 MIN_ERROR ("MinParser failed to be created, params:"
    2270                 :                             "[%s][%s]: errno: %d",
    2271                 :                             cfg_file_backup, c, errno);
    2272               0 :                 retval = -1;
    2273               0 :                 goto EXIT;
    2274                 :         }
    2275                 : 
    2276                 : 
    2277                 :         /* Lets validate DEFINE section if present */
    2278              63 :         msp = mp_section (sp, "[Define]", "[Enddefine]", 1);
    2279              63 :         if (msp != INITPTR) {
    2280               0 :                 if (validate_define (msp) == ESFalse) {
    2281                 :                         /* define section is not correct --> no sense 
    2282                 :                            to process further */
    2283               0 :                         mmp_destroy (&msp);
    2284               0 :                         mp_destroy (&sp);
    2285               0 :                         DELETE (cfg_file_backup);
    2286               0 :                         dl_list_free (&tp_handlers);
    2287               0 :                         goto EXIT;
    2288                 :                 }
    2289                 :         }
    2290                 : 
    2291              63 :         mmp_destroy (&msp);
    2292                 : 
    2293                 :         /* Let's validate TEST CASES */
    2294              63 :         msp = mp_section (sp, "[Test]", "[Endtest]", section_number);
    2295            1088 :         while (msp != INITPTR) {
    2296                 : 
    2297                 :                 /* validate syntax. In return we get TC name or INITPTR */
    2298             962 :                 test_case_name = validate_test_case (msp);
    2299             962 :                 if (test_case_name == NULL)
    2300              76 :                         test_case_name = INITPTR;
    2301                 : 
    2302                 :                 /* add TC to list */
    2303             962 :                 if (test_case_name != INITPTR) {
    2304             886 :                         ENTRY2 (*cases  /* List of cases */
    2305                 :                                 , test_case_name        /* TC name       */
    2306                 :                                 , section_number);      /* TC id         */
    2307             886 :                         DELETE (test_case_name);
    2308                 :                 } else {
    2309              76 :                         MIN_WARN ("Test case is not valid! [%d]",
    2310                 :                                    section_number);
    2311                 : 
    2312                 :                 }
    2313                 : 
    2314                 :                 /* fetch next TC from file */
    2315             962 :                 section_number++;
    2316             962 :                 mmp_destroy (&msp);
    2317             962 :                 msp = mp_section (sp, "[Test]", "[Endtest]", section_number);
    2318                 :         }
    2319                 : 
    2320              63 :         tx_destroy(&homemindir);
    2321              63 :         mp_destroy (&sp);
    2322              63 :         DELETE (cfg_file_backup);
    2323              63 :         MIN_INFO ("Number of cases %d", dl_list_size (*cases));
    2324              63 :       EXIT:
    2325                 : 
    2326              63 :         return retval;
    2327                 : }
    2328                 : 
    2329                 : /* ------------------------------------------------------------------------- */
    2330                 : int testclass_print (MinItemParser * mip)
    2331              41 : {
    2332              41 :         int             retval = ENOERR;
    2333              41 :         char           *token = INITPTR;
    2334                 :         Text           *txt;
    2335                 :         
    2336              41 :         txt = tx_create (INITPTR);
    2337                 : 
    2338             217 :         while (mip_get_next_string (mip, &token) == ENOERR) {
    2339             135 :                 tx_c_append (txt, var_value (token));
    2340             135 :                 tx_c_append (txt, " ");
    2341                 :         }
    2342              41 :         DELETE (token);
    2343              41 :         tx_c_prepend (txt, "script: ");
    2344              41 :         tm_printf (5, "script", tx_share_buf (txt));
    2345                 : 
    2346              41 :         tx_destroy (&txt);
    2347              41 :         return retval;
    2348                 : }
    2349                 : 
    2350                 : /* ------------------------------------------------------------------------- */
    2351                 : int testclass_allownextresult (int nextresult, MinItemParser * mip)
    2352               2 : {
    2353               2 :         int             retval = ENOERR;
    2354               2 :         int            *result = INITPTR;
    2355                 : 
    2356               2 :         if (allowedresults == INITPTR) {
    2357               1 :                 allowedresults = dl_list_create ();
    2358                 :         }
    2359                 : 
    2360                 :         /* Add one mandatory result and continue if there are more of them */
    2361                 :         do {
    2362               2 :                 result = NEW (int);
    2363               2 :                 *result = nextresult;
    2364               2 :                 dl_list_add (allowedresults, (void *)result);
    2365               2 :                 retval = mip_get_next_int (mip, &nextresult);
    2366               2 :         } while (retval == ENOERR);
    2367                 : 
    2368                 :         /* At this point function return no error */
    2369               2 :         retval = ENOERR;
    2370               2 :         return retval;
    2371                 : }
    2372                 : 
    2373                 : /* ------------------------------------------------------------------------- */
    2374                 : int testclass_allowerrorcodes (int nexterrorcode, MinItemParser * mip)
    2375               0 : {
    2376               0 :         int             retval = ENOERR;
    2377               0 :         int            *error = INITPTR;
    2378                 : 
    2379               0 :         if (allowederrors == INITPTR) {
    2380               0 :                 allowederrors = dl_list_create ();
    2381                 :         }
    2382                 : 
    2383                 :         /* Add one mandatory error and continue if there are more of them */
    2384                 :         do {
    2385               0 :                 error = NEW (int);
    2386               0 :                 *error = nexterrorcode;
    2387               0 :                 dl_list_add (allowederrors, (void *)error);
    2388               0 :                 retval = mip_get_next_int (mip, &nexterrorcode);
    2389               0 :         } while (retval == ENOERR);
    2390                 : 
    2391                 :         /* At this point function return no error */
    2392               0 :         retval = ENOERR;
    2393               0 :         return retval;
    2394                 : }
    2395                 : 
    2396                 : /* ------------------------------------------------------------------------- */
    2397                 : int test_complete (const char *testid)
    2398               0 : {
    2399               0 :         int             retval = ENOERR;
    2400               0 :         DLListIterator  it = DLListNULLIterator;
    2401                 :         ScriptedTestProcessDetails *stpd;
    2402               0 :         int             tc_not_ended=0;
    2403                 : 
    2404               0 :         if (testid == INITPTR) {
    2405               0 :                 retval = -1;
    2406               0 :                 errno = EINVAL;
    2407               0 :                 SCRIPTER_RTERR ("test id missing");
    2408               0 :                 goto EXIT;
    2409                 :         }
    2410                 : 
    2411                 :         /* Check if test of given testid exists */
    2412               0 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
    2413                 :                            , dl_list_tail (scripter_mod.tp_details)
    2414                 :                            , _findid, (void *)testid);
    2415               0 :         if (it == DLListNULLIterator) {
    2416               0 :                 SCRIPTER_RTERR_ARG ("No test of specified testid", testid);
    2417               0 :                 MIN_WARN ("No test of specified testid [%s]", testid);
    2418               0 :                 retval = -1;
    2419               0 :                 goto EXIT;
    2420                 :         }
    2421                 : 
    2422                 :         /* Check if test with given testid has already completed */
    2423               0 :         while (it != DLListNULLIterator) {
    2424               0 :                 stpd = dl_list_data (it);
    2425               0 :                 if (stpd->status_ != TP_ENDED) {
    2426               0 :                         tc_not_ended = tc_not_ended + 1;
    2427                 :                 }
    2428               0 :                 it = dl_list_next (it);
    2429               0 :                 if (it == DLListNULLIterator)
    2430               0 :                         break;
    2431               0 :                 it = dl_list_find (it, dl_list_tail (scripter_mod.tp_details),
    2432                 :                                    _findid, (void *)testid);
    2433                 :         }
    2434               0 :         if(tc_not_ended==0){
    2435               0 :                 MIN_WARN ("All tests with testid= %s already completed", testid);
    2436               0 :                 goto EXIT;
    2437                 :         }
    2438                 :         /* Set 'wait for complete' flag */
    2439               0 :         scripter_mod.testcomplete = NEW2 (char, strlen (testid) + 1);
    2440               0 :         STRCPY (scripter_mod.testcomplete, testid, strlen (testid) + 1);
    2441                 : 
    2442               0 :       EXIT:
    2443               0 :         return retval;
    2444                 : }
    2445                 : 
    2446                 : /* ------------------------------------------------------------------------- */
    2447                 : int test_pause (char *testid, MinItemParser * mip)
    2448               2 : {
    2449               2 :         int             retval = ENOERR;
    2450                 :         union sigval    val;
    2451                 :         int             time;
    2452               2 :         DLListIterator  it = INITPTR;
    2453               2 :         ScriptedTestProcessDetails *stpd = INITPTR;
    2454                 :         char            tmp[12];
    2455                 : 
    2456               2 :         if (testid == INITPTR || strlen (testid) == 0) {
    2457               0 :                 errno = EINVAL;
    2458               0 :                 retval = -1;
    2459               0 :                 SCRIPTER_RTERR("test id missing");
    2460               0 :                 goto EXIT;
    2461                 :         }
    2462                 : 
    2463               2 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
    2464                 :                            , dl_list_tail (scripter_mod.tp_details)
    2465                 :                            , _findid, (void *)testid);
    2466                 : 
    2467               2 :         if (it == DLListNULLIterator) {
    2468               0 :                 errno = ENODATA;
    2469               0 :                 retval = -1;
    2470               0 :                 SCRIPTER_RTERR_ARG ("Testid not found", testid);
    2471               0 :                 MIN_ERROR ("Testid not found on list");
    2472               0 :                 goto EXIT;
    2473                 :         }
    2474                 : 
    2475               2 :         val.sival_int = 0;
    2476               2 :         if (mip_get_next_tagged_int (mip, "time", &time) == ENOERR)
    2477               1 :                 val.sival_int = time;
    2478                 : 
    2479               2 :         stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
    2480                 : 
    2481               2 :         if (stpd->status_ == TP_RUNNING) {
    2482               2 :                 sched_yield ();
    2483               2 :                 retval = sigqueue (stpd->pid_, SIGTSTP, val);
    2484               2 :                 if (retval == -1) {
    2485               0 :                         sprintf (tmp, "%u", stpd->pid_);
    2486               0 :                         SCRIPTER_RTERR_ARG ("Cannot pause", tmp);
    2487               0 :                         MIN_WARN ("Cannot pause %d", stpd->pid_);
    2488                 :                 }
    2489                 :                 else {
    2490               2 :                         stpd->status_ = TP_PAUSED;
    2491               2 :                         MIN_INFO ("paused %d", stpd->pid_);
    2492                 :                 }
    2493                 :         }
    2494                 : 
    2495               2 :       EXIT:
    2496               2 :         return retval;
    2497                 : }
    2498                 : 
    2499                 : /* ------------------------------------------------------------------------- */
    2500                 : int test_resume (char *testid)
    2501               1 : {
    2502               1 :         int             retval = ENOERR;
    2503               1 :         DLListIterator  it = INITPTR;;
    2504               1 :         ScriptedTestProcessDetails *stpd = INITPTR;
    2505                 :         char            tmp [12];
    2506                 : 
    2507               1 :         if (testid == INITPTR || strlen (testid) == 0) {
    2508               0 :                 errno = EINVAL;
    2509               0 :                 retval = -1;
    2510               0 :                 SCRIPTER_RTERR ("Test id missing");
    2511               0 :                 goto EXIT;
    2512                 :         }
    2513                 : 
    2514               1 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
    2515                 :                            , dl_list_tail (scripter_mod.tp_details)
    2516                 :                            , _findid, (void *)testid);
    2517                 : 
    2518               1 :         if (it == DLListNULLIterator) {
    2519               0 :                 errno = ENODATA;
    2520               0 :                 retval = -1;
    2521               0 :                 SCRIPTER_RTERR_ARG ("Testid not found", testid);
    2522               0 :                 MIN_ERROR ("Testid not found on list");
    2523               0 :                 goto EXIT;
    2524                 :         }
    2525                 : 
    2526               1 :         stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
    2527                 : 
    2528               1 :         if (stpd->status_ == TP_PAUSED) {
    2529               1 :                 retval = kill (stpd->pid_, SIGCONT);
    2530               1 :                 if (retval == -1) {
    2531               0 :                         sprintf (tmp, "%u", stpd->pid_);
    2532               0 :                         SCRIPTER_RTERR_ARG ("Cannot resume", tmp);
    2533               0 :                         MIN_WARN ("Cannot resume %d", stpd->pid_);
    2534                 :                 }
    2535                 :                 else {
    2536               1 :                         stpd->status_ = TP_RUNNING;
    2537               1 :                         MIN_INFO ("Resumed %d", stpd->pid_);
    2538                 :                 }
    2539                 :         }
    2540                 : 
    2541               1 :       EXIT:
    2542               1 :         return retval;
    2543                 : }
    2544                 : 
    2545                 : /* ------------------------------------------------------------------------- */
    2546                 : int test_cancel (char *testid)
    2547               1 : {
    2548               1 :         int             retval = ENOERR;
    2549               1 :         DLListIterator  it = INITPTR;;
    2550               1 :         ScriptedTestProcessDetails *stpd = INITPTR;
    2551                 :         char            tmp [12];
    2552                 : 
    2553               1 :         if (testid == INITPTR || strlen (testid) == 0) {
    2554               0 :                 errno = EINVAL;
    2555               0 :                 retval = -1;
    2556               0 :                 SCRIPTER_RTERR ("Test id missing");
    2557               0 :                 goto EXIT;
    2558                 :         }
    2559                 : 
    2560               1 :         it = dl_list_find (dl_list_head (scripter_mod.tp_details)
    2561                 :                            , dl_list_tail (scripter_mod.tp_details)
    2562                 :                            , _findid, (void *)testid);
    2563                 : 
    2564               1 :         if (it == DLListNULLIterator) {
    2565               0 :                 errno = ENODATA;
    2566               0 :                 retval = -1;
    2567               0 :                 SCRIPTER_RTERR_ARG ("Testid not found", testid);
    2568               0 :                 MIN_ERROR ("Testid not found on list");
    2569               0 :                 goto EXIT;
    2570                 :         }
    2571                 : 
    2572               1 :         stpd = (ScriptedTestProcessDetails *) dl_list_data (it);
    2573                 : 
    2574               1 :         retval = kill (stpd->pid_, SIGKILL);
    2575               1 :         if (retval == -1) {
    2576               0 :                 sprintf (tmp, "%u", stpd->pid_);
    2577               0 :                 SCRIPTER_RTERR_ARG ("Cannot cancel", tmp);
    2578               0 :                 MIN_WARN ("Cannot cancel %d", stpd->pid_);
    2579                 :         }
    2580                 :         else {
    2581               1 :                 stpd->status_ = TP_ABORTED;
    2582               1 :                 update_variables (TP_NC);
    2583               1 :                 MIN_INFO ("cancelled %d", stpd->pid_);
    2584                 :         }
    2585                 : 
    2586               1 :       EXIT:
    2587               1 :         return retval;
    2588                 : }
    2589                 : 
    2590                 : /* ------------------------------------------------------------------------- */
    2591                 : int test_allocate_slave (const char *slave_type, const char *slave_name)
    2592               3 : {
    2593               3 :         int             retval = ENOERR;
    2594                 :         MsgBuffer       msg;
    2595               3 :         msg.receiver_ = getppid ();
    2596               3 :         msg.sender_ = getpid ();
    2597               3 :         msg.type_ = MSG_EXTIF;
    2598               3 :         msg.param_ = 0;
    2599               3 :         msg.extif_msg_type_ = EAllocateSlave;
    2600                 : 
    2601               3 :         if (slave_type == INITPTR) {
    2602               0 :                 retval = -1;
    2603               0 :                 errno = EINVAL;
    2604               0 :                 SCRIPTER_RTERR ("slave type missing");
    2605               0 :                 goto EXIT;
    2606                 :         }
    2607               3 :         if (slave_name == INITPTR || strlen (slave_name) == 0) {
    2608               0 :                 retval = -1;
    2609               0 :                 errno = EINVAL;
    2610               0 :                 SCRIPTER_RTERR ("slave name missing");
    2611               0 :                 goto EXIT;
    2612                 :         }
    2613                 : 
    2614               3 :         STRCPY (msg.desc_, slave_type, MaxDescSize);
    2615               3 :         STRCPY (msg.message_, slave_name, MaxMsgSize);
    2616               3 :         mq_send_message (scripter_mod.mqid, &msg);
    2617                 : 
    2618                 :         /* Stop execution till response comes */
    2619               3 :         scripter_mod.extif_pending = ESTrue;
    2620               3 :       EXIT:
    2621               3 :         return retval;
    2622                 : }
    2623                 : 
    2624                 : /* ------------------------------------------------------------------------- */
    2625                 : int test_free_slave (const char *slave_name)
    2626               3 : {
    2627               3 :         int             retval = ENOERR;
    2628                 :         MsgBuffer       msg;
    2629               3 :         msg.receiver_ = getppid ();
    2630               3 :         msg.sender_ = getpid ();
    2631               3 :         msg.type_ = MSG_EXTIF;
    2632               3 :         msg.param_ = 0;
    2633               3 :         msg.extif_msg_type_ = EFreeSlave;
    2634                 : 
    2635               3 :         if (slave_name == INITPTR || strlen (slave_name) == 0) {
    2636               0 :                 retval = -1;
    2637               0 :                 errno = EINVAL;
    2638               0 :                 SCRIPTER_RTERR ("slave_name missing");
    2639               0 :                 goto EXIT;
    2640                 :         }
    2641                 : 
    2642               3 :         STRCPY (msg.message_, slave_name, MaxMsgSize);
    2643               3 :         mq_send_message (scripter_mod.mqid, &msg);
    2644                 : 
    2645                 :         /* Stop execution till response comes */
    2646               3 :         scripter_mod.extif_pending = ESTrue;
    2647               3 :       EXIT:
    2648               3 :         return retval;
    2649                 : }
    2650                 : 
    2651                 : /* ------------------------------------------------------------------------- */
    2652                 : int test_remote_exe (const char *slave_name, MinItemParser * mip)
    2653               3 : {
    2654                 :         MsgBuffer       msg;
    2655               3 :         int             retval = ENOERR;
    2656               3 :         int             send_extif = 1;
    2657               3 :         char           *kw = INITPTR;
    2658               3 :         char           *token = INITPTR;
    2659               3 :         char           *token2 = INITPTR;
    2660                 :         char           *p;
    2661                 : 
    2662               3 :         if (slave_name == INITPTR || strlen (slave_name) == 0) {
    2663               0 :                 retval = -1;
    2664               0 :                 errno = EINVAL;
    2665               0 :                 SCRIPTER_RTERR ("slave name missing");
    2666               0 :                 goto EXIT;
    2667                 :         }
    2668                 : 
    2669               3 :         if (mip == INITPTR) {
    2670               0 :                 retval = -1;
    2671               0 :                 errno = EINVAL;
    2672               0 :                 SCRIPTER_RTERR ("item parser argument missing");
    2673               0 :                 goto EXIT;
    2674                 :         }
    2675                 : 
    2676                 :         /* save in case we need to send */
    2677               3 :         STRCPY (msg.message_, slave_name, MaxMsgSize);
    2678               3 :         STRCPY (msg.desc_, mip->item_skip_and_mark_pos_, MaxDescSize);
    2679                 : 
    2680               3 :         mip_get_next_string (mip, &kw);
    2681                 : 
    2682               3 :         switch (get_keyword (kw)) {
    2683                 :         case EKeywordRequest:
    2684                 :                 /*
    2685                 :                  ** Create a local "shadow" event for the remote
    2686                 :                  */
    2687               0 :                 mip_get_next_string (mip, &token);
    2688               0 :                 mip_get_next_string (mip, &token2);
    2689               0 :                 if (token2 != INITPTR && !strcmp (token2, "state"))
    2690               0 :                         event_request (token, 1);
    2691                 :                 else
    2692               0 :                         event_request (token, 0);
    2693               0 :                 break;
    2694                 :         case EKeywordRelease:
    2695               0 :                 mip_get_next_string (mip, &token);
    2696               0 :                 event_release (token);
    2697               0 :                 break;
    2698                 :         case EKeywordWait:
    2699               0 :                 mip_get_next_string (mip, &token);
    2700               0 :                 send_extif = 0;
    2701               0 :                 event_wait (token);
    2702               0 :                 break;
    2703                 :         case EKeywordRun:
    2704                 :                 /* Stop execution till response comes */
    2705               2 :                 scripter_mod.extif_pending = ESTrue;
    2706               2 :                 break;
    2707                 :         case EKeywordExpect:
    2708               1 :                 scripter_mod.extif_pending = ESTrue;
    2709               1 :                 mip_get_next_string (mip, &scripter_mod.expected_var);
    2710               1 :                 MIN_DEBUG ("master expecting variable %s",
    2711                 :                              scripter_mod.expected_var);
    2712               1 :                 break;
    2713                 :         case EKeywordSendreceive:
    2714               0 :                 mip_get_next_string (mip, &token);
    2715               0 :                 p = strchr (token, '=');
    2716               0 :                 *p = '\0';
    2717               0 :                 p++;
    2718               0 :                 snprintf (msg.desc_, MaxDescSize, "sendreceive %s=%s",
    2719                 :                           token, var_value(p));
    2720                 : 
    2721               0 :                 break;
    2722                 :         default:
    2723               0 :                 MIN_WARN ("Unknown keyword [%s]", kw);
    2724                 :                 break;
    2725                 :         }
    2726                 : 
    2727               3 :         if (send_extif) {
    2728               3 :                 msg.receiver_ = getppid ();
    2729               3 :                 msg.sender_ = getpid ();
    2730               3 :                 msg.type_ = MSG_EXTIF;
    2731               3 :                 msg.param_ = 0;
    2732               3 :                 msg.extif_msg_type_ = ERemoteSlave;
    2733               3 :                 mq_send_message (scripter_mod.mqid, &msg);
    2734                 :         }
    2735               3 :       EXIT:
    2736               3 :         return retval;
    2737                 : }
    2738                 : 
    2739                 : /* ------------------------------------------------------------------------- */
    2740                 : int test_canceliferror ()
    2741               3 : {
    2742               3 :         scripter_mod.canceliferror = ESTrue;
    2743               3 :         return ENOERR;
    2744                 : }
    2745                 : 
    2746                 : /* ------------------------------------------------------------------------- */
    2747                 : int testclass_test_timeout (unsigned long interval)
    2748               0 : {
    2749               0 :         unsigned long   timeout = 0;
    2750               0 :         int             retval = ENOERR;
    2751                 : 
    2752                 :         /* ualarm fails when timeout greater that 1000^2 useconds, we have to
    2753                 :          * use either alarm or ualarm.
    2754                 :          * alarm for timeouts >= 1 [sec] 
    2755                 :          * ualarm for timeouts < 1 [sec] 
    2756                 :          */
    2757               0 :         if (interval > 999) {
    2758               0 :                 timeout = interval / (unsigned long)1000;
    2759               0 :                 retval = alarm (timeout);
    2760               0 :                 signal (SIGALRM, scripter_sigalrm_handler);
    2761                 :         } else {
    2762               0 :                 timeout = interval * (unsigned long)1000;
    2763               0 :                 retval = ualarm (timeout, 0);
    2764               0 :                 signal (SIGALRM, scripter_sigalrm_handler);
    2765                 :         }
    2766                 : 
    2767               0 :         if (retval == -1) {
    2768               0 :                 SCRIPTER_RTERR_ARG ("Error in setting the timeout", 
    2769                 :                                     strerror (errno));
    2770               0 :                 MIN_ERROR ("Error in setting the timeout: [%s]",
    2771                 :                             strerror (errno));
    2772                 :         } else {
    2773               0 :                 MIN_DEBUG ("Starting timeout: [%d] miliseconds", interval);
    2774               0 :                 retval = ENOERR;
    2775                 :         }
    2776               0 :         return retval;
    2777                 : }
    2778                 : 
    2779                 : /* ------------------------------------------------------------------------- */
    2780                 : int testclass_test_sleep (unsigned long interval)
    2781              10 : {
    2782              10 :         scripter_mod.sleep = interval;
    2783              10 :         gettimeofday (&scripter_mod.time, NULL);
    2784              10 :         MIN_DEBUG ("Starting sleep: [%d] miliseconds", interval);
    2785              10 :         return ENOERR;
    2786                 : }
    2787                 : 
    2788                 : /* ------------------------------------------------------------------------- */
    2789                 : int declare_var (char *name, TSBool initialize, char *val)
    2790             383 : {
    2791                 : 
    2792                 :         ScriptVar      *var;
    2793                 : 
    2794             383 :         if ((var = var_find (name)) != INITPTR) {
    2795               1 :                 if (initialize == ESFalse) {
    2796               0 :                         SCRIPTER_RTERR_ARG ("Variable already declared", name);
    2797               0 :                         return -1;
    2798                 :                 }
    2799               1 :                 var_assign (name, val);
    2800               1 :                 return ENOERR;
    2801                 :         }
    2802             382 :         if (var_find (name) != INITPTR) {
    2803               0 :                 MIN_WARN ("variable %s already declared", name);
    2804               0 :                 return -1;
    2805                 :         }
    2806             382 :         var = NEW (ScriptVar);
    2807             382 :         var->name_ = name;
    2808             382 :         var->initialized_ = initialize;
    2809             382 :         if (initialize)
    2810             382 :                 var->value_ = val;
    2811                 :         else
    2812               0 :                 var->value_ = INITPTR;
    2813             382 :         dl_list_add (variables, var);
    2814             382 :         MIN_DEBUG ("name=%s init. val=%s", name, initialize ? val : "none");
    2815             382 :         return ENOERR;
    2816                 : }
    2817                 : 
    2818                 : /* ------------------------------------------------------------------------- */
    2819                 : LOCAL int declare_internal_var (const char *name)
    2820             378 : {
    2821                 :         char *var_name, *var_value;
    2822             378 :         var_value = NEW2(char, 32);
    2823             378 :         var_name = NEW2(char, strlen (name) + 1);
    2824                 : 
    2825             378 :         sprintf (var_name, "%s", name);
    2826             378 :         sprintf (var_value, "%d", 0);
    2827             378 :         declare_var (var_name, 1, var_value);
    2828             378 :         return ENOERR;
    2829                 : }
    2830                 : 
    2831                 : /* ------------------------------------------------------------------------- */
    2832                 : int sendreceive_slave_send (char *variable, char *value)
    2833               0 : {
    2834                 :         MsgBuffer       msg;
    2835                 : 
    2836               0 :         MIN_DEBUG ("sendreceive var=%s value=%s", variable, value);
    2837               0 :         msg.receiver_ = getppid ();
    2838               0 :         msg.sender_ = getpid ();
    2839               0 :         msg.type_ = MSG_SNDRCV;
    2840               0 :         STRCPY (msg.message_, variable, MaxMsgSize);
    2841               0 :         STRCPY (msg.desc_, var_value (value), MaxDescSize);
    2842               0 :         mq_send_message (scripter_mod.mqid, &msg);
    2843                 : 
    2844               0 :         return ENOERR;
    2845                 : }
    2846                 : 
    2847                 : /* ------------------------------------------------------------------------- */
    2848                 : int sendreceive_slave_expect (char *variable)
    2849               0 : {
    2850                 :         MsgBuffer       msg;
    2851               0 :         msg.receiver_ = getppid ();
    2852               0 :         msg.sender_ = getpid ();
    2853               0 :         msg.type_ = MSG_EXTIF;
    2854               0 :         msg.extif_msg_type_ = ERemoteSlave;
    2855                 : 
    2856               0 :         if (strlen (variable) >= MaxDescSize - strlen ("expect ")) {
    2857               0 :                 SCRIPTER_RTERR ("too long variable name for expect!");
    2858               0 :                 MIN_ERROR ("Too long variable name!");
    2859               0 :                 return -1;
    2860                 :         }
    2861                 : 
    2862               0 :         scripter_mod.expected_var = variable;
    2863               0 :         scripter_mod.extif_pending = ESTrue;
    2864               0 :         STRCPY (msg.message_, "master", MaxMsgSize);
    2865               0 :         sprintf (msg.desc_, "expect %s", variable);
    2866               0 :         mq_send_message (scripter_mod.mqid, &msg);
    2867                 : 
    2868               0 :         return ENOERR;
    2869                 : }
    2870                 : /* ------------------------------------------------------------------------- */
    2871                 : int test_interference(MinItemParser* args)
    2872              27 : {
    2873              27 :         char*   command = INITPTR;
    2874              27 :         char*   name = INITPTR;
    2875              27 :         char*   typename = INITPTR;
    2876              27 :         int     value = 0;
    2877              27 :         int     idle_time = 0;
    2878              27 :         int     busy_time = 0;
    2879              27 :         TInterferenceType       type = ECpuLoad;
    2880              27 :         InterfHandle*           handle = INITPTR;
    2881                 :         DLListIterator          work_inter;
    2882                 :         
    2883              27 :         mip_get_next_string(args,&name);
    2884              27 :         mip_get_next_string(args,&command);
    2885                 : 
    2886              27 :         if (strcmp(command,"start") == 0) {
    2887              15 :                 if (interference_handles == INITPTR)
    2888               6 :                           interference_handles = dl_list_create();
    2889              15 :                 mip_get_next_string(args,&typename);
    2890              15 :                 mip_get_next_int(args,&value);
    2891              15 :                 mip_get_next_int(args,&idle_time);
    2892              15 :                 mip_get_next_int(args,&busy_time);
    2893                 : 
    2894              15 :                 if (strcmp(typename,"cpuload") == 0) type = ECpuLoad;
    2895               9 :                 else if (strcmp(typename,"memload") == 0) type = EMemLoad;
    2896               3 :                 else if (strcmp(typename,"ioload") == 0) type = EIOLoad;
    2897                 :                 /*validation was successful so there is no point in 
    2898                 :                 handling other cases here*/
    2899                 : 
    2900              15 :                 handle = NEW(InterfHandle);
    2901              15 :                 sprintf(handle->name_,"%s",name);
    2902              15 :                 handle->instance_ = ti_start_interference_timed (type, 
    2903                 :                                                                  idle_time,
    2904                 :                                                                  busy_time,
    2905                 :                                                                  value);
    2906              12 :                 dl_list_add(interference_handles,(void*)handle);
    2907                 :         }
    2908                 :         /*if validation was successful (and we asume so) 
    2909                 :           then command is "stop"*/
    2910                 :         else {
    2911              12 :                 work_inter = dl_list_head(interference_handles);
    2912              24 :                 while (work_inter != DLListNULLIterator){
    2913              12 :                         handle = (InterfHandle*)dl_list_data(work_inter);
    2914              12 :                         if (strcmp(handle->name_,name) == 0) break;
    2915               0 :                         work_inter = dl_list_next(work_inter);
    2916                 :                 }
    2917              12 :                 ti_stop_interference(handle->instance_);
    2918              12 :                 dl_list_remove_it(work_inter);
    2919              12 :                 DELETE(handle);
    2920                 :         }
    2921              24 :         return 0;
    2922                 : }
    2923                 : 
    2924                 : /* ------------------------------------------------------------------------- */
    2925                 : 
    2926              13 : TSBool eval_if (char *condition) {
    2927              13 :         int i,isnumber = ESTrue;
    2928                 :         const char *value;
    2929                 : 
    2930              13 :         MIN_DEBUG ("condition = %s", condition);
    2931                 : 
    2932              13 :         value = var_value (condition);
    2933              36 :         for (i = 0; i < strlen (value); i++) {
    2934              35 :                 if (!isxdigit(value[i])) {
    2935              12 :                         isnumber = ESFalse;
    2936              12 :                         break;
    2937                 :                 }
    2938                 :         }
    2939              13 :         if (isnumber == ESTrue && strtol (value, NULL, 16) == 0) {
    2940               1 :                 return ESFalse;
    2941                 :         }
    2942              12 :         if (isnumber == ESFalse && strcasecmp (value, "false") == 0) {
    2943              11 :                 return ESFalse;
    2944                 :         }
    2945                 : 
    2946               1 :         return ESTrue;
    2947                 : }
    2948                 :                 
    2949                 : 
    2950                 : 
    2951                 : /* ------------------------------------------------------------------------- */
    2952                 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
    2953                 : /* None */
    2954                 : 
    2955                 : /* ------------------------------------------------------------------------- */
    2956                 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
    2957                 : #ifdef MIN_UNIT_TEST
    2958                 : #include "min_scripter_if.tests"
    2959                 : #endif                          /* MIN_UNIT_TEST */
    2960                 : /* End of file */

Generated by: LTP GCOV extension version 1.6