LTP GCOV extension - code coverage report
Current view: directory - src/engine/tec - tec.c
Test: min.info
Date: 2009-06-18 Instrumented lines: 1421
Code covered: 71.9 % Executed lines: 1022

       1                 : /*
       2                 :  * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
       3                 :  * and/or its subsidiary(-ies).
       4                 :  * Contact: Robert Galkowski
       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       tec.c
      22                 :  *  @version    0.1
      23                 :  *  @brief      This file contains implementation of test execution 
      24                 :  *              controller functionality
      25                 :  */
      26                 : 
      27                 : /* ----------------------------------------------------------------------------
      28                 :  * INCLUDE FILES
      29                 :  */
      30                 : #include <stdio.h>
      31                 : #include <signal.h>
      32                 : #include <time.h>
      33                 : #include <sys/wait.h>
      34                 : #include <dirent.h>
      35                 : #include <sys/stat.h>
      36                 : #include <sys/types.h>
      37                 : #include <regex.h>
      38                 : 
      39                 : #include <min_parser.h>
      40                 : #include <tec.h>
      41                 : #include <min_common.h>
      42                 : #include <consoleui.h>
      43                 : #include <data_api.h>
      44                 : #include <tec_events.h>
      45                 : #include <min_logger.h>
      46                 : #include <min_engine_api.h>
      47                 : #ifndef MIN_EXTIF
      48                 : #include <tec_tcp_handling.h>
      49                 : #endif
      50                 : /* ----------------------------------------------------------------------------
      51                 :  * GLOBAL VARIABLES
      52                 :  */
      53                 : pthread_mutex_t tec_mutex_ = PTHREAD_MUTEX_INITIALIZER;
      54                 : char          **envp;
      55                 : #ifdef MIN_UNIT_TEST
      56                 : int             unit_test_result;
      57                 : #endif                          /*MINMIN_UNIT_TEST */
      58                 : struct logger_settings_t logger_settings;
      59                 : eapiIn_t in_str;
      60                 : eapiIn_t *in = &in_str;
      61                 : DLList   *available_modules = INITPTR;   /*list of available test modules */
      62                 : DLList   *filters = INITPTR;
      63                 : int min_return_value = 0;
      64                 : /* ----------------------------------------------------------------------------
      65                 :  * EXTERNAL DATA STRUCTURES
      66                 :  */
      67                 : /* None */
      68                 : 
      69                 : /* ---------------------------------------------------------------------------
      70                 :  * EXTERNAL FUNCTION PROTOTYPES
      71                 :  */
      72                 : extern int      ec_msg_ms_handler (MsgBuffer * message);
      73                 : extern int      ec_msg_sndrcv_handler (MsgBuffer * message);
      74                 : extern int      event_system_up (void);
      75                 : extern int      event_system_cleanup (void);
      76                 : 
      77                 : /* ----------------------------------------------------------------------------
      78                 :  * CONSTANTS
      79                 :  */
      80                 : 
      81                 : /* ----------------------------------------------------------------------------
      82                 :  * MACROS
      83                 :  */
      84                 : 
      85                 : #ifndef MIN_CONF_DIR
      86                 : # define MIN_CONF_DIR "/etc"
      87                 : #endif
      88                 : 
      89                 : #ifndef MIN_BIN_DIR
      90                 : # define MIN_BIN_DIR "/usr/bin"
      91                 : #endif
      92                 : 
      93                 : 
      94                 : /* ----------------------------------------------------------------------------
      95                 :  * LOCAL CONSTANTS AND MACROS
      96                 :  */
      97                 : 
      98                 : /* ----------------------------------------------------------------------------
      99                 :  * MODULE DATA STRUCTURES
     100                 :  */
     101                 : typedef struct {
     102                 :         Text *filter_;
     103                 :         int regexp_;
     104                 : } title_filter;
     105                 : 
     106                 : /* ----------------------------------------------------------------------------
     107                 :  * LOCAL FUNCTION PROTOTYPES
     108                 :  */
     109                 : /* ------------------------------------------------------------------------- */
     110                 : /** Waits for process to be ended - collects the zombie.
     111                 :  */
     112                 : LOCAL void      wait_for_pid (void *pid);
     113                 : /* ------------------------------------------------------------------------- */
     114                 : /** Signal handler to signal SIGSEGV
     115                 :  * FATAL. Segmentation violation
     116                 :  * @param signum signal number
     117                 :  */
     118                 : LOCAL void      handle_sigsegv (int signum);
     119                 : /* ------------------------------------------------------------------------- */
     120                 : /** Signal handler to signal SIGQUIT
     121                 :  * FATAL. Process should dump core on this signal.
     122                 :  * @param signum signal number
     123                 :  */
     124                 : /* ------------------------------------------------------------------------- */
     125                 : LOCAL void      handle_sigquit (int signum);
     126                 : /** Signal handler to signal SIGBUS
     127                 :  * FATAL. Bus error.
     128                 :  * @param signum signal number
     129                 :  */
     130                 : /* ------------------------------------------------------------------------- */
     131                 : LOCAL void      handle_sigbus (int signum);
     132                 : /** Signal handler to signal SIGTERM
     133                 :  * Signal generated by (kill <processnumber>)
     134                 :  * @param signum signal number
     135                 :  */
     136                 : /* ------------------------------------------------------------------------- */
     137                 : LOCAL void      handle_sigterm (int signum);
     138                 : /** Signal handler to signal SIGINT
     139                 :  * Signal generated by CTRL-C
     140                 :  * @param signum signal number
     141                 :  */
     142                 : /* ------------------------------------------------------------------------- */
     143                 : LOCAL void      handle_sigint (int signum);
     144                 : /** Signal handler for SIGCHLD
     145                 :  * @param signum signal number
     146                 :  */
     147                 : /* LOCAL void handle_sigchld (int signum); not used */
     148                 : /** Function that wraps test module controller process starting. 
     149                 :  * In case of failure to start
     150                 :  * a module, information will be logged.
     151                 :  * @param work_module_item item from available modules list
     152                 :  * @return pid of newly created process, or -1 in case of failure
     153                 :  */
     154                 : LOCAL pid_t     ec_start_tmc (DLListIterator work_module_item);
     155                 : /** Parses the module configuration section(s) from the min configuraion file 
     156                 :  *  @param inifile the min configuration file 
     157                 :  *  @return 0, always
     158                 :  */
     159                 : LOCAL int       ec_read_module_section (MinParser * inifile);
     160                 : /* ------------------------------------------------------------------------- */
     161                 : /** Looks for files in directory /etc/min.d and tries to find module
     162                 :  *  configurations from them
     163                 :  *  @return 1 if the directory /etc/min.d does not exists or an error occurs,
     164                 :  *          0 otherwise
     165                 :  */
     166                 : LOCAL int       ec_read_module_confdir (void);
     167                 : 
     168                 : /* -------------------------------------------------------------------------
     169                 :  * FORWARD DECLARATIONS
     170                 :  */
     171                 : /* None */
     172                 : 
     173                 : /* ==================== LOCAL FUNCTIONS ==================================== */
     174                 : /* ------------------------------------------------------------------------- */
     175                 : LOCAL void wait_for_pid (void *arg)
     176               0 : {
     177                 :         //int* pid = (int*)arg;
     178               0 :         pthread_exit (0);
     179                 : }
     180                 : 
     181                 : /* ------------------------------------------------------------------------- */
     182                 : /*temp code for summary generation*/
     183                 : void log_summary ()
     184               0 : {
     185               0 :         DLListIterator  work_result_item = INITPTR;
     186               0 :         DLListIterator  work_case_item = INITPTR;
     187               0 :         DLListIterator  work_module_item = INITPTR;
     188                 : 
     189               0 :         char           *case_title = NEW2 (char, MaxTestCaseName);
     190               0 :         char           *module_name = NEW2 (char, MaxFileName);
     191               0 :         min_log_open ("SUMMARY", 1);
     192                 : 
     193               0 :         MIN_DEBUG (">>>>>>>>>>>>>>>SUMMARY<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
     194                 : 
     195               0 :         work_module_item = dl_list_head (available_modules);
     196               0 :         while (work_module_item != DLListNULLIterator) {
     197               0 :                 tm_get_module_filename (work_module_item, module_name);
     198               0 :                 MIN_DEBUG ("module: %s", module_name);
     199               0 :                 work_case_item =
     200                 :                     dl_list_head (tm_get_tclist (work_module_item));
     201               0 :                 while (work_case_item != DLListNULLIterator) {
     202               0 :                         tc_get_title (work_case_item, case_title);
     203               0 :                         MIN_DEBUG ("case: %s", case_title);
     204               0 :                         work_result_item =
     205                 :                             dl_list_head (tc_get_tr_list (work_case_item));
     206               0 :                         while (work_result_item != DLListNULLIterator) {
     207               0 :                                 MIN_DEBUG ("result = %d",
     208                 :                                             tr_get_result_type
     209                 :                                             (work_result_item));
     210               0 :                                 work_result_item =
     211                 :                                     dl_list_next (work_result_item);
     212                 :                         }
     213               0 :                         work_case_item = dl_list_next (work_case_item);
     214                 :                 }
     215               0 :                 work_module_item = dl_list_next (work_module_item);
     216                 :         }
     217               0 :         MIN_DEBUG (">>>>>>>>>>>>>>>END OF SUMMARY<<<<<<<<<<<<<<<<<<<<<");
     218               0 :         DELETE (module_name);
     219               0 :         DELETE (case_title);
     220               0 :         min_log_close ();
     221                 : 
     222               0 : }
     223                 : 
     224                 : 
     225                 : /**Function used to select test case for execution - passed test case is 
     226                 :  * copied, and then copied case is added to  "selected" list. As this function 
     227                 :  * modifies "selected" list, code that calls it should first lock "tec_mutex_",
     228                 :  * and unlock it after executing the function.
     229                 :  * @param work_case_item DLList item containing selected case
     230                 :  * @param group_id id of group to which case belongs
     231                 :  * @return item from "selected cases" list
     232                 :  */
     233                 : DLListIterator ec_select_case (DLListIterator work_case_item, int group_id)
     234             106 : {
     235                 : 
     236                 : 
     237             106 :         test_case_s    *dest_case = INITPTR;
     238             106 :         test_result_s  *test_result = INITPTR;
     239             106 :         DLListIterator  selected_case = DLListNULLIterator;
     240                 :         filename_t      config;
     241                 :         title_string_t  title;
     242             106 :         DLListIterator  work_result_item = DLListNULLIterator;
     243                 : 
     244             106 :         tc_get_cfg_filename (work_case_item, config);
     245             106 :         tc_get_title (work_case_item, title);
     246                 : 
     247             106 :         dest_case =
     248                 :             tc_create (tc_get_test_module_ptr (work_case_item), config,
     249                 :                        title);
     250                 : 
     251             106 :         selected_case = tc_add (selected_cases, dest_case);
     252                 : 
     253             106 :         tc_set_group_id (selected_case, group_id);
     254             106 :         tc_set_id (selected_case, tc_get_id (work_case_item));
     255             106 :         tc_set_priority (work_case_item, tc_get_priority (work_case_item));
     256             106 :         dest_case->tc_ext_id_ = tc_get_ext_id (work_case_item);
     257                 : 
     258             106 :         test_result = tr_create_data_item (selected_case);
     259             106 :         work_result_item =
     260                 :             tr_add (tc_get_tr_list (selected_case), test_result);
     261                 : 
     262             106 :         return selected_case;
     263                 : }
     264                 : 
     265                 : /*---------------------------------------------------------------------------*/
     266                 : 
     267                 : /** Function used to create shared memory segment and write settings to it, 
     268                 :  * so that they can be used by other processes (TMCs). Currently sent settings
     269                 :  *  are: logger's settings placed in apropriate structure, and search paths 
     270                 :  * (if there are any search paths defined), concatenated into one 
     271                 :  *  NULL-terminated string, separated by ":" character. If program fails to 
     272                 :  * createshared memory segment, it will exit the application.
     273                 :  */
     274                 : LOCAL void ec_settings_send ()
     275             119 : {
     276                 : 
     277             119 :         int             shared_segm_id = 0;
     278             119 :         void           *sh_mem_handle = NULL;
     279             119 :         int             paths_size = 0;
     280             119 :         char           *work_path = INITPTR;
     281             119 :         DLListIterator  work_path_item = DLListNULLIterator;
     282             119 :         char           *concat_paths = INITPTR;
     283                 :         void           *temp_ptr;
     284             119 :         work_path_item = dl_list_head (ec_settings.search_dirs);
     285                 : 
     286             476 :         while (work_path_item != DLListNULLIterator) {
     287                 : 
     288             238 :                 work_path = (char *)dl_list_data (work_path_item);
     289             238 :                 paths_size = paths_size + strlen (work_path) + 1;
     290             238 :                 work_path_item = dl_list_next (work_path_item);
     291                 : 
     292                 :         }
     293                 : 
     294             119 :         if (paths_size > 0) {
     295             119 :                 concat_paths = NEW2 (char, paths_size);
     296             119 :                 *concat_paths = '\0';
     297             119 :                 work_path_item = dl_list_head (ec_settings.search_dirs);
     298             476 :                 while (work_path_item != DLListNULLIterator) {
     299             238 :                         work_path = (char *)dl_list_data (work_path_item);
     300             238 :                         strcat (concat_paths, work_path);
     301             238 :                         work_path_item = dl_list_next (work_path_item);
     302             238 :                         if (work_path_item != DLListNULLIterator)
     303             119 :                                 strcat (concat_paths, ":");
     304                 :                 }
     305                 :         }
     306                 :         /*create shared memory segment */
     307             119 :         shared_segm_id =
     308                 :                 sm_create ('a', sizeof (struct logger_settings_t) + paths_size);
     309                 :         /*
     310                 :         ** Try to clean up
     311                 :         */
     312                 : 
     313             119 :         if (shared_segm_id < 0) {
     314               1 :                 MIN_WARN ("failed to create shared memory segment "
     315                 :                           " - trying to clean up");
     316               1 :                 system ("/usr/bin/min-clean.sh");
     317                 :         }
     318                 : 
     319                 : 
     320             119 :         shared_segm_id =
     321                 :             sm_create ('a', sizeof (struct logger_settings_t) + paths_size);
     322             119 :         if (shared_segm_id < 0) {
     323               1 :                 MIN_FATAL ("Failed to create shared memory segment: %s",
     324                 :                             strerror (errno));
     325               1 :                 min_log_close ();
     326                 : #ifdef MIN_UNIT_TEST
     327               1 :                 exit (0);
     328                 : #endif
     329               0 :                 exit (-1);
     330                 :         }
     331                 : 
     332             118 :         ec_settings.sh_mem_id_ = shared_segm_id;
     333             118 :         sh_mem_handle = sm_attach (shared_segm_id);
     334             118 :         sm_write (sh_mem_handle,
     335                 :                   (void *)(&logger_settings),
     336                 :                   sizeof (struct logger_settings_t));
     337             118 :         temp_ptr = sh_mem_handle + sizeof (struct logger_settings_t);
     338             118 :         if (paths_size > 0) {
     339             118 :                 sm_write (temp_ptr, (void *)concat_paths, paths_size);
     340             118 :                 DELETE (concat_paths);
     341                 :         }
     342                 : 
     343             118 :         sm_detach (sh_mem_handle);
     344             118 : }
     345                 : 
     346                 : /* ------------------------------------------------------------------------- */
     347                 : /** Function used check test case title agains filters
     348                 :  * @param test case title string
     349                 :  * @return 0 if the test case matches filter, 1 if not
     350                 :  */
     351                 : LOCAL int 
     352                 : ec_filter_it(char *title)
     353             623 : {
     354                 :         DLListIterator it;
     355                 :         title_filter *filt;
     356                 :         regex_t   re;
     357                 :         int val;
     358                 : 
     359             623 :         if (filters == INITPTR)
     360             593 :                 return 0;
     361                 : 
     362                 :         /*
     363                 :         ** We have filters specified, see if the case should be filtered
     364                 :         */
     365              30 :         for (it = dl_list_head(filters);
     366              86 :              it != DLListNULLIterator;
     367              26 :              it = dl_list_next(it)) {
     368              30 :                 filt = dl_list_data (it);
     369              30 :                 if (filt->regexp_ == 0 && !strcmp (title, 
     370                 :                                                    tx_share_buf 
     371                 :                                                    (filt->filter_)))
     372               2 :                         return 0;
     373              28 :                 if (filt->regexp_) {
     374              10 :                         val = regcomp (&re, tx_share_buf (filt->filter_), 
     375                 :                                        REG_EXTENDED);
     376              10 :                         if (val) {
     377               0 :                                 regfree (&re);
     378               0 :                                 continue; /* regcomp failed */
     379                 :                         }
     380              10 :                         val = regexec (&re, title, 0, NULL, 0);
     381              10 :                         regfree (&re);
     382              10 :                         if (val == 0)
     383               2 :                                 return 0; /* Match */
     384                 :                 }
     385                 :         }
     386                 : 
     387              26 :         return 1;
     388                 : }
     389                 : 
     390                 : 
     391                 : /*---------------------------------------------------------------------------*/
     392                 : /** Function used to read logger settings. It was moved to separate function to
     393                 :  * keep functions shorter. It uses section andf item parser functionalities to
     394                 :  * write data to logger settings struct.
     395                 :  * @param section fetched from config file
     396                 : */
     397                 : LOCAL void ec_get_logger_settings (MinSectionParser * settings)
     398             238 : {
     399             238 :         MinItemParser *linebreaker = INITPTR;  /* used if it is necessary 
     400                 :                                                    to breakdown line into
     401                 :                                                    parts */
     402             238 :         char           *opt_val = NULL; /* used to hold option value if 
     403                 :                                          * it is single */
     404             238 :         int             fresult = 0;
     405                 : 
     406             238 :         fresult = mmp_get_line (settings,
     407                 :                                 "CreateLogDirectories=", &opt_val, ESNoTag);
     408             238 :         if (fresult == 0) {
     409             119 :                 logger_settings.is_defined_.create_log_dir_ = ESTrue;
     410             119 :                 if (strcasecmp (opt_val, "YES") == 0) {
     411             119 :                         logger_settings.create_log_dir_ = ESTrue;
     412               0 :                 } else if (strcasecmp (opt_val, "NO") == 0) {
     413               0 :                         logger_settings.create_log_dir_ = ESFalse;
     414                 :                 } else {
     415               0 :                         MIN_WARN ("Error in config file (CreateLogDirectories) !");
     416               0 :                         logger_settings.is_defined_.create_log_dir_ = ESFalse;
     417                 :                 }
     418             119 :                 DELETE (opt_val);
     419                 :         }
     420                 : 
     421             238 :         fresult = mmp_get_line (settings,
     422                 :                                 "EmulatorBasePath=", &opt_val, ESNoTag);
     423             238 :         if (fresult == 0) {
     424             238 :                 sprintf (logger_settings.emulator_path_, "%s", opt_val);
     425             238 :                 logger_settings.is_defined_.path_ = ESTrue;
     426             238 :                 DELETE (opt_val);
     427                 :         }
     428                 : 
     429             238 :         linebreaker = mmp_get_item_line (settings,
     430                 :                                          "EmulatorFormat=", ESNoTag);
     431                 : 
     432             238 :         if (linebreaker != INITPTR) {
     433             238 :                 fresult = mip_get_string (linebreaker, "", &opt_val);
     434             714 :                 while (fresult == 0) {
     435             238 :                         if (strcasecmp (opt_val, "HTML") == 0) {
     436               0 :                                 logger_settings.emulator_format_ =
     437                 :                                     logger_settings.emulator_format_ | ESHtml;
     438               0 :                                 logger_settings.is_defined_.format_ = ESTrue;
     439                 :                         }
     440             238 :                         if (strcasecmp (opt_val, "TXT") == 0) {
     441             238 :                                 logger_settings.emulator_format_ =
     442                 :                                     logger_settings.emulator_format_ | ESTxt;
     443             238 :                                 logger_settings.is_defined_.format_ = ESTrue;
     444                 :                         }
     445             238 :                         if (strcasecmp (opt_val, "DATA") == 0) {
     446               0 :                                 logger_settings.emulator_format_ =
     447                 :                                     logger_settings.emulator_format_ | ESData;
     448               0 :                                 logger_settings.is_defined_.format_ = ESTrue;
     449                 :                         }
     450             238 :                         DELETE (opt_val);
     451             238 :                         fresult = mip_get_next_string (linebreaker, &opt_val);
     452                 :                 }
     453                 :         }
     454                 : 
     455             238 :         mip_destroy (&linebreaker);
     456             238 :         linebreaker = mmp_get_item_line (settings,
     457                 :                                          "EmulatorOutput=", ESNoTag);
     458                 : 
     459             238 :         if (linebreaker != INITPTR) {
     460             238 :                 fresult = mip_get_string (linebreaker, "", &opt_val);
     461             714 :                 while (fresult == 0) {
     462             238 :                         if (strcasecmp (opt_val, "NULL") == 0) {
     463               0 :                                 logger_settings.emulator_output_ =
     464                 :                                     logger_settings.emulator_output_ | ESNull;
     465               0 :                                 logger_settings.is_defined_.output_ = ESTrue;
     466                 :                         }
     467             238 :                         if (strcasecmp (opt_val, "FILE") == 0) {
     468             119 :                                 logger_settings.emulator_output_ =
     469                 :                                     logger_settings.emulator_output_ | ESFile;
     470             119 :                                 logger_settings.is_defined_.output_ = ESTrue;
     471                 :                         }
     472             238 :                         if (strcasecmp (opt_val, "SYSLOG") == 0) {
     473             119 :                                 logger_settings.emulator_output_ =
     474                 :                                     logger_settings.
     475                 :                                     emulator_output_ | ESSyslog;
     476             119 :                                 logger_settings.is_defined_.output_ = ESTrue;
     477                 :                         }
     478                 : 
     479             238 :                         DELETE (opt_val);
     480             238 :                         fresult = mip_get_next_string (linebreaker, &opt_val);
     481                 :                 }
     482                 : 
     483                 :         }
     484                 : 
     485             238 :         mip_destroy (&linebreaker);
     486                 : 
     487             238 :         fresult = mmp_get_line (settings,
     488                 :                                 "ThreadIdToLogFile=", &opt_val, ESNoTag);
     489             238 :         if (fresult == 0) {
     490             238 :                 logger_settings.is_defined_.pidid_ = ESTrue;
     491             238 :                 if (strcasecmp (opt_val, "YES") == 0) {
     492               0 :                         logger_settings.pidid_ = ESTrue;
     493             238 :                 } else if (strcasecmp (opt_val, "NO") == 0) {
     494             238 :                         logger_settings.pidid_ = ESFalse;
     495                 :                 } else {
     496               0 :                         MIN_WARN ("Error in config file (ThreadIdToLogFile) !");
     497               0 :                         logger_settings.is_defined_.pidid_ = ESFalse;
     498                 :                 }
     499             238 :                 DELETE (opt_val);
     500                 :         }
     501                 : 
     502             238 :         fresult = mmp_get_line (settings,
     503                 :                                 "WithTimeStamp=", &opt_val, ESNoTag);
     504             238 :         if (fresult == 0) {
     505             119 :                 logger_settings.is_defined_.time_stamp_ = ESTrue;
     506             119 :                 if (strcasecmp (opt_val, "YES") == 0) {
     507             119 :                         logger_settings.time_stamp_ = ESTrue;
     508               0 :                 } else if (strcasecmp (opt_val, "NO") == 0) {
     509               0 :                         logger_settings.time_stamp_ = ESFalse;
     510                 :                 } else {
     511               0 :                         MIN_WARN ("Error in config file (WithTimeStamp) !");
     512               0 :                         logger_settings.is_defined_.time_stamp_ = ESFalse;
     513                 :                 }
     514             119 :                 DELETE (opt_val);
     515                 :         }
     516                 : 
     517             238 :         fresult = mmp_get_line (settings,
     518                 :                                 "WithLineBreak=", &opt_val, ESNoTag);
     519             238 :         if (fresult == 0) {
     520             119 :                 logger_settings.is_defined_.line_break_ = ESTrue;
     521             119 :                 if (strcasecmp (opt_val, "YES") == 0) {
     522               0 :                         logger_settings.line_break_ = ESTrue;
     523             119 :                 } else if (strcasecmp (opt_val, "NO") == 0) {
     524             119 :                         logger_settings.line_break_ = ESFalse;
     525                 :                 } else {
     526               0 :                         MIN_WARN ("Error in config file (WithLineBreak) !");
     527               0 :                         logger_settings.is_defined_.line_break_ = ESFalse;
     528                 :                 }
     529                 : 
     530             119 :                 DELETE (opt_val);
     531                 :         }
     532                 : 
     533             238 :         fresult = mmp_get_line (settings,
     534                 :                                 "WithEventRanking=", &opt_val, ESNoTag);
     535             238 :         if (fresult == 0) {
     536             119 :                 logger_settings.is_defined_.event_ranking_ = ESTrue;
     537             119 :                 if (strcasecmp (opt_val, "YES") == 0) {
     538             119 :                         logger_settings.event_ranking_ = ESTrue;
     539               0 :                 } else if (strcasecmp (opt_val, "NO") == 0) {
     540               0 :                         logger_settings.event_ranking_ = ESFalse;
     541                 :                 } else {
     542               0 :                         MIN_WARN ("Error in config file (WithEventRanking) !");
     543               0 :                         logger_settings.is_defined_.event_ranking_ = ESFalse;
     544                 :                 }
     545                 : 
     546             119 :                 DELETE (opt_val);
     547                 :         }
     548                 : 
     549             238 :         fresult = mmp_get_line (settings,
     550                 :                                 "FileCreationMode=", &opt_val, ESNoTag);
     551             238 :         if (fresult == 0) {
     552             119 :                 logger_settings.is_defined_.overwrite_ = ESTrue;
     553             119 :                 if (strcasecmp (opt_val, "APPEND") == 0) {
     554             119 :                         logger_settings.overwrite_ = ESFalse;
     555               0 :                 } else if (strcasecmp (opt_val, "OVERWRITE") == 0) {
     556               0 :                         logger_settings.overwrite_ = ESTrue;
     557                 :                 } else {
     558               0 :                         logger_settings.is_defined_.overwrite_ = ESFalse;
     559               0 :                         MIN_WARN ("Error in config file (FileCreationMode) !");
     560                 :                 }
     561                 : 
     562             119 :                 DELETE (opt_val);
     563                 :         }
     564                 :         
     565             238 :         fresult = mmp_get_line (settings,
     566                 :                                 "LogLevel=", &opt_val, ESNoTag);
     567             238 :         if (fresult == 0) {
     568               0 :                 if (strcasecmp (opt_val, "fatal") == 0) {
     569               0 :                         logger_settings.loglevel_ = ESFatal;
     570               0 :                         logger_settings.is_defined_.loglevel_ = ESTrue;
     571               0 :                 } else if (strcasecmp (opt_val, "error")==0) {
     572               0 :                         logger_settings.loglevel_ = ESError;
     573               0 :                         logger_settings.is_defined_.loglevel_ = ESTrue;
     574               0 :                 } else if (strcasecmp (opt_val, "warn")==0) {
     575               0 :                         logger_settings.loglevel_ = ESWarning;
     576               0 :                         logger_settings.is_defined_.loglevel_ = ESTrue;
     577               0 :                 } else if (strcasecmp (opt_val, "info")==0) {
     578               0 :                         logger_settings.loglevel_ = ESInfo;
     579               0 :                         logger_settings.is_defined_.loglevel_ = ESTrue;
     580               0 :                 } else if (strcasecmp (opt_val, "notice")==0) {
     581               0 :                         logger_settings.loglevel_ = ESNotice;
     582               0 :                         logger_settings.is_defined_.loglevel_ = ESTrue;
     583               0 :                 } else if (strcasecmp (opt_val, "debug")==0) {
     584               0 :                         logger_settings.loglevel_ = ESDebug;
     585               0 :                         logger_settings.is_defined_.loglevel_ = ESTrue;
     586               0 :                 } else if (strcasecmp (opt_val, "trace")==0) {
     587               0 :                         logger_settings.loglevel_ = ESTrace;
     588               0 :                         logger_settings.is_defined_.loglevel_ = ESTrue;
     589                 :                 } else {
     590               0 :                         MIN_WARN ("Error in config file (LogLevel) !");
     591                 :                 }
     592               0 :                 DELETE (opt_val);
     593                 :         }
     594             238 : }
     595                 : 
     596                 : /**Function used for temporary module instantiation and test case execution, 
     597                 :  * used when there is a need to execute two test cases from the same module 
     598                 :  * in parallel.
     599                 :  * @param work_case_item DLListItem containing test case to be executed
     600                 :  */
     601                 : LOCAL int ec_start_module_temp (DLListIterator work_case_item)
     602               7 : {
     603                 :         /* this will be the module that will be used as a source of data for 
     604                 :          * instantiating temporary module */
     605               7 :         DLListIterator  source_module_item = DLListNULLIterator;        
     606                 :         /* this will contain handle to temporaryily instantiated module */
     607               7 :         DLListIterator  temporary_module_item = DLListNULLIterator;    
     608                 :         /* we will need also the copy of case to be executed */
     609               7 :         DLList         *work_cases_list = dl_list_create ();
     610               7 :         DLList         *cfgs_work_list = dl_list_create ();
     611               7 :         pid_t           temp_mod_pid = 0;
     612                 :         filename_t      library_name;
     613               7 :         test_module_info_s *temporary_module = INITPTR;
     614                 : 
     615               7 :         source_module_item = tc_get_test_module_ptr (work_case_item);
     616                 : 
     617               7 :         tm_get_module_filename (source_module_item, library_name);
     618                 : 
     619               7 :         temporary_module =
     620                 :             tm_create (library_name,
     621                 :                        tm_get_cfg_filenames (source_module_item),
     622                 :                        tm_get_module_id (source_module_item));
     623               7 :         temporary_module_item =
     624                 :             tm_add (instantiated_modules, temporary_module);
     625               7 :         tm_set_cfg_filenames (temporary_module_item, cfgs_work_list);
     626               7 :         temp_mod_pid = ec_start_tmc (temporary_module_item);
     627               2 :         if (temp_mod_pid == -1) {
     628               0 :                 MIN_WARN ("Failed to create module");
     629               0 :                 return -1;
     630                 : 
     631                 :         }
     632               2 :         tm_set_status (temporary_module_item, TEST_MODULE_INITIALIZED_TEMP);
     633               2 :         tm_set_tclist (temporary_module_item, work_cases_list);
     634               2 :         tm_set_pid (temporary_module_item, temp_mod_pid);
     635                 : 
     636               2 :         tc_add (work_cases_list, dl_list_data (work_case_item));
     637               2 :         tc_set_test_module_ptr (work_case_item, temporary_module_item);
     638                 : 
     639               2 :         return 1;
     640                 : }
     641                 : 
     642                 : /*--------------------------------------------------------------------*/
     643                 : 
     644                 : /** Function used to initialize logger_settings structure
     645                 : */
     646                 : LOCAL void ec_init_logger_settings ()
     647             119 : {
     648             119 :         logger_settings.create_log_dir_ = ESFalse;
     649             119 :         logger_settings.unicode_ = ESFalse;
     650             119 :         logger_settings.time_stamp_ = ESFalse;
     651             119 :         logger_settings.pidid_ = ESFalse;
     652             119 :         logger_settings.overwrite_ = ESFalse;
     653             119 :         logger_settings.line_break_ = ESFalse;
     654             119 :         logger_settings.event_ranking_ = ESFalse;
     655             119 :         *logger_settings.emulator_path_ = '\0';
     656             119 :         logger_settings.emulator_output_ = ESNull;
     657             119 :         logger_settings.emulator_format_ = 0;
     658             119 :         logger_settings.is_defined_.create_log_dir_ = ESFalse;
     659             119 :         logger_settings.is_defined_.unicode_ = ESFalse;
     660             119 :         logger_settings.is_defined_.time_stamp_ = ESFalse;
     661             119 :         logger_settings.is_defined_.pidid_ = ESFalse;
     662             119 :         logger_settings.is_defined_.path_ = ESFalse;
     663             119 :         logger_settings.is_defined_.overwrite_ = ESFalse;
     664             119 :         logger_settings.is_defined_.output_ = ESFalse;
     665             119 :         logger_settings.is_defined_.line_break_ = ESFalse;
     666             119 :         logger_settings.is_defined_.hw_path_ = ESFalse;
     667             119 :         logger_settings.is_defined_.hw_output_ = ESFalse;
     668             119 :         logger_settings.is_defined_.hw_format_ = ESFalse;
     669             119 :         logger_settings.is_defined_.format_ = ESFalse;
     670             119 :         logger_settings.is_defined_.event_ranking_ = ESFalse;
     671             119 : }
     672                 : 
     673                 : /*-----------------------------------------------------------------------*/
     674                 : 
     675                 : /** Function called to execute one test case. Prequisite: before calling this
     676                 :  * function, case should be put in "selected_cases" list, and that's from 
     677                 :  * where argument should be taken.
     678                 :  * @param work_case_item pointer to item from "selected_cases" containing 
     679                 :  *        test case to be executed.
     680                 :  *  @return result of operation (TBD)
     681                 :  */
     682                 : int ec_exec_case (DLListIterator work_case_item)
     683             105 : {
     684                 : 
     685             105 :         DLList         *work_result_list = tc_get_tr_list (work_case_item);
     686                 :         DLListIterator  test_result_item;
     687                 :         int             work_module_status;
     688             105 :         test_case_s    *work_case = INITPTR;
     689                 :         MsgBuffer       message;
     690             105 :         int             res = -1;
     691                 :         DLListIterator  work_module_item =
     692             105 :             tc_get_test_module_ptr (work_case_item);
     693                 : 
     694             105 :         if (work_module_item == INITPTR) {
     695               0 :                 MIN_DEBUG (" exec case %x", work_case_item);
     696               0 :                 MIN_WARN ("Faulty test case data");
     697               0 :                 goto EXIT;
     698                 : 
     699                 :         }
     700                 : 
     701             105 :         work_case = dl_list_data (work_case_item);
     702                 : 
     703             105 :         if (work_case == DLListNULLIterator) {
     704                 : 
     705               0 :                 MIN_WARN ("Faulty test case data (2)");
     706               0 :                 goto EXIT;
     707                 : 
     708                 :         }
     709             105 :         work_module_status = tm_get_status (work_module_item);
     710                 : 
     711             105 :         switch (work_module_status) {
     712                 : 
     713                 :         case TEST_MODULE_READY:
     714              98 :                 tm_set_status (work_module_item, TEST_MODULE_BUSY);
     715              98 :                 tc_set_status (work_case_item, TEST_CASE_ONGOING);
     716              98 :                 test_result_item = dl_list_head (work_result_list);
     717                 :                 /* it is enough to get "head of the list, since item in 
     718                 :                  * selected list is just a copy of test case containing one 
     719                 :                  * result in the list */
     720              98 :                 tr_set_start_time (test_result_item, time (NULL));
     721              98 :                 tr_set_priontouts_list (test_result_item, dl_list_create ());
     722              98 :                 message.type_ = MSG_EXE;
     723              98 :                 message.sender_ = ec_settings.engine_pid_;
     724              98 :                 message.receiver_ = tm_get_pid (work_module_item);
     725              98 :                 message.param_ = tc_get_id (work_case_item);
     726              98 :                 STRCPY (message.desc_, "\0", MaxDescSize);
     727              98 :                 tc_get_cfg_filename (work_case_item, message.message_);
     728              98 :                 res = mq_send_message (mq_id, &message);
     729              98 :                 break;
     730                 : 
     731                 :         case TEST_MODULE_BUSY:
     732               7 :                 ec_start_module_temp (work_case_item);
     733               2 :                 res = 0;
     734               2 :                 break;
     735                 : 
     736                 :         default:
     737               0 :                 MIN_WARN ("module status fault");
     738               0 :                 res = -1;
     739                 : 
     740                 :         }
     741             100 : EXIT:
     742             100 :         return res;
     743                 : }
     744                 : 
     745                 : 
     746                 : 
     747                 : 
     748                 : /**Function used to check if there is a test case with given group id 
     749                 :  * in "selected_cases" list waiting to be executed and runs it if it is the 
     750                 :  * case.
     751                 :  * @param group_id - id og group of test cases in question.
     752                 : */
     753                 : LOCAL void ec_check_next_in_group (int group_id)
     754              67 : {
     755                 : 
     756              67 :         DLListIterator  work_case_item = DLListNULLIterator;
     757                 : 
     758              67 :         pthread_mutex_lock (&tec_mutex_);
     759                 : 
     760              67 :         work_case_item = dl_list_head (selected_cases);
     761                 : 
     762             744 :         while (work_case_item != DLListNULLIterator) {
     763                 : 
     764             669 :                 if ((tc_get_group_id (work_case_item) == group_id) &&
     765                 :                     (tc_get_status (work_case_item) == TEST_CASE_IDLE))
     766              59 :                         break;
     767                 :                 
     768             610 :                 work_case_item = dl_list_next (work_case_item);
     769                 :         }
     770                 :         
     771              67 :         pthread_mutex_unlock (&tec_mutex_);
     772                 :         
     773              67 :         if (work_case_item != DLListNULLIterator) {
     774              59 :                 ec_exec_case (work_case_item);
     775                 :         }
     776                 : 
     777                 :         return;
     778                 : }
     779                 : 
     780                 : /**Function for removal of temporary instantiated module.
     781                 :  * @param work_module_item pointer to dllistitem containing module in question.
     782                 :  */
     783                 : LOCAL int ec_remove_module_temp (DLListIterator work_module_item)
     784               1 : {
     785                 : 
     786                 :         pthread_t       threadid;
     787               1 :         long            address = tm_get_pid (work_module_item);
     788                 :         test_module_info_s *work_module =
     789               1 :             (test_module_info_s *) dl_list_data (work_module_item);
     790                 : 
     791               1 :         mq_send_message2 (mq_id, address, MSG_END, 0, "Shut down !");
     792                 : #ifndef MIN_UNIT_TEST
     793                 :         /*waitpid ( address, NULL, 0); */
     794               0 :         pthread_create (&threadid, NULL, (void *)&wait_for_pid,
     795                 :                         (void *)&address);
     796                 : #endif
     797               1 :         tm_delete (work_module);
     798               1 :         tm_remove (work_module_item);
     799                 : 
     800               1 :         return 0;
     801                 : }
     802                 : 
     803                 : /**Function used to start test case from temporarily instantianted module -
     804                 :  * process is slightly different than starting test case from ordinary module.
     805                 :  * "Temp" module has only one test case in list, so only that has to be passed
     806                 :  * to this function is module item.
     807                 :  * @param work_module_item pointer to dllistitem containg "current" module.
     808                 : */
     809                 : LOCAL int ec_exec_case_temp (DLListIterator work_module_item)
     810               2 : {
     811                 :         MsgBuffer       message;
     812                 :         DLListIterator  work_result_item;
     813                 :         DLListIterator  work_case_item =
     814               2 :                 dl_list_head (tm_get_tclist (work_module_item));
     815               2 :         test_case_s    *work_case = dl_list_data (work_case_item);
     816                 : 
     817                 :         /*let's look for test case in "selected list" */
     818               2 :         pthread_mutex_lock (&tec_mutex_);
     819                 : 
     820               2 :         work_case_item = dl_list_head (selected_cases);
     821                 : 
     822               6 :         while (work_case_item != DLListNULLIterator) {
     823                 : 
     824               4 :                 if (dl_list_data (work_case_item) == work_case)
     825               2 :                         break;
     826               2 :                 work_case_item = dl_list_next (work_case_item);
     827                 : 
     828                 :         }
     829                 : 
     830               2 :         pthread_mutex_unlock (&tec_mutex_);
     831                 : 
     832               2 :         if (work_case_item == DLListNULLIterator) {
     833               0 :                 MIN_WARN ("Test case not found in selected list");
     834               0 :                 return -1;
     835                 :         }
     836                 : 
     837               2 :         tm_set_status (work_module_item, TEST_MODULE_BUSY_TEMP);
     838               2 :         tc_set_status (work_case_item, TEST_CASE_ONGOING);
     839               2 :         work_result_item = dl_list_head (tc_get_tr_list (work_case_item));
     840               2 :         tr_set_start_time (work_result_item, time (NULL));
     841               2 :         tr_set_priontouts_list (work_result_item, dl_list_create ());
     842                 : 
     843                 :         /*create and send message */
     844               2 :         message.type_ = MSG_EXE;
     845               2 :         message.sender_ = ec_settings.engine_pid_;
     846               2 :         message.receiver_ = tm_get_pid (work_module_item);
     847               2 :         message.param_ = tc_get_id (work_case_item);
     848               2 :         STRCPY (message.desc_, "\0", MaxDescSize);
     849               2 :         tc_get_cfg_filename (work_case_item, message.message_);
     850               2 :         mq_send_message (mq_id, &message);
     851                 :         
     852               2 :         return 0;
     853                 : }
     854                 : 
     855                 : /**Function for handling test results obtained from "temp" module
     856                 :  * @param temp_module_item DLListIterator containing module to be worked on
     857                 :  * @param message pointer to received message buffer
     858                 :  */
     859                 : LOCAL int ec_handle_temp_results (DLListIterator temp_module_item,
     860                 :                                   MsgBuffer * message)
     861               0 : {
     862                 :         /* This module has only one test case */
     863                 :         DLListIterator  work_case_item =
     864               0 :             dl_list_head (tm_get_tclist (temp_module_item));
     865               0 :         int             group_id = tc_get_group_id (work_case_item);
     866                 :         DLListIterator  orig_case;
     867               0 :         DLListIterator  work_module_item = DLListNULLIterator;
     868                 :         DLListIterator  temp_result;
     869               0 :         DLListIterator  work_result_item = DLListNULLIterator;
     870               0 :         test_result_s  *work_result = INITPTR;
     871                 :         filename_t      name;
     872                 :         filename_t      name2;
     873                 :         filename_t      work_conf;
     874                 :         filename_t      orig_conf;
     875                 :         int             id, id2;
     876               0 :         int             result = 0;
     877               0 :         int             it = 1; /*general purpose loop iterator */
     878                 : 
     879               0 :         int             cont_flag = 1;
     880                 : #ifndef MIN_EXTIF
     881                 :         test_case_s    *work_case;
     882                 : #endif
     883               0 :         work_module_item = dl_list_head (instantiated_modules);
     884               0 :         tm_get_module_filename (temp_module_item, name);
     885                 : 
     886                 :         /* first we will search for module that was the source for "temp", 
     887                 :          * using filename */
     888               0 :         while (work_module_item != DLListNULLIterator) {
     889               0 :                 tm_get_module_filename (work_module_item, name2);
     890               0 :                 it = strcmp (name, name2);
     891                 : 
     892               0 :                 if (it == 0) {
     893               0 :                         tc_get_cfg_filename (work_case_item, work_conf);
     894               0 :                         orig_case =
     895                 :                             dl_list_head (tm_get_tclist (work_module_item));
     896               0 :                         if (orig_case == DLListNULLIterator)
     897               0 :                                 break;
     898               0 :                         while (orig_case != DLListNULLIterator) {
     899               0 :                                 tc_get_cfg_filename (orig_case, orig_conf);
     900               0 :                                 if (strstr (work_conf, orig_conf) != NULL) {
     901               0 :                                         cont_flag = 0;
     902               0 :                                         break;
     903                 :                                 } else
     904               0 :                                         orig_case = dl_list_next (orig_case);
     905                 :                         }
     906                 :                 }
     907                 : 
     908               0 :                 if (cont_flag == 1)
     909               0 :                         work_module_item = dl_list_next (work_module_item);
     910                 :                 else
     911               0 :                         break;
     912                 :         }
     913                 : 
     914               0 :         if (work_module_item == DLListNULLIterator) {
     915               0 :                 MIN_WARN ("MODULE Data fault");
     916               0 :                 return -1;
     917                 :         }
     918                 : 
     919                 :         /*now we will search for original test case, using id and config
     920                 :           filename */
     921               0 :         id = tc_get_id (work_case_item);
     922               0 :         tc_get_cfg_filename (work_case_item, work_conf);
     923               0 :         orig_case = dl_list_head (tm_get_tclist (work_module_item));
     924                 : 
     925               0 :         while (orig_case != DLListNULLIterator) {
     926               0 :                 tc_get_cfg_filename (orig_case, orig_conf);
     927               0 :                 id2 = tc_get_id (orig_case);
     928               0 :                 if ((id == id2) && (strcmp (work_conf, orig_conf) == 0))
     929                 :                         break;
     930                 :                 else
     931               0 :                         orig_case = dl_list_next (orig_case);
     932                 :         }
     933                 : 
     934               0 :         if (orig_case == DLListNULLIterator) {
     935               0 :                 MIN_WARN ("CASE Data fault");
     936               0 :                 return -1;
     937                 :         }
     938                 : 
     939               0 :         work_result = tr_create_data_item (orig_case);
     940               0 :         work_result_item = tr_add (tc_get_tr_list (orig_case), work_result);
     941                 :         /* since module was started to run just one case once, it will have
     942                 :          * only one test result, from which we will now copy data to 
     943                 :          * original test case 
     944                 :          */
     945               0 :         temp_result = dl_list_head (tc_get_tr_list (work_case_item));   
     946               0 :         tr_set_result_description (work_result_item, message->message_);
     947               0 :         tr_set_start_time (work_result_item, tr_get_start_time (temp_result));
     948               0 :         tr_set_result_description (work_result_item, message->message_);
     949               0 :         tr_set_end_time (work_result_item, time (NULL));
     950                 : 
     951               0 :         switch (message->param_) {
     952                 :         case TP_CRASHED:
     953               0 :                 min_return_value ++;
     954               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_CRASHED);
     955               0 :                 break;
     956                 : 
     957                 :         case TP_TIMEOUTED:
     958               0 :                 min_return_value ++;
     959               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_TIMEOUT);
     960               0 :                 break;
     961                 : 
     962                 :         case TP_PASSED:
     963               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_PASSED);
     964               0 :                 break;
     965                 : 
     966                 :         case TP_FAILED:
     967               0 :                 min_return_value ++;
     968               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_FAILED);
     969               0 :                 break;
     970                 : 
     971                 :         case TP_NC:
     972               0 :                 min_return_value ++;
     973               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_NOT_RUN);
     974               0 :                 break;
     975                 : 
     976                 :         case TP_LEAVE:
     977               0 :                 min_return_value ++;
     978               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_FAILED);
     979               0 :                 break;
     980                 : 
     981                 :         default:
     982                 : 
     983               0 :                 MIN_WARN ("Faulty data received");
     984               0 :                 return (-1);
     985                 : 
     986                 :         }
     987                 : 
     988               0 :         tr_set_priontouts_list (work_result_item,
     989                 :                                 tr_get_priontouts_list (temp_result));
     990               0 :         ((test_result_s *) dl_list_data (temp_result))->printouts_list_ =
     991                 :             INITPTR;
     992                 : 
     993                 : 
     994               0 :         MINAPI_PLUGIN_CALL (case_result,
     995                 :                             case_result (tc_get_run_id (work_case_item), 
     996                 :                                          message->param_, 
     997                 :                                          message->message_,
     998                 :                                          tr_get_start_time (work_result_item),
     999                 :                                          tr_get_end_time (work_result_item)));
    1000                 : 
    1001               0 :         pthread_mutex_lock (&tec_mutex_);
    1002                 :         
    1003               0 :         work_case_item = dl_list_head (selected_cases);
    1004               0 :         while (work_case_item != DLListNULLIterator) {
    1005               0 :                 if (tc_get_test_module_ptr (work_case_item) ==
    1006                 :                     temp_module_item)
    1007               0 :                         break;
    1008               0 :                 work_case_item = dl_list_next (work_case_item);
    1009                 :         }
    1010               0 :         pthread_mutex_unlock (&tec_mutex_);
    1011                 :         
    1012               0 :         if (work_case_item == DLListNULLIterator) {
    1013               0 :                 MIN_WARN ("could not find case in list");
    1014               0 :                 return -1;
    1015                 :         }
    1016               0 :         work_module_item =
    1017                 :                 tm_get_ptr_by_pid (instantiated_modules, message->sender_);
    1018               0 :         tc_set_status (work_case_item, TEST_CASE_TERMINATED);
    1019                 : #ifndef MIN_EXTIF
    1020               0 :         work_case = (test_case_s *)dl_list_data (work_case_item);
    1021               0 :         if (work_case->ip_slave_case_) {
    1022               0 :                 MIN_DEBUG ("ip slave case");
    1023               0 :                 tcp_master_report (work_case->tc_run_id_, 1, message->param_,
    1024                 :                                    message->desc_);
    1025                 : 
    1026                 :         } 
    1027                 : #endif
    1028                 : 
    1029               0 :         pthread_mutex_lock (&tec_mutex_);
    1030               0 :         pthread_mutex_unlock (&tec_mutex_);
    1031                 :         
    1032               0 :         ec_remove_module_temp (work_module_item);
    1033               0 :         ec_check_next_in_group (group_id);
    1034               0 :         result = 1;
    1035                 : 
    1036               0 :         return result;
    1037                 : }
    1038                 : 
    1039                 : /** Function handling MSG_OK. As it is first message sent by module, 
    1040                 :  * function set's module status to TC_SENDING, initilaizes test cases list
    1041                 :  * for module and sends message MSG_GTC
    1042                 :  * @param message pointer to MsgBuffer structure containing message
    1043                 :  * @return result of message handling, 0 if message handling was succesful, 
    1044                 :  *         -1 otherwise
    1045                 :  */
    1046                 : LOCAL int ec_msg_ok_handler (MsgBuffer * message)
    1047             183 : {
    1048             183 :         int             result = -1;
    1049             183 :         long            sender = message->sender_;
    1050                 :         int             work_module_status;
    1051                 :         int             retry_count;
    1052                 :         DLListIterator  work_module =
    1053             183 :             tm_get_ptr_by_pid (instantiated_modules, sender);
    1054                 :         MsgBuffer       message_gtc;
    1055                 : 
    1056                 :         /*Possible error handling will be inserted here */
    1057             183 :         retry_count = 0;
    1058             386 :         while (work_module == DLListNULLIterator) {
    1059                 : 
    1060              22 :                 MIN_WARN ("Could not fetch module data, pid = %d", sender);
    1061                 :                 /*
    1062                 :                 ** Synchronization issue try again a few times
    1063                 :                 */
    1064              22 :                 usleep (100000);
    1065              22 :                 work_module =
    1066                 :                         tm_get_ptr_by_pid (instantiated_modules, sender);
    1067              22 :                 retry_count++;
    1068              22 :                 if (retry_count > 10)
    1069               2 :                         return result;
    1070                 :         }
    1071                 : 
    1072             181 :         work_module_status = tm_get_status (work_module);
    1073                 : 
    1074             181 :         switch (work_module_status) {
    1075                 :         case TEST_MODULE_INITIALIZED:
    1076             178 :                 tm_set_status (work_module, TEST_MODULE_TC_SENDING);
    1077             178 :                 result = 0;
    1078             178 :                 message_gtc.type_ = MSG_GTC;
    1079             178 :                 message_gtc.sender_ = ec_settings.engine_pid_;
    1080             178 :                 message_gtc.receiver_ = message->sender_;
    1081             178 :                 message_gtc.param_ = 0;
    1082             178 :                 message_gtc.special_ = ESTrue;  /*TCDs should be sent */
    1083             178 :                 mq_send_message (mq_id, &message_gtc);
    1084             178 :                 break;
    1085                 : 
    1086                 :         case TEST_MODULE_INITIALIZED_TEMP:
    1087                 : 
    1088               3 :                 result = 0;
    1089               3 :                 message_gtc.type_ = MSG_GTC;
    1090               3 :                 message_gtc.sender_ = ec_settings.engine_pid_;
    1091               3 :                 message_gtc.receiver_ = message->sender_;
    1092               3 :                 message_gtc.param_ = 0;
    1093               3 :                 message_gtc.special_ = ESFalse; /*don't care about 
    1094                 :                                                    TCDs */
    1095               3 :                 mq_send_message (mq_id, &message_gtc);
    1096               3 :                 break;
    1097                 : 
    1098                 :         default:
    1099                 : 
    1100               0 :                 MIN_WARN ("Unexpected message sequence");
    1101               0 :                 result = -1;
    1102                 :                 break;
    1103                 : 
    1104                 :         }
    1105                 : 
    1106                 : #ifdef MIN_UNIT_TEST
    1107               2 :         unit_test_result = result;
    1108                 : #endif                          /*MIN_UNIT_TEST */
    1109                 : 
    1110             181 :         return result;
    1111                 : }
    1112                 : 
    1113                 : /**Function handling MSG_KO message, which means that some trouble occured on
    1114                 :  * tmc's side. Hadling depends on state of module: if it's 
    1115                 :  * TEST_MODULE_INITIALIZED, it means that test case extraction is impossible.
    1116                 :  * Module will be removed from "instantiated" list and terminated.Problems 
    1117                 :  * will be logged.
    1118                 :  * @param message - pointer to MsgBuffer containing message
    1119                 :  */
    1120                 : LOCAL int ec_msg_ko_handler (MsgBuffer * message)
    1121               1 : {
    1122               1 :         int             result = -1;
    1123               1 :         int             status = 0;
    1124               1 :         DLListIterator  work_module_item = DLListNULLIterator;
    1125                 :         /*work module fetched from list of instantiated modules */
    1126                 : 
    1127               1 :         work_module_item =
    1128                 :             tm_get_ptr_by_pid (instantiated_modules, message->sender_);
    1129                 : 
    1130               1 :         if (work_module_item == DLListNULLIterator) {
    1131                 : 
    1132               0 :                 MIN_WARN ("Could not fetch module data");
    1133               0 :                 return result;
    1134                 :         }
    1135                 : 
    1136               1 :         status = tm_get_status (work_module_item);
    1137               1 :         switch (status) {
    1138                 :         case TEST_MODULE_INITIALIZED:
    1139               1 :                 mq_send_message2 (mq_id, message->sender_, MSG_END, 0,
    1140                 :                                   "Useless module");
    1141               1 :                 waitpid (message->sender_, NULL, 0);
    1142               1 :                 dl_list_remove_it (work_module_item);
    1143               1 :                 MIN_WARN ("Could not fetch test cases");
    1144               1 :                 result = 0;
    1145               1 :                 break;
    1146                 : 
    1147                 :         default:
    1148                 : 
    1149               0 :                 result = -1;
    1150               0 :                 MIN_WARN ("Unexpected message sequence");
    1151                 :                 break;
    1152                 : 
    1153                 :         }
    1154                 : 
    1155               1 :         return result;
    1156                 : }
    1157                 : 
    1158                 : /**Function handling MSG_RET with test case results
    1159                 :  * @param message - pointer to MsgBuffer containing message
    1160                 :  */
    1161                 : LOCAL int ec_msg_ret_handler (MsgBuffer * message)
    1162              74 : {
    1163                 : 
    1164              74 :         DLListIterator  work_case_item = INITPTR;
    1165              74 :         DLListIterator  dest_case_item = INITPTR;
    1166              74 :         DLListIterator  work_module_item = INITPTR;
    1167              74 :         test_case_s    *work_case = INITPTR;
    1168              74 :         DLList         *work_result_list = INITPTR;
    1169              74 :         DLListIterator  work_result_item = INITPTR;
    1170                 :         int             group_id;
    1171                 :         filename_t      orig_conf;
    1172                 :         filename_t      work_conf;
    1173                 :         test_result_s  *result;
    1174              74 :         int             fun_result = 0;
    1175                 :         const char     *test_result_type_str[] = {
    1176                 :                 "not run",
    1177                 :                 "passed",
    1178                 :                 "failed",
    1179                 :                 "crashed",
    1180                 :                 "aborted",
    1181                 :                 "timeout",
    1182                 :                 "all"
    1183              74 :         };
    1184                 : 
    1185              74 :         work_module_item =
    1186                 :             tm_get_ptr_by_pid (instantiated_modules, message->sender_);
    1187              74 :         if (work_module_item == DLListNULLIterator) {
    1188                 : 
    1189               1 :                 MIN_WARN ("Failed to fetch module data");
    1190               1 :                 fun_result = -1;
    1191               1 :                 goto EXIT;
    1192                 :         }
    1193                 :         /* if module was instantiated as temporary, handling is different 
    1194                 :          * since it was created only to run one test case
    1195                 :          */
    1196              73 :         if (tm_get_status (work_module_item) == TEST_MODULE_BUSY_TEMP) {
    1197               0 :                 ec_handle_temp_results (work_module_item, message);
    1198               0 :                 fun_result = 1;
    1199               0 :                 goto EXIT;
    1200                 :         }
    1201                 :         /* in current design, there is only one test case with status : ongoing
    1202                 :          * belonging to module with given PID, so we search "selected cases" 
    1203                 :          * list for test case based on that information
    1204                 :          */
    1205              73 :         pthread_mutex_lock (&tec_mutex_);
    1206                 : 
    1207                 : 
    1208              73 :         work_case_item = dl_list_head (selected_cases);
    1209             690 :         while (work_case_item != DLListNULLIterator) {
    1210                 : 
    1211             617 :                 work_case = (test_case_s *) dl_list_data (work_case_item);
    1212             617 :                 if (((tc_get_status (work_case_item)) == TEST_CASE_ONGOING) &&
    1213                 :                     ((tm_get_pid (tc_get_test_module_ptr (work_case_item))) ==
    1214                 :                      message->sender_))
    1215                 :                         /* we found ongoing case with module matching message 
    1216                 :                          * sender's pid, co we can stop
    1217                 :                          * iterating through list 
    1218                 :                          */
    1219              73 :                         break;
    1220             544 :                 work_case_item = dl_list_next (work_case_item);
    1221                 : 
    1222                 :         }
    1223                 : 
    1224              73 :         pthread_mutex_unlock (&tec_mutex_);
    1225                 : 
    1226              73 :         if (work_case_item == DLListNULLIterator) {
    1227               0 :                 fun_result = -1;
    1228               0 :                 goto EXIT;
    1229                 :         }
    1230                 : 
    1231                 : 
    1232              73 :         work_result_list = tc_get_tr_list (work_case_item);
    1233              73 :         if (work_result_list == INITPTR) {
    1234               0 :                 MIN_WARN ("Fault in test data");
    1235               0 :                 fun_result = -1;
    1236               0 :                 goto EXIT;
    1237                 :         }
    1238                 : 
    1239              73 :         work_result_item = dl_list_head (work_result_list);
    1240              73 :         tr_set_result_description (work_result_item, message->message_);
    1241              73 :         tr_set_end_time (work_result_item, time (NULL));
    1242                 : 
    1243              73 :         switch (message->param_) {
    1244                 : 
    1245                 :         case TP_CRASHED:
    1246               0 :                 min_return_value ++;
    1247               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_CRASHED);
    1248               0 :                 break;
    1249                 : 
    1250                 :         case TP_TIMEOUTED:
    1251               0 :                 min_return_value ++;
    1252               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_TIMEOUT);
    1253               0 :                 break;
    1254                 : 
    1255                 :         case TP_PASSED:
    1256                 : 
    1257              64 :                 tr_set_result_type (work_result_item, TEST_RESULT_PASSED);
    1258              64 :                 break;
    1259                 : 
    1260                 :         case TP_FAILED:
    1261               8 :                 min_return_value ++;
    1262               8 :                 tr_set_result_type (work_result_item, TEST_RESULT_FAILED);
    1263               8 :                 break;
    1264                 : 
    1265                 :         case TP_NC:
    1266               1 :                 min_return_value ++;
    1267               1 :                 tr_set_result_type (work_result_item, TEST_RESULT_ABORTED);
    1268               1 :                 break;
    1269                 : 
    1270                 :         case TP_LEAVE:
    1271               0 :                 min_return_value ++;
    1272               0 :                 tr_set_result_type (work_result_item, TEST_RESULT_FAILED);
    1273               0 :                 break;
    1274                 : 
    1275                 :         default:
    1276                 : 
    1277               0 :                 MIN_WARN ("Faulty data received");
    1278               0 :                 fun_result = -1;
    1279               0 :                 goto EXIT;
    1280                 :         }
    1281              73 :         MIN_DEBUG ("RESULT CODE = %s (%d)",
    1282                 :                     test_result_type_str [tr_get_result_type
    1283                 :                                           (work_result_item)],
    1284                 :                     tr_get_result_type (work_result_item));
    1285              73 :         tm_set_status (work_module_item, TEST_MODULE_READY);
    1286              73 :         tc_set_status (work_case_item, TEST_CASE_TERMINATED);
    1287              73 :         group_id = tc_get_group_id (work_case_item);
    1288                 : 
    1289                 :         /*if (in->case_result) in->case_result (tc_get_run_id (work_case_item), 
    1290                 :                                               message->param_, 
    1291                 :                                               message->message_,
    1292                 :                                               tr_get_start_time
    1293                 :                                               (work_result_item),
    1294                 :                                               tr_get_end_time
    1295                 :                                               (work_result_item));*/
    1296              73 :         MINAPI_PLUGIN_CALL (case_result,
    1297                 :                             case_result (tc_get_run_id (work_case_item), 
    1298                 :                                          message->param_, 
    1299                 :                                          message->message_,
    1300                 :                                          tr_get_start_time
    1301                 :                                          (work_result_item),
    1302                 :                                          tr_get_end_time
    1303                 :                                          (work_result_item)));
    1304                 :         
    1305                 : #ifndef MIN_EXTIF
    1306              67 :         MIN_DEBUG ("is it ip slave case ?");
    1307              67 :         work_case = (test_case_s *)dl_list_data (work_case_item);
    1308              67 :         if (work_case->ip_slave_case_) {
    1309               0 :                 MIN_DEBUG ("ip slave case");
    1310                 : 
    1311               0 :                 tcp_master_report (work_case->tc_run_id_, 1, message->param_,
    1312                 :                                    message->desc_);
    1313                 : 
    1314                 :         } 
    1315                 : #endif
    1316                 :         /* Now let's link created result item to original test case. 
    1317                 :          * We will use module link, test case id and test case filename 
    1318                 :          */
    1319              73 :         dest_case_item = dl_list_head (tm_get_tclist (work_module_item));
    1320              73 :         tc_get_cfg_filename (work_case_item, work_conf);
    1321                 : 
    1322                 : 
    1323             691 :         while (dest_case_item != DLListNULLIterator) {
    1324             618 :                 tc_get_cfg_filename (dest_case_item, orig_conf);
    1325             618 :                 if ((tc_get_id (dest_case_item) == tc_get_id (work_case_item))
    1326                 :                     && (strcmp (work_conf, orig_conf) == 0)) {
    1327              73 :                         break;
    1328                 :                 }
    1329             545 :                 dest_case_item = dl_list_next (dest_case_item);
    1330                 :         }
    1331              73 :         result = NEW (test_result_s);
    1332              73 :         memcpy (result,
    1333                 :                 dl_list_data (work_result_item), sizeof (test_result_s));
    1334              73 :         ((test_result_s *) dl_list_data (work_result_item))->printouts_list_ =
    1335                 :             INITPTR;
    1336              73 :         work_result_item = tr_add (tc_get_tr_list (dest_case_item), result);
    1337                 : 
    1338              73 :         ((test_result_s *) dl_list_data (work_result_item))->tc_data_item_ =
    1339                 :             dest_case_item;
    1340                 :         /*now add result to global "results" list */
    1341                 :         /*dl_list_add(dl_list_data(work_result_item),results); */
    1342                 : 
    1343              73 :         MIN_DEBUG ("orig_case has %d results now",
    1344                 :                     dl_list_size (tc_get_tr_list (dest_case_item)));
    1345              73 :         work_result_item = dl_list_head (tc_get_tr_list (dest_case_item));
    1346             220 :         while (work_result_item != DLListNULLIterator) {
    1347              74 :                 MIN_DEBUG ("RESULT CODE = %s (%d)",
    1348                 :                              test_result_type_str
    1349                 :                              [tr_get_result_type (work_result_item)],
    1350                 :                              tr_get_result_type (work_result_item));
    1351                 : 
    1352              74 :                 work_result_item = dl_list_next (work_result_item);
    1353                 :         }
    1354                 : 
    1355                 : 
    1356              73 :         if (group_id != 0)
    1357              66 :                 ec_check_next_in_group (group_id);
    1358              74 : EXIT:
    1359              74 :         return fun_result;
    1360                 : }
    1361                 : 
    1362                 : /** Function handling MSG_TCD message. It creates new test_case_s structure and
    1363                 :  * inserts it into
    1364                 :  * apropriate module's case list.
    1365                 :  * @param message - pointer to MsgBuffer containing message
    1366                 :  * @return result of message handling, 0 if message was handled, -1 otherwise
    1367                 :  */
    1368                 : LOCAL int ec_msg_tcd_handler (MsgBuffer * message)
    1369             802 : {
    1370             802 :         int             result = -1;
    1371             802 :         int             work_module_status = 0;
    1372             802 :         int             address = 0;
    1373             802 :         DLListIterator  work_module_item = DLListNULLIterator;
    1374             802 :         DLListIterator  work_case_item = DLListNULLIterator;
    1375             802 :         test_case_s    *work_case = INITPTR;
    1376             802 :         DLList         *work_tclist = INITPTR;
    1377                 : 
    1378             802 :         work_module_item =
    1379                 :             tm_get_ptr_by_pid (instantiated_modules, message->sender_);
    1380             802 :         if (work_module_item == DLListNULLIterator)
    1381               0 :                 goto EXIT;
    1382                 : 
    1383             802 :         work_module_status = tm_get_status (work_module_item);
    1384                 : 
    1385             802 :         work_tclist = tm_get_tclist (work_module_item);
    1386             802 :         if (work_tclist == INITPTR)
    1387               0 :                 goto EXIT;
    1388                 : 
    1389             802 :         if (message->param_ == 0) {
    1390                 : 
    1391             179 :                 switch (work_module_status) {
    1392                 :                 case TEST_MODULE_TC_SENDING:
    1393             177 :                         MIN_DEBUG ("finished tc gathering");
    1394             177 :                         if (dl_list_size (tm_get_tclist (work_module_item)) ==
    1395                 :                             0) {
    1396                 :                                 /* something went wrong, module has 0 tcs, 
    1397                 :                                  * and can be removed - at least in current 
    1398                 :                                  * design 
    1399                 :                                  */
    1400                 :                                 /*if (in->module_ready) 
    1401                 :                                         in->module_ready 
    1402                 :                                                 (tm_get_module_id 
    1403                 :                                                  (work_module_item));*/
    1404               6 :                                 MINAPI_PLUGIN_CALL (module_ready,
    1405                 :                                                     module_ready
    1406                 :                                                     (tm_get_module_id 
    1407                 :                                                      (work_module_item)));
    1408               6 :                                 address = tm_get_pid (work_module_item);
    1409               6 :                                 mq_send_message2 (mq_id, address, MSG_END, 0,
    1410                 :                                                   "Shut down !");
    1411               6 :                                 tm_remove (work_module_item);
    1412               6 :                                 waitpid (address, NULL, 0);
    1413                 : 
    1414               6 :                                 result = 0;
    1415               6 :                                 goto EXIT;
    1416                 :                                 break;
    1417                 :                         } else {
    1418             171 :                                 tm_set_status (work_module_item,
    1419                 :                                                TEST_MODULE_READY);
    1420             171 :                                 result = 0;
    1421                 :                                 /*if (in->module_ready) 
    1422                 :                                         in->module_ready 
    1423                 :                                                 (tm_get_module_id 
    1424                 :                                                  (work_module_item));*/
    1425             171 :                                 MINAPI_PLUGIN_CALL (module_ready, 
    1426                 :                                                     module_ready 
    1427                 :                                                     (tm_get_module_id 
    1428                 :                                                      (work_module_item)));
    1429             171 :                                 goto EXIT;
    1430                 :                         }
    1431                 :                         break;
    1432                 :                 case TEST_MODULE_INITIALIZED_TEMP:
    1433               2 :                         tm_set_status (work_module_item,
    1434                 :                                        TEST_MODULE_BUSY_TEMP);
    1435                 :                         /* first case from list will be fetched and executed,
    1436                 :                          * since temp module has only one case in list 
    1437                 :                          */
    1438               2 :                         result = ec_exec_case_temp (work_module_item);
    1439               2 :                         goto EXIT;
    1440                 :                         break;
    1441                 :                 default:
    1442               0 :                         MIN_WARN (" UNEXPECTED MESSAGE SEQUENCE ");
    1443               0 :                         result = -1;
    1444               0 :                         goto EXIT;
    1445                 :                         break;
    1446                 :                 }
    1447                 :         }
    1448                 : 
    1449             623 :         if (work_module_status == TEST_MODULE_TC_SENDING &&
    1450                 :             !ec_filter_it(message->message_)) {
    1451             597 :                 work_case =
    1452                 :                     tc_create (work_module_item, message->desc_,
    1453                 :                                message->message_);
    1454             597 :                 work_case_item = tc_add (work_tclist, work_case);
    1455             597 :                 tc_set_id (work_case_item, message->param_);
    1456             597 :                 work_case->tc_ext_id_ =
    1457                 :                         dl_list_size (work_tclist);
    1458             597 :                 MINAPI_PLUGIN_CALL (new_case,
    1459                 :                                     new_case (tm_get_module_id 
    1460                 :                                               (work_module_item),
    1461                 :                                               work_case->tc_ext_id_,
    1462                 :                                               work_case->title_));
    1463                 :         }
    1464             623 :         result = 0;
    1465             802 : EXIT:
    1466             802 :         return result;
    1467                 : }
    1468                 : 
    1469                 : 
    1470                 : /** Function handling MSG_EVENT message.
    1471                 :  * @param message - pointer to MsgBuffer containing message
    1472                 :  * @return result of message handling, 0 if message was handled, -1 otherwise
    1473                 :  */
    1474                 : LOCAL int ec_msg_event_handler (MsgBuffer * message)
    1475              14 : {
    1476                 :         minTestEventParam_t param;
    1477                 :         minEventSrc_t  esrc;
    1478              14 :         int result = 0;
    1479                 :         int status;
    1480                 : 
    1481              14 :         if (!event_system_up ()) {
    1482               0 :                 MIN_WARN ("Event System is not initialized, can not handle "
    1483                 :                            "message");
    1484               0 :                 result = -1;
    1485               0 :                 goto EXIT;
    1486                 :         }
    1487              14 :         param.event.event_type_ = (message->param_ >> 8) & 0xff;
    1488              14 :         param.command_ = message->param_ & 0xff;
    1489                 : 
    1490              14 :         param.event.event_name_ = NEW2 (char, strlen (message->message_) + 1);
    1491                 : 
    1492              14 :         STRCPY (param.event.event_name_, message->message_,
    1493                 :                 strlen (message->message_) + 1);
    1494                 : 
    1495              14 :         esrc.remote = 0;
    1496              14 :         esrc.pid = message->special_;
    1497              14 :         switch (param.event.event_type_) {
    1498                 :         case EIndication:
    1499               4 :                 switch (param.command_) {
    1500                 :                 case EReqEvent:
    1501               3 :                         MIN_DEBUG ("Indication Event: REQUEST");
    1502               3 :                         ind_event_handle_request (&param, &esrc);
    1503               3 :                         break;
    1504                 :                 case EWaitEvent:
    1505               0 :                         MIN_DEBUG ("Indication Event: WAIT");
    1506               0 :                         ind_event_handle_wait (&param, &esrc, &status);
    1507               0 :                         break;
    1508                 :                 case ERelEvent:
    1509               0 :                         MIN_DEBUG ("Indication Event: RELEASE");
    1510               0 :                         ind_event_handle_release (&param, &esrc);
    1511               0 :                         break;
    1512                 :                 case ESetEvent:
    1513               1 :                         MIN_DEBUG ("Indication Event: SET");
    1514               1 :                         ind_event_handle_set (&param, &esrc);
    1515               1 :                         break;
    1516                 :                 case EUnsetEvent:
    1517               0 :                         MIN_DEBUG ("Indication Event: UNSET N/A for"
    1518                 :                                      " Indications");
    1519                 :                         break;
    1520                 :                 default:
    1521                 :                         break;
    1522                 :                 }
    1523               4 :                 break;
    1524                 :         case EState:
    1525              10 :                 switch (param.command_) {
    1526                 :                 case EReqEvent:
    1527               4 :                         MIN_DEBUG ("State Event: REQUEST");
    1528               4 :                         state_event_handle_request (&param, &esrc);
    1529               4 :                         break;
    1530                 :                 case EWaitEvent:
    1531               1 :                         MIN_DEBUG ("State Event: WAIT");
    1532               1 :                         state_event_handle_wait (&param, &esrc,
    1533                 :                                                  &status);
    1534               1 :                         break;
    1535                 :                 case ERelEvent:
    1536               1 :                         MIN_DEBUG ("State Event: RELEASE");
    1537               1 :                         state_event_handle_release (&param, &esrc);
    1538               1 :                         break;
    1539                 :                 case ESetEvent:
    1540               3 :                         MIN_DEBUG ("State Event: SET");
    1541               3 :                         state_event_handle_set (&param, &esrc);
    1542               3 :                         break;
    1543                 :                 case EUnsetEvent:
    1544               1 :                         MIN_DEBUG ("State Event: UNSET");
    1545               1 :                         state_event_handle_unset (&param, &esrc);
    1546                 :                         break;
    1547                 :                 default:
    1548                 :                         break;
    1549                 :                 }
    1550              10 :                 break;
    1551                 :         default:
    1552               0 :                 MIN_WARN ("Unsupported event type %d\n",
    1553                 :                            param.event.event_type_);
    1554                 :                 break;
    1555                 :         }
    1556                 : 
    1557              14 :         DELETE (param.event.event_name_);
    1558              14 : EXIT:
    1559              14 :         return result;
    1560                 : }
    1561                 : 
    1562                 : 
    1563                 : /** Function handling MSG_USR message. this message is used to pass 
    1564                 :  * "printouts" from test case to console UI. Handler will write received 
    1565                 :  * data to apropriate place in test result's printouts list according to 
    1566                 :  * priority of printout. Accessing proper
    1567                 :  * test case/result data will be done in a way similar to MSG_RET handler.
    1568                 :  * @param message pointer to MsgBuffer containing read message
    1569                 :  * @return result of message handling, 0 if message was handled, -1 otherwise.
    1570                 :  */
    1571                 : LOCAL int ec_msg_usr_handler (MsgBuffer * message)
    1572              68 : {
    1573                 : 
    1574              68 :         DLListIterator  work_module_item = INITPTR;
    1575              68 :         DLListIterator  work_case_item = INITPTR;
    1576              68 :         DLListIterator  work_printout_item = INITPTR;
    1577              68 :         test_case_s    *work_case = INITPTR;
    1578              68 :         DLListIterator  work_result_item = INITPTR;
    1579              68 :         DLList         *work_list = INITPTR;
    1580                 :         test_result_printout_s *print_msg;
    1581              68 :         unsigned int    it = 0; /*general purpose iterator */
    1582                 :         int             case_id;
    1583              68 :         int             result = 0;
    1584                 : 
    1585              68 :         work_module_item =
    1586                 :             tm_get_ptr_by_pid (instantiated_modules, message->sender_);
    1587              68 :         print_msg = tr_create_printout (message->param_, message->message_);
    1588                 :         
    1589                 :         /* 
    1590                 :         ** Messages with descriction __error_console__ have a special handling
    1591                 :         */
    1592              68 :         if (!strcmp (message->desc_, "__error_console__")) {
    1593                 :                 /*if (in->error_report) in->error_report (message->message_);*/
    1594               2 :                 MINAPI_PLUGIN_CALL (error_report,
    1595                 :                                     error_report (message->message_));
    1596               2 :                 tr_remove_printout (print_msg);
    1597               2 :                 goto EXIT;
    1598                 :         }
    1599                 : 
    1600              66 :         if (work_module_item == DLListNULLIterator) {
    1601               0 :                 MIN_WARN ("Failed to fetch module data");
    1602               0 :                 result = -1;
    1603               0 :                 tr_remove_printout (print_msg);
    1604               0 :                 goto EXIT;
    1605                 :         }
    1606                 : 
    1607                 :        /* in current design, there is only one test case with status : 
    1608                 :         * ongoing belonging to module with given PID, so we search 
    1609                 :         * "selected cases" list for test case based on that
    1610                 :         * information
    1611                 :         */
    1612              66 :         pthread_mutex_lock (&tec_mutex_);
    1613                 : 
    1614              66 :         case_id = 0;
    1615              66 :         work_case_item = dl_list_head (selected_cases);
    1616             480 :         while (work_case_item != DLListNULLIterator) {
    1617                 : 
    1618             414 :                 work_case = (test_case_s *) dl_list_data (work_case_item);
    1619                 : 
    1620             414 :                 if (((tc_get_status (work_case_item)) == TEST_CASE_ONGOING) &&
    1621                 :                     ((tm_get_pid (tc_get_test_module_ptr (work_case_item))) ==
    1622                 :                      message->sender_))
    1623                 :                         /* we found ongoing case with module matching message
    1624                 :                          * sender's pid, co we can stop iterating through list
    1625                 :                          */
    1626              66 :                         break;
    1627             348 :                 case_id++;
    1628             348 :                 work_case_item = dl_list_next (work_case_item);
    1629                 : 
    1630                 :         }
    1631                 :         
    1632              66 :         pthread_mutex_unlock (&tec_mutex_);
    1633                 : 
    1634              66 :         if (work_case_item == DLListNULLIterator){
    1635               0 :                 result = -1;
    1636               0 :                 tr_remove_printout (print_msg);
    1637               0 :                 goto EXIT;
    1638                 :         }
    1639                 : 
    1640              66 :         work_list = tc_get_tr_list (work_case_item);
    1641              66 :         if (work_list == INITPTR) {
    1642               0 :                 MIN_WARN ("Fault in test data");
    1643               0 :                 result = -1;
    1644               0 :                 tr_remove_printout (print_msg);
    1645               0 :                 goto EXIT;
    1646                 :         }
    1647                 : 
    1648              66 :         work_result_item = dl_list_head (work_list);
    1649             132 :         while (work_result_item != DLListNULLIterator) {
    1650              66 :                 if (tr_get_result_type (work_result_item) ==
    1651                 :                     TEST_RESULT_NOT_RUN)
    1652              66 :                         break;
    1653               0 :                 work_result_item = dl_list_next (work_result_item);
    1654                 :         }
    1655                 :         
    1656                 :         /*if (in->module_prints) in->module_prints (message->sender_, 
    1657                 :                                                   message->message_);
    1658                 :         MINAPI_PLUGIN_CALL (module_prints, module_prints (message->sender_, 
    1659                 :                                                           message->message_));
    1660                 :         Why twice ??
    1661                 :         */
    1662              66 :         work_list = tr_get_priontouts_list (work_result_item);
    1663              66 :         work_printout_item = dl_list_head (work_list);
    1664             356 :         while (work_printout_item != DLListNULLIterator) {
    1665             224 :                 if (((test_result_printout_s *)
    1666                 :                      dl_list_data (work_printout_item))->priority_ >
    1667                 :                     message->param_)
    1668               0 :                         break;
    1669             224 :                 it++;
    1670             224 :                 work_printout_item = dl_list_next (work_printout_item);
    1671                 :         }
    1672                 :         //dl_list_add_at (work_list, ( void* ) print_msg, it);
    1673              66 :         dl_list_add (work_list, (void *)print_msg);
    1674                 :         /*if (in->module_prints)
    1675                 :                 in->module_prints (tc_get_run_id (work_case_item),
    1676                 :                                    message->message_);*/
    1677              66 :         MINAPI_PLUGIN_CALL(module_prints,
    1678                 :                            module_prints (tc_get_run_id (work_case_item),
    1679                 :                                           message->message_));
    1680              68 : EXIT:
    1681              68 :         return result;
    1682                 : }
    1683                 : 
    1684                 : 
    1685                 : /** Function handling MSG_RUN_ID message. 
    1686                 :  * @param message - pointer to MsgBuffer containing message
    1687                 :  * @return result of message handling, 0 if message was handled, -1 otherwise
    1688                 :  */
    1689                 : LOCAL int ec_msg_run_id_handler (MsgBuffer * message)
    1690              95 : {
    1691              95 :         int             result = -1;
    1692              95 :         DLListIterator  work_module_item = DLListNULLIterator;
    1693              95 :         DLListIterator  work_case_item = DLListNULLIterator;
    1694              95 :         test_case_s    *work_case = INITPTR;
    1695                 : 
    1696                 : 
    1697              95 :         work_module_item =
    1698                 :             tm_get_ptr_by_pid (instantiated_modules, message->sender_);
    1699              95 :         if (work_module_item == DLListNULLIterator)
    1700               0 :                 goto EXIT;
    1701                 : 
    1702              95 :         work_case_item = dl_list_head (selected_cases);
    1703             736 :         while (work_case_item != DLListNULLIterator) {
    1704                 : 
    1705             641 :                 work_case = (test_case_s *) dl_list_data (work_case_item);
    1706             641 :                 if (((tc_get_status (work_case_item)) == TEST_CASE_ONGOING) &&
    1707                 :                     ((tm_get_pid (tc_get_test_module_ptr (work_case_item))) ==
    1708                 :                      message->sender_))
    1709              95 :                         break;
    1710             546 :                 work_case_item = dl_list_next (work_case_item);
    1711                 : 
    1712                 :         }
    1713              95 :         if (work_case_item == DLListNULLIterator)
    1714               0 :                 goto EXIT;
    1715                 : 
    1716              95 :         tc_set_run_id (work_case_item, message->param_);
    1717                 : 
    1718              95 :         MINAPI_PLUGIN_CALL(case_started,
    1719                 :                            case_started(tm_get_module_id(work_module_item),
    1720                 :                                         tc_get_ext_id (work_case_item),
    1721                 :                                         tc_get_run_id (work_case_item)));
    1722                 :                                       
    1723                 :         
    1724              95 :         result = 0;
    1725              95 : EXIT:
    1726              95 :         return result;
    1727                 : }
    1728                 : 
    1729                 : /** Function called to dispatch message - it recognizes message type and
    1730                 :  * calls function that handles message. If received message is not of the type
    1731                 :  * expected by engine, function logs error information.
    1732                 :  * @param message - pointer to received MsgBuffer
    1733                 :  * @return result of message handling, 0 if message was handled, -1 otherwise.
    1734                 : */
    1735                 : LOCAL int ec_message_dispatch (MsgBuffer * rcvd_message)
    1736            1243 : {
    1737            1243 :         int             msg_handling_result = -1;
    1738                 : 
    1739            1243 :         MIN_DEBUG ("MsgBuffer::message = %s", rcvd_message->message_);
    1740            1243 :         MIN_DEBUG ("MsgBuffer::desc = %s", rcvd_message->desc_);
    1741            1243 :         MIN_DEBUG ("MsgBuffer::type = %d", rcvd_message->type_);
    1742            1243 :         switch (rcvd_message->type_) {
    1743                 :         case MSG_OK:
    1744                 : 
    1745             183 :                 msg_handling_result = ec_msg_ok_handler (rcvd_message);
    1746             183 :                 break;
    1747                 : 
    1748                 :         case MSG_USR:
    1749                 : 
    1750              68 :                 msg_handling_result = ec_msg_usr_handler (rcvd_message);
    1751              68 :                 break;
    1752                 : 
    1753                 :         case MSG_RET:
    1754                 : 
    1755              74 :                 msg_handling_result = ec_msg_ret_handler (rcvd_message);
    1756              74 :                 break;
    1757                 : 
    1758                 :         case MSG_KO:
    1759                 : 
    1760               1 :                 msg_handling_result = ec_msg_ko_handler (rcvd_message);
    1761               1 :                 break;
    1762                 : 
    1763                 :         case MSG_TCD:
    1764                 : 
    1765             801 :                 msg_handling_result = ec_msg_tcd_handler (rcvd_message);
    1766             801 :                 break;
    1767                 : 
    1768                 :         case MSG_EVENT:
    1769              14 :                 msg_handling_result = ec_msg_event_handler (rcvd_message);
    1770              14 :                 break;
    1771                 :         case MSG_EXTIF:
    1772               6 :                 msg_handling_result = ec_msg_ms_handler (rcvd_message);
    1773               6 :                 break;
    1774                 :         case MSG_SNDRCV:
    1775               0 :                 msg_handling_result = ec_msg_sndrcv_handler (rcvd_message);
    1776               0 :                 break;
    1777                 :         case MSG_RUN_ID:
    1778              95 :                 msg_handling_result = ec_msg_run_id_handler (rcvd_message);
    1779              95 :                 break;
    1780                 :                 
    1781                 :         default:
    1782                 : 
    1783               1 :                 MIN_WARN ("Faulty message received of type: %d", 
    1784                 :                           rcvd_message->type_);
    1785                 :         }
    1786                 : 
    1787            1243 :         return msg_handling_result;
    1788                 : 
    1789                 : }
    1790                 : 
    1791                 : 
    1792                 : /** Function that is the basis for message listening thread. Contains while 
    1793                 :  * loop that checks messages in queue and calls ec_msg_dispatch to handle any
    1794                 :  * message
    1795                 :  * @param arg some dummy pointer, to keep compiler from complaining
    1796                 :  */
    1797                 : LOCAL void     *ec_message_listener (void *arg)
    1798             124 : {
    1799                 : 
    1800             124 :         int             handling_result = 0;
    1801             124 :         long            own_address = 0;
    1802             124 :         unsigned long   wait_time = 2;  /*time in miliseconds that thread 
    1803                 :                                            spends sleeping during periods
    1804                 :                                            with no IPC traffic */
    1805                 :         MsgBuffer       received_msg;
    1806                 : 
    1807             124 :         pthread_mutex_lock (&tec_mutex_);
    1808                 :         /* Engine's process id was made global, because passing it to message
    1809                 :          * listener function as a pointer has proven to be unreliable, 
    1810                 :          * especially on ARM targets. 
    1811                 :          */
    1812             124 :         own_address = ec_settings.engine_pid_;  
    1813             124 :         pthread_mutex_unlock (&tec_mutex_);
    1814                 : 
    1815                 : #ifdef MIN_UNIT_TEST
    1816               7 :         unit_test_result = 1;
    1817                 : #endif                          /*MIN_UNIT_TEST */
    1818                 :         while (1) {
    1819            5449 :                 handling_result = mq_peek_message (mq_id, own_address);
    1820            5449 :                 if (handling_result != 0) {
    1821            1238 :                         wait_time = 2;
    1822            1238 :                         handling_result =
    1823                 :                             mq_read_message (mq_id, own_address,
    1824                 :                                              &received_msg);
    1825            1238 :                         if (handling_result > 8) {
    1826            1238 :                                 ec_message_dispatch (&received_msg);
    1827                 :                         } else {
    1828               0 :                                 MIN_WARN ("Message_handling_fault");
    1829                 :                         }
    1830                 :                 } else {
    1831            4211 :                         if (errno == EINVAL) {
    1832              19 :                                 MIN_INFO ("Message queue was destroyed,"
    1833                 :                                             " exiting listener thread");
    1834              19 :                                 pthread_exit (NULL);
    1835                 :                         } else {
    1836            4192 :                                 if (wait_time < 200000)
    1837            2868 :                                         wait_time = wait_time * 10;
    1838                 :                                 /*sleep should not be longer than 0.2 sec. */
    1839            4192 :                                 usleep (wait_time);
    1840                 :                         }
    1841                 :                 }
    1842                 : 
    1843                 : 
    1844                 : 
    1845                 : #ifdef MIN_UNIT_TEST
    1846              38 :                 unit_test_result = handling_result;
    1847                 : #endif
    1848            5325 :         }
    1849                 : 
    1850                 :         return NULL;
    1851                 : }
    1852                 : 
    1853                 : /*-----------------------------------------------------------------------*/
    1854                 : /** Function that wraps test module controller process starting. In case of 
    1855                 : * failure to start a module, information will be logged.
    1856                 : * @param work_module_item item from available modules list
    1857                 : * @return pid of newly created process, or -1 in case of failure*/
    1858                 : 
    1859                 : LOCAL pid_t ec_start_tmc (DLListIterator work_module_item)
    1860             257 : {
    1861             257 :         char          **exec_args = NULL;
    1862                 : 
    1863                 :         DLListIterator  work_file_item;
    1864             257 :         char           *mod_fpath = NULL;
    1865             257 :         char           *mod_fpath_new = NULL;
    1866             257 :         char           *dir = NULL;
    1867             257 :         char           *mod_name = NULL;
    1868             257 :         char           *conf_name = NULL;
    1869             257 :         char           *conf_path = NULL;
    1870                 : 
    1871             257 :         int             it = 0; /*general purpose loop iterator */
    1872                 :         /*position of directory in search paths list */
    1873             257 :         int             path_pos = 0;   
    1874             257 :         int             result = -1;
    1875             257 :         int             retval = -1;
    1876             257 :         pid_t           res_pid = 0;
    1877                 : 
    1878                 :         DLList         *work_list;
    1879                 : 
    1880             257 :         work_list  = tm_get_cfg_filenames (work_module_item);
    1881             257 :         exec_args = NEW2 (char *, dl_list_size (work_list) + 3);
    1882             257 :         exec_args[it++] = ec_settings.tmc_app_path_;
    1883                 : 
    1884             257 :         if (*((test_module_info_s *) dl_list_data (work_module_item))->
    1885                 :             module_filename_ == '/') {
    1886              11 :                 mod_fpath =
    1887                 :                     ((test_module_info_s *) dl_list_data (work_module_item))->
    1888                 :                     module_filename_;
    1889              11 :                 result = access (mod_fpath, F_OK);
    1890              11 :                 if (result != 0) {
    1891               0 :                         MIN_WARN ("Module not found %s",mod_fpath);
    1892               0 :                         retval = -1;
    1893               0 :                         goto out;
    1894                 :                 }
    1895                 :         } else {
    1896             246 :                 mod_name =
    1897                 :                     NEW2 (char,
    1898                 :                           strlen (((test_module_info_s *)
    1899                 :                                    dl_list_data (work_module_item))->
    1900                 :                                   module_filename_) + 4);
    1901             246 :                 sprintf (mod_name, "%s.so",
    1902                 :                          ((test_module_info_s *)
    1903                 :                           dl_list_data (work_module_item))->module_filename_);
    1904             246 :                 path_pos = ec_search_lib (mod_name);
    1905                 : 
    1906             246 :                 if (path_pos != -1) {
    1907             245 :                         dir =
    1908                 :                             (char *)
    1909                 :                             dl_list_data (dl_list_at
    1910                 :                                           (ec_settings.search_dirs,
    1911                 :                                            path_pos));
    1912             245 :                         mod_fpath_new =
    1913                 :                             NEW2 (char, strlen (dir) + strlen (mod_name) + 2);
    1914             245 :                         mod_fpath = mod_fpath_new;
    1915             245 :                         sprintf (mod_fpath, "%s/%s", dir, mod_name);
    1916                 :                 }
    1917                 :         }
    1918                 : 
    1919             257 :         if (mod_fpath == NULL) {
    1920               1 :                 MIN_WARN ("Module not found");
    1921               1 :                 retval = -1;
    1922               1 :                 goto out;
    1923                 :         }
    1924             256 :         exec_args[it++] = mod_fpath;
    1925             256 :         work_file_item = dl_list_head (work_list);
    1926             569 :         while (work_file_item != DLListNULLIterator) {
    1927              57 :                 conf_name = (char *)dl_list_data (work_file_item);
    1928              57 :                 work_file_item = dl_list_next (work_file_item);
    1929              57 :                 if (*conf_name == '/') {
    1930                 :                         /*config file was defined as full path */
    1931               2 :                         conf_path = NEW2 (char, strlen (conf_name) + 1);
    1932               2 :                         sprintf (conf_path, "%s", conf_name);
    1933               2 :                         exec_args[it++] = conf_path;
    1934               2 :                         continue;
    1935                 :                 }
    1936                 : 
    1937              55 :                 conf_path = NEW2 (char, strlen (conf_name) +
    1938                 :                                   strlen ((char *)
    1939                 :                                           dl_list_data (dl_list_at
    1940                 :                                                         (ec_settings.
    1941                 :                                                          search_dirs,
    1942                 :                                                          path_pos))) + 2);
    1943              55 :                 sprintf (conf_path, "%s/%s",
    1944                 :                          (char *)
    1945                 :                          dl_list_data (dl_list_at
    1946                 :                                        (ec_settings.search_dirs, path_pos)),
    1947                 :                          conf_name);
    1948                 :                 /* now check if config exists in the same directory as 
    1949                 :                    module */
    1950              55 :                 result = access (conf_path, F_OK);
    1951              55 :                 if (result == 0) {
    1952               0 :                         exec_args[it++] = conf_path;
    1953               0 :                         continue;
    1954                 :                 }
    1955                 :                 /*config not found so far, let's look for it in search
    1956                 :                    paths */
    1957              55 :                 path_pos = ec_search_lib (conf_name);
    1958              55 :                 if (path_pos != -1) {
    1959              55 :                         dir =
    1960                 :                             (char *)
    1961                 :                             dl_list_data (dl_list_at
    1962                 :                                           (ec_settings.search_dirs,
    1963                 :                                            path_pos));
    1964              55 :                         if (conf_path)
    1965              55 :                                 DELETE (conf_path);
    1966              55 :                         conf_path =
    1967                 :                             NEW2 (char,
    1968                 :                                   strlen (dir) + strlen (conf_name) + 2);
    1969              55 :                         sprintf (conf_path, "%s/%s", dir, conf_name);
    1970              55 :                         exec_args[it++] = conf_path;
    1971              55 :                         continue;
    1972                 :                 }
    1973               0 :                 MIN_WARN ("specified config not found : %s", conf_name);
    1974               0 :                 retval = -1;
    1975               0 :                 goto out;
    1976                 : 
    1977                 :         }
    1978             256 :         exec_args[it++] = NULL;
    1979             256 :         res_pid = fork ();
    1980             313 :         switch (res_pid) {
    1981                 :         case -1:
    1982               0 :                 MIN_FATAL ("Failed to create process !");
    1983               0 :                 break;
    1984                 :         case 0:
    1985             125 :                 sched_yield ();
    1986             125 :                 execve (exec_args[0], exec_args, envp);
    1987               5 :                 MIN_FATAL ("Failed to load test module controller app :%s",
    1988                 :                              strerror (errno));
    1989               5 :                 exit (-1);
    1990                 :                 break;
    1991                 :         default:
    1992                 :                 break;
    1993                 :         };
    1994             188 :         tm_set_pid (work_module_item, res_pid);
    1995             188 :         retval = res_pid;
    1996             189 :       out:
    1997             189 :         DELETE (exec_args);
    1998             189 :         DELETE (mod_fpath_new);
    1999             189 :         DELETE (mod_name);
    2000             189 :         DELETE (conf_path);
    2001             189 :         return retval;
    2002                 : }
    2003                 : 
    2004                 : 
    2005                 : /** Function that initializes data for instantiated module
    2006                 :  * @param work_module_item list item with module
    2007                 :  * @param proc_id PID of associated TMC process
    2008                 :  * @return always 0
    2009                 :  */
    2010                 : LOCAL int ec_init_module_data (DLListItem * work_module_item)
    2011             187 : {
    2012                 : 
    2013             187 :         int             result = 0;
    2014                 :         DLList         *cases_list;
    2015                 : 
    2016             187 :         tm_set_status (work_module_item, TEST_MODULE_INITIALIZED);
    2017             187 :         cases_list = dl_list_create ();
    2018             187 :         tm_set_tclist (work_module_item, cases_list);
    2019                 : 
    2020             187 :         return result;
    2021                 : }
    2022                 : 
    2023                 : /** Function that instantializes all modules from available moduls list at
    2024                 : * startup of the application.
    2025                 : * @return: number of started modules
    2026                 : */
    2027                 : int ec_start_modules ()
    2028             120 : {
    2029                 : 
    2030             120 :         int             result = 0;
    2031             120 :         pid_t           module_started = 0;
    2032                 :         test_module_info_s *work_module;
    2033             120 :         DLListIterator  work_list_item = dl_list_head (available_modules);
    2034                 :         DLListIterator  result_list_item;
    2035             120 :         int             opresult = 0;
    2036                 :         
    2037             120 :         MIN_DEBUG ("%d available modules",
    2038                 :                      dl_list_size (available_modules));
    2039                 : 
    2040             120 :         work_module = (test_module_info_s *) dl_list_data (work_list_item);
    2041             284 :         while (work_list_item != DLListNULLIterator) {
    2042              44 :                 module_started = ec_start_tmc (work_list_item);
    2043                 : 
    2044              44 :                 if (module_started > 0) {
    2045              44 :                         result_list_item =
    2046                 :                             tm_add (instantiated_modules, work_module);
    2047              44 :                         opresult = ec_init_module_data (result_list_item);
    2048              44 :                         if (opresult < 0)
    2049               0 :                                 MIN_WARN ("Failed to initialize "
    2050                 :                                            "data for module");
    2051                 :                         /* To be decided if additional handling of that 
    2052                 :                          * fault is needed 
    2053                 :                          */
    2054              44 :                         result++;
    2055                 :                 }
    2056                 : 
    2057              44 :                 work_list_item = dl_list_next (work_list_item);
    2058                 : 
    2059              44 :                 if (work_list_item != DLListNULLIterator) {
    2060              26 :                         work_module = dl_list_data (work_list_item);
    2061                 :                 }
    2062                 :         }
    2063                 : 
    2064             120 :         return result;
    2065                 : }
    2066                 : 
    2067                 : LOCAL int ec_read_module_section (MinParser * inifile)
    2068              42 : {
    2069              42 :         test_module_info_s      *module         = INITPTR;
    2070              42 :         DLListIterator          module_item = DLListNULLIterator;
    2071              42 :         MinSectionParser       *module_def = INITPTR;
    2072                 :         MinItemParser          *line_item; 
    2073              42 :         char           *bin_path = INITPTR, *tc_file_path = NULL;
    2074              42 :         int            it = 1;
    2075                 :         DLList         *work_list;
    2076                 : 
    2077                 : 
    2078              42 :         module_def = mp_section (inifile, "[New_Module]", "[End_Module]", it);
    2079                 : 
    2080             126 :         while (module_def != INITPTR) {
    2081                 : 
    2082                 : 
    2083              42 :                 line_item = mmp_get_item_line(module_def,
    2084                 :                                              "ModuleName",
    2085                 :                                              ESTag);
    2086                 : 
    2087              42 :                 if (line_item == INITPTR){
    2088               0 :                         MIN_WARN ("Data fault!");
    2089               0 :                         break;
    2090                 :                 }
    2091                 : 
    2092              42 :                 mip_get_string(line_item,
    2093                 :                               "ModuleName",
    2094                 :                               &bin_path);
    2095                 : 
    2096                 : 
    2097              42 :                 if (bin_path == INITPTR) {
    2098               0 :                         MIN_WARN ("Could not read module definition");
    2099               0 :                         break;
    2100                 :                 }
    2101                 :                 /* make dummy list of cfgs for now */
    2102                 : 
    2103              42 :                 work_list = dl_list_create ();
    2104              42 :                 module = tm_create (bin_path, work_list, 0);
    2105              42 :                 module_item = tm_add (available_modules, module);
    2106                 :                 /*if (in->new_module) {
    2107                 :                         in->new_module (bin_path, module->module_id_);
    2108                 :                 }*/
    2109              42 :                 MINAPI_PLUGIN_CALL(new_module,
    2110                 :                                    new_module (bin_path, module->module_id_));
    2111                 : 
    2112              42 :                 if (module_item == DLListNULLIterator) {
    2113               0 :                         MIN_WARN ("Could not insert %s into list",
    2114                 :                                    bin_path);
    2115               0 :                         break;
    2116                 :                 }
    2117                 : 
    2118                 :                 /* Now let's read test case files, tag : TestCaseFile= */
    2119                 :                 do {
    2120              56 :                         DELETE (bin_path);
    2121              56 :                         mip_destroy(&line_item);
    2122                 : 
    2123              56 :                         line_item = mmp_get_next_item_line(module_def);
    2124                 : 
    2125              56 :                         mip_get_string(line_item,
    2126                 :                                       "TestCaseFile",
    2127                 :                                       &bin_path);
    2128                 : 
    2129                 : 
    2130                 : 
    2131              56 :                         if (bin_path != INITPTR) {
    2132              14 :                                 tc_file_path = NEW2 (char,
    2133                 :                                                      strlen (bin_path) + 2);
    2134              14 :                                 STRCPY (tc_file_path, bin_path,
    2135                 :                                         strlen (bin_path) + 1);
    2136              14 :                                 dl_list_add (work_list, (void *)tc_file_path);
    2137                 :                         }
    2138                 : 
    2139              56 :                 } while (bin_path != INITPTR);;
    2140                 : 
    2141              42 :                 mmp_destroy (&module_def);
    2142              42 :                 it++;
    2143                 : 
    2144              42 :                 module_def = mp_section (inifile,
    2145                 :                                          "[New_Module]", "[End_Module]", it);
    2146                 : 
    2147                 :         }
    2148              42 :         return 0;
    2149                 : }
    2150                 : 
    2151                 : #ifndef MIN_EXTIF
    2152                 : LOCAL int ec_read_slaves_section (MinParser * inifile)
    2153              25 : {
    2154              25 :         char *hostname = NULL;
    2155              25 :         char *slavetype = NULL;
    2156                 :         MinSectionParser *slave_def;
    2157                 :         MinItemParser    *line; 
    2158              25 :         struct addrinfo hints, *result = NULL;
    2159              25 :         int i = 1, ret;
    2160                 : 
    2161              25 :         slave_def = mp_section (inifile, "[Slaves]", "[End_Slaves]", i);
    2162              65 :         while (slave_def != INITPTR) {
    2163                 :                 
    2164              15 :                 line = mmp_get_item_line (slave_def, "", ESNoTag);
    2165                 : 
    2166              45 :                 while (line != INITPTR) {
    2167              15 :                         ret = mip_get_string (line, "", &hostname);
    2168              15 :                         if (ret != ENOERR) {
    2169               0 :                                 MIN_WARN ("error parsing slaves section:"
    2170                 :                                           "no hostname specified");
    2171               0 :                                 goto next_line;
    2172                 :                         }
    2173                 : 
    2174              15 :                         memset(&hints, 0, sizeof(struct addrinfo));
    2175              15 :                         hints.ai_family = AF_INET;    
    2176              15 :                         hints.ai_socktype = SOCK_STREAM; 
    2177              15 :                         hints.ai_flags = 0;
    2178              15 :                         hints.ai_protocol = 0;          
    2179                 :                         
    2180              15 :                         ret = getaddrinfo(hostname, "51551", &hints, &result);
    2181              15 :                         if (ret != 0) {
    2182               0 :                                 MIN_WARN ("failed to resolve host %s: %s",
    2183                 :                                           strerror (h_errno));
    2184               0 :                                 return 1;
    2185                 :                         }
    2186                 :        
    2187                 :                 
    2188              15 :                         mip_get_next_string (line, &slavetype);
    2189                 : 
    2190              15 :                         tec_add_ip_slave_to_pool (&result, 
    2191                 :                                                   slavetype ? 
    2192                 :                                                   slavetype : "phone");
    2193              15 :                         result = NULL;
    2194              15 :                         DELETE (slavetype);
    2195              15 :                         DELETE (hostname);
    2196              15 :                 next_line:
    2197              15 :                         mip_destroy(&line);
    2198                 :                         
    2199              15 :                         line = mmp_get_next_item_line (slave_def);
    2200                 :                 }
    2201              15 :                 mmp_destroy (&slave_def);
    2202              15 :                 i ++;
    2203              15 :                 slave_def = mp_section (inifile, "[Slaves]", "[End_Slaves]", i);
    2204                 :         }
    2205                 : 
    2206              25 :         return 0;
    2207                 : }
    2208                 : #endif /* ndef MIN_EXTIF */
    2209                 : LOCAL int ec_read_module_confdir ()
    2210              14 : {
    2211                 : 
    2212                 :         DIR            *dir;
    2213                 :         struct dirent  *dirent;
    2214              14 :         MinParser     *modfile = INITPTR;
    2215                 : 
    2216              14 :         dir = opendir ("/etc/min.d");
    2217                 : 
    2218              14 :         if (dir == NULL) {
    2219               0 :                 MIN_WARN ("directory /etc/min.d missing");
    2220               0 :                 return 1;
    2221                 :         }
    2222                 : 
    2223              14 :         dirent = readdir (dir);
    2224              70 :         while (dirent != NULL) {
    2225              42 :                 if (dirent->d_type == DT_LNK || dirent->d_type == DT_REG) {
    2226              14 :                         modfile = mp_create ("/etc/min.d/",
    2227                 :                                              dirent->d_name, ENoComments);
    2228              14 :                         ec_read_module_section (modfile);
    2229                 : #ifndef MIN_EXTIF
    2230               5 :                         ec_read_slaves_section (modfile);
    2231                 : #endif
    2232                 :                 }
    2233              42 :                 dirent = readdir (dir);
    2234                 :         }
    2235                 : 
    2236              14 :         closedir (dir);
    2237                 : 
    2238              14 :         return 0;
    2239                 : }
    2240                 : 
    2241                 : /** Function reads data from config file given as argument
    2242                 :  */
    2243                 : LOCAL int ec_read_conf (MinParser * inifile, int operation_mode)
    2244             238 : {
    2245             238 :         MinSectionParser *engine_def = INITPTR;
    2246             238 :         MinSectionParser *logger_def = INITPTR;
    2247             238 :         MinItemParser    *line_item  = INITPTR;
    2248                 :         struct  stat    tmcstat;   
    2249             238 :         char           *search_path = INITPTR;
    2250             238 :         char           *path_string = NULL;
    2251             238 :         char           *bin_path = INITPTR;
    2252             238 :         char           *locdir = NULL;
    2253             238 :         char           *home_d = getenv ("HOME");
    2254                 :         /*int res = 0;for checking funtion return values */
    2255                 : 
    2256                 :         /*read engine's settings */
    2257             238 :         engine_def = mp_section (inifile,
    2258                 :                                  "[Engine_Defaults]", "[End_Defaults]", 1);
    2259                 : 
    2260             238 :         if (engine_def == INITPTR) {
    2261             119 :                 MIN_FATAL ("For information about mandatory min.conf"
    2262                 :                              " contents refer to manual");
    2263                 :         }
    2264                 : 
    2265                 : 
    2266             238 :         line_item = mmp_get_item_line(engine_def,
    2267                 :                                       "TmcBinPath",
    2268                 :                                       ESTag);
    2269                 : 
    2270             238 :         mip_get_string(line_item,
    2271                 :                        "TmcBinPath",
    2272                 :                        &bin_path);
    2273                 : 
    2274                 : 
    2275             238 :         if (bin_path == INITPTR) {
    2276             238 :                 bin_path = NEW2(char, 
    2277                 :                                 strlen(MIN_BIN_DIR) + strlen("/tmc") + 1 );
    2278             238 :                 sprintf (bin_path, "%s/tmc", MIN_BIN_DIR);
    2279                 :         }
    2280                 :         
    2281                 :         /*
    2282                 :         ** Check if tmc lies in the specified place
    2283                 :         */
    2284             238 :         memset (&tmcstat, 0, sizeof (struct stat));
    2285             238 :         if (stat (bin_path, &tmcstat)) {
    2286               0 :                 MIN_FATAL ("TMC binary not available: %s. Exiting..\n",
    2287                 :                             strerror (errno));
    2288               0 :                 goto err_exit;
    2289                 :         }
    2290             238 :         if (!(tmcstat.st_mode & S_IXUSR &&
    2291                 :               tmcstat.st_mode & S_IXGRP &&
    2292                 :               tmcstat.st_mode & S_IXOTH)) {
    2293               0 :                 MIN_FATAL ("TMC binary %s does not have execution permission."
    2294                 :                             "Exiting..\n", bin_path);
    2295               0 :                 goto err_exit;
    2296                 : 
    2297                 :         }
    2298             238 :         STRCPY (ec_settings.tmc_app_path_, bin_path, MaxFileName);
    2299                 : 
    2300                 : 
    2301             238 :         if (line_item != INITPTR) mip_destroy(&line_item);
    2302                 : 
    2303             238 :         line_item = mmp_get_item_line(engine_def,
    2304                 :                                       "ModSearchPath",
    2305                 :                                       ESTag);
    2306                 : 
    2307             238 :         mip_get_string(line_item,
    2308                 :                        "ModSearchPath",
    2309                 :                        &search_path);
    2310                 : 
    2311             714 :         while (search_path != INITPTR) {
    2312             238 :                 if (strstr (search_path, "$HOME") == NULL) {
    2313             119 :                         path_string = NEW2 (char, strlen (search_path) + 1);
    2314             119 :                         sprintf (path_string, "%s", search_path);
    2315             119 :                         dl_list_add (ec_settings.search_dirs,
    2316                 :                                      (void *)path_string);
    2317                 :                 } else {
    2318             119 :                         if (home_d == NULL) {
    2319               0 :                                 MIN_WARN ("$HOME == NULL, not adding "
    2320                 :                                            "%s to engine settings", 
    2321                 :                                            search_path);
    2322               0 :                                 goto next_item;
    2323                 :                         }
    2324             119 :                         locdir = strchr (search_path, '/');
    2325             119 :                         if (locdir != NULL) {
    2326             119 :                                 path_string =
    2327                 :                                         NEW2 (char,
    2328                 :                                               strlen (locdir) 
    2329                 :                                               + strlen (home_d) +
    2330                 :                                               1);
    2331             119 :                                 sprintf (path_string, "%s%s", home_d, locdir);
    2332             119 :                                 dl_list_add (ec_settings.search_dirs,
    2333                 :                                              (void *)path_string);
    2334                 :                         } else {
    2335               0 :                                 MIN_WARN ("Invalid path");
    2336                 :                         }
    2337                 :                 }
    2338             238 :         next_item:
    2339             238 :                 mip_destroy(&line_item);
    2340             238 :                 line_item = mmp_get_next_item_line(engine_def);
    2341             238 :                 DELETE(search_path);
    2342             238 :                 mip_get_string(line_item,
    2343                 :                                "ModSearchPath",
    2344                 :                                &search_path);
    2345                 :                 
    2346                 :                 
    2347                 :         }
    2348             238 :         if (bin_path != INITPTR) {
    2349             238 :                 DELETE (bin_path);
    2350                 :         }
    2351             238 :         mmp_destroy (&engine_def);
    2352                 :         /* check if logger settings are present and read them */
    2353             238 :         logger_def = mp_section (inifile,
    2354                 :                                  "[Logger_Defaults]",
    2355                 :                                  "[End_Logger_Defaults]", 1);
    2356                 : 
    2357             238 :         if (logger_def != INITPTR) {
    2358             238 :                 ec_get_logger_settings (logger_def);
    2359             238 :                 mmp_destroy (&logger_def);
    2360                 :         }
    2361             238 :         if (operation_mode == 0) {
    2362                 :                 /*we should read module definitions only
    2363                 :                    if we don't use external controller */
    2364              28 :                 ec_read_module_section (inifile);
    2365                 :         }
    2366                 : #ifndef MIN_EXTIF
    2367              20 :         ec_read_slaves_section (inifile);
    2368                 : #endif
    2369             238 :         return 0;
    2370               0 : err_exit:
    2371               0 :         ec_cleanup();
    2372               0 :         exit (-1);
    2373                 :         
    2374                 :         return -1;
    2375                 : }
    2376                 : /** Function reads config files in following order : MIN_CONF_DIR/min.conf, 
    2377                 :  * $HOME/.min/min.conf, ./min.conf. Settings with single value are 
    2378                 :  * overwritten, module and search paths are appended.
    2379                 :  */
    2380                 : int ec_configure ()
    2381             119 : {
    2382             119 :         MinParser     *inifile = INITPTR;
    2383             119 :         char           *home_d = getenv ("HOME");
    2384             119 :         char           *curr_d = getenv ("PWD");
    2385             119 :         char           *def_d = MIN_CONF_DIR;
    2386                 :         char           *min_d;
    2387             119 :         int             op_mode = ec_settings.operation_mode_;
    2388                 : 
    2389             119 :         ec_init_logger_settings ();
    2390                 : 
    2391                 :         /*Initialize logger settings */
    2392                 :         /*Read settings from global .conf */
    2393             119 :         if (curr_d == NULL || strcmp (MIN_CONF_DIR, curr_d) != 0) {
    2394             119 :                 inifile = mp_create (def_d, "min.conf", ENoComments);
    2395                 : 
    2396             119 :                 if (inifile == INITPTR) {
    2397               0 :                         MIN_WARN ("Could not open %s/min.conf %s\n",
    2398                 :                                    MIN_CONF_DIR, strerror (errno));
    2399                 :                 } else {
    2400             119 :                         ec_read_conf (inifile, op_mode);
    2401             119 :                         mp_destroy (&inifile);
    2402                 :                 }
    2403                 :         }
    2404                 :         /*Read $HOME/.min/min.conf */
    2405             119 :         if (home_d != NULL) {
    2406             119 :                 min_d = NEW2 (char, strlen (home_d) + 7);
    2407             119 :                 sprintf (min_d, "%s/.min", home_d);
    2408             119 :                 if (strcmp (min_d, curr_d) != 0) {
    2409             119 :                         inifile = mp_create (min_d, "min.conf", ENoComments);
    2410                 :                         
    2411             119 :                         if (inifile == INITPTR) {
    2412               0 :                                 MIN_WARN ("Could not open "
    2413                 :                                              "%s/min.conf %s\n",
    2414                 :                                              min_d, strerror (errno));
    2415                 :                         } else {
    2416             119 :                                 ec_read_conf (inifile, op_mode);
    2417             119 :                                 mp_destroy (&inifile);
    2418                 :                         }
    2419                 :                 }
    2420             119 :                 DELETE (min_d);
    2421                 :         } else {
    2422               0 :                 MIN_WARN ("$HOME == NULL, not reading "
    2423                 :                            "min.conf from ~/.min");
    2424                 :         }
    2425                 :         /*try to read ./min.conf */
    2426             119 :         if (curr_d != NULL) {
    2427             119 :                 inifile = mp_create (curr_d, "min.conf", ENoComments);
    2428                 :                 
    2429             119 :                 if (inifile == INITPTR) {
    2430             119 :                         MIN_DEBUG ("Could not open %s/min.conf %s\n", 
    2431                 :                                     curr_d,
    2432                 :                                     strerror (errno));
    2433                 :                 } else {
    2434               0 :                         ec_read_conf (inifile, op_mode);
    2435               0 :                         mp_destroy (&inifile);
    2436                 :                 }
    2437                 :         } else {
    2438               0 :                 MIN_WARN ("$PWD == NULL, not reading "
    2439                 :                            "min.conf from .");
    2440                 :         }
    2441                 : 
    2442                 :         /*
    2443                 :          ** Read module definitions from /etc/min.d/
    2444                 :          */
    2445             119 :         if (op_mode == 0)
    2446              14 :                 ec_read_module_confdir ();
    2447             119 :         ec_settings_send ();
    2448                 : 
    2449             118 :         min_log_open ("MIN", 3);
    2450                 : 
    2451             118 :         return 0;
    2452                 : }
    2453                 : 
    2454                 : /** Checks if the user configuration dir exists and creates it if not
    2455                 :  */
    2456                 : LOCAL void create_local_confdir ()
    2457              19 : {
    2458                 :         struct stat dirstat;
    2459                 :         Text *confpath;
    2460              19 :         char *home = getenv ("HOME");
    2461                 :         
    2462              19 :         if (home == NULL)
    2463               0 :                 return;
    2464                 : 
    2465              19 :         confpath = tx_create (home);
    2466              19 :         tx_c_append (confpath, "/.min");
    2467                 : 
    2468              19 :         memset (&dirstat, 0, sizeof (struct stat));
    2469              19 :         if (stat (tx_share_buf(confpath), &dirstat)) {
    2470                 :                 /* directory does not exist, try to create */
    2471               0 :                 if (mkdir (tx_share_buf(confpath), S_IRWXU)) {
    2472               0 :                         MIN_FATAL ("Failed to create %s: %s\n"
    2473                 :                                     "Exiting ...\n",tx_share_buf,
    2474                 :                                     strerror (errno));
    2475               0 :                         goto err_exit;
    2476                 :                 }
    2477                 :         } 
    2478                 :         /*
    2479                 :         ** Check that the directory has write permissions
    2480                 :         */
    2481              19 :         else if (!(dirstat.st_mode & S_IWUSR)) {
    2482               0 :                 MIN_FATAL ("User does not have write permission to %s\n"
    2483                 :                             "Exiting ...\n", tx_share_buf (confpath));
    2484                 :                 
    2485               0 :                 goto err_exit;
    2486                 :                 
    2487                 :         }
    2488                 : 
    2489              19 :         tx_destroy (&confpath);
    2490              19 :         return; 
    2491                 :        
    2492               0 : err_exit:
    2493               0 :         tx_destroy (&confpath);
    2494               0 :         ec_cleanup ();
    2495               0 :         exit (-1);
    2496                 :         return;
    2497                 : }
    2498                 : 
    2499                 : /**Function initializes all engine's global variables, creates message queues 
    2500                 :  * and threads. In case of problems during operations vital to test execution,
    2501                 :  * function exits process  - since if any of those operations fail - MIN will
    2502                 :  * not be able to work anyway
    2503                 :  * @param completecallbk pointer to function called when test case completes
    2504                 :  * @param printcallbk pointer to function called when test case tries to print
    2505                 :  *         output
    2506                 :  * @param extifsendcallbk pointer to function sending external controller 
    2507                 :  *        messages
    2508                 :  * @param envp pointer to enviroment settings var
    2509                 :  * @param operation_mode - describes what is the operation mode of min
    2510                 :  *         instance - 0 means console interface, 
    2511                 :  *                    1 - external controller interface.
    2512                 :  */
    2513                 : void ec_min_init (char *envp_[], int operation_mode)
    2514             124 : {
    2515                 :         int             thread_creation_result;
    2516                 :         pthread_t       listener_thread;
    2517                 : #ifndef MIN_EXTIF
    2518                 :         pthread_t       socket_thread;
    2519                 : #endif
    2520             124 :         long            tmp = 0;
    2521                 :   
    2522             124 :         ec_settings.operation_mode_ = operation_mode;
    2523                 : 
    2524             124 :         envp = envp_;
    2525             124 :         if (operation_mode == 0)
    2526              19 :                 create_local_confdir();
    2527                 : 
    2528                 :         /*
    2529                 :          ** Global data initialization
    2530                 :          */
    2531             124 :         available_modules = dl_list_create ();
    2532             124 :         instantiated_modules = dl_list_create ();
    2533             124 :         selected_cases = dl_list_create ();
    2534                 : 
    2535             124 :         pthread_mutex_lock (&tec_mutex_);
    2536             124 :         rcp_handling_init ();
    2537                 : 
    2538             124 :         ec_settings.engine_pid_ = getpid ();
    2539             124 :         pthread_mutex_unlock (&tec_mutex_);
    2540             124 :         ec_settings.search_dirs = dl_list_create ();
    2541                 : 
    2542                 : 
    2543                 : #ifndef MIN_EXTIF
    2544              15 :         in->send_rcp = socket_send_rcp;
    2545                 : #endif /* MIN_EXTIF */
    2546                 : 
    2547             124 :         MIN_DEBUG ("available_modules %x", available_modules);
    2548                 :         /* results = dl_list_create ( ); */
    2549             124 :         if ((available_modules == INITPTR)
    2550                 :             || (instantiated_modules == INITPTR)
    2551                 :             || (selected_cases == INITPTR) || (results == INITPTR)) {
    2552                 : 
    2553               0 :                 MIN_FATAL ("Not enough memory to create list");
    2554               0 :                 min_log_close ();
    2555               0 :                 exit (-1);
    2556                 : 
    2557                 :         }
    2558                 : 
    2559             124 :         mq_id = mq_open_queue ('a');
    2560                 :         /*
    2561                 :         ** Try to clean up
    2562                 :         */
    2563             124 :         if (mq_id < 0) {
    2564               0 :                 MIN_WARN ("failed to create message queue "
    2565                 :                           " - trying to clean up");
    2566               0 :                 system ("/usr/bin/min-clean.sh");
    2567                 :         }
    2568                 : 
    2569             124 :         mq_id = mq_open_queue ('a');
    2570             124 :         if (mq_id < 0) {
    2571               0 :                 MIN_WARN ("Failed to create message queue: %s",
    2572                 :                            strerror (errno));
    2573               0 :                 min_log_close ();
    2574               0 :                 exit (-1);
    2575                 :         }
    2576             124 :         event_system_init ();
    2577                 : 
    2578                 : 
    2579                 :         /*start modules */
    2580                 :         /* ec_start_modules (); */
    2581                 :         /* Listener thread(s) creation */
    2582             124 :         thread_creation_result =
    2583                 :             pthread_create (&listener_thread, NULL, ec_message_listener,
    2584                 :                             (void *)tmp);
    2585             124 :         if (thread_creation_result != 0) {
    2586               0 :                 MIN_WARN ("Failed to create new thread");
    2587               0 :                 char           *fault_text = "unspecified problem";
    2588               0 :                 switch (thread_creation_result) {
    2589                 :                 case EAGAIN:
    2590               0 :                         fault_text =
    2591                 :                             "Limit of threads in the system exceeded";
    2592               0 :                         break;
    2593                 :                 case EPERM:
    2594               0 :                         fault_text =
    2595                 :                             "Insufficient user rights to create thread";
    2596                 :                         break;
    2597                 :                 }
    2598               0 :                 MIN_FATAL ("%s", fault_text);
    2599               0 :                 min_log_close ();
    2600               0 :                 exit (-1);
    2601                 :         }
    2602                 : #ifndef MIN_EXTIF
    2603              15 :         thread_creation_result =
    2604                 :             pthread_create (&socket_thread, NULL, ec_poll_sockets,
    2605                 :                             (void *)tmp);
    2606              15 :         if (thread_creation_result != 0) {
    2607               0 :                 MIN_WARN ("Failed to create new thread");
    2608               0 :                 char           *fault_text = "unspecified problem";
    2609               0 :                 switch (thread_creation_result) {
    2610                 :                 case EAGAIN:
    2611               0 :                         fault_text =
    2612                 :                             "Limit of threads in the system exceeded";
    2613               0 :                         break;
    2614                 :                 case EPERM:
    2615               0 :                         fault_text =
    2616                 :                             "Insufficient user rights to create thread";
    2617                 :                         break;
    2618                 :                 }
    2619               0 :                 MIN_FATAL ("%s", fault_text);
    2620               0 :                 min_log_close ();
    2621               0 :                 exit (-1);
    2622                 :         }
    2623                 : 
    2624                 : #endif
    2625             124 :         sl_set_sighandler (SIGSEGV, handle_sigsegv);
    2626             124 :         sl_set_sighandler (SIGTERM, handle_sigterm);
    2627             124 :         sl_set_sighandler (SIGBUS, handle_sigbus);
    2628             124 :         sl_set_sighandler (SIGQUIT, handle_sigquit);
    2629             124 :         sl_set_sighandler (SIGINT, handle_sigint);
    2630             124 : }
    2631                 : 
    2632                 : LOCAL void handle_sigsegv (int signum)
    2633               1 : {
    2634               1 :         raise (SIGQUIT);
    2635               1 : }
    2636                 : 
    2637                 : LOCAL void handle_sigquit (int signum)
    2638               1 : {
    2639               1 :         ec_cleanup ();
    2640               1 :         exit (-1);
    2641                 : }
    2642                 : 
    2643                 : LOCAL void handle_sigbus (int signum)
    2644               0 : {
    2645               0 :         raise (SIGQUIT);
    2646               0 : }
    2647                 : 
    2648                 : LOCAL void handle_sigterm (int signum)
    2649               0 : {
    2650               0 :         ec_cleanup ();
    2651               0 :         exit (0);
    2652                 : }
    2653                 : 
    2654                 : LOCAL void handle_sigint (int signum)
    2655               0 : {
    2656               0 :         ec_cleanup ();
    2657               0 :         exit (0);
    2658                 : }
    2659                 : 
    2660                 : /* ======================== FUNCTIONS ====================================== */
    2661                 : /**Function called to execute one selected test case.
    2662                 :  * It adds test case to selected test cases list, sets its status to ongoing
    2663                 :  * and group id to 0, since it does not belong to group. Also, it adds
    2664                 :  * new item to test case's results list.Function Sets module status to busy, 
    2665                 :  * then creates and sends MSG_EXE using data fetched from test case and 
    2666                 :  * module info
    2667                 :  * @param work_case_item pointer to list itemwith case to be executed
    2668                 :  * @return result of operation(TBD)
    2669                 :  */
    2670                 : int ec_exec_test_case (DLListIterator work_case_item)
    2671              10 : {
    2672              10 :         int             result = 0;
    2673              10 :         pthread_mutex_lock (&tec_mutex_);
    2674                 :         /*add to selected cases list */
    2675              10 :         work_case_item = ec_select_case (work_case_item, 0);
    2676                 : 
    2677              10 :         pthread_mutex_unlock (&tec_mutex_);
    2678              10 :         result = ec_exec_case (work_case_item);
    2679                 : 
    2680              10 :         return result;
    2681                 : }
    2682                 : 
    2683                 : 
    2684                 : /** Function called by UI to pause execution of selected test case.
    2685                 :  * @param work_case_item pointer to dl_list_item containig selected test case.
    2686                 :  * @return result of operation :0 if message was sent successfully, -1 in case
    2687                 :  *        of data or message queue error, -2 if case is already paused,
    2688                 :  *        -3 if case is not running
    2689                 : */
    2690                 : int ec_pause_test_case (DLListIterator work_case_item)
    2691               6 : {
    2692                 :         DLListIterator  work_module_item;
    2693               6 :         int             result = 0;
    2694               6 :         int             case_status = tc_get_status (work_case_item);
    2695               6 :         long            addr = 0;
    2696                 : 
    2697               6 :         switch (case_status) {
    2698                 :         case TEST_CASE_ONGOING:
    2699               6 :                 work_module_item = tc_get_test_module_ptr (work_case_item);
    2700               6 :                 addr = tm_get_pid (work_module_item);
    2701               6 :                 result = mq_send_message2 (mq_id, addr, MSG_PAUSE, 0, "\0");
    2702               6 :                 if (result == 0)
    2703               6 :                         tc_set_status (work_case_item, TEST_CASE_PAUSED);
    2704                 :                 /*if (in->case_paused) in->case_paused 
    2705                 :                                              (tc_get_run_id (work_case_item));*/
    2706               6 :                 MINAPI_PLUGIN_CALL (case_paused,case_paused 
    2707                 :                                     (tc_get_run_id (work_case_item)));
    2708               6 :                 break;
    2709                 :         case TEST_CASE_PAUSED:
    2710               0 :                 result = -2;
    2711               0 :                 break;
    2712                 :         default:
    2713               0 :                 result = -3;
    2714                 :         }
    2715                 : 
    2716               6 :         return result;
    2717                 : }
    2718                 : 
    2719                 : 
    2720                 : /** Function called by UI to resume execution of previously paused case:
    2721                 :  * @param work_case_item pointer to dl_list_item containing selected test case
    2722                 :  * @return : result of operation: 0 if message was sent successfully, 
    2723                 :  *                               -1 in case of data or message queue error,
    2724                 :  *                               -2 if case was not paused, 
    2725                 :  *                               -3 if case is not running (not started or
    2726                 :  *                                  already finished).
    2727                 :  */
    2728                 : int ec_resume_test_case (DLListIterator work_case_item)
    2729               2 : {
    2730                 :         DLListIterator  work_module_item;
    2731               2 :         int             result = 0;
    2732               2 :         int             case_status = tc_get_status (work_case_item);
    2733               2 :         long            addr = 0;
    2734                 : 
    2735               2 :         switch (case_status) {
    2736                 :         case TEST_CASE_PAUSED:
    2737               2 :                 work_module_item = tc_get_test_module_ptr (work_case_item);
    2738               2 :                 addr = tm_get_pid (work_module_item);
    2739               2 :                 result = mq_send_message2 (mq_id, addr, MSG_RESUME, 0, "\0");
    2740               2 :                 if (result == 0) {
    2741               2 :                         tc_set_status (work_case_item, TEST_CASE_ONGOING);
    2742                 :                 }
    2743               2 :                 MINAPI_PLUGIN_CALL(case_resumed,
    2744                 :                                    case_resumed (tc_get_run_id 
    2745                 :                                                  (work_case_item)));
    2746               2 :                 break;
    2747                 :         case TEST_CASE_ONGOING:
    2748               0 :                 result = -2;
    2749               0 :                 break;
    2750                 :         default:
    2751               0 :                 result = -3;
    2752                 :                 break;
    2753                 :         }
    2754                 : 
    2755               2 :         return result;
    2756                 : }
    2757                 : 
    2758                 : 
    2759                 : /**Function called byu UI to stop test case execution.
    2760                 : * @param work_case_item pointer to dl_list_item containing selected test case
    2761                 : * @return result of operation: 0 if message was sent successfully, -1 in case
    2762                 : * of data or message queue error, -2 if case has already finished execution.
    2763                 : */
    2764                 : int ec_abort_test_case (DLListIterator work_case_item)
    2765               3 : {
    2766                 :         DLListIterator  work_module_item;
    2767               3 :         int             result = 0;
    2768               3 :         int             case_status = tc_get_status (work_case_item);
    2769               3 :         long            addr = 0;
    2770                 : 
    2771               3 :         switch (case_status) {
    2772                 :         case TEST_CASE_PAUSED:
    2773                 :         case TEST_CASE_ONGOING:
    2774               3 :                 work_module_item = tc_get_test_module_ptr (work_case_item);
    2775               3 :                 addr = tm_get_pid (work_module_item);
    2776               3 :                 result = mq_send_message2 (mq_id, addr, MSG_STOP, 0, "\0");
    2777               3 :                 break;
    2778                 :         case TEST_CASE_TERMINATED:
    2779               0 :                 result = -2;
    2780               0 :                 break;
    2781                 :         default:
    2782               0 :                 result = -1;
    2783                 :         }
    2784                 : 
    2785               3 :         return result;
    2786                 : }
    2787                 : /* ------------------------------------------------------------------------- */
    2788                 : /** Function for freeing the "session" 
    2789                 :  */
    2790                 : 
    2791                 : void ec_reinit()
    2792              51 : {
    2793                 :         long            address;
    2794                 :         DLListIterator  work_module_item;
    2795                 :         DLListIterator  work_module_item2;
    2796                 :         DLListIterator  work_case_item;
    2797                 :         DLListIterator  work_case_item2;
    2798                 :         DLListIterator  filter_item;
    2799              51 :         test_case_s    *work_case = INITPTR;
    2800                 :         DLList         *work_list;
    2801                 :         title_filter   *filter;
    2802                 : 
    2803              51 :         work_module_item = dl_list_head (instantiated_modules);
    2804                 :         /*shutdown all running tmcs and free list*/
    2805             178 :         while (work_module_item != DLListNULLIterator) {
    2806              76 :                 address = tm_get_pid (work_module_item);
    2807              76 :                 mq_send_message2 (mq_id, address, MSG_END, 0, "Shut down !");
    2808              76 :                 waitpid (address, NULL, 0);
    2809                 :                 /*we suppose that sending this message to TMC will ensure
    2810                 :                    that it shuts down properly */
    2811              76 :                 work_module_item2 = dl_list_next (work_module_item);
    2812              76 :                 tm_remove (work_module_item);
    2813              76 :                 work_module_item = work_module_item2;
    2814                 :         }
    2815                 : 
    2816              51 :         work_module_item = dl_list_head (instantiated_modules);
    2817             102 :         while (work_module_item != DLListNULLIterator) {
    2818               0 :                 work_module_item2 = dl_list_next (work_module_item);
    2819               0 :                 work_list = tm_get_tclist (work_module_item);
    2820               0 :                 work_case_item = dl_list_head (work_list);
    2821               0 :                 while (work_case_item != DLListNULLIterator) {
    2822               0 :                         work_case_item2 = dl_list_next (work_case_item);
    2823               0 :                         tc_delete ((test_case_s *)
    2824                 :                                    dl_list_data (work_case_item));
    2825               0 :                         tc_remove (work_case_item);
    2826               0 :                         work_case_item = work_case_item2;
    2827                 :                 }
    2828               0 :                 tm_delete ((test_module_info_s *)
    2829                 :                            dl_list_data (work_module_item));
    2830               0 :                 tm_remove (work_module_item);
    2831               0 :                 work_module_item = work_module_item2;
    2832                 :         }
    2833                 :         
    2834              51 :         work_case_item = dl_list_head (selected_cases);
    2835             183 :         while (work_case_item != DLListNULLIterator) {
    2836              81 :                 work_case = (test_case_s *) dl_list_data (work_case_item);
    2837              81 :                 tc_remove (work_case_item);
    2838              81 :                 tc_delete (work_case);
    2839              81 :                 work_case_item = dl_list_head (selected_cases);
    2840                 :         }
    2841                 : 
    2842              51 :         filter_item = dl_list_head (filters);
    2843             105 :         while (filter_item != DLListNULLIterator) {
    2844               3 :                 filter = (title_filter *) dl_list_data (filter_item);
    2845               3 :                 tx_destroy (&filter->filter_);
    2846               3 :                 DELETE (filter);
    2847               3 :                 dl_list_remove_it (filter_item);
    2848               3 :                 filter_item = dl_list_head (filters);
    2849                 :         }
    2850                 :         
    2851              51 : }
    2852                 : /* ------------------------------------------------------------------------- */
    2853                 : /** Function that takes care of removal of all created objects, freeing
    2854                 :  * memory and so on.
    2855                 :  */
    2856                 : void ec_cleanup ()
    2857              19 : {
    2858              19 :         event_system_cleanup ();
    2859              19 :         rcp_handling_cleanup ();
    2860              19 :         ec_reinit();
    2861                 : 
    2862              19 :         dl_list_free (&instantiated_modules);
    2863              19 :         dl_list_free (&available_modules);
    2864              19 :         dl_list_free (&selected_cases);
    2865              19 :         dl_list_free (&filters);
    2866              19 :         dl_list_free_data (&ec_settings.search_dirs);
    2867              19 :         dl_list_free (&ec_settings.search_dirs);
    2868                 : 
    2869                 :         /* This sleep period allows for handling of all sent messages before
    2870                 :          * destroying message queue 
    2871                 :          */
    2872                 : 
    2873              19 :         usleep (50000);
    2874              19 :         sm_destroy (ec_settings.sh_mem_id_);
    2875              19 :         mq_close_queue (mq_id);
    2876              19 :         min_log_close();
    2877              19 :         usleep (30000);
    2878              19 : }
    2879                 : 
    2880                 : /**Function called by user (external controller or console IF) to execute 
    2881                 :  * sequence of test cases
    2882                 :  * @param work_cases_list list of test cases to be executed - user has to build
    2883                 :  * list of test cases by himself.
    2884                 :  */
    2885                 : int ec_run_cases_seq (DLList * work_cases_list)
    2886               1 : {
    2887               1 :         DLListIterator  work_case_item = dl_list_head (work_cases_list);
    2888               1 :         DLListIterator  exec_case = DLListNULLIterator;
    2889               1 :         int             group_id = random ();   /* generate unique group id */
    2890                 : 
    2891               1 :         if (work_case_item == DLListNULLIterator) {
    2892               0 :                 MIN_WARN ("Invalid list of test cases passed !");
    2893               0 :                 return -1;
    2894                 :         }
    2895               1 :         pthread_mutex_lock (&tec_mutex_);
    2896                 : 
    2897                 :         /*we mark first case of the group to be executed */
    2898               1 :         exec_case = ec_select_case (work_case_item, group_id);
    2899               1 :         work_case_item = dl_list_next (work_case_item);
    2900                 :         /*now we will iterate through the remaining cases in received list */
    2901               3 :         while (work_case_item != DLListNULLIterator) {
    2902               1 :                 ec_select_case (work_case_item, group_id);
    2903               1 :                 work_case_item = dl_list_next (work_case_item);
    2904                 :         }
    2905               1 :         pthread_mutex_unlock (&tec_mutex_);
    2906                 : 
    2907                 :         /*now we need to clear passed list, so we don't leave any garbage
    2908                 :            behind. The list itself cannot be destroyed,because it is
    2909                 :            console's global variable. This can change, though. */
    2910               1 :         work_case_item = dl_list_head (work_cases_list);
    2911               4 :         while (work_case_item != DLListNULLIterator) {
    2912               2 :                 dl_list_remove_it (work_case_item);
    2913               2 :                 work_case_item = dl_list_head (work_cases_list);
    2914                 :         }
    2915                 :         /*all done, now start execution of group with first case */
    2916               1 :         ec_exec_case (exec_case);
    2917               1 :         return 0;
    2918                 : }
    2919                 : 
    2920                 : 
    2921                 : 
    2922                 : 
    2923                 : int ec_run_cases_par (DLList * work_cases_list)
    2924               1 : {
    2925               1 :         DLListIterator  work_case_item = dl_list_head (work_cases_list);
    2926               1 :         DLListIterator  exec_case = DLListNULLIterator;
    2927                 : 
    2928               1 :         if (work_case_item == DLListNULLIterator) {
    2929               0 :                 MIN_WARN ("Invalid list of test cases passed !!");
    2930               0 :                 return -1;
    2931                 :         }
    2932               1 :         pthread_mutex_lock (&tec_mutex_);
    2933                 : 
    2934                 :         /*"select" all cases in received list */
    2935               4 :         while (work_case_item != DLListNULLIterator) {
    2936               2 :                 exec_case = ec_select_case (work_case_item, 0);
    2937               2 :                 ec_exec_case (exec_case);
    2938               2 :                 work_case_item = dl_list_next (work_case_item);
    2939                 :         }
    2940               1 :         pthread_mutex_unlock (&tec_mutex_);
    2941                 : 
    2942                 :         /*now we need to clear passed list, so that we don't leave any garbage
    2943                 :            behind. The list itself cannot be destroyed,because it is
    2944                 :            console's global variable. This can change, though. */
    2945               1 :         work_case_item = dl_list_head (work_cases_list);
    2946               4 :         while (work_case_item != DLListNULLIterator) {
    2947               2 :                 dl_list_remove_it (work_case_item);
    2948               2 :                 work_case_item = dl_list_head (work_cases_list);
    2949                 :         }
    2950                 : 
    2951               1 :         return 0;
    2952                 : }
    2953                 : 
    2954                 : /**Function used to add test module to MIN framework at any time.
    2955                 :  * @param mod_name name of module to be added
    2956                 :  * @param testcase_files list containing names of testcasefiles associated
    2957                 :  * with module.
    2958                 :  * @param id test module identifier
    2959                 :  * @return result of operation: WARNING: function fails if there is problem 
    2960                 :  * with initializing data for module entity, possibly some memory problem, or
    2961                 :  * if any of specified files does not exist. Information, if module was 
    2962                 :  * started successfully, (returned test cases) is not available. Indication of
    2963                 :  * problems of
    2964                 :  * that kind would  be failure to start case from that module later.
    2965                 :  */
    2966                 : int ec_add_module (TSChar * mod_name, DLList * testcase_files, 
    2967                 :                    test_module_id_t  id, int report)
    2968             206 : {
    2969             206 :         DLListIterator  work_module_item = DLListNULLIterator;
    2970             206 :         test_module_info_s *work_module = INITPTR;
    2971             206 :         pid_t           result = 0;
    2972             206 :         int             retval = -1;
    2973                 : 
    2974             206 :         work_module = tm_create (mod_name, testcase_files, id);
    2975             206 :         if (work_module == INITPTR)
    2976               0 :                 goto FAULT;
    2977             206 :         work_module_item = tm_add (available_modules, work_module);
    2978             206 :         result = ec_start_tmc (work_module_item);
    2979             143 :         ec_init_module_data (work_module_item);
    2980             143 :         if (result > 0) {
    2981             142 :                 pthread_mutex_lock (&tec_mutex_);
    2982             142 :                 tm_add (instantiated_modules, work_module);
    2983             142 :                 pthread_mutex_unlock (&tec_mutex_);
    2984             142 :                 retval = 0;
    2985             142 :                 if (report) {
    2986               5 :                         MINAPI_PLUGIN_CALL(new_module,
    2987                 :                                            new_module (mod_name, 
    2988                 :                                                        work_module->module_id_)
    2989                 :                                 );
    2990                 : 
    2991                 :                 }
    2992                 :         } else {
    2993               1 :                 retval = -1;
    2994                 :         }
    2995                 : 
    2996             143 :       FAULT:
    2997             143 :         return retval;
    2998                 : }
    2999                 : 
    3000                 : 
    3001                 : /**Function searches defined library search paths for library with given name
    3002                 :  * @param name of file to be found
    3003                 :  * @return position of correct path on search paths list, or -1 if file is
    3004                 :  *         not found.
    3005                 :  */
    3006                 : int ec_search_lib (char *mod_name)
    3007             301 : {
    3008             301 :         char           *full_path = NULL;
    3009             301 :         DLListIterator  work_path_item = DLListNULLIterator;
    3010             301 :         int             result = 666;
    3011             301 :         int             pos = 0;
    3012             301 :         char           *work_path = NULL;
    3013             301 :         int             retval = -1;
    3014                 : 
    3015             438 :         for (pos = 0; pos < dl_list_size (ec_settings.search_dirs); pos++) {
    3016             437 :                 work_path_item = dl_list_at (ec_settings.search_dirs, pos);
    3017             437 :                 work_path = (char *)dl_list_data (work_path_item);
    3018             437 :                 full_path =
    3019                 :                     NEW2 (char, strlen (work_path) + strlen (mod_name) + 2);
    3020             437 :                 sprintf (full_path, "%s/%s", work_path, mod_name);
    3021             437 :                 result = access (full_path, F_OK);
    3022             437 :                 DELETE (full_path);
    3023             437 :                 if (result == 0) {
    3024             300 :                         retval = pos;
    3025             300 :                         break;
    3026                 :                 }
    3027                 :         }
    3028                 : 
    3029             301 :         return retval;
    3030                 : }
    3031                 : /* ------------------------------------------------------------------------- */
    3032                 : void
    3033                 : ec_add_title_filter (char *filter_str, int regexp)
    3034               4 : {
    3035                 :         title_filter *filter;
    3036               4 :         filter = NEW (title_filter);
    3037                 : 
    3038               4 :         filter->filter_ = tx_create (filter_str);
    3039               4 :         filter->regexp_ = regexp;
    3040                 : 
    3041               4 :         if (filters == INITPTR) filters = dl_list_create();
    3042                 : 
    3043               4 :         dl_list_add (filters, filter);
    3044                 : 
    3045                 :         return;
    3046                 : }
    3047                 : /* ------------------------------------------------------------------------- */
    3048                 : int ec_read_settings (char *engine_ini)
    3049               0 : {
    3050               0 :         MinParser     *passed_config = INITPTR;
    3051               0 :         char           *out = NULL;
    3052               0 :         char           *fname = NULL;
    3053               0 :         char           *dir = NULL;
    3054               0 :         int             cont_flag = 0;
    3055               0 :         int             status = 0;
    3056               0 :         int             result = 0;
    3057               0 :         int             i = 0;
    3058               0 :         DLListIterator  work_module_item = DLListNULLIterator;
    3059               0 :         char           *temp = engine_ini;
    3060                 : 
    3061                 :         do {
    3062               0 :                 out = &temp[1];
    3063               0 :                 temp = strchr (out, '/');
    3064               0 :         } while (temp != NULL);
    3065                 : 
    3066               0 :         fname = out;
    3067               0 :         dir = NEW2 (char, strlen (engine_ini) - strlen (fname));
    3068               0 :         strncpy (dir, engine_ini, strlen (engine_ini) - strlen (fname) - 1);
    3069               0 :         dir[strlen (engine_ini) - strlen (fname) - 1] = '\0';
    3070               0 :         printf (" read : %s | %s \n", dir, fname);
    3071               0 :         passed_config = mp_create (dir, fname, ENoComments);
    3072               0 :         ec_read_conf (passed_config, 0);
    3073                 :         /*in case settings shared memory segment exists already, destroy it */
    3074               0 :         sm_destroy (ec_settings.sh_mem_id_);
    3075                 :         /*now send new settings */
    3076               0 :         ec_settings_send ();
    3077                 : 
    3078               0 :         ec_start_modules ();
    3079               0 :         while (cont_flag == 0) {
    3080               0 :                 usleep (500000);
    3081               0 :                 i++;
    3082               0 :                 work_module_item = dl_list_head (instantiated_modules);
    3083               0 :                 cont_flag = 1;
    3084               0 :                 while (work_module_item != DLListNULLIterator) {
    3085               0 :                         status = tm_get_status (work_module_item);
    3086               0 :                         if (status == TEST_MODULE_READY)
    3087               0 :                                 cont_flag = cont_flag | 1;
    3088                 :                         else
    3089               0 :                                 cont_flag = 0;
    3090               0 :                         work_module_item = dl_list_next (work_module_item);
    3091                 :                 }
    3092               0 :                 if (i > 20) {
    3093               0 :                         result = -1;
    3094               0 :                         break;
    3095                 :                 };
    3096                 :         }
    3097                 : 
    3098               0 :         return result;
    3099                 : }
    3100                 : 
    3101                 : 
    3102                 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
    3103                 : /* None */
    3104                 : 
    3105                 : 
    3106                 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
    3107                 : #ifdef MIN_UNIT_TEST
    3108                 : #include "tec.tests"
    3109                 : #endif                          /* MIN_UNIT_TEST */
    3110                 : 
    3111                 : /* End of file */

Generated by: LTP GCOV extension version 1.6