LCOV - code coverage report
Current view: top level - libs/rational/tests/src - test_librational_0004.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 99.4 % 336 334
Test Date: 2026-07-12 01:01:34 Functions: 100.0 % 36 36
Branches: 50.0 % 6 3

             Branch data     Line data    Source code
       1                 :             : #include "test_librational_all.h"
       2                 :             : #include <errno.h>
       3                 :             : 
       4                 :             : static const char expected_report_stderr_pattern[] =
       5                 :             :         "\\A"
       6                 :             :         "ERROR: [^\\n]*src/test_librational_0004\\.c:report_test:\\d+ Memory reallocation failed with bytes 10 Errno: [^\\n]+ \\(errno: [0-9]+\\)\n"
       7                 :             :         "ERROR: [^\\n]*src/test_librational_0004\\.c:report_test:\\d+ Buffer overflow at position 42 with value overflow Errno: [^\\n]+ \\(errno: [0-9]+\\)\\Z";
       8                 :             : 
       9                 :             : /* Regex fragments for slog() output fields that change between source layouts and test runs */
      10                 :             : #define SLOG_TIME_PATTERN "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}:[0-9]{3} "
      11                 :             : #define SLOG_SOURCE_PATTERN "[^\\n]*src/test_librational_0004\\.c:[0-9]+:slog_test:"
      12                 :             : #define SLOG_DECORATED_PATTERN SLOG_TIME_PATTERN SLOG_SOURCE_PATTERN
      13                 :             : 
      14                 :             : static const char expected_slog_stdout_pattern[] =
      15                 :             :         "\\A"
      16                 :             :         "All available combinations:\n"
      17                 :             :         "REGULAR\n"
      18                 :             :         "VERBOSE\n"
      19                 :             :         "TESTING\n"
      20                 :             :         "SILENT\n"
      21                 :             :         "REGULAR\\|VERBOSE\n"
      22                 :             :         "REGULAR\\|TESTING\n"
      23                 :             :         "VERBOSE\\|TESTING\n"
      24                 :             :         "REGULAR\\|VERBOSE\\|TESTING\n"
      25                 :             :         "ERROR\n"
      26                 :             :         "UNDECOR\n"
      27                 :             :         "EVERY\\|UNDECOR\n"
      28                 :             :         "ERROR\\|UNDECOR\n"
      29                 :             :         "VISIBLE_IN_SILENT\n"
      30                 :             :         "Mode: REGULAR\n"
      31                 :             :         "1\\.  Must print:true\n"
      32                 :             :         "2\\. Won't print:\n"
      33                 :             :         "3\\. Won't print:\n"
      34                 :             :         "4\\.  Must print:ERROR: true\n"
      35                 :             :         "Mode: VERBOSE\n"
      36                 :             :         "5\\. Won't print:\n"
      37                 :             :         "6\\.  Must print:" SLOG_DECORATED_PATTERN "true\n"
      38                 :             :         "7\\. Won't print:\n"
      39                 :             :         "8\\.  Must print:" SLOG_DECORATED_PATTERN "ERROR:true\n"
      40                 :             :         "Mode: TESTING\n"
      41                 :             :         "9\\.  Won't print:\n"
      42                 :             :         "10\\. Won't print:\n"
      43                 :             :         "11\\.  Must print:TESTING:true\n"
      44                 :             :         "12\\.  Must print:ERROR:true\n"
      45                 :             :         "Mode: SILENT\n"
      46                 :             :         "13\\. Won't print:\n"
      47                 :             :         "14\\. Won't print:\n"
      48                 :             :         "15\\. Won't print:\n"
      49                 :             :         "16\\. Won't print:\n"
      50                 :             :         "Mode: REGULAR \\| VERBOSE\n"
      51                 :             :         "17\\.  Must print:true\n"
      52                 :             :         "18\\.  Must print:" SLOG_DECORATED_PATTERN "true\n"
      53                 :             :         "19\\. Won't print:\n"
      54                 :             :         "20\\.  Must print:" SLOG_DECORATED_PATTERN "ERROR: true\n"
      55                 :             :         "Mode: REGULAR \\| TESTING\n"
      56                 :             :         "21\\.  Must print:true\n"
      57                 :             :         "22\\. Won't print:\n"
      58                 :             :         "23\\.  Must print:TESTING:true\n"
      59                 :             :         "24\\.  Must print:ERROR: true\n"
      60                 :             :         "Mode: VERBOSE \\| TESTING\n"
      61                 :             :         "25\\. Won't print:\n"
      62                 :             :         "26\\.  Must print:" SLOG_DECORATED_PATTERN "true\n"
      63                 :             :         "27\\.  Must print:TESTING:true\n"
      64                 :             :         "28\\.  Must print:" SLOG_DECORATED_PATTERN "ERROR:true\n"
      65                 :             :         "Mode: REGULAR \\| VERBOSE \\| TESTING\n"
      66                 :             :         "29\\. Must print:true\n"
      67                 :             :         "30\\. Must print:" SLOG_DECORATED_PATTERN "true\n"
      68                 :             :         "31\\. Must print:TESTING:true\n"
      69                 :             :         "32\\. Must print:" SLOG_DECORATED_PATTERN "ERROR: true\n"
      70                 :             :         "Mode: ERROR\n"
      71                 :             :         "33\\. Won't print:\n"
      72                 :             :         "34\\. Won't print:\n"
      73                 :             :         "35\\. Won't print:\n"
      74                 :             :         "36\\.  Must print:ERROR: true\n"
      75                 :             :         "Mode: REGULAR \\| VERBOSE \\| TESTING \\| ERROR\n"
      76                 :             :         "37\\. Must print no prefixes:\\|true\\|\n"
      77                 :             :         "38\\. Must print no ERROR prefix:\\|true\\|\n"
      78                 :             :         "Mode: VERBOSE\n"
      79                 :             :         "39\\. Must print no time/file/line/func:\\|true\\|\n"
      80                 :             :         "Mode: TESTING\n"
      81                 :             :         "40\\. Must print no TESTING prefix:\\|true\\|\n"
      82                 :             :         "Mode: REGULAR\n"
      83                 :             :         "41\\. Must not print \\(VERBOSE not enabled\\):\\|\\|\n"
      84                 :             :         "Mode: SILENT\n"
      85                 :             :         "42\\. Must print in SILENT without prefixes:\\|true\\|\n"
      86                 :             :         "43\\. Must print no ERROR prefix in SILENT:\\|true\\|\\Z";
      87                 :             : 
      88                 :             : static const char expected_serp_stderr_pattern[] =
      89                 :             :         "\\A"
      90                 :             :         "ERROR: Failed to open file \\[File: [^\\n]*src/test_librational_0004\\.c, Function: serp_case\\] Errno: \\(2\\) No such file or directory\\Z";
      91                 :             : 
      92                 :             : #ifndef EVIL_EMPIRE_OS
      93                 :             : static const char expected_write_fallback_stderr_pattern[] =
      94                 :             :         "\\AERROR: Failed to write error message\n\\Z";
      95                 :             : 
      96                 :             : static const char expected_logger_time_failure_stdout_pattern[] =
      97                 :             :         "\\A"
      98                 :             :         " [^\\n]*src/test_librational_0004\\.c:[0-9]+:logger_time_failure_cases:gettimeofday failure\n"
      99                 :             :         " [^\\n]*src/test_librational_0004\\.c:[0-9]+:logger_time_failure_cases:localtime_r failure\n"
     100                 :             :         " [^\\n]*src/test_librational_0004\\.c:[0-9]+:logger_time_failure_cases:snprintf failure\\Z";
     101                 :             : #endif
     102                 :             : 
     103                 :             : /**
     104                 :             :  * @brief Emit two report() messages with controlled errno values
     105                 :             :  */
     106                 :           1 : static void report_test(void)
     107                 :             : {
     108                 :           1 :         errno = ENOMEM;
     109                 :             : 
     110                 :             :         /* report() must include the formatted message and decoded errno */
     111                 :           1 :         report("Memory reallocation failed with bytes %d",10);
     112                 :             : 
     113                 :           1 :         errno = EOVERFLOW;
     114                 :             : 
     115                 :             :         /* The second call verifies that several printf arguments are preserved */
     116                 :           1 :         report("Buffer overflow at position %d with value %s",42,"overflow");
     117                 :           1 : }
     118                 :             : 
     119                 :             : /**
     120                 :             :  * @brief Emit the complete slog() mode matrix used by the strict stdout pattern
     121                 :             :  */
     122                 :           1 : static void slog_test(void)
     123                 :             : {
     124                 :           1 :         printf("All available combinations:\n");
     125                 :           1 :         printf("%s\n",rational_convert(REGULAR));
     126                 :           1 :         printf("%s\n",rational_convert(VERBOSE));
     127                 :           1 :         printf("%s\n",rational_convert(TESTING));
     128                 :           1 :         printf("%s\n",rational_convert(SILENT));
     129                 :           1 :         printf("%s\n",rational_convert(REGULAR|VERBOSE));
     130                 :           1 :         printf("%s\n",rational_convert(REGULAR|TESTING));
     131                 :           1 :         printf("%s\n",rational_convert(VERBOSE|TESTING));
     132                 :           1 :         printf("%s\n",rational_convert(REGULAR|VERBOSE|TESTING));
     133                 :           1 :         printf("%s\n",rational_convert(ERROR));
     134                 :           1 :         printf("%s\n",rational_convert(UNDECOR));
     135                 :           1 :         printf("%s\n",rational_convert(EVERY|UNDECOR));
     136                 :           1 :         printf("%s\n",rational_convert(ERROR|UNDECOR));
     137                 :           1 :         printf("%s\n",rational_convert(VISIBLE_IN_SILENT));
     138                 :             : 
     139                 :             :         /* Test REGULAR mode combinations */
     140                 :           1 :         rational_logger_mode = REGULAR;
     141                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     142                 :           1 :         printf("1.  Must print:"); slog(REGULAR,"true"); printf("\n");
     143                 :           1 :         printf("2. Won't print:"); slog(VERBOSE,"but printed!"); printf("\n");
     144                 :           1 :         printf("3. Won't print:"); slog(TESTING,"but printed!"); printf("\n");
     145                 :           1 :         printf("4.  Must print:");   slog(ERROR,"true"); printf("\n");
     146                 :             : 
     147                 :             :         /* Test VERBOSE mode combinations */
     148                 :           1 :         rational_logger_mode = VERBOSE;
     149                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     150                 :           1 :         printf("5. Won't print:"); slog(REGULAR,"but printed!"); printf("\n");
     151                 :           1 :         printf("6.  Must print:"); slog(VERBOSE,"true"); printf("\n");
     152                 :           1 :         printf("7. Won't print:"); slog(TESTING,"but printed!"); printf("\n");
     153                 :           1 :         printf("8.  Must print:");   slog(ERROR,"true"); printf("\n");
     154                 :             : 
     155                 :             :         /* Test TESTING mode combinations */
     156                 :           1 :         rational_logger_mode = TESTING;
     157                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     158                 :           1 :         printf("9.  Won't print:"); slog(REGULAR,"but printed!"); printf("\n");
     159                 :           1 :         printf("10. Won't print:"); slog(VERBOSE,"but printed!"); printf("\n");
     160                 :           1 :         printf("11.  Must print:"); slog(TESTING,"true"); printf("\n");
     161                 :           1 :         printf("12.  Must print:");   slog(ERROR,"true"); printf("\n");
     162                 :             : 
     163                 :             :         /* Test SILENT mode combinations */
     164                 :           1 :         rational_logger_mode = SILENT;
     165                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     166                 :           1 :         printf("13. Won't print:"); slog(REGULAR,"but printed!"); printf("\n");
     167                 :           1 :         printf("14. Won't print:"); slog(VERBOSE,"but printed!"); printf("\n");
     168                 :           1 :         printf("15. Won't print:"); slog(TESTING,"but printed!"); printf("\n");
     169                 :           1 :         printf("16. Won't print:");   slog(ERROR,"but printed!"); printf("\n");
     170                 :             : 
     171                 :             :         /* Test REGULAR|VERBOSE combinations */
     172                 :           1 :         rational_logger_mode = REGULAR|VERBOSE;
     173                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     174                 :           1 :         printf("17.  Must print:"); slog(REGULAR,"true"); printf("\n");
     175                 :           1 :         printf("18.  Must print:"); slog(VERBOSE,"true"); printf("\n");
     176                 :           1 :         printf("19. Won't print:"); slog(TESTING,"but printed!"); printf("\n");
     177                 :           1 :         printf("20.  Must print:");   slog(ERROR,"true"); printf("\n");
     178                 :             : 
     179                 :             :         /* Test REGULAR|TESTING combinations */
     180                 :           1 :         rational_logger_mode = REGULAR|TESTING;
     181                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     182                 :           1 :         printf("21.  Must print:"); slog(REGULAR,"true"); printf("\n");
     183                 :           1 :         printf("22. Won't print:"); slog(VERBOSE,"but printed!"); printf("\n");
     184                 :           1 :         printf("23.  Must print:"); slog(TESTING,"true"); printf("\n");
     185                 :           1 :         printf("24.  Must print:"); slog(ERROR,"true"); printf("\n");
     186                 :             : 
     187                 :             :         /* Test VERBOSE|TESTING combinations */
     188                 :           1 :         rational_logger_mode = VERBOSE|TESTING;
     189                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     190                 :           1 :         printf("25. Won't print:"); slog(REGULAR,"but printed!"); printf("\n");
     191                 :           1 :         printf("26.  Must print:"); slog(VERBOSE,"true"); printf("\n");
     192                 :           1 :         printf("27.  Must print:"); slog(TESTING,"true"); printf("\n");
     193                 :           1 :         printf("28.  Must print:");   slog(ERROR,"true"); printf("\n");
     194                 :             : 
     195                 :             :         /* Test REGULAR|VERBOSE|TESTING combinations */
     196                 :           1 :         rational_logger_mode = REGULAR|VERBOSE|TESTING;
     197                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     198                 :           1 :         printf("29. Must print:"); slog(REGULAR,"true"); printf("\n");
     199                 :           1 :         printf("30. Must print:"); slog(VERBOSE,"true"); printf("\n");
     200                 :           1 :         printf("31. Must print:"); slog(TESTING,"true"); printf("\n");
     201                 :           1 :         printf("32. Must print:");   slog(ERROR,"true"); printf("\n");
     202                 :             : 
     203                 :             :         /* Test ERROR mode combinations */
     204                 :           1 :         rational_logger_mode = ERROR;
     205                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     206                 :           1 :         printf("33. Won't print:"); slog(REGULAR,"but printed!"); printf("\n");
     207                 :           1 :         printf("34. Won't print:"); slog(VERBOSE,"but printed!"); printf("\n");
     208                 :           1 :         printf("35. Won't print:"); slog(TESTING,"but printed!"); printf("\n");
     209                 :           1 :         printf("36.  Must print:");   slog(ERROR,"true"); printf("\n");
     210                 :             : 
     211                 :             :         /*
     212                 :             :          * Test UNDECOR flag: suppress logger prefixes (TESTING:, time/file/line/func, ERROR:)
     213                 :             :          * The output between the '|' markers should contain only the message payload
     214                 :             :          */
     215                 :           1 :         rational_logger_mode = EVERY|ERROR;
     216                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     217                 :           1 :         printf("37. Must print no prefixes:|"); slog(EVERY|UNDECOR,"true"); printf("|\n");
     218                 :           1 :         printf("38. Must print no ERROR prefix:|"); slog(ERROR|UNDECOR,"true"); printf("|\n");
     219                 :             : 
     220                 :           1 :         rational_logger_mode = VERBOSE;
     221                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     222                 :           1 :         printf("39. Must print no time/file/line/func:|"); slog(VERBOSE|UNDECOR,"true"); printf("|\n");
     223                 :             : 
     224                 :           1 :         rational_logger_mode = TESTING;
     225                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     226                 :           1 :         printf("40. Must print no TESTING prefix:|"); slog(TESTING|UNDECOR,"true"); printf("|\n");
     227                 :             : 
     228                 :           1 :         rational_logger_mode = REGULAR;
     229                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     230                 :           1 :         printf("41. Must not print (VERBOSE not enabled):|"); slog(VERBOSE|UNDECOR,"but printed!"); printf("|\n");
     231                 :             : 
     232                 :           1 :         rational_logger_mode = SILENT;
     233                 :           1 :         printf("Mode: %s\n",rational_reconvert(rational_logger_mode));
     234                 :           1 :         printf("42. Must print in SILENT without prefixes:|"); slog(EVERY|VISIBLE_IN_SILENT,"true"); printf("|\n");
     235                 :           1 :         printf("43. Must print no ERROR prefix in SILENT:|"); slog(ERROR|VISIBLE_IN_SILENT,"true"); printf("|\n");
     236                 :           1 : }
     237                 :             : 
     238                 :             : /**
     239                 :             :  * @brief Emit one serp() message with a controlled missing-file errno
     240                 :             :  */
     241                 :           1 : static void serp_case(void)
     242                 :             : {
     243                 :           1 :         errno = ENOENT;
     244                 :           1 :         serp("Failed to open file");
     245                 :           1 : }
     246                 :             : 
     247                 :             : /**
     248                 :             :  * @brief Do nothing while function_capture() checks pending stdout behavior
     249                 :             :  */
     250                 :           1 : static void no_output_test(void)
     251                 :             : {
     252                 :           1 : }
     253                 :             : 
     254                 :             : #ifndef EVIL_EMPIRE_OS
     255                 :             : /**
     256                 :             :  * @brief Exercise slog() when timestamp construction helpers fail
     257                 :             :  */
     258                 :           1 : static void logger_time_failure_cases(void)
     259                 :             : {
     260                 :           1 :         rational_logger_mode = VERBOSE;
     261                 :             : 
     262                 :             :         /* Missing timestamp data should leave an empty prefix slot but keep the message */
     263                 :           1 :         testmocking_gettimeofday_fail_next(1);
     264                 :           1 :         slog(VERBOSE,"gettimeofday failure");
     265                 :           1 :         printf("\n");
     266                 :           1 :         testmocking_gettimeofday_disable();
     267                 :             : 
     268                 :             :         /* localtime_r() failure follows the same fallback path */
     269                 :           1 :         testmocking_localtime_r_fail_next(1);
     270                 :           1 :         slog(VERBOSE,"localtime_r failure");
     271                 :           1 :         printf("\n");
     272                 :           1 :         testmocking_localtime_r_disable();
     273                 :             : 
     274                 :             :         /* snprintf() failure while formatting the timestamp must not hide the payload */
     275                 :           1 :         testmocking_snprintf_fail_next(1);
     276                 :           1 :         slog(VERBOSE,"snprintf failure");
     277                 :           1 :         testmocking_snprintf_disable();
     278                 :             : 
     279                 :           1 :         rational_logger_mode = REGULAR;
     280                 :           1 : }
     281                 :             : 
     282                 :             : /**
     283                 :             :  * @brief Emit one report() message with a controlled I/O errno
     284                 :             :  */
     285                 :           4 : static void report_single_case(void)
     286                 :             : {
     287                 :           4 :         errno = EIO;
     288                 :           4 :         report("Mocked report output");
     289                 :           4 : }
     290                 :             : 
     291                 :             : /**
     292                 :             :  * @brief Emit one report() message while snprintf is forced to truncate
     293                 :             :  */
     294                 :           1 : static void report_truncated_case(void)
     295                 :             : {
     296                 :           1 :         testmocking_snprintf_truncate_next(1);
     297                 :           1 :         report_single_case();
     298                 :           1 :         testmocking_snprintf_disable();
     299                 :           1 : }
     300                 :             : 
     301                 :             : /**
     302                 :             :  * @brief Capture slog() output when logger line allocation fails
     303                 :             :  *
     304                 :             :  * @return Return describing success or failure
     305                 :             :  */
     306                 :           1 : static Return capture_librational_logger_realloc_failure(void)
     307                 :             : {
     308                 :           1 :         INITTEST;
     309                 :             : 
     310                 :             :         /* The logger should stay silent when it cannot grow the output line */
     311                 :           1 :         testmocking_realloc_fail_next(1);
     312                 :           1 :         rational_logger_mode = REGULAR;
     313                 :           1 :         slog(REGULAR|UNDECOR,"hidden");
     314                 :           1 :         rational_logger_mode = REGULAR;
     315                 :           1 :         testmocking_realloc_disable();
     316                 :             : 
     317                 :           1 :         deliver(status);
     318                 :             : }
     319                 :             : 
     320                 :             : /**
     321                 :             :  * @brief Capture slog() output from timestamp failure scenarios
     322                 :             :  *
     323                 :             :  * @return Return describing success or failure
     324                 :             :  */
     325                 :           1 : static Return capture_librational_logger_time_failures(void)
     326                 :             : {
     327                 :           1 :         INITTEST;
     328                 :             : 
     329                 :             :         /* Cleanup disables every mock in case the captured scenario exits early */
     330                 :           1 :         logger_time_failure_cases();
     331                 :           1 :         rational_logger_mode = REGULAR;
     332                 :           1 :         testmocking_gettimeofday_disable();
     333                 :           1 :         testmocking_localtime_r_disable();
     334                 :           1 :         testmocking_snprintf_disable();
     335                 :           1 :         testmocking_write_disable();
     336                 :             : 
     337                 :           1 :         deliver(status);
     338                 :             : }
     339                 :             : 
     340                 :             : /**
     341                 :             :  * @brief Capture slog() output when vsnprintf fails before line allocation
     342                 :             :  *
     343                 :             :  * @return Return describing success or failure
     344                 :             :  */
     345                 :           1 : static Return capture_librational_logger_vsnprintf_failure(void)
     346                 :             : {
     347                 :           1 :         INITTEST;
     348                 :             : 
     349                 :             :         /* A failed payload size calculation should suppress the incomplete line */
     350                 :           1 :         testmocking_vsnprintf_fail_next(1);
     351                 :           1 :         rational_logger_mode = REGULAR;
     352                 :           1 :         slog(REGULAR|UNDECOR,"hidden");
     353                 :           1 :         rational_logger_mode = REGULAR;
     354                 :           1 :         testmocking_vsnprintf_disable();
     355                 :             : 
     356                 :           1 :         deliver(status);
     357                 :             : }
     358                 :             : #endif
     359                 :             : 
     360                 :             : /**
     361                 :             :  * @brief Capture an ERROR log while no logger mode accepts it
     362                 :             :  *
     363                 :             :  * @return Return describing success or failure
     364                 :             :  */
     365                 :           1 : static Return capture_librational_logger_disabled_error_mode(void)
     366                 :             : {
     367                 :           1 :         INITTEST;
     368                 :             : 
     369                 :             :         /* With no active mode bits, even ERROR must stay silent */
     370                 :           1 :         rational_logger_mode = (LOGMODES)0;
     371                 :           1 :         slog(ERROR,"hidden");
     372                 :           1 :         rational_logger_mode = REGULAR;
     373                 :             : 
     374                 :           1 :         deliver(status);
     375                 :             : }
     376                 :             : 
     377                 :             : #ifndef EVIL_EMPIRE_OS
     378                 :             : /**
     379                 :             :  * @brief Capture REMEMBER calls that have no usable payload
     380                 :             :  *
     381                 :             :  * @return Return describing success or failure
     382                 :             :  */
     383                 :           1 : static Return capture_librational_logger_remember_without_payload(void)
     384                 :             : {
     385                 :           1 :         INITTEST;
     386                 :             : 
     387                 :             :         /* Empty payload produces no remembered or printed line */
     388                 :           1 :         rational_logger_mode = REGULAR;
     389                 :           1 :         slog(REGULAR|UNDECOR|REMEMBER,"");
     390                 :             : 
     391                 :             :         /* Failed formatting also leaves REMEMBER without a payload to deliver */
     392                 :           1 :         testmocking_vsnprintf_fail_next(1);
     393                 :           1 :         slog(REGULAR|UNDECOR|REMEMBER,"hidden");
     394                 :           1 :         testmocking_vsnprintf_disable();
     395                 :             : 
     396                 :           1 :         rational_logger_mode = REGULAR;
     397                 :             : 
     398                 :           1 :         deliver(status);
     399                 :             : }
     400                 :             : #endif
     401                 :             : 
     402                 :             : /**
     403                 :             :  * @brief Capture the basic report() stderr contract
     404                 :             :  *
     405                 :             :  * @return Return describing success or failure
     406                 :             :  */
     407                 :           1 : static Return capture_librational_report_test(void)
     408                 :             : {
     409                 :           1 :         INITTEST;
     410                 :             : 
     411                 :           1 :         report_test();
     412                 :             : 
     413                 :           1 :         deliver(status);
     414                 :             : }
     415                 :             : 
     416                 :             : /**
     417                 :             :  * @brief Capture the full slog() mode matrix
     418                 :             :  *
     419                 :             :  * @return Return describing success or failure
     420                 :             :  */
     421                 :           1 : static Return capture_librational_slog_test(void)
     422                 :             : {
     423                 :           1 :         INITTEST;
     424                 :             : 
     425                 :             :         /* Reset the global logger mode after the matrix leaves it in SILENT */
     426                 :           1 :         slog_test();
     427                 :           1 :         rational_logger_mode = REGULAR;
     428                 :             : 
     429                 :           1 :         deliver(status);
     430                 :             : }
     431                 :             : 
     432                 :             : /**
     433                 :             :  * @brief Capture a log line that contains unsafe terminal bytes
     434                 :             :  */
     435                 :           1 : static void librational_logger_terminal_safety_case(void)
     436                 :             : {
     437                 :             :         /*
     438                 :             :          * The payload mixes terminal-hostile bytes with ordinary UTF-8 text.
     439                 :             :          * It deliberately keeps raw ESC because this first sanitizer pass preserves
     440                 :             :          * existing logger decorations until an explicit decoration whitelist exists
     441                 :             :          */
     442                 :             :         static const char payload[] =
     443                 :             :                 "ascii"
     444                 :             :                 "\001"
     445                 :             :                 "del"
     446                 :             :                 "\177"
     447                 :             :                 "c1"
     448                 :             :                 "\302\220"
     449                 :             :                 "invalid"
     450                 :             :                 "\303("
     451                 :             :                 "overlong"
     452                 :             :                 "\300\257"
     453                 :             :                 "keep"
     454                 :             :                 "\t\r\n"
     455                 :             :                 "esc"
     456                 :             :                 "\033[1m"
     457                 :             :                 "utf8"
     458                 :             :                 "°"
     459                 :             :                 "à"
     460                 :             :                 "Привет"
     461                 :             :                 "天地玄黄宇宙洪荒日月盈昃辰宿列張"
     462                 :             :                 "いろはにほへとちりぬるを"
     463                 :             :                 "日本語漢字仮名交じり文";
     464                 :             : 
     465                 :           1 :         rational_logger_mode = REGULAR;
     466                 :           1 :         slog(REGULAR|UNDECOR,"%s",payload);
     467                 :           1 :         rational_logger_mode = REGULAR;
     468                 :           1 : }
     469                 :             : 
     470                 :             : /**
     471                 :             :  * @brief Capture one serp() stderr message
     472                 :             :  *
     473                 :             :  * @return Return describing success or failure
     474                 :             :  */
     475                 :           1 : static Return capture_librational_serp_case(void)
     476                 :             : {
     477                 :           1 :         INITTEST;
     478                 :             : 
     479                 :           1 :         serp_case();
     480                 :             : 
     481                 :           1 :         deliver(status);
     482                 :             : }
     483                 :             : 
     484                 :             : #ifndef EVIL_EMPIRE_OS
     485                 :             : /**
     486                 :             :  * @brief Capture report() when formatting the final message fails
     487                 :             :  *
     488                 :             :  * @return Return describing success or failure
     489                 :             :  */
     490                 :           1 : static Return capture_librational_report_snprintf_failure(void)
     491                 :             : {
     492                 :           1 :         INITTEST;
     493                 :             : 
     494                 :             :         /* REPORT() should avoid writing a malformed message after snprintf failure */
     495                 :           1 :         testmocking_snprintf_fail_next(1);
     496                 :           1 :         report_single_case();
     497                 :           1 :         testmocking_snprintf_disable();
     498                 :             : 
     499                 :           1 :         deliver(status);
     500                 :             : }
     501                 :             : 
     502                 :             : /**
     503                 :             :  * @brief Capture report() when the primary write fails but fallback write works
     504                 :             :  *
     505                 :             :  * @return Return describing success or failure
     506                 :             :  */
     507                 :           1 : static Return capture_librational_report_write_fallback(void)
     508                 :             : {
     509                 :           1 :         INITTEST;
     510                 :             : 
     511                 :             :         /* The first write fails, so REPORT() should emit its fixed fallback text */
     512                 :           1 :         testmocking_write_fail_next(1,EIO);
     513                 :           1 :         report_single_case();
     514                 :           1 :         testmocking_write_disable();
     515                 :             : 
     516                 :           1 :         deliver(status);
     517                 :             : }
     518                 :             : 
     519                 :             : /**
     520                 :             :  * @brief Capture report() when both primary and fallback writes fail
     521                 :             :  *
     522                 :             :  * @return Return describing success or failure
     523                 :             :  */
     524                 :           1 : static Return capture_librational_report_write_full_failure(void)
     525                 :             : {
     526                 :           1 :         INITTEST;
     527                 :             : 
     528                 :             :         /* Both writes fail, so REPORT() must give up without leaking partial output */
     529                 :           1 :         testmocking_write_fail_next(2,EIO);
     530                 :           1 :         report_single_case();
     531                 :           1 :         testmocking_write_disable();
     532                 :             : 
     533                 :           1 :         deliver(status);
     534                 :             : }
     535                 :             : #endif
     536                 :             : 
     537                 :             : /**
     538                 :             :  * @brief Check report() formatting with errno and source location
     539                 :             :  *
     540                 :             :  * @return Return describing success or failure
     541                 :             :  */
     542                 :           1 : static Return test_librational_0004_1(void)
     543                 :             : {
     544                 :           1 :         INITTEST;
     545                 :             : 
     546                 :             :         /* report() output goes to stderr and includes file, function, line, message, and errno */
     547                 :           1 :         ASSERT(SUCCESS == match_function_output(
     548                 :             :                 NULL,
     549                 :             :                 expected_report_stderr_pattern,
     550                 :             :                 capture_librational_report_test));
     551                 :             : 
     552                 :           1 :         RETURN_STATUS;
     553                 :             : }
     554                 :             : 
     555                 :             : /**
     556                 :             :  * @brief Check slog() mode filtering, prefixes, and silent visibility
     557                 :             :  *
     558                 :             :  * @return Return describing success or failure
     559                 :             :  */
     560                 :           1 : static Return test_librational_0004_2(void)
     561                 :             : {
     562                 :           1 :         INITTEST;
     563                 :             : 
     564                 :             :         /* The pattern covers every printed line; variable fields are limited to time, path, and line */
     565                 :           1 :         ASSERT(SUCCESS == match_function_output(
     566                 :             :                 expected_slog_stdout_pattern,
     567                 :             :                 NULL,
     568                 :             :                 capture_librational_slog_test));
     569                 :             : 
     570                 :           1 :         RETURN_STATUS;
     571                 :             : }
     572                 :             : 
     573                 :             : /**
     574                 :             :  * @brief Check serp() formatting with errno and source location
     575                 :             :  *
     576                 :             :  * @return Return describing success or failure
     577                 :             :  */
     578                 :           1 : static Return test_librational_0004_3(void)
     579                 :             : {
     580                 :           1 :         INITTEST;
     581                 :             : 
     582                 :             :         /* serp() writes directly to stderr without printf-style formatting */
     583                 :           1 :         ASSERT(SUCCESS == match_function_output(
     584                 :             :                 NULL,
     585                 :             :                 expected_serp_stderr_pattern,
     586                 :             :                 capture_librational_serp_case));
     587                 :             : 
     588                 :           1 :         RETURN_STATUS;
     589                 :             : }
     590                 :             : 
     591                 :             : #ifndef EVIL_EMPIRE_OS
     592                 :             : /**
     593                 :             :  * @brief Check that report() stays silent when message formatting fails
     594                 :             :  *
     595                 :             :  * @return Return describing success or failure
     596                 :             :  */
     597                 :           1 : static Return test_librational_0004_4(void)
     598                 :             : {
     599                 :           1 :         INITTEST;
     600                 :             : 
     601                 :             :         /* NULL patterns require both captured streams to stay empty */
     602                 :           1 :         ASSERT(SUCCESS == match_function_output(
     603                 :             :                 NULL,
     604                 :             :                 NULL,
     605                 :             :                 capture_librational_report_snprintf_failure));
     606                 :             : 
     607                 :           1 :         RETURN_STATUS;
     608                 :             : }
     609                 :             : 
     610                 :             : /**
     611                 :             :  * @brief Check the exact buffer state after report() truncation
     612                 :             :  *
     613                 :             :  * @return Return describing success or failure
     614                 :             :  */
     615                 :           1 : static Return test_librational_0004_5(void)
     616                 :             : {
     617                 :           1 :         INITTEST;
     618                 :             : 
     619                 :           1 :         m_create(char,captured_stdout,MEMORY_STRING);
     620                 :           1 :         m_create(char,captured_stderr,MEMORY_STRING);
     621                 :             : 
     622                 :             :         /* This test inspects raw buffer lengths, so it uses function_capture() directly */
     623                 :           1 :         ASSERT(SUCCESS == function_capture(
     624                 :             :                 report_truncated_case,
     625                 :             :                 captured_stdout,
     626                 :             :                 captured_stderr));
     627                 :             : 
     628                 :           1 :         ASSERT(captured_stdout->length == 0U);
     629                 :           1 :         ASSERT(captured_stderr->length == MAX_CHARACTERS + 1U);
     630                 :           1 :         ASSERT(captured_stderr->string_length == MAX_CHARACTERS);
     631                 :             : 
     632                 :           1 :         const char *stderr_data = m_data_ro(char,captured_stderr);
     633                 :           1 :         ASSERT(stderr_data != NULL);
     634                 :             : 
     635                 :           1 :         IF(stderr_data != NULL)
     636                 :             :         {
     637                 :           1 :                 const char expected_tail[MAX_CHARACTERS] = {0};
     638                 :             : 
     639                 :             :                 /* The snprintf mock writes one visible byte and leaves the rest zero-filled */
     640                 :           1 :                 ASSERT(stderr_data[0] == 'T');
     641                 :           1 :                 ASSERT(0 == memcmp(stderr_data + 1,expected_tail,MAX_CHARACTERS));
     642                 :             :         }
     643                 :             : 
     644                 :           1 :         call(m_del(captured_stdout));
     645                 :           1 :         call(m_del(captured_stderr));
     646                 :             : 
     647                 :           1 :         RETURN_STATUS;
     648                 :             : }
     649                 :             : 
     650                 :             : /**
     651                 :             :  * @brief Check the report() fallback message after primary write failure
     652                 :             :  *
     653                 :             :  * @return Return describing success or failure
     654                 :             :  */
     655                 :           1 : static Return test_librational_0004_6(void)
     656                 :             : {
     657                 :           1 :         INITTEST;
     658                 :             : 
     659                 :           1 :         ASSERT(SUCCESS == match_function_output(
     660                 :             :                 NULL,
     661                 :             :                 expected_write_fallback_stderr_pattern,
     662                 :             :                 capture_librational_report_write_fallback));
     663                 :             : 
     664                 :           1 :         RETURN_STATUS;
     665                 :             : }
     666                 :             : 
     667                 :             : /**
     668                 :             :  * @brief Check that report() stays silent when both writes fail
     669                 :             :  *
     670                 :             :  * @return Return describing success or failure
     671                 :             :  */
     672                 :           1 : static Return test_librational_0004_7(void)
     673                 :             : {
     674                 :           1 :         INITTEST;
     675                 :             : 
     676                 :           1 :         ASSERT(SUCCESS == match_function_output(
     677                 :             :                 NULL,
     678                 :             :                 NULL,
     679                 :             :                 capture_librational_report_write_full_failure));
     680                 :             : 
     681                 :           1 :         RETURN_STATUS;
     682                 :             : }
     683                 :             : #endif
     684                 :             : 
     685                 :             : /**
     686                 :             :  * @brief Check rational_reconvert() edge cases around empty and REMEMBER modes
     687                 :             :  *
     688                 :             :  * @return Return describing success or failure
     689                 :             :  */
     690                 :           1 : static Return test_librational_0004_8(void)
     691                 :             : {
     692                 :           1 :         INITTEST;
     693                 :             : 
     694                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(0),""));
     695                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(REMEMBER),"REMEMBER"));
     696                 :           1 :         ASSERT(0 == strcmp(
     697                 :             :                 rational_reconvert(REGULAR|REMEMBER|VISIBLE_IN_SILENT),
     698                 :             :                 "REGULAR | REMEMBER | VISIBLE_IN_SILENT"));
     699                 :             : 
     700                 :           1 :         RETURN_STATUS;
     701                 :             : }
     702                 :             : 
     703                 :             : /**
     704                 :             :  * @brief Check rational_reconvert() names every logger mode flag
     705                 :             :  *
     706                 :             :  * @return Return describing success or failure
     707                 :             :  */
     708                 :           1 : static Return test_librational_0004_9(void)
     709                 :             : {
     710                 :           1 :         INITTEST;
     711                 :             : 
     712                 :             :         /* Pin all single-flag names and the full mapping order used in diagnostics */
     713                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(REGULAR),"REGULAR"));
     714                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(VERBOSE),"VERBOSE"));
     715                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(TESTING),"TESTING"));
     716                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(ERROR),"ERROR"));
     717                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(SILENT),"SILENT"));
     718                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(UNDECOR),"UNDECOR"));
     719                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(REMEMBER),"REMEMBER"));
     720                 :           1 :         ASSERT(0 == strcmp(rational_reconvert(VISIBLE_IN_SILENT),"VISIBLE_IN_SILENT"));
     721                 :           1 :         ASSERT(0 == strcmp(
     722                 :             :                 rational_reconvert(REGULAR|VERBOSE|TESTING|ERROR|SILENT|UNDECOR|REMEMBER|VISIBLE_IN_SILENT),
     723                 :             :                 "REGULAR | VERBOSE | TESTING | ERROR | SILENT | UNDECOR | REMEMBER | VISIBLE_IN_SILENT"));
     724                 :             : 
     725                 :           1 :         RETURN_STATUS;
     726                 :             : }
     727                 :             : 
     728                 :             : #ifndef EVIL_EMPIRE_OS
     729                 :             : /**
     730                 :             :  * @brief Check that slog() stays silent when logger line allocation fails
     731                 :             :  *
     732                 :             :  * @return Return describing success or failure
     733                 :             :  */
     734                 :           1 : static Return test_librational_0004_10(void)
     735                 :             : {
     736                 :           1 :         INITTEST;
     737                 :             : 
     738                 :           1 :         ASSERT(SUCCESS == match_function_output(
     739                 :             :                 NULL,
     740                 :             :                 NULL,
     741                 :             :                 capture_librational_logger_realloc_failure));
     742                 :             : 
     743                 :           1 :         RETURN_STATUS;
     744                 :             : }
     745                 :             : 
     746                 :             : /**
     747                 :             :  * @brief Check slog() output when timestamp helper calls fail
     748                 :             :  *
     749                 :             :  * @return Return describing success or failure
     750                 :             :  */
     751                 :           1 : static Return test_librational_0004_11(void)
     752                 :             : {
     753                 :           1 :         INITTEST;
     754                 :             : 
     755                 :           1 :         ASSERT(SUCCESS == match_function_output(
     756                 :             :                 expected_logger_time_failure_stdout_pattern,
     757                 :             :                 NULL,
     758                 :             :                 capture_librational_logger_time_failures));
     759                 :             : 
     760                 :           1 :         RETURN_STATUS;
     761                 :             : }
     762                 :             : 
     763                 :             : /**
     764                 :             :  * @brief Check that slog() stays silent when vsnprintf fails
     765                 :             :  *
     766                 :             :  * @return Return describing success or failure
     767                 :             :  */
     768                 :           1 : static Return test_librational_0004_12(void)
     769                 :             : {
     770                 :           1 :         INITTEST;
     771                 :             : 
     772                 :           1 :         ASSERT(SUCCESS == match_function_output(
     773                 :             :                 NULL,
     774                 :             :                 NULL,
     775                 :             :                 capture_librational_logger_vsnprintf_failure));
     776                 :             : 
     777                 :           1 :         RETURN_STATUS;
     778                 :             : }
     779                 :             : #endif
     780                 :             : 
     781                 :             : /**
     782                 :             :  * @brief Check that slog(ERROR) stays silent when no mode accepts ERROR
     783                 :             :  *
     784                 :             :  * @return Return describing success or failure
     785                 :             :  */
     786                 :           1 : static Return test_librational_0004_13(void)
     787                 :             : {
     788                 :           1 :         INITTEST;
     789                 :             : 
     790                 :           1 :         ASSERT(SUCCESS == match_function_output(
     791                 :             :                 NULL,
     792                 :             :                 NULL,
     793                 :             :                 capture_librational_logger_disabled_error_mode));
     794                 :             : 
     795                 :           1 :         RETURN_STATUS;
     796                 :             : }
     797                 :             : 
     798                 :             : #ifndef EVIL_EMPIRE_OS
     799                 :             : /**
     800                 :             :  * @brief Check that REMEMBER has no output when no payload is available
     801                 :             :  *
     802                 :             :  * @return Return describing success or failure
     803                 :             :  */
     804                 :           1 : static Return test_librational_0004_14(void)
     805                 :             : {
     806                 :           1 :         INITTEST;
     807                 :             : 
     808                 :           1 :         ASSERT(SUCCESS == match_function_output(
     809                 :             :                 NULL,
     810                 :             :                 NULL,
     811                 :             :                 capture_librational_logger_remember_without_payload));
     812                 :             : 
     813                 :           1 :         RETURN_STATUS;
     814                 :             : }
     815                 :             : #endif
     816                 :             : 
     817                 :             : /**
     818                 :             :  * @brief Check that slog() escapes terminal-hostile text without damaging normal UTF-8
     819                 :             :  *
     820                 :             :  * @return Return describing success or failure
     821                 :             :  */
     822                 :           1 : static Return test_librational_0004_15(void)
     823                 :             : {
     824                 :           1 :         INITTEST;
     825                 :             : 
     826                 :           1 :         m_create(char,captured_stdout,MEMORY_STRING);
     827                 :           1 :         m_create(char,captured_stderr,MEMORY_STRING);
     828                 :             : 
     829                 :             :         static const char expected_stdout[] =
     830                 :             :                 "ascii"
     831                 :             :                 "\\x01"
     832                 :             :                 "del"
     833                 :             :                 "\\x7F"
     834                 :             :                 "c1"
     835                 :             :                 "\\xC2\\x90"
     836                 :             :                 "invalid"
     837                 :             :                 "\\xC3("
     838                 :             :                 "overlong"
     839                 :             :                 "\\xC0\\xAF"
     840                 :             :                 "keep"
     841                 :             :                 "\t\r\n"
     842                 :             :                 "esc"
     843                 :             :                 "\033[1m"
     844                 :             :                 "utf8"
     845                 :             :                 "°"
     846                 :             :                 "à"
     847                 :             :                 "Привет"
     848                 :             :                 "天地玄黄宇宙洪荒日月盈昃辰宿列張"
     849                 :             :                 "いろはにほへとちりぬるを"
     850                 :             :                 "日本語漢字仮名交じり文";
     851                 :             : 
     852                 :           1 :         ASSERT(SUCCESS == function_capture(
     853                 :             :                 librational_logger_terminal_safety_case,
     854                 :             :                 captured_stdout,
     855                 :             :                 captured_stderr));
     856                 :             : 
     857                 :           1 :         ASSERT(0 == strcmp(m_text(captured_stdout),expected_stdout));
     858                 :           1 :         ASSERT(captured_stderr->length == 0U);
     859                 :             : 
     860                 :           1 :         call(m_del(captured_stdout));
     861                 :           1 :         call(m_del(captured_stderr));
     862                 :             : 
     863                 :           1 :         RETURN_STATUS;
     864                 :             : }
     865                 :             : 
     866                 :             : /**
     867                 :             :  * @brief Check that function_capture() flushes pending stdout before redirection
     868                 :             :  *
     869                 :             :  * @return Return describing success or failure
     870                 :             :  */
     871                 :           1 : static Return test_librational_0004_capture_flush(void)
     872                 :             : {
     873                 :           1 :         INITTEST;
     874                 :             : 
     875                 :           1 :         m_create(char,captured_stdout,MEMORY_STRING);
     876                 :           1 :         m_create(char,captured_stderr,MEMORY_STRING);
     877                 :           1 :         int saved_stdout_fd = -1;
     878                 :           1 :         FILE *stdout_tmp = NULL;
     879                 :             : 
     880                 :           1 :         saved_stdout_fd = dup(STDOUT_FILENO);
     881                 :           1 :         ASSERT(saved_stdout_fd != -1);
     882                 :             : 
     883                 :             :         /* Redirect stdout away from the terminal, then leave text pending in stdio */
     884         [ +  - ]:           1 :         if(SUCCESS == status)
     885                 :             :         {
     886                 :           1 :                 stdout_tmp = tmpfile();
     887                 :             :         }
     888                 :             : 
     889                 :           1 :         ASSERT(stdout_tmp != NULL);
     890                 :           1 :         ASSERT(0 == fflush(stdout));
     891                 :           1 :         ASSERT(dup2(fileno(stdout_tmp),STDOUT_FILENO) != -1);
     892                 :           1 :         ASSERT(fprintf(stdout,"pending stdout before function_capture") > 0);
     893                 :             : 
     894                 :             :         /* function_capture() should flush that pending text before installing its own redirection */
     895                 :           1 :         ASSERT(SUCCESS == function_capture(no_output_test,captured_stdout,captured_stderr));
     896                 :           1 :         ASSERT(captured_stdout->length == 0);
     897                 :           1 :         ASSERT(captured_stderr->length == 0);
     898                 :             : 
     899                 :           1 :         IF(stdout_tmp != NULL)
     900                 :             :         {
     901                 :           1 :                 (void)fflush(stdout);
     902                 :             :         }
     903                 :             : 
     904         [ +  - ]:           1 :         if(saved_stdout_fd != -1)
     905                 :             :         {
     906         [ -  + ]:           1 :                 if(dup2(saved_stdout_fd,STDOUT_FILENO) == -1)
     907                 :             :                 {
     908                 :           0 :                         testitall_failure_location_record(__FILE__,__func__,__LINE__);
     909                 :           0 :                         status = FAILURE;
     910                 :             :                 }
     911                 :             : 
     912                 :           1 :                 (void)close(saved_stdout_fd);
     913                 :             :         }
     914                 :             : 
     915                 :           1 :         IF(stdout_tmp != NULL)
     916                 :             :         {
     917                 :           1 :                 (void)fclose(stdout_tmp);
     918                 :             :         }
     919                 :             : 
     920                 :           1 :         call(m_del(captured_stdout));
     921                 :           1 :         call(m_del(captured_stderr));
     922                 :             : 
     923                 :           1 :         RETURN_STATUS;
     924                 :             : }
     925                 :             : 
     926                 :             : /**
     927                 :             :  * @brief Exercise report(), serp(), slog(), and logger mode conversion
     928                 :             :  *
     929                 :             :  * The suite checks formatted report output, plain errno reporting through serp(),
     930                 :             :  * slog() mode filtering and decoration, logger conversion helpers, failure paths
     931                 :             :  * for formatting/allocation/time/write helpers, and the output-capture guard that
     932                 :             :  * flushes pending stdout before redirecting streams
     933                 :             :  *
     934                 :             :  * @return SUCCESS when all subtests pass
     935                 :             :  */
     936                 :           1 : Return test_librational_0004(void)
     937                 :             : {
     938                 :           1 :         INITTEST;
     939                 :             : 
     940                 :           1 :         TEST(test_librational_0004_capture_flush,"function_capture() flushes pending stdout before redirection");
     941                 :           1 :         TEST(test_librational_0004_1,"report() writes formatted errno messages with source location");
     942                 :           1 :         TEST(test_librational_0004_2,"slog() honors logger modes, decorations and silent visibility");
     943                 :           1 :         TEST(test_librational_0004_3,"serp() writes errno, source file and function name");
     944                 :             : #ifndef EVIL_EMPIRE_OS
     945                 :           1 :         TEST(test_librational_0004_4,"report() stays silent when final message formatting fails");
     946                 :           1 :         TEST(test_librational_0004_5,"report() keeps a truncated fixed-size message buffer terminated");
     947                 :           1 :         TEST(test_librational_0004_6,"report() writes fallback text after primary write failure");
     948                 :           1 :         TEST(test_librational_0004_7,"report() stays silent when primary and fallback writes fail");
     949                 :             : #endif
     950                 :           1 :         TEST(test_librational_0004_8,"rational_reconvert() covers empty and REMEMBER edge cases");
     951                 :           1 :         TEST(test_librational_0004_9,"rational_reconvert() names every logger flag");
     952                 :             : #ifndef EVIL_EMPIRE_OS
     953                 :           1 :         TEST(test_librational_0004_10,"slog() stays silent when line allocation fails");
     954                 :           1 :         TEST(test_librational_0004_11,"slog() keeps payloads visible when time formatting fails");
     955                 :           1 :         TEST(test_librational_0004_12,"slog() stays silent when vsnprintf fails");
     956                 :             : #endif
     957                 :           1 :         TEST(test_librational_0004_13,"slog(ERROR) stays silent when no mode accepts ERROR");
     958                 :             : #ifndef EVIL_EMPIRE_OS
     959                 :           1 :         TEST(test_librational_0004_14,"slog(REMEMBER) skips empty or unformatted payloads");
     960                 :             : #endif
     961                 :           1 :         TEST(test_librational_0004_15,"slog() escapes unsafe terminal bytes while preserving normal UTF-8");
     962                 :             : 
     963                 :           1 :         RETURN_STATUS;
     964                 :             : }
        

Generated by: LCOV version 2.0-1