#include #include #include #include #include #include #include #include "ucore/logging.h" #define FILE_NAME "logfile_test.log" #define SUBDIR "log_subdir" #define SUBDIR_FILE_NAME SUBDIR "/" FILE_NAME //Note that these tests are comewhat fragile as they depend on the //file sizes that are created, which depends on the (relative)paths of this file. //for cleaning the created log files.. static void logging_rm_files(void) { remove(FILE_NAME); } //setting up subdir static void logging_setup_subdir(void) { mkdir(SUBDIR, 0750); } static void logging_rm_subdir(void) { remove(SUBDIR_FILE_NAME); remove(SUBDIR); } START_TEST (test_logfile_location) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); uc_log_add_destination(dest); uc_log_add_destination(dest); //adding this twice should do nothing UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2"); UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3"); UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4"); UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5"); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 380, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_delete_destination) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); uc_log_add_destination(dest); uc_log_add_destination(dest); //adding this twice should do nothing UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2"); UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3"); UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4"); UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5"); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 380, "was %ld", (long)st.st_size); uc_log_delete_destination(dest); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2"); UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3"); UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4"); UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5"); //since we deleted destinatiion, no more logging should appear in the file rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 380, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_no_location) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 0); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 52*2, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_loglevel_surpressed_dest) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); //file destination have UC_LL_WARNING, so nothing should be logged dest = uc_log_new_file(FILE_NAME, UC_LL_WARNING, 10); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGF(UC_LL_INFO, 1, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_loglevel_surpressed_module) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", //file destination have UC_LL_WARNING, so nothing should be logged .log_level = UC_LL_WARNING, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 100); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_reopen_files) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size); rc = remove(FILE_NAME); fail_if(rc != 0, "Remove failed %s", strerror(errno)); rc = uc_log_reopen_files(); fail_if(rc != 0, "uc_log_reopen_files failed: %d", rc); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "2. stat failed: %s", strerror(errno)); fail_if(st.st_size != 77, "was %ld", (long)st.st_size);//should only one line there now END_TEST START_TEST (test_logfile_remove_dest) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest1, *dest2; int rc; uc_log_init(&mods); dest1 = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest1 == NULL); dest2 = uc_log_new_stderr(UC_LL_WARNING, 1); fail_if(dest2 == NULL); uc_log_add_destination(dest1); uc_log_add_destination(dest2); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size); uc_log_remove_destination(dest1); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); //should not be logged now rc = stat(FILE_NAME, &st); fail_if(rc != 0, "2. stat failed: %s", strerror(errno)); fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size //removing the last destination should be fine too uc_log_remove_destination(dest2); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "2. stat failed: %s", strerror(errno)); fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size END_TEST START_TEST (test_logfile_full_filesystem) //logging to a full filesystem shouldn't crash struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct UCLogDestination *dest; int i; uc_log_init(&mods); dest = uc_log_new_file("/dev/full", UC_LL_DEBUG, 1); fail_if(dest == NULL, "Cannot open /dev/full"); uc_log_add_destination(dest); for (i = 0; i < 1024; i++) { UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1); } END_TEST START_TEST (test_logfile_invalid_file) //check behavior when a log file cannot be opened struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct UCLogDestination *dest; uc_log_init(&mods); dest = uc_log_new_file("PATH/to/nonexisting.log", UC_LL_DEBUG, 1); fail_if(dest != NULL); END_TEST START_TEST (test_logfile_invalid_file_after_reopen) //check behavior when a log file cannot be re-opened struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct UCLogDestination *dest; int rc; uc_log_init(&mods); printf("SUBDIR_FILE_NAME= " SUBDIR_FILE_NAME " "); dest = uc_log_new_file(SUBDIR_FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); logging_rm_subdir(); rc = access(SUBDIR_FILE_NAME, W_OK); fail_if(rc == 0, "Test setup is wrong. Can still access" SUBDIR_FILE_NAME ""); UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1); uc_log_reopen_files(); //this should not crash now. UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1); UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1); END_TEST START_TEST (test_logfile_raw) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_dest_mask) struct UCLogModule m[] = { { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_WARNING, }, { .id = 1, .short_name = "MOD2", .long_name = "Module 2", .log_level = UC_LL_WARNING, } }; struct UCLogModules mods = { .mods = m, .cnt = 2, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 0, "was %ld", (long)st.st_size); uc_log_destination_set_mask(dest, "MOD1=DEBUG:mod2=Debug"); UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); UC_LOGFR(UC_LL_DEBUG, 1, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size); END_TEST START_TEST (test_loglevel_module_none) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_NONE, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST START_TEST (test_loglevel_dest_none) struct UCLogModule m = { .id = 0, .short_name = "MOD1", .long_name = "Module 1", .log_level = UC_LL_DEBUG, }; struct UCLogModules mods = { .mods = &m, .cnt = 1, }; struct stat st; struct UCLogDestination *dest; int rc; uc_log_init(&mods); dest = uc_log_new_file(FILE_NAME, UC_LL_NONE, 1); fail_if(dest == NULL); uc_log_add_destination(dest); UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); fail_if(rc != 0, "stat failed: %s", strerror(errno)); fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST Suite *logging_suite(void) { Suite *s = suite_create("logging"); TCase *tc1 = tcase_create("ucore_logging1"); TCase *tc2 = tcase_create("ucore_logging2"); tcase_add_test(tc1, test_logfile_location); tcase_add_test(tc1, test_logfile_delete_destination); tcase_add_test(tc1, test_logfile_no_location); tcase_add_test(tc1, test_logfile_loglevel_surpressed_dest); tcase_add_test(tc1, test_logfile_loglevel_surpressed_module); tcase_add_test(tc1, test_logfile_reopen_files); tcase_add_test(tc1, test_logfile_remove_dest); tcase_add_test(tc1, test_logfile_dest_mask); if (access("/dev/full", R_OK) == 0) { tcase_add_test(tc1, test_logfile_full_filesystem); } else { puts("Cannot access /dev/full. Not testing test_logfile_full_filesystem"); } tcase_add_test(tc1, test_logfile_invalid_file); tcase_add_test(tc2, test_logfile_invalid_file_after_reopen); tcase_add_test(tc1, test_logfile_raw); tcase_add_test(tc1, test_loglevel_module_none); tcase_add_test(tc1, test_loglevel_dest_none); tcase_add_checked_fixture(tc1, logging_rm_files, logging_rm_files); tcase_add_checked_fixture(tc2, logging_setup_subdir, logging_rm_subdir); suite_add_tcase(s, tc1); suite_add_tcase(s, tc2); return s; }