#include "../src/trace.c" #include "../src/testing.h" #include "slurp.h" static const char FNAME[] = __FILE__ ".txt"; static int test_ftracef(void) { int rc = -1; test_start("ftracef()"); FILE *file = NULL; char *str = NULL; const enum TraceLevel orig = (enum TraceLevel)(intptr_t)pthread_getspecific(LEVEL_KEY); trace_set_level(TraceLevel_INFO); { testing("empty varargs"); file = fopen(FNAME, "w"); if (file == NULL) { perror("fopen(FNAME, \"w\")"); goto out; } #line 100 ftracef(__FILE__, __func__, __LINE__, file, TraceLevel_INFO, ""); const int ret = fclose(file); file = NULL; if (ret) { perror("fclose(file)"); goto out; } if (slurp_for_tests(FNAME, &str)) { perror("slurp_for_tests(FNAME, &str)"); goto out; } const char expected[] = "tests/trace.c:test_ftracef:100: \n"; assert(strcmp(expected, str) == 0); free(str); str = NULL; test_ok(); } { testing("multiple format strings"); file = fopen(FNAME, "w"); if (file == NULL) { perror("fopen(FNAME, \"w\")"); goto out; } trace_set_stream(file); #line 200 ftracef(__FILE__, __func__, __LINE__, file, TraceLevel_INFO, "int (%d), string (%s) and char (%c)", 123, "another-str", 'z'); const int ret = fclose(file); file = NULL; if (ret) { perror("fclose(file)"); goto out; } if (slurp_for_tests(FNAME, &str)) { perror("slurp_for_tests(FNAME, &str)"); goto out; } const char expected[] = "tests/trace.c:test_ftracef:200: " "int (123), string (another-str) and char (z)\n"; assert(strcmp(expected, str) == 0); free(str); str = NULL; test_ok(); } { testing("insufficient trace level"); file = fopen(FNAME, "w"); if (file == NULL) { perror("fopen(FNAME, \"w\")"); goto out; } trace_set_stream(file); ftracef(__FILE__, __func__, __LINE__, file, TraceLevel_DEBUG, "ignored"); const int ret = fclose(file); file = NULL; if (ret) { perror("fclose(file)"); goto out; } if (slurp_for_tests(FNAME, &str)) { perror("slurp_for_tests(FNAME, &str)"); goto out; } assert(strcmp("", str) == 0); free(str); str = NULL; test_ok(); } rc = 0; out: trace_set_level(orig); if (str != NULL) { free(str); str = NULL; } if (file != NULL) { if (fclose(file)) { perror("fclose(file)"); rc = -1; } } return rc; } static int test_trace(void) { int rc = -1; test_start("trace()"); FILE *file = fopen("/dev/null", "w"); if (file == NULL) { logerr("fopen(\"/dev/null\", \"w\")"); goto out; } trace_set_stream(file); { testing("can be called with an empty string"); trace(TraceLevel_INFO, ""); test_ok(); } { testing("can be called with formatting arguments"); trace(TraceLevel_INFO, "int: %d\tstr: %s", 123, "example"); test_ok(); } rc = 0; out: if (file != NULL) { if (fclose(file)) { perror("fclose(file)"); rc = -1; } } return rc; } int main(void) { int rc = EXIT_FAILURE; if (pthread_once(&ONCE, init)) { perror("pthread_once()"); goto out; } if (trace_set_level(TraceLevel_DEBUG)) { perror("trace_set_level()"); goto out; } if (test_ftracef()) { perror("test_ftracef()"); goto out; } if (test_trace()) { perror("test_trace()"); goto out; } rc = EXIT_SUCCESS; out: return rc; }