Lhogho  0.0.028
 All Data Structures Files Functions Variables Typedefs Macros Pages
tester_internal.c
Go to the documentation of this file.
1 //===================================================
2 // Project:TestSystem Author: Peter Armianov
3 //===================================================
4 //
5 // CONFPARSER.C
6 //
7 // This file contains implementation of configuration
8 // parseing module.
9 //
10 // Revision history:
11 // 2007-05-14 - file created
12 // 2007-06-23 - several bug fixes
13 // 2007-07-01 - additional working modes implemented
14 // 2007-07-12 - additional comments in Doxygen style
15 // 2007-08-09 - Fixed bug #1762633
16 // 2007-09-03 - Fixing failed tests count; Additional info for failed tests.
17 // 2007-09-08 - Implementing strict mode option
18 // 2007-09-23 - Support for shell comments in test file
19 // 2007-10-13 - Added -Zm test
20 // 2009-05-30 - Support for shell tests
21 // 2013-06-27 - Adding INTEST flag /P. Boytchev/
22 //===================================================
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/stat.h>
28 
29 #include "error.h"
30 #include "TestMaker.h"
31 #include "internal.h"
32 #include "param_parsers.h"
33 
34 int g_first;
35 
36 //===========================================================
49 //===========================================================
50 RESULT
51 parse_line(FILE * input_file, TCHAR ** parameter_name, TCHAR ** parameter_optipons)
52 {
53  TCHAR buffer[MAX_LINE_LENGTH];
54  TCHAR * str, *start, *end;
55  size_t read_size;
56 
57  m_fgets(input_file, buffer, MAX_LINE_LENGTH, &read_size);
58  if (!read_size)
59  {
60  return SUCCESS_EMPTY;
61  }
62  str = buffer;
63  while (*str && m_isspace(*str))
64  {
65  ++str;
66  }
67  if (!*str)
68  {
69  return SUCCESS_EMPTY;
70  }
71 
72  // Skiping shell comments
73  if (str[0] == '#' && str[1] == '!' && g_first)
74  {
75  g_first = 0;
76  return parse_line(input_file, parameter_name, parameter_optipons);
77  }
78 
79  if (*str != COMMENT_SYMBOL)
80  {
81  LOG_ERROR("parse_line - no comment line");
82  return ERR_GENERIC;
83  }
84 
85  while (*str == COMMENT_SYMBOL || m_isspace(*str))
86  {
87  ++str;
88  }
89 
90  start = str;
91  while (*str && *str != PARAM_SET_SYMBOL)
92  {
93  ++str;
94  }
95  if (*str)
96  {
97  end = str;
98  --str;
99  while(str > start && m_isspace(*str))
100  --str;
101  if (str == start)
102  {
103  LOG_ERROR("parse_line - no param name");
104  return ERR_GENERIC;
105  }
106  if (*str != PARAM_SET_SYMBOL)
107  ++str;
108 
109  *parameter_name = (TCHAR*)malloc((str - start + 1) * sizeof(TCHAR));
110  str[0] = 0;
111  m_strcpy(*parameter_name, start);
112  }
113  else
114  {
115  LOG_ERROR("parse_line - no value specified");
116  return SUCCESS_EMPTY;
117  }
118 
119  str = end+1;
120  while (*str && m_isspace(*str))
121  {
122  ++str;
123  }
124  m_strdup(parameter_optipons, str);
125  return SUCCESS_FULL;
126 }
127 
128 
129 //===========================================================
140 //===========================================================
141 RESULT
142 extract_args(FILE * input_file, test_case_info * test_info)
143 {
144  TCHAR * test_name = NULL;
145  TCHAR * test_options = NULL;
146  RESULT res;
147  int i;
148 
149  g_first = 1;
150 
151  while ((res = parse_line(input_file, &test_name, &test_options)) != SUCCESS_EMPTY)
152  {
153  if (IS_ERROR(res))
154  {
155  LOG_ERROR("Couldn't read parameter from input file");
156  break;
157  }
158  for (i = 0; i < PARSERS_COUNT; ++i)
159  {
160  if (g_parsers[i])
161  {
162  res = g_parsers[i](test_name, test_options, test_info);
163  if (IS_ERROR(res) && res != ERR_INVALID_ARG)
164  {
165  break;
166  }
167  }
168  }
169  free (test_name);
170  free (test_options);
171 
172  res = SUCCESS_FULL;
173  }
174 
175  return IS_ERROR(res) ? res : SUCCESS_FULL;
176 }
177 
178 
179 //===========================================================
189 //===========================================================
190 static RESULT
191 write_one_line_result(const TCHAR * result, FILE * out_file)
192 {
193  if (!result || !out_file)
194  {
195  return ERR_INVALID_ARG;
196  }
197  if (*result != COMMENT_SYMBOL)
198  {
199  return SUCCESS_EMPTY;
200  }
201 
202  ++result; /* skip COMMENT_SYMBOL */
203 
204  if (result)
205  {
206  fwrite(result, m_strlen(result) * sizeof(TCHAR), 1, out_file);
207  }
208  return SUCCESS_FULL;
209 }
210 
211 
212 //===========================================================
222 //===========================================================
223 RESULT extract_expected_results(FILE * input_file, const char * file_name)
224 {
225  TCHAR buffer [MAX_LINE_LENGTH];
226  TCHAR * str;
227  size_t real_read_size;
228  RESULT res = SUCCESS_FULL;
229  char new_file_name [MAX_LINE_LENGTH];
230  FILE * test_file = NULL;
231 
232  strcpy(new_file_name, file_name);
233  strcat(new_file_name, "."EXPECTED_RESULTS_EXT);
234 
235  if (!(test_file = fopen(new_file_name, "wb")))
236  {
237  return ERR_FILE;
238  }
239 
240  do
241  {
242  str = m_fgets(input_file, buffer, MAX_LINE_LENGTH, &real_read_size);
243 
244  while (str && *str && m_isspace(*str))
245  {
246  ++str;
247  }
248  res = write_one_line_result(str, test_file);
249  }while (res == SUCCESS_FULL);
250 
251  fclose(test_file);
252  return IS_ERROR(res) ? res : SUCCESS_FULL;
253 }
254 
255 
256 //===========================================================
266 //===========================================================
267 RESULT execute_test(const char * file_name, test_case_info test_info)
268 {
269  char cmd_buffer[MAX_LINE_LENGTH] = "";
270  int ret;
271 
272 #if defined(__WIN32__) && defined (__GNUC__)
273  // If executed in Cygwin there is problem with system primitive
274  // 'cause system is calling 'cmd' , not 'bash'
275  strcpy(cmd_buffer, "bash -c \"");
276 #endif
277 
280  {
281  /* will compile a source */
283  {
284  strcat(cmd_buffer, g_parameters.compiler_name);
285  }
286  else
287  {
288  strcat(cmd_buffer, LOGO_NAME);
289  }
290  strcat(cmd_buffer, " ");
291  }
292  else
293  {
294  /* will execute precompiled program */
295  char * end = (char *)strrchr(file_name, '.');
296  if (end) *end = '\0';
297  strcpy(cmd_buffer, file_name);
298  if (end) *end = '.';
299  }
300 
301 
303  {
304  strcat(cmd_buffer, MEMORY_CHECK_OPTION);
305  strcat(cmd_buffer, " ");
306  }
307 
309  {
310  strcat(cmd_buffer, g_parameters.global_params);
311  strcat(cmd_buffer, " ");
312  }
313 
314  if (test_info.command_line_param)
315  {
316  strcat(cmd_buffer, test_info.command_line_param);
317  strcat(cmd_buffer, " ");
318  }
319 
322  {
323  strcat(cmd_buffer, file_name);
324  }
325 
326  strcat(cmd_buffer, " 1> ");
327  strcat(cmd_buffer, file_name);
328  strcat(cmd_buffer, "."REAL_RESULTS_EXT);
329  strcat(cmd_buffer, " 2> ");
330  strcat(cmd_buffer, file_name);
331  strcat(cmd_buffer, "."ERROR_RESULTS_EXT);
332 
333 #if defined(__WIN32__) && defined (__GNUC__)
334  strcat(cmd_buffer, "\"");
335 #endif
336 
337  ret = system(cmd_buffer);
338  if (ret == -1)
339  {
340  LOG_ERROR("execution failed");
341  return ERR_GENERIC;
342  }
343  return MAKE_SUCCESS(ret);
344 }
345 
346 
347 //===========================================================
355 //===========================================================
356 RESULT compile_test(const char * file_name, test_case_info test_info)
357 {
358  char cmd_buffer[MAX_LINE_LENGTH];
359  int ret;
360 
362  {
363  strcpy(cmd_buffer, g_parameters.compiler_name);
364  }
365  else
366  {
367  strcpy(cmd_buffer, LOGO_NAME);
368  }
369  strcat(cmd_buffer, " -x ");
370 
372  {
373  strcat(cmd_buffer, g_parameters.global_params);
374  strcat(cmd_buffer, " ");
375  }
376 
377  if (test_info.command_line_param)
378  {
379  strcat(cmd_buffer, test_info.command_line_param);
380  strcat(cmd_buffer, " ");
381  }
382 
383  strcat(cmd_buffer, file_name);
384 
385  if ((ret = system(cmd_buffer)) == -1)
386  {
387  LOG_ERROR("execution failed");
388  return ERR_GENERIC;
389  }
390  return MAKE_SUCCESS(ret);
391 }
392 
393 
394 //===========================================================
402 //===========================================================
403 static RESULT
404 get_file_size(const char * file_name, UINT64 * size_ptr)
405 {
406  struct stat info;
407  if (stat(file_name, &info))
408  {
409  return ERR_FILE;
410  }
411  *size_ptr = info.st_size;
412  return SUCCESS_FULL;
413 }
414 
415 
416 //===========================================================
425 //===========================================================
426 RESULT check_results(const char * file_name, test_case_info test_info, UINT32 exec_result)
427 {
428  BOOL is_success = TRUE;
429  UINT64 size;
430  RESULT res;
431  char par_name[MAX_NAME_LEN];
432  size_t file_name_len;
433 
434  file_name_len = m_strlen(file_name);
435  strcpy(par_name, file_name);
436 
437  if (0 && exec_result) // No exit code tests now!
438  {
440  {
441  fprintf(g_parameters.output_file, "Error executing test :");
442  m_fputs(g_parameters.output_file, test_info.test_name ? test_info.test_name : file_name);
443  fprintf(g_parameters.output_file, "Exit code : %u\n", exec_result);
444  }
445  return MAKE_SUCCESS(exec_result);
446  }
447 
448  strcpy(par_name + file_name_len, "."ERROR_RESULTS_EXT);
449  res = get_file_size(par_name, &size);
450  if (IS_ERROR(res))
451  {
452  LOG_ERROR("get_file_size failed");
453  return res;
454  }
455  if (size)
456  {
458  {
459  fprintf(g_parameters.output_file, "Executing test ");
460  m_fputs(g_parameters.output_file, test_info.test_name ? test_info.test_name : file_name);
461  fprintf(g_parameters.output_file, " caused output to stderr\n");
463  }
464  return MAKE_SUCCESS((UINT32)size);
465  }
466 
467  if (res = file_compare(file_name, test_info))
468  {
469  return res;
470  }
471 
473  {
474  fprintf(g_parameters.output_file, "Executing test ");
475  m_fputs(g_parameters.output_file, test_info.test_name ? test_info.test_name : file_name);
476  fprintf(g_parameters.output_file, " success!\n");
477  }
478 
480  {
481  fprintf(g_parameters.output_file, " %d (",g_parameters.num_passed );
482  const char* c = test_info.test_name ? test_info.test_name : file_name;
483  c = strrchr (c, '/')+1;
485  fprintf(g_parameters.output_file, ") \r");
486  }
487 
488  return SUCCESS_FULL;
489 }
490 
491 
492 //===========================================================
500 //===========================================================
501 RESULT import_results(const char * file_name, test_case_info test_info)
502 {
503  TCHAR line[MAX_LINE_LENGTH];
504  size_t real_size;
505 
506  char exp_name[MAX_NAME_LEN];
507  char temp_name[MAX_NAME_LEN];
508 
509  FILE * expected_file;
510  FILE * source_file;
511  FILE * temp_file;
512 
513 
514  strcpy(exp_name, file_name);
515  strcat(exp_name, "."REAL_RESULTS_EXT);
516  expected_file = fopen(exp_name, "rb");
517  if (!expected_file)
518  {
519  LOG_ERROR("Can't open expected file");
520  return ERR_FILE;
521  }
522 
523  strcpy(temp_name, file_name);
524  strcat(temp_name, "."LTEMP_EXT);
525  temp_file = fopen(temp_name, "wb");
526  if (!temp_file)
527  {
528  LOG_ERROR("Can't open temp file");
529  return ERR_FILE;
530  }
531 
532  source_file = fopen(file_name, "rb");
533  if (!source_file)
534  {
535  LOG_ERROR("Can't open source file");
536  return ERR_FILE;
537  }
538 
539  fprintf(temp_file, "\n");
540 
541  while (m_fgets(expected_file, line, MAX_LINE_LENGTH, &real_size))
542  {
543  if (real_size && real_size < MAX_LINE_LENGTH)
544  {
545  m_fputc(temp_file, COMMENT_SYMBOL);
546  }
547  m_fputs(temp_file, line);
548  }
549 
550  fprintf(temp_file, "\n");
551  fclose(expected_file);
552  unlink(exp_name);
553 
554  while (m_fgets(source_file, line, MAX_LINE_LENGTH, &real_size))
555  {
556  m_fputs(temp_file, line);
557  }
558  fclose(temp_file);
559  fclose(source_file);
560  unlink(file_name);
561  return rename(temp_name, file_name) == 0 ? SUCCESS_FULL : ERR_FILE;
562 }
563 
564 
565 //===========================================================
571 //===========================================================
572 void clean_up(const char * file_name)
573 {
574  char name[MAX_NAME_LEN];
575  size_t file_name_len;
576 
577  file_name_len = m_strlen(file_name);
578  strcpy(name, file_name);
579 
580  strcpy(name + file_name_len, "."EXPECTED_RESULTS_EXT);
581  unlink(name);
582 
583  strcpy(name + file_name_len, "."REAL_RESULTS_EXT);
584  unlink(name);
585 
586  strcpy(name + file_name_len, "."ERROR_RESULTS_EXT);
587  unlink(name);
588 }
589 
590 
591 //===========================================================
598 //===========================================================
599 void print_file(const char * file_name, FILE * output_file)
600 {
601  TCHAR buffer[MAX_LINE_LENGTH];
602  size_t size;
603 
604  FILE * f = fopen(file_name, "rb");
605  if (!f)
606  {
607  LOG_ERROR("Open file to print failed");
608  return;
609  }
610  while(m_fgets(f, buffer, MAX_LINE_LENGTH, &size))
611  {
612  m_fputs(output_file, buffer);
613  }
614  fclose(f);
615 }
616 
617 
618 //===========================================================
627 //===========================================================
628 static RESULT
629 compare_strings_output(const TCHAR * test_line, const TCHAR * expected_line)
630 {
632  {
633  TCHAR * test_end, ch_test;
634  TCHAR * expect_end, ch_exp;
635  int compare_res;
636 
637  while (m_isspace(*expected_line))
638  ++expected_line;
639 
640  while (m_isspace(*test_line))
641  ++test_line;
642 
643  test_end = (TCHAR*)test_line + m_strlen(test_line) - 1;
644  while (test_end > test_line && m_isspace(*test_end))
645  --test_end;
646  ch_test = test_end[1];
647  test_end[1] = 0;
648 
649 
650  expect_end = (TCHAR*)expected_line + m_strlen(expected_line) - 1;
651 
652  while (expect_end > expected_line && m_isspace(*expect_end))
653  --expect_end;
654 
655  ch_exp = expect_end[1];
656  expect_end[1] = 0;
657 
658  compare_res = m_strcmp(test_line, expected_line);
659  test_end[1] = ch_test;
660  expect_end[1] = ch_exp;
661 
662  return compare_res ? ERR_GENERIC : SUCCESS_FULL;
663  }
664  else
665  {
666  return (m_strcmp(test_line, expected_line)==0 ? SUCCESS_FULL : ERR_GENERIC);
667  }
668 }
669 
670 
671 //===========================================================
681 //===========================================================
682 RESULT file_compare(const char * test_file_name, test_case_info test_info)
683 {
684  TCHAR expected[MAX_LINE_LENGTH];
685  TCHAR expected_mem[] = EXPECTED_MEMORY;
686  TCHAR real[MAX_LINE_LENGTH];
687  size_t real_size, exp_size;
688  char name[MAX_NAME_LEN];
689  RESULT res = SUCCESS_FULL;
690  int mem_checked = 0;
691 
692  FILE * expected_file;
693  FILE * real_file;
694 
695  strcpy(name, test_file_name);
696  strcat(name, "."EXPECTED_RESULTS_EXT);
697  expected_file = fopen(name, "rb");
698  if (!expected_file)
699  {
700  LOG_ERROR("Can't open expected file");
701  return ERR_FILE;
702  }
703 
704  strcpy(name, test_file_name);
705  strcat(name, "."REAL_RESULTS_EXT);
706  real_file = fopen(name, "rb");
707  if (!real_file)
708  {
709  LOG_ERROR("Can't open real file");
710  return ERR_FILE;
711  }
712 
713  while (m_fgets(real_file, real, MAX_LINE_LENGTH, &real_size))
714  {
715  if (!m_fgets(expected_file, expected, MAX_LINE_LENGTH, &exp_size))
716  {
717  if (!mem_checked)
718  {
719  mem_checked = 1;
720  if (SUCCESS_FULL == compare_strings_output(real, expected_mem))
721  {
722  continue;
723  }
724  }
725 
727  {
728  fprintf(g_parameters.output_file, "Test %s failed. Extra line in output: \n%s\n",
729  test_info.test_name ? test_info.test_name : test_file_name, real);
730  }
731  else
732  {
733  fprintf(g_parameters.output_file, "Test failed\n");
734  }
735  res = ERR_GENERIC;
736  break;
737  }
738  if (IS_ERROR(compare_strings_output(real, expected)))
739  {
741  {
742  fprintf(g_parameters.output_file, "Test %s failed. Unexpected line in output: \n\"%s\"\n"
743  "\tExpected\n\"%s\"\n",
744  test_info.test_name ? test_info.test_name : test_file_name, real, expected);
745  }
746  else
747  {
748  fprintf(g_parameters.output_file, "Test failed\n");
749  }
750  res = ERR_GENERIC;
751  break;
752  }
753  }
754 
755  if (m_fgets(expected_file, expected, MAX_LINE_LENGTH, &exp_size))
756  {
757  int i = 0;
758  if (expected[i])
759  {
761  {
762  fprintf(g_parameters.output_file, "Test %s failed. Extra line in output: \n%s\n",
763  test_info.test_name ? test_info.test_name : test_file_name, real);
764  }
765  else
766  {
767  fprintf(g_parameters.output_file, "Test failed\n");
768  }
769  res = ERR_GENERIC;
770  }
771  }
772 
773  if (!mem_checked)
774  {
776  {
777  fprintf(g_parameters.output_file, "Test %s failed. No memory check performed!\n",
778  test_info.test_name ? test_info.test_name : test_file_name);
779  }
780  else
781  {
782  fprintf(g_parameters.output_file, "Test failed\n");
783  }
784  res = ERR_GENERIC;
785  }
786 
787  fclose(real_file);
788  fclose(expected_file);
789 
790  return res;
791 }
792 
793 //===========================================================
802 //===========================================================
803 RESULT exec_shell(const char * file_name)
804 {
805  RESULT res = SUCCESS_FILE;
806  FILE * test_file;
807  char sh_name[512];
808  char command[512] = "bash -c ";
809  size_t len;
810  int ret_code;
811  char * dot_pos = strrchr(file_name, '.');
812 
813  // Prepare shell file name
814  if (dot_pos && dot_pos != file_name)
815  {
816  len = dot_pos - file_name;
817  }
818  else
819  {
820  len = strlen(file_name);
821  }
822 
823  strncpy(sh_name, file_name, len);
824  sh_name[len++] = '.';
825  strcpy(sh_name+len, SHELL_FILE_EXTENSION);
826 
827  // Try to open file
828  test_file = fopen(sh_name, "r");
829  if (!test_file)
830  {
831  return SUCCESS_FILE;
832  }
833  fclose(test_file);
834  ret_code = system(strcat(command, sh_name));
836  {
837  fprintf(stderr, "execution:%s-> %d\n", sh_name, ret_code);
838  }
839  if (g_parameters.intest_flag && ret_code)
840  {
841  fprintf(stderr, "execution:%s-> %d\n", sh_name, ret_code);
842  }
843  if (ret_code == -1) // execution failed!
844  {
845  LOG_ERROR("execution failed");
846  return SUCCESS_FILE;
847  }
848  if (ret_code == 0)
849  {
851  return SUCCESS_FULL;
852  }
853 
855  return ERR_GENERIC;
856 }

[ HOME | INDEX | ATOMS | VARS | REFERENCE ]
Lhogho Developer's Documentation
Wed Jul 10 2013