2
2
* Acutest -- Another C/C++ Unit Test facility
3
3
* <http://github.com/mity/acutest>
4
4
*
5
- * Copyright (c) 2013-2019 Martin Mitas
5
+ * Copyright 2013-2020 Martin Mitas
6
+ * Copyright 2019 Garrett D'Amore
6
7
*
7
8
* Permission is hereby granted, free of charge, to any person obtaining a
8
9
* copy of this software and associated documentation files (the "Software"),
178
179
* the last test case after exiting the loop), you may use TEST_CASE(NULL).
179
180
*/
180
181
#define TEST_CASE_ (...) test_case__(__VA_ARGS__)
181
- #define TEST_CASE (name ) test_case__(" %s" , name);
182
+ #define TEST_CASE (name ) test_case__(" %s" , name)
182
183
183
184
184
185
/* printf-like macro for outputting an extra information about a failure.
277
278
#include < exception>
278
279
#endif
279
280
281
+ /* Load valgrind.h, if available. This allows to detect valgrind's presence via RUNNING_ON_VALGRIND. */
282
+ #ifdef __has_include
283
+ #if __has_include(<valgrind.h>)
284
+ #include < valgrind.h>
285
+ #endif
286
+ #endif
287
+
280
288
281
289
/* Note our global private identifiers end with '__' to mitigate risk of clash
282
290
* with the unit tests implementation. */
@@ -325,6 +333,7 @@ static int test_skip_mode__ = 0;
325
333
static int test_worker__ = 0 ;
326
334
static int test_worker_index__ = 0 ;
327
335
static int test_cond_failed__ = 0 ;
336
+ static int test_was_aborted__ = 0 ;
328
337
static FILE *test_xml_output__ = NULL ;
329
338
330
339
static int test_stat_failed_units__ = 0 ;
@@ -364,8 +373,8 @@ static jmp_buf test_abort_jmp_buf__;
364
373
static double
365
374
test_timer_diff__ (LARGE_INTEGER start, LARGE_INTEGER end)
366
375
{
367
- double duration = end.QuadPart - start.QuadPart ;
368
- duration /= test_timer_freq__.QuadPart ;
376
+ double duration = ( double )( end.QuadPart - start.QuadPart ) ;
377
+ duration /= ( double ) test_timer_freq__.QuadPart ;
369
378
return duration;
370
379
}
371
380
@@ -384,12 +393,7 @@ static jmp_buf test_abort_jmp_buf__;
384
393
test_timer_init__ (void )
385
394
{
386
395
if (test_timer__ == 1 )
387
- #ifdef CLOCK_MONOTONIC_RAW
388
- /* linux specific; not subject of NTP adjustments or adjtime() */
389
- test_timer_id__ = CLOCK_MONOTONIC_RAW;
390
- #else
391
396
test_timer_id__ = CLOCK_MONOTONIC;
392
- #endif
393
397
else if (test_timer__ == 2 )
394
398
test_timer_id__ = CLOCK_PROCESS_CPUTIME_ID;
395
399
}
@@ -403,11 +407,18 @@ static jmp_buf test_abort_jmp_buf__;
403
407
static double
404
408
test_timer_diff__ (struct timespec start, struct timespec end)
405
409
{
406
- return ((double ) end.tv_sec +
407
- (double ) end.tv_nsec * 10e-9 )
408
- -
409
- ((double ) start.tv_sec +
410
- (double ) start.tv_nsec * 10e-9 );
410
+ double endns;
411
+ double startns;
412
+
413
+ endns = end.tv_sec ;
414
+ endns *= 1e9 ;
415
+ endns += end.tv_nsec ;
416
+
417
+ startns = start.tv_sec ;
418
+ startns *= 1e9 ;
419
+ startns += start.tv_nsec ;
420
+
421
+ return ((endns - startns)/ 1e9 );
411
422
}
412
423
413
424
static void
@@ -614,21 +625,19 @@ test_check__(int cond, const char* file, int line, const char* fmt, ...)
614
625
615
626
test_line_indent__ (test_case_name__[0 ] ? 2 : 1 );
616
627
if (file != NULL ) {
617
- if (test_verbose_level__ < 3 ) {
618
628
#ifdef ACUTEST_WIN__
619
- const char * lastsep1 = strrchr (file, ' \\ ' );
620
- const char * lastsep2 = strrchr (file, ' /' );
621
- if (lastsep1 == NULL )
622
- lastsep1 = file-1 ;
623
- if (lastsep2 == NULL )
624
- lastsep2 = file-1 ;
625
- file = (lastsep1 > lastsep2 ? lastsep1 : lastsep2) + 1 ;
629
+ const char * lastsep1 = strrchr (file, ' \\ ' );
630
+ const char * lastsep2 = strrchr (file, ' /' );
631
+ if (lastsep1 == NULL )
632
+ lastsep1 = file-1 ;
633
+ if (lastsep2 == NULL )
634
+ lastsep2 = file-1 ;
635
+ file = (lastsep1 > lastsep2 ? lastsep1 : lastsep2) + 1 ;
626
636
#else
627
- const char * lastsep = strrchr (file, ' /' );
628
- if (lastsep != NULL )
629
- file = lastsep+1 ;
637
+ const char * lastsep = strrchr (file, ' /' );
638
+ if (lastsep != NULL )
639
+ file = lastsep+1 ;
630
640
#endif
631
- }
632
641
printf (" %s:%d: Check " , file, line);
633
642
}
634
643
@@ -881,16 +890,6 @@ test_error__(const char* fmt, ...)
881
890
if (test_verbose_level__ == 0 )
882
891
return ;
883
892
884
- if (test_verbose_level__ <= 2 && !test_current_already_logged__ && test_current_unit__ != NULL ) {
885
- if (test_tap__) {
886
- test_finish_test_line__ (-1 );
887
- } else {
888
- printf (" [ " );
889
- test_print_in_color__ (TEST_COLOR_RED_INTENSIVE__, " FAILED" );
890
- printf (" ]\n " );
891
- }
892
- }
893
-
894
893
if (test_verbose_level__ >= 2 ) {
895
894
test_line_indent__ (1 );
896
895
if (test_verbose_level__ >= 3 )
@@ -910,6 +909,7 @@ test_error__(const char* fmt, ...)
910
909
static int
911
910
test_do_run__ (const struct test__ * test, int index)
912
911
{
912
+ test_was_aborted__ = 0 ;
913
913
test_current_unit__ = test;
914
914
test_current_index__ = index ;
915
915
test_current_failures__ = 0 ;
@@ -928,8 +928,10 @@ test_do_run__(const struct test__* test, int index)
928
928
929
929
if (!test_worker__) {
930
930
test_abort_has_jmp_buf__ = 1 ;
931
- if (setjmp (test_abort_jmp_buf__) != 0 )
931
+ if (setjmp (test_abort_jmp_buf__) != 0 ) {
932
+ test_was_aborted__ = 1 ;
932
933
goto aborted;
934
+ }
933
935
}
934
936
935
937
test_timer_get_time__ (&test_timer_start__);
@@ -952,10 +954,14 @@ test_do_run__(const struct test__* test, int index)
952
954
}
953
955
} else {
954
956
test_print_in_color__ (TEST_COLOR_RED_INTENSIVE__, " FAILED: " );
955
- printf (" %d condition%s %s failed.\n " ,
956
- test_current_failures__,
957
- (test_current_failures__ == 1 ) ? " " : " s" ,
958
- (test_current_failures__ == 1 ) ? " has" : " have" );
957
+ if (!test_was_aborted__) {
958
+ printf (" %d condition%s %s failed.\n " ,
959
+ test_current_failures__,
960
+ (test_current_failures__ == 1 ) ? " " : " s" ,
961
+ (test_current_failures__ == 1 ) ? " has" : " have" );
962
+ } else {
963
+ printf (" Aborted.\n " );
964
+ }
959
965
}
960
966
printf (" \n " );
961
967
} else if (test_verbose_level__ >= 1 && test_current_failures__ == 0 ) {
@@ -972,9 +978,23 @@ test_do_run__(const struct test__* test, int index)
972
978
test_check__ (0 , NULL , 0 , " Threw std::exception" );
973
979
if (what != NULL )
974
980
test_message__ (" std::exception::what(): %s" , what);
981
+
982
+ if (test_verbose_level__ >= 3 ) {
983
+ test_line_indent__ (1 );
984
+ test_print_in_color__ (TEST_COLOR_RED_INTENSIVE__, " FAILED: " );
985
+ printf (" C++ exception.\n\n " );
986
+ }
987
+
975
988
return -1 ;
976
989
} catch (...) {
977
990
test_check__ (0 , NULL , 0 , " Threw an exception" );
991
+
992
+ if (test_verbose_level__ >= 3 ) {
993
+ test_line_indent__ (1 );
994
+ test_print_in_color__ (TEST_COLOR_RED_INTENSIVE__, " FAILED: " );
995
+ printf (" C++ exception.\n\n " );
996
+ }
997
+
978
998
return -1 ;
979
999
}
980
1000
#endif
@@ -1036,9 +1056,9 @@ test_run__(const struct test__* test, int index, int master_index)
1036
1056
case SIGTERM: signame = " SIGTERM" ; break ;
1037
1057
default : sprintf (tmp, " signal %d" , WTERMSIG (exit_code)); signame = tmp; break ;
1038
1058
}
1039
- test_error__ (" Test interrupted by %s" , signame);
1059
+ test_error__ (" Test interrupted by %s. " , signame);
1040
1060
} else {
1041
- test_error__ (" Test ended in an unexpected way [%d]" , exit_code);
1061
+ test_error__ (" Test ended in an unexpected way [%d]. " , exit_code);
1042
1062
}
1043
1063
}
1044
1064
@@ -1053,7 +1073,7 @@ test_run__(const struct test__* test, int index, int master_index)
1053
1073
* through a command line arguments. */
1054
1074
_snprintf (buffer, sizeof (buffer)-1 ,
1055
1075
" %s --worker=%d %s --no-exec --no-summary %s --verbose=%d --color=%s -- \" %s\" " ,
1056
- test_argv0__, index , test_timer__ ? " --timer " : " " ,
1076
+ test_argv0__, index , test_timer__ ? " --time " : " " ,
1057
1077
test_tap__ ? " --tap" : " " , test_verbose_level__,
1058
1078
test_colorize__ ? " always" : " never" ,
1059
1079
test->name );
@@ -1065,6 +1085,13 @@ test_run__(const struct test__* test, int index, int master_index)
1065
1085
CloseHandle (processInfo.hThread );
1066
1086
CloseHandle (processInfo.hProcess );
1067
1087
failed = (exitCode != 0 );
1088
+ if (exitCode > 1 ) {
1089
+ switch (exitCode) {
1090
+ case 3 : test_error__ (" Aborted." ); break ;
1091
+ case 0xC0000005 : test_error__ (" Access violation." ); break ;
1092
+ default : test_error__ (" Test ended in an unexpected way [%lu]." , exitCode); break ;
1093
+ }
1094
+ }
1068
1095
} else {
1069
1096
test_error__ (" Cannot create unit test subprocess [%ld]." , GetLastError ());
1070
1097
failed = 1 ;
@@ -1281,14 +1308,14 @@ test_help__(void)
1281
1308
printf (" -s, --skip Execute all unit tests but the listed ones\n " );
1282
1309
printf (" --exec[=WHEN] If supported, execute unit tests as child processes\n " );
1283
1310
printf (" (WHEN is one of 'auto', 'always', 'never')\n " );
1311
+ printf (" -E, --no-exec Same as --exec=never\n " );
1284
1312
#if defined ACUTEST_WIN__
1285
- printf (" -t, --timer Measure test duration\n " );
1313
+ printf (" -t, --time Measure test duration\n " );
1286
1314
#elif defined ACUTEST_HAS_POSIX_TIMER__
1287
- printf (" -t, --timer Measure test duration (real time)\n " );
1288
- printf (" --timer =TIMER Measure test duration, using given timer\n " );
1315
+ printf (" -t, --time Measure test duration (real time)\n " );
1316
+ printf (" --time =TIMER Measure test duration, using given timer\n " );
1289
1317
printf (" (TIMER is one of 'real', 'cpu')\n " );
1290
1318
#endif
1291
- printf (" -E, --no-exec Same as --exec=never\n " );
1292
1319
printf (" --no-summary Suppress printing of test results summary\n " );
1293
1320
printf (" --tap Produce TAP-compliant output\n " );
1294
1321
printf (" (See https://testanything.org/)\n " );
@@ -1300,6 +1327,7 @@ test_help__(void)
1300
1327
printf (" 1 ... Output one line per test (and summary)\n " );
1301
1328
printf (" 2 ... As 1 and failed conditions (this is default)\n " );
1302
1329
printf (" 3 ... As 1 and all conditions (and extended summary)\n " );
1330
+ printf (" -q, --quiet Same as --verbose=0\n " );
1303
1331
printf (" --color[=WHEN] Enable colorized output\n " );
1304
1332
printf (" (WHEN is one of 'auto', 'always', 'never')\n " );
1305
1333
printf (" --no-color Same as --color=never\n " );
@@ -1316,14 +1344,17 @@ static const TEST_CMDLINE_OPTION__ test_cmdline_options__[] = {
1316
1344
{ 0 , " exec" , ' e' , TEST_CMDLINE_OPTFLAG_OPTIONALARG__ },
1317
1345
{ ' E' , " no-exec" , ' E' , 0 },
1318
1346
#if defined ACUTEST_WIN__
1319
- { ' t' , " timer" , ' t' , 0 },
1347
+ { ' t' , " time" , ' t' , 0 },
1348
+ { 0 , " timer" , ' t' , 0 }, /* kept for compatibility */
1320
1349
#elif defined ACUTEST_HAS_POSIX_TIMER__
1321
- { ' t' , " timer" , ' t' , TEST_CMDLINE_OPTFLAG_OPTIONALARG__ },
1350
+ { ' t' , " time" , ' t' , TEST_CMDLINE_OPTFLAG_OPTIONALARG__ },
1351
+ { 0 , " timer" , ' t' , TEST_CMDLINE_OPTFLAG_OPTIONALARG__ }, /* kept for compatibility */
1322
1352
#endif
1323
1353
{ 0 , " no-summary" , ' S' , 0 },
1324
1354
{ 0 , " tap" , ' T' , 0 },
1325
1355
{ ' l' , " list" , ' l' , 0 },
1326
1356
{ ' v' , " verbose" , ' v' , TEST_CMDLINE_OPTFLAG_OPTIONALARG__ },
1357
+ { ' q' , " quiet" , ' q' , 0 },
1327
1358
{ 0 , " color" , ' c' , TEST_CMDLINE_OPTFLAG_OPTIONALARG__ },
1328
1359
{ 0 , " no-color" , ' C' , 0 },
1329
1360
{ ' h' , " help" , ' h' , 0 },
@@ -1367,7 +1398,7 @@ test_cmdline_callback__(int id, const char* arg)
1367
1398
test_timer__ = 2 ;
1368
1399
#endif
1369
1400
} else {
1370
- fprintf (stderr, " %s: Unrecognized argument '%s' for option --timer .\n " , test_argv0__, arg);
1401
+ fprintf (stderr, " %s: Unrecognized argument '%s' for option --time .\n " , test_argv0__, arg);
1371
1402
fprintf (stderr, " Try '%s --help' for more information.\n " , test_argv0__);
1372
1403
exit (2 );
1373
1404
}
@@ -1390,6 +1421,10 @@ test_cmdline_callback__(int id, const char* arg)
1390
1421
test_verbose_level__ = (arg != NULL ? atoi (arg) : test_verbose_level__+1 );
1391
1422
break ;
1392
1423
1424
+ case ' q' :
1425
+ test_verbose_level__ = 0 ;
1426
+ break ;
1427
+
1393
1428
case ' c' :
1394
1429
if (arg == NULL || strcmp (arg, " always" ) == 0 ) {
1395
1430
test_colorize__ = 1 ;
@@ -1509,8 +1544,6 @@ main(int argc, char** argv)
1509
1544
test_colorize__ = 0 ;
1510
1545
#endif
1511
1546
1512
- test_timer_init__ ();
1513
-
1514
1547
/* Count all test units */
1515
1548
test_list_size__ = 0 ;
1516
1549
for (i = 0 ; test_list__[i].func != NULL ; i++)
@@ -1525,6 +1558,9 @@ main(int argc, char** argv)
1525
1558
/* Parse options */
1526
1559
test_cmdline_read__ (test_cmdline_options__, argc, argv, test_cmdline_callback__);
1527
1560
1561
+ /* Initialize the proper timer. */
1562
+ test_timer_init__ ();
1563
+
1528
1564
#if defined(ACUTEST_WIN__)
1529
1565
SetUnhandledExceptionFilter (test_seh_exception_filter__);
1530
1566
#endif
@@ -1549,6 +1585,11 @@ main(int argc, char** argv)
1549
1585
#ifdef ACUTEST_LINUX__
1550
1586
if (test_is_tracer_present__ ())
1551
1587
test_no_exec__ = 1 ;
1588
+ #endif
1589
+ #ifdef RUNNING_ON_VALGRIND
1590
+ /* RUNNING_ON_VALGRIND is provided by valgrind.h */
1591
+ if (RUNNING_ON_VALGRIND)
1592
+ test_no_exec__ = 1 ;
1552
1593
#endif
1553
1594
}
1554
1595
}
0 commit comments