/* * Copyright (c) 2020 Nordic Semiconductor * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Test logging to file system * */ #include #include #include #include #include #define DT_DRV_COMPAT zephyr_fstab_littlefs #define TEST_AUTOMOUNT DT_PROP(DT_DRV_INST(0), automount) #if !TEST_AUTOMOUNT #include #define PARTITION_NODE DT_NODELABEL(lfs1) FS_FSTAB_DECLARE_ENTRY(PARTITION_NODE); #endif #define MAX_PATH_LEN (256 + 7) static const char *log_prefix = CONFIG_LOG_BACKEND_FS_FILE_PREFIX; int write_log_to_file(uint8_t *data, size_t length, void *ctx); ZTEST(test_log_backend_fs, test_fs_nonexist) { #if TEST_AUTOMOUNT ztest_test_skip(); #else uint8_t to_log[] = "Log to left behind"; int rc; rc = write_log_to_file(to_log, sizeof(to_log), NULL); zassert_equal(rc, sizeof(to_log), "Unexpected rteval."); struct fs_mount_t *mp = &FS_FSTAB_ENTRY(PARTITION_NODE); rc = fs_mount(mp); zassert_equal(rc, 0, "Can not mount FS."); #endif } ZTEST(test_log_backend_fs, test_wipe_fs_logs) { int rc; struct fs_dir_t dir; struct fs_file_t file; char fname[MAX_PATH_LEN]; fs_dir_t_init(&dir); fs_file_t_init(&file); rc = fs_opendir(&dir, CONFIG_LOG_BACKEND_FS_DIR); if (rc) { /* log directory might not exist jet */ return; } /* Iterate over logging directory. */ while (1) { struct fs_dirent ent = { 0 }; rc = fs_readdir(&dir, &ent); zassert_equal(rc, 0, "Can not read directory."); if ((rc < 0) || (ent.name[0] == 0)) { break; } if (ent.type == FS_DIR_ENTRY_FILE && strncmp(ent.name, log_prefix, strlen(log_prefix)) == 0) { sprintf(fname, "%s/%s", CONFIG_LOG_BACKEND_FS_DIR, ent.name); rc = fs_unlink(fname); zassert_equal(rc, 0, "Can not remove file %s.", fname); TC_PRINT("removed: %s\n", fname); } } (void)fs_closedir(&dir); } ZTEST(test_log_backend_fs, test_log_fs_file_content) { int rc; struct fs_file_t file; char log_read[MAX_PATH_LEN]; uint8_t to_log[] = "Correct Log 1"; static char fname[MAX_PATH_LEN]; fs_file_t_init(&file); rc = write_log_to_file(to_log, sizeof(to_log), NULL); sprintf(fname, "%s/%s0000", CONFIG_LOG_BACKEND_FS_DIR, log_prefix); zassert_equal(fs_open(&file, fname, FS_O_READ), 0, "Can not open log file."); zassert_true(fs_read(&file, log_read, MAX_PATH_LEN) >= 0, "Can not read log file."); rc = strncmp(log_read, to_log, sizeof(log_read)); zassert_equal(rc, 0, "Text inside log file is not correct."); zassert_equal(fs_close(&file), 0, "Can not close log file."); to_log[sizeof(to_log)-2] = '2'; rc = write_log_to_file(to_log, sizeof(to_log), NULL); zassert_equal(fs_open(&file, fname, FS_O_READ), 0, "Can not open log file."); zassert_equal(fs_seek(&file, sizeof(to_log), FS_SEEK_SET), 0, "Bad file size"); zassert_true(fs_read(&file, log_read, MAX_PATH_LEN) >= 0, "Can not read log file."); rc = strncmp(log_read, to_log, sizeof(log_read)); zassert_equal(rc, 0, "Text inside log file is not correct."); zassert_equal(fs_close(&file), 0, "Can not close log file."); } ZTEST(test_log_backend_fs, test_log_fs_file_size) { int rc; int i; struct fs_dir_t dir; int file_ctr = 0; static char fname[MAX_PATH_LEN]; uint8_t to_log[] = "Text Log"; struct fs_dirent entry; fs_dir_t_init(&dir); sprintf(fname, "%s/%s0000", CONFIG_LOG_BACKEND_FS_DIR, log_prefix); zassert_equal(fs_stat(fname, &entry), 0, "Can not get file info."); /* Fill in log file over size limit. */ for (i = 0; i <= (CONFIG_LOG_BACKEND_FS_FILE_SIZE - entry.size) / sizeof(to_log); i++) { rc = write_log_to_file(to_log, sizeof(to_log), NULL); /* Written length not tracked here. */ ARG_UNUSED(rc); } zassert_equal(fs_stat(fname, &entry), 0, "Can not get file info."); size_t exp_size = CONFIG_LOG_BACKEND_FS_FILE_SIZE - (CONFIG_LOG_BACKEND_FS_FILE_SIZE - entry.size) % sizeof(to_log); zassert_equal(entry.size, exp_size, "Unexpected %s file size (%d B)", fname, entry.size); sprintf(fname, "%s/%s0001", CONFIG_LOG_BACKEND_FS_DIR, log_prefix); zassert_equal(fs_stat(fname, &entry), 0, "Can not get file info."); zassert_equal(entry.size, sizeof(to_log), "Unexpected %s file size (%d B)", fname, entry.size); rc = fs_opendir(&dir, CONFIG_LOG_BACKEND_FS_DIR); zassert_equal(rc, 0, "Can not open directory."); /* Count number of log files. */ while (rc >= 0) { struct fs_dirent ent = { 0 }; rc = fs_readdir(&dir, &ent); if ((rc < 0) || (ent.name[0] == 0)) { break; } if (strstr(ent.name, log_prefix) != NULL) { ++file_ctr; } } (void)fs_closedir(&dir); zassert_equal(file_ctr, 2, "File changing failed"); } ZTEST(test_log_backend_fs, test_log_fs_files_max) { int rc; int i; struct fs_dir_t dir; int file_ctr = 0; uint8_t to_log[] = "Text Log"; struct fs_dirent ent; uint32_t test_mask = 0; fs_dir_t_init(&dir); /* Fill in log files over files count limit. */ for (i = 0; i <= CONFIG_LOG_BACKEND_FS_FILE_SIZE / sizeof(to_log) * (CONFIG_LOG_BACKEND_FS_FILES_LIMIT - 1); i++) { rc = write_log_to_file(to_log, sizeof(to_log), NULL); /* Written length not tracked here. */ ARG_UNUSED(rc); } rc = fs_opendir(&dir, CONFIG_LOG_BACKEND_FS_DIR); zassert_equal(rc, 0, "Can not open directory."); /* Count log files. */ while (rc >= 0) { rc = fs_readdir(&dir, &ent); if ((rc < 0) || (ent.name[0] == 0)) { break; } if (strstr(ent.name, log_prefix) != NULL) { ++file_ctr; test_mask |= 1 << atoi(&ent.name[strlen(log_prefix)]); } } (void)fs_closedir(&dir); zassert_equal(file_ctr, CONFIG_LOG_BACKEND_FS_FILES_LIMIT, "Bad files count: expected %d, got %d ", CONFIG_LOG_BACKEND_FS_FILES_LIMIT, file_ctr); /*expected files: log.0001, log.0002, log.0003, log.0004 */ zassert_equal(test_mask, 0b11110, "Unexpected file numeration"); } ZTEST_SUITE(test_log_backend_fs, NULL, NULL, NULL, NULL, NULL);