1 : /*
2 : * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
3 : * and/or its subsidiary(-ies).
4 : * Contact: Sampo Saaristo
5 : * Contact e-mail: DG.MIN-Support@nokia.com
6 : *
7 : * This program is free software: you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the Free
9 : * Software Foundation, version 2 of the License.
10 : *
11 : * This program is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 : * more details. You should have received a copy of the GNU General Public
15 : * License along with this program. If not, see
16 : * <http://www.gnu.org/licenses/>.
17 : */
18 :
19 :
20 : /**
21 : * @file min_engine_api.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 <dllist.h>
31 : #include <tec.h>
32 : #include <tec_rcp_handling.h>
33 : #include <min_logger.h>
34 : #include <data_api.h>
35 : #include <min_engine_api.h>
36 :
37 : #include <dirent.h>
38 : #include <netdb.h>
39 : #include <sys/socket.h>
40 : #include <assert.h>
41 : /* ----------------------------------------------------------------------------
42 : * GLOBAL VARIABLES
43 : */
44 : DLList *modules;
45 : //eapiIn_t *in;
46 :
47 : DLList *plugins = INITPTR;
48 : DLListIterator it = DLListNULLIterator;
49 : static int open;
50 : /* ----------------------------------------------------------------------------
51 : * EXTERNAL DATA STRUCTURES
52 : */
53 : extern pthread_mutex_t tec_mutex_;
54 :
55 :
56 : /* ---------------------------------------------------------------------------
57 : * EXTERNAL FUNCTION PROTOTYPES
58 : */
59 : /* None */
60 :
61 : /* ----------------------------------------------------------------------------
62 : * CONSTANTS
63 : */
64 : /* None */
65 :
66 : /* ----------------------------------------------------------------------------
67 : * MACROS
68 : */
69 : /* None */
70 :
71 :
72 : /* ----------------------------------------------------------------------------
73 : * LOCAL CONSTANTS AND MACROS
74 : */
75 : /* None */
76 :
77 : /* ----------------------------------------------------------------------------
78 : * MODULE DATA STRUCTURES
79 : */
80 : /* None */
81 :
82 : /* ----------------------------------------------------------------------------
83 : * LOCAL FUNCTION PROTOTYPES
84 : */
85 : /** Searches for test case by runid from the given list
86 : * @param list_handle pointer to linked list of test case data
87 : * @param runid search key
88 : * @return pointer to test case data item,
89 : * or returns INITPTR if operation failed.
90 : *
91 : */
92 : LOCAL DLListIterator tc_find_by_runid (DLList * list_handle, long runid);
93 :
94 : /* -------------------------------------------------------------------------
95 : * FORWARD DECLARATIONS
96 : */
97 : /* None */
98 :
99 : /* ==================== LOCAL FUNCTIONS ==================================== */
100 :
101 :
102 : /* ------------------------------------------------------------------------- */
103 :
104 : LOCAL int eapi_add_test_module (char *modulepath)
105 195 : {
106 195 : test_module_info_s *modinfo = INITPTR;
107 195 : int ret = 1;
108 :
109 195 : modinfo = tm_create (modulepath, INITPTR, 0);
110 195 : if (tm_add (modules, modinfo) != INITPTR) {
111 195 : MIN_DEBUG ("Number of plugins %d",
112 : dl_list_size (get_plugin_list()));
113 195 : MINAPI_PLUGIN_CALL(new_module,new_module (modulepath,
114 : modinfo->module_id_));
115 195 : ret = 0;
116 : } else {
117 0 : MIN_WARN ("failed to add module");
118 0 : MINAPI_PLUGIN_CALL(no_module,no_module(modulepath));
119 : }
120 :
121 195 : return ret;
122 : }
123 :
124 : /* ------------------------------------------------------------------------- */
125 :
126 : LOCAL int eapi_add_test_case_file (unsigned module_id, char *testcasefile)
127 242 : {
128 : DLListIterator it;
129 : test_module_info_s *modinfo;
130 : char *p;
131 :
132 242 : it = tm_find_by_module_id (modules, module_id);
133 :
134 242 : if (it == INITPTR) {
135 0 : MIN_WARN ("No module with id %u found", module_id);
136 0 : return 1;
137 : }
138 242 : modinfo = dl_list_data (it);
139 242 : if (*testcasefile != '\0') {
140 42 : p = NEW2 (char, strlen (testcasefile) + 1);
141 42 : STRCPY (p, testcasefile, strlen (testcasefile) + 1);
142 42 : if (modinfo->cfg_filename_list_ == INITPTR)
143 42 : modinfo->cfg_filename_list_ = dl_list_create();
144 42 : dl_list_add (modinfo->cfg_filename_list_, p);
145 : } else {
146 : /* we have all the test case files for the module,
147 : so we can add the module into engine */
148 200 : if(ec_add_module (modinfo->module_filename_,
149 : modinfo->cfg_filename_list_,
150 : modinfo->module_id_,
151 : 0))
152 1 : return 1;
153 : }
154 178 : return 0;
155 : }
156 :
157 : /* ------------------------------------------------------------------------- */
158 :
159 : LOCAL int eapi_start_test_case (unsigned module_id, unsigned case_id,
160 : unsigned groupid)
161 91 : {
162 91 : int result = 0, run = 1, stat;
163 : DLListIterator mod_it, case_it, case_it2;
164 : test_module_info_s *module;
165 :
166 91 : pthread_mutex_lock (&tec_mutex_);
167 :
168 91 : mod_it = tm_find_by_module_id (instantiated_modules, module_id);
169 91 : if (mod_it == INITPTR) {
170 0 : MIN_WARN ("No module by id %d found", module_id);
171 0 : return 1;
172 : }
173 91 : module = (test_module_info_s *)dl_list_data (mod_it);
174 91 : case_it = tc_find_by_id (module->test_case_list_, case_id);
175 91 : if (case_it == INITPTR) {
176 0 : MIN_WARN ("No case by id %d found", case_id);
177 0 : return 1;
178 : }
179 :
180 : /* if we have a groupid, check if there already is an ongoing case
181 : * with the id */
182 91 : if (groupid != 0) {
183 66 : for (case_it2 = dl_list_head (selected_cases);
184 132 : case_it2 != INITPTR;
185 0 : case_it2 = dl_list_next (case_it2)) {
186 58 : if (tc_get_group_id (case_it2) == groupid) {
187 58 : stat = tc_get_status (case_it2);
188 58 : if (stat == TEST_CASE_ONGOING ||
189 : stat == TEST_CASE_PAUSED) {
190 58 : run = 0;
191 58 : break;
192 : }
193 :
194 : }
195 : }
196 : }
197 91 : pthread_mutex_unlock (&tec_mutex_);
198 91 : case_it = ec_select_case (case_it, groupid);
199 :
200 91 : if (run)
201 33 : result = ec_exec_case (case_it);
202 :
203 86 : return result;
204 : }
205 :
206 : /* ------------------------------------------------------------------------- */
207 :
208 : LOCAL int eapi_pause_case (long test_run_id)
209 4 : {
210 : DLListIterator it;
211 :
212 4 : it = tc_find_by_runid (selected_cases, test_run_id);
213 4 : if (it != INITPTR)
214 4 : return ec_pause_test_case (it);
215 0 : return 1;
216 : }
217 :
218 : /* ------------------------------------------------------------------------- */
219 :
220 : LOCAL int eapi_resume_case (long test_run_id)
221 1 : {
222 : DLListIterator it;
223 :
224 1 : it = tc_find_by_runid (selected_cases, test_run_id);
225 1 : if (it != INITPTR)
226 1 : return ec_resume_test_case (it);
227 0 : return 1;
228 : }
229 :
230 : /* ------------------------------------------------------------------------- */
231 :
232 : LOCAL int eapi_abort_case (long test_run_id)
233 2 : {
234 : DLListIterator it;
235 :
236 2 : it = tc_find_by_runid (selected_cases, test_run_id);
237 2 : if (it != INITPTR)
238 2 : return ec_abort_test_case (it);
239 0 : return 1;
240 : }
241 :
242 : /* ------------------------------------------------------------------------- */
243 :
244 : LOCAL int eapi_error (const char *what, const char *msg)
245 0 : {
246 0 : MIN_FATAL ("%s - %s",what,msg);
247 0 : return 0;
248 : }
249 :
250 : /* ------------------------------------------------------------------------- */
251 :
252 : LOCAL int eapi_open ()
253 108 : {
254 108 : MIN_DEBUG ("Opening");
255 : //assert (open == 0);
256 108 : open = 1;
257 108 : ec_configure ();
258 108 : return ec_start_modules();
259 : }
260 :
261 :
262 : /* ------------------------------------------------------------------------- */
263 :
264 : LOCAL int eapi_close (char *what, char *msg)
265 32 : {
266 32 : MIN_DEBUG ("Closing");
267 32 : ec_reinit();
268 32 : MIN_DEBUG ("Closed");
269 32 : open = 0;
270 32 : return 0;
271 : }
272 :
273 : /* ------------------------------------------------------------------------- */
274 :
275 : LOCAL DLListIterator tc_find_by_runid (DLList * list_handle, long runid)
276 7 : {
277 : test_case_s *tc;
278 : DLListIterator it;
279 :
280 :
281 14 : for (it = dl_list_head (list_handle); it != INITPTR;
282 0 : it = dl_list_next(it)) {
283 7 : tc = (test_case_s *)dl_list_data (it);
284 7 : if (tc->tc_run_id_ == runid)
285 7 : return it;
286 : }
287 :
288 :
289 0 : return INITPTR;
290 :
291 : }
292 :
293 : /* ------------------------------------------------------------------------- */
294 :
295 : LOCAL int eapi_query_test_modules(char **modulelist)
296 0 : {
297 0 : char *modules = INITPTR;
298 0 : char *tmpmodules = INITPTR;
299 :
300 0 : int i = 0;
301 0 : int currlength = 0;
302 0 : int tmplen = 0;
303 0 : DLListIterator dl_item = DLListNULLIterator;
304 : char *dir;
305 : char *ptr;
306 : char *test_module;
307 0 : int n = 0;
308 : struct dirent **namelist;
309 :
310 0 : dl_item = dl_list_head (ec_settings.search_dirs);
311 0 : while (dl_item != INITPTR) {
312 : /* get data from list iterator */
313 0 : dir = (char *)dl_list_data (dl_item);
314 :
315 : /* return the number of directory entries */
316 0 : n = scandir (dir, &namelist, 0, alphasort);
317 :
318 : /* add .so files to test sets list */
319 0 : while (n--) {
320 0 : ptr = strrchr (namelist[n]->d_name, '.');
321 0 : if ((ptr != NULL) && (strcmp (ptr, ".so") == 0)) {
322 :
323 0 : tmplen = strlen (namelist[n]->d_name);
324 0 : if (modules==INITPTR) {
325 0 : modules = NEW2(char,tmplen+2);
326 0 : memset(modules,'\0',tmplen+2);
327 0 : test_module = &modules[currlength];
328 : } else {
329 0 : tmpmodules = modules;
330 0 : modules = NEW2(char,tmplen+currlength+2);
331 0 : memset(modules,'\0',tmplen+currlength+2);
332 0 : memcpy(modules,tmpmodules,currlength);
333 0 : free(tmpmodules);
334 0 : test_module = &modules[currlength];
335 : }
336 :
337 0 : strncpy (test_module,namelist[n]->d_name,tmplen);
338 0 : currlength = currlength + tmplen + 1;
339 :
340 0 : i++;
341 : }
342 0 : free (namelist[n]);
343 : }
344 0 : free (namelist);
345 :
346 : /* get next item */
347 0 : dl_item = dl_list_next (dl_item);
348 : }
349 :
350 0 : *modulelist = modules;
351 0 : return 0;
352 : }
353 :
354 : /* ------------------------------------------------------------------------- */
355 :
356 : LOCAL int eapi_query_test_files(char **filelist)
357 0 : {
358 0 : char *files = INITPTR;
359 0 : char *tmpfiles = INITPTR;
360 0 : char *case_file = INITPTR, *p;
361 0 : TSBool addcasefile = ESTrue;
362 0 : char *dir = INITPTR;
363 : struct dirent **namelist;
364 0 : FILE *shell_pipe = INITPTR;
365 0 : char *shell_io = INITPTR;
366 0 : int tmplen = 0;
367 0 : int currlength = 0;
368 :
369 0 : DLListItem *dl_item = INITPTR;
370 0 : int i = 0;
371 0 : int n = 0;
372 :
373 0 : dl_item = dl_list_head (ec_settings.search_dirs);
374 0 : while (dl_item != INITPTR) {
375 : /* get data from list iterator */
376 0 : dir = (char *)dl_list_data (dl_item);
377 :
378 : /* return the number of directory entries */
379 0 : n = scandir (dir, &namelist, 0, alphasort);
380 :
381 : /* add files to test sets list */
382 0 : while (n--) {
383 : /* only normal files, not dots (. and ..)
384 : * and basic filter for non-case-files */
385 0 : if ((strcmp (namelist[n]->d_name, ".") != 0) &&
386 : (strcmp (namelist[n]->d_name, "..") != 0) &&
387 : (strncmp (namelist[n]->d_name +
388 : strlen(namelist[n]->d_name) - 3
389 : , ".la", 3) != 0) &&
390 : (strncmp (namelist[n]->d_name +
391 : strlen(namelist[n]->d_name) - 1
392 : , "~", 1) !=0 ))
393 : {
394 :
395 0 : addcasefile=ESTrue; /* restore flag value */
396 :
397 0 : shell_io = malloc (sizeof(char) *
398 : (strlen ( "which file 2>/dev/null" ) +1) );
399 0 : strcpy(shell_io, "which file 2>/dev/null");
400 0 : if ((shell_pipe=popen(shell_io, "r")) != NULL ) {
401 0 : free(shell_io);
402 0 : shell_io = malloc (sizeof(char) * 1);
403 0 : *shell_io = (char)fgetc(shell_pipe);
404 0 : pclose(shell_pipe);
405 0 : if (strncmp (shell_io, "/", 1) == 0) {
406 0 : free(shell_io);
407 0 : shell_io = malloc (sizeof(char) *
408 : (strlen (namelist[n]->d_name) +
409 : strlen (dir) +
410 : strlen ("file -i -b ") +
411 : 2 +
412 : strlen (" 2>/dev/null")));
413 0 : strcpy (shell_io, "file -i -b ");
414 0 : strcat (shell_io, dir );
415 0 : strcat (shell_io, "/" );
416 0 : strcat (shell_io, namelist[n]->d_name );
417 0 : strcat (shell_io, " 2>/dev/null" );
418 0 : if ((shell_pipe = popen (shell_io , "r"))
419 : != NULL) {
420 0 : free (shell_io);
421 0 : shell_io = malloc (sizeof(char) * 5);
422 0 : p = fgets (shell_io, 5, shell_pipe);
423 0 : *(shell_io+4)=0x00;
424 0 : if (strcmp(shell_io, "text" ) != 0) {
425 : /* don't add file if not text*/
426 0 : addcasefile=ESFalse;
427 : }
428 0 : pclose (shell_pipe);
429 : }
430 : }
431 : }
432 :
433 : /* add file to the list if it's not marked to omit
434 : * by previous checks */
435 0 : if(addcasefile==ESTrue){
436 0 : tmplen = strlen (namelist[n]->d_name);
437 0 : if (files==INITPTR) {
438 0 : files = NEW2(char,tmplen+2);
439 0 : memset(files,'\0',tmplen+2);
440 0 : case_file = &files[currlength];
441 : } else {
442 0 : tmpfiles = files;
443 0 : files = NEW2(char,tmplen+currlength+2);
444 0 : memset(files,'\0',tmplen+currlength+2);
445 0 : memcpy(files,tmpfiles,currlength);
446 0 : free(tmpfiles);
447 0 : case_file = &files[currlength];
448 : }
449 :
450 0 : strncpy (case_file,namelist[n]->d_name,tmplen);
451 0 : currlength = currlength + tmplen + 1;
452 :
453 0 : i++;
454 : }
455 :
456 0 : free (shell_io);
457 : }
458 0 : free (namelist[n]);
459 : }
460 0 : free (namelist);
461 :
462 : /* get next item */
463 0 : dl_item = dl_list_next (dl_item);
464 : }
465 :
466 0 : *filelist = files;
467 0 : return 0;
468 : }
469 :
470 : /* ------------------------------------------------------------------------- */
471 :
472 : LOCAL int eapi_receive_rcp (char *message, int length)
473 7 : {
474 7 : return tec_extif_message_received (message, length);
475 : }
476 :
477 : /* ------------------------------------------------------------------------- */
478 :
479 : LOCAL int eapi_register_slave (char *host, char *slavetype)
480 1 : {
481 : int ret;
482 : struct addrinfo hints, *result;
483 :
484 :
485 :
486 1 : memset(&hints, 0, sizeof(struct addrinfo));
487 1 : hints.ai_family = AF_INET;
488 1 : hints.ai_socktype = SOCK_STREAM;
489 1 : hints.ai_flags = 0;
490 1 : hints.ai_protocol = 0; /* Any protocol */
491 :
492 1 : ret = getaddrinfo(host, "51551", &hints, &result);
493 1 : if (ret != 0) {
494 0 : MIN_WARN ("failed to resolve host %s: %s",
495 : strerror (h_errno));
496 0 : return 1;
497 : }
498 :
499 :
500 1 : return tec_add_ip_slave_to_pool (&result,
501 : slavetype ? slavetype : "phone");
502 : }
503 :
504 : /* ------------------------------------------------------------------------- */
505 :
506 :
507 : /* ======================== FUNCTIONS ====================================== */
508 :
509 : void eapi_init (eapiIn_t *inp, eapiOut_t *out)
510 129 : {
511 129 : if (plugins == INITPTR) plugins = dl_list_create();
512 129 : dl_list_add (plugins, (void*)inp);
513 :
514 129 : modules = dl_list_create();
515 129 : out->add_test_module = eapi_add_test_module;
516 129 : out->add_test_case_file = eapi_add_test_case_file;
517 129 : out->start_case = eapi_start_test_case;
518 129 : out->pause_case = eapi_pause_case;
519 129 : out->resume_case = eapi_resume_case;
520 129 : out->abort_case = eapi_abort_case;
521 129 : out->fatal_error = eapi_error;
522 :
523 129 : out->min_close = eapi_close;
524 129 : out->min_open = eapi_open;
525 129 : out->query_test_modules = eapi_query_test_modules;
526 129 : out->query_test_files = eapi_query_test_files;
527 :
528 129 : out->register_slave = eapi_register_slave;
529 129 : out->receive_rcp = eapi_receive_rcp;
530 129 : }
531 :
532 : /* ------------------------------------------------------------------------- */
533 :
534 : DLList* get_plugin_list()
535 1455 : {
536 1455 : return plugins;
537 : }
538 :
539 : DLListIterator* get_it()
540 0 : {
541 0 : return ⁢
542 : }
543 :
544 : /* ------------------------------------------------------------------------- */
545 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
546 : /* None */
547 :
548 :
549 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
550 : #ifdef MIN_UNIT_TEST
551 : //#include "min_engine_api.tests"
552 : #endif /* MIN_UNIT_TEST */
553 :
554 : /* End of file */
|