44
55#include " base.hpp"
66#include " test_helpers.h"
7+ #include " utils/utils_sanitizers.h"
78
89#define MOCK_FILE_PTR (FILE *)0xBADBEEF
910#define INVALID_ERRNO 42
1011std::string expected_filename;
1112int expect_fopen_count = 0 ;
1213int fopen_count = 0 ;
14+ FILE *fopen_return = MOCK_FILE_PTR;
1315
1416FILE *mock_fopen (const char *filename, const char *mode) {
1517 fopen_count++;
1618 EXPECT_STREQ (filename, expected_filename.c_str ());
1719 EXPECT_STREQ (mode, " a" );
18- return MOCK_FILE_PTR ;
20+ return fopen_return ;
1921}
2022
2123const std::string MOCK_FN_NAME = " MOCK_FUNCTION_NAME" ;
@@ -110,11 +112,18 @@ const char *env_variable = "";
110112#ifndef UMF_VERSION
111113#define UMF_VERSION " test version"
112114#endif
115+ // This trick to not work on windows
116+ #ifndef _WIN32
117+ #define abort ()
118+ #endif
113119#include " utils/utils_log.c"
114120#undef utils_env_var
115121#undef fopen
116122#undef fputs
117123#undef fflush
124+ #ifndef _WIN32
125+ #undef abort
126+ #endif
118127}
119128using umf_test::test;
120129
@@ -139,6 +148,7 @@ void helper_checkConfig(utils_log_config_t *expected, utils_log_config_t *is) {
139148TEST_F (test, parseEnv_errors) {
140149 expected_message = " " ;
141150 loggerConfig = {0 , 0 , LOG_ERROR, LOG_ERROR, NULL };
151+ fopen_return = MOCK_FILE_PTR;
142152
143153 expect_fput_count = 0 ;
144154 expected_stream = stderr;
@@ -164,6 +174,7 @@ TEST_F(test, parseEnv_errors) {
164174TEST_F (test, parseEnv) {
165175 utils_log_config_t b = loggerConfig;
166176 expected_message = " " ;
177+ fopen_return = MOCK_FILE_PTR;
167178
168179 std::vector<std::pair<std::string, int >> logLevels = {
169180 {" level:debug" , LOG_DEBUG},
@@ -250,6 +261,20 @@ TEST_F(test, parseEnv) {
250261 }
251262 }
252263}
264+ TEST_F (test, fopen_fail) {
265+ expected_stream = stderr;
266+ expect_fopen_count = 1 ;
267+ loggerConfig = {0 , 0 , LOG_ERROR, LOG_ERROR, NULL };
268+ utils_log_config_t b = loggerConfig = {0 , 0 , LOG_ERROR, LOG_ERROR, NULL };
269+
270+ expected_filename = " filepath" ;
271+ expected_message = " [ERROR UMF] utils_log_init: Cannot open output file "
272+ " filepath - logging disabled: \n " ;
273+
274+ fopen_return = NULL ;
275+ helper_log_init (" output:file,filepath" );
276+ helper_checkConfig (&b, &loggerConfig);
277+ }
253278
254279template <typename ... Args> void helper_test_log (Args... args) {
255280 fput_count = 0 ;
@@ -279,6 +304,7 @@ static std::string helper_log_str(int l) {
279304
280305TEST_F (test, log_levels) {
281306 expected_stream = stderr;
307+ fopen_return = MOCK_FILE_PTR;
282308 for (int i = LOG_DEBUG; i <= LOG_ERROR; i++) {
283309 for (int j = LOG_DEBUG; j <= LOG_ERROR; j++) {
284310 loggerConfig = {0 , 0 , (utils_log_level_t )i, LOG_DEBUG, stderr};
@@ -302,6 +328,7 @@ TEST_F(test, log_outputs) {
302328 std::vector<FILE *> outs = {stdout, stderr, MOCK_FILE_PTR};
303329 expect_fput_count = 1 ;
304330 expect_fflush_count = 1 ;
331+ fopen_return = MOCK_FILE_PTR;
305332 expected_message = " [DEBUG UMF] " + MOCK_FN_NAME + " : example log\n " ;
306333 for (auto o : outs) {
307334 loggerConfig = {0 , 0 , LOG_DEBUG, LOG_DEBUG, o};
@@ -313,6 +340,7 @@ TEST_F(test, log_outputs) {
313340TEST_F (test, flush_levels) {
314341 expected_stream = stderr;
315342 expect_fput_count = 1 ;
343+ fopen_return = MOCK_FILE_PTR;
316344 for (int i = LOG_DEBUG; i <= LOG_ERROR; i++) {
317345 for (int j = LOG_DEBUG; j <= LOG_ERROR; j++) {
318346 loggerConfig = {0 , 0 , LOG_DEBUG, (utils_log_level_t )i, stderr};
@@ -332,6 +360,7 @@ TEST_F(test, flush_levels) {
332360TEST_F (test, long_log) {
333361 expect_fput_count = 1 ;
334362 expect_fflush_count = 1 ;
363+ fopen_return = MOCK_FILE_PTR;
335364 loggerConfig = {0 , 0 , LOG_DEBUG, LOG_DEBUG, stderr};
336365 expected_message = " [DEBUG UMF] " + MOCK_FN_NAME + " : " +
337366 std::string (8189 - MOCK_FN_NAME.size (), ' x' ) + " \n " ;
@@ -347,6 +376,7 @@ TEST_F(test, long_log) {
347376TEST_F (test, timestamp_log) {
348377 expect_fput_count = 1 ;
349378 expect_fflush_count = 1 ;
379+ fopen_return = MOCK_FILE_PTR;
350380 loggerConfig = {1 , 0 , LOG_DEBUG, LOG_DEBUG, stderr};
351381 // TODO: for now we do not check output message,
352382 // as it requires more sophisticated message validation (a.k.a regrex)
@@ -357,6 +387,7 @@ TEST_F(test, timestamp_log) {
357387TEST_F (test, pid_log) {
358388 expect_fput_count = 1 ;
359389 expect_fflush_count = 1 ;
390+ fopen_return = MOCK_FILE_PTR;
360391 loggerConfig = {0 , 1 , LOG_DEBUG, LOG_DEBUG, stderr};
361392 // TODO: for now we do not check output message,
362393 // as it requires more sophisticated message validation (a.k.a regrex)
@@ -369,6 +400,7 @@ TEST_F(test, log_fatal) {
369400 expected_stream = stderr;
370401 expect_fput_count = 1 ;
371402 expect_fflush_count = 1 ;
403+ fopen_return = MOCK_FILE_PTR;
372404
373405 expected_message = " [FATAL UMF] " + MOCK_FN_NAME + " : example log\n " ;
374406 strerror_ret_static = 0 ;
@@ -379,6 +411,7 @@ TEST_F(test, log_macros) {
379411 expected_stream = stderr;
380412 expect_fput_count = 1 ;
381413 expect_fflush_count = 1 ;
414+ fopen_return = MOCK_FILE_PTR;
382415 loggerConfig = {0 , 0 , LOG_DEBUG, LOG_DEBUG, stderr};
383416
384417 expected_message = " [DEBUG UMF] TestBody: example log\n " ;
@@ -428,6 +461,7 @@ template <typename... Args> void helper_test_plog(Args... args) {
428461TEST_F (test, plog_basic) {
429462 loggerConfig = {0 , 0 , LOG_DEBUG, LOG_DEBUG, stderr};
430463 expected_stream = stderr;
464+ fopen_return = MOCK_FILE_PTR;
431465 errno = 1 ;
432466 strerr = " test error" ;
433467 expect_fput_count = 1 ;
@@ -448,6 +482,7 @@ TEST_F(test, plog_invalid) {
448482 strerr = " test error" ;
449483 expect_fput_count = 1 ;
450484 expect_fflush_count = 1 ;
485+ fopen_return = MOCK_FILE_PTR;
451486
452487 expected_message =
453488 " [DEBUG UMF] " + MOCK_FN_NAME + " : example log: unknown error\n " ;
@@ -465,6 +500,7 @@ TEST_F(test, plog_long_message) {
465500 strerror_ret_static = 0 ;
466501 strerr = " test error" ;
467502 errno = 1 ;
503+ fopen_return = MOCK_FILE_PTR;
468504
469505 expected_message = " [DEBUG UMF] " + MOCK_FN_NAME + " : " +
470506 std::string (8178 - MOCK_FN_NAME.length (), ' x' ) +
@@ -487,6 +523,7 @@ TEST_F(test, plog_long_error) {
487523 std::string tmp = std::string (2000 , ' x' );
488524 strerr = tmp.c_str ();
489525 errno = 1 ;
526+ fopen_return = MOCK_FILE_PTR;
490527#ifdef WIN32
491528 /* On windows limit is shorter, and there is no truncated detection*/
492529 expected_message = " [DEBUG UMF] " + MOCK_FN_NAME +
@@ -508,6 +545,7 @@ TEST_F(test, log_pmacros) {
508545 loggerConfig = {0 , 0 , LOG_DEBUG, LOG_DEBUG, stderr};
509546 errno = 1 ;
510547 strerr = " test error" ;
548+ fopen_return = MOCK_FILE_PTR;
511549
512550 expected_message = " [DEBUG UMF] TestBody: example log: test error\n " ;
513551 fput_count = 0 ;
@@ -544,3 +582,24 @@ TEST_F(test, log_pmacros) {
544582 EXPECT_EQ (fput_count, expect_fput_count);
545583 EXPECT_EQ (fflush_count, expect_fflush_count);
546584}
585+
586+ // this test doesn't work on windows as we cannot mock abort on windows
587+ // also it is not supported if UndefinedBehaviorSanitizer is enabled
588+ #if !defined(_WIN32) && !defined(__SANITIZE_UNDEFINED__)
589+ TEST_F (test, invalid_log_level) {
590+ fopen_return = MOCK_FILE_PTR;
591+ loggerConfig = {0 , 0 , LOG_DEBUG, LOG_DEBUG, stderr};
592+ #ifndef NDEBUG
593+ expect_fput_count = 2 ;
594+ expect_fflush_count = 2 ;
595+ #else
596+ expect_fput_count = 1 ;
597+ expect_fflush_count = 1 ;
598+ #endif
599+ // TODO: we do not check output message, as there will be two separate messages
600+ // which is not supported by this simple test framework.
601+ expected_message = " " ;
602+ helper_test_log ((utils_log_level_t )10 , MOCK_FN_NAME.c_str (), " %s" ,
603+ " example log" );
604+ }
605+ #endif
0 commit comments