tests/fs: NFFS has been replaced with Littlefs in multifs tests

With removal of NFFS from Zaphyr it would be no longer possible to
test multifs with NFFS and LittleFS will be now used instead.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
This commit is contained in:
Dominik Ermel 2020-01-16 12:28:37 +00:00 committed by Carles Cufí
commit 9c0fb144ee
29 changed files with 575 additions and 1717 deletions

View file

@ -1,8 +0,0 @@
tests:
filesystem.multifs:
platform_whitelist: qemu_x86
tags: nffs fatfs filesystem
filesystem.fs_shell:
extra_args: CONF_FILE="prj_fs_shell.conf"
platform_whitelist: qemu_x86
tags: nffs fatfs filesystem

View file

@ -1,11 +1,15 @@
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_LOG=y
CONFIG_FS_LITTLEFS_FC_MEM_POOL=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_DISK_ACCESS_RAM=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH=y
CONFIG_DISK_RAM_VOLUME_SIZE=80
CONFIG_TEST_FLASH_DRIVERS=y
CONFIG_HEAP_MEM_POOL_SIZE=1024
CONFIG_MAIN_STACK_SIZE=1024
CONFIG_ZTEST_STACKSIZE=2048
CONFIG_HEAP_MEM_POOL_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_ZTEST_STACKSIZE=4096
CONFIG_ZTEST=y

View file

@ -1,4 +1,8 @@
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_LOG=y
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=n
@ -7,8 +11,7 @@ CONFIG_SHELL_CMD_BUFF_SIZE=90
CONFIG_FILE_SYSTEM_SHELL=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_DISK_ACCESS_RAM=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH=y
CONFIG_DISK_RAM_VOLUME_SIZE=80
CONFIG_TEST_FLASH_DRIVERS=y
CONFIG_HEAP_MEM_POOL_SIZE=1024
CONFIG_MAIN_STACK_SIZE=1024

View file

@ -1,24 +0,0 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/delete-node/ &storage_partition;
&flash_sim0 {
/*
* For more information, see:
* http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions
*/
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
storage_partition: partition@0 {
label = "storage";
reg = <0x00000000 0x100000>;
};
};
};

View file

@ -1,21 +0,0 @@
/*
* Copyright (c) 2016 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "test_fat.h"
struct fs_file_t filep;
const char test_str[] = "hello world!";
int check_file_dir_exists(const char *path)
{
int res;
struct fs_dirent entry;
/* Verify fs_stat() */
res = fs_stat(path, &entry);
return !res;
}

View file

@ -4,65 +4,34 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include "test_common.h"
#include "test_fat.h"
#include "test_nffs.h"
#include "test_littlefs.h"
#include "test_fs_shell.h"
static struct nffs_area_desc nffs_selftest_area_descs[] = {
{ 0x00000000, 16 * 1024 },
{ 0x00004000, 16 * 1024 },
{ 0x00008000, 16 * 1024 },
{ 0x0000c000, 16 * 1024 },
{ 0x00010000, 64 * 1024 },
{ 0x00020000, 128 * 1024 },
{ 0x00040000, 128 * 1024 },
{ 0x00060000, 128 * 1024 },
{ 0x00080000, 128 * 1024 },
{ 0x000a0000, 128 * 1024 },
{ 0x000c0000, 128 * 1024 },
{ 0x000e0000, 128 * 1024 },
{ 0, 0 },
};
static struct nffs_area_desc *save_area_descs;
static void test_setup(void)
{
save_area_descs = nffs_current_area_descs;
nffs_current_area_descs = nffs_selftest_area_descs;
}
static void test_teardown(void)
{
nffs_current_area_descs = save_area_descs;
}
void test_main(void)
{
ztest_test_suite(multifs_fs_test,
ztest_unit_test(clear_flash),
ztest_unit_test(test_fat_mount),
ztest_unit_test_setup_teardown(test_nffs_mount,
test_setup, test_teardown),
ztest_unit_test(test_littlefs_mount),
ztest_unit_test(test_fat_mkdir),
ztest_unit_test_setup_teardown(test_nffs_mkdir,
test_setup, test_teardown),
ztest_unit_test(test_littlefs_mkdir),
ztest_unit_test(test_fat_readdir),
ztest_unit_test(test_littlefs_readdir),
ztest_unit_test(test_fat_rmdir),
ztest_unit_test_setup_teardown(test_nffs_readdir,
test_setup, test_teardown),
ztest_unit_test(test_littlefs_rmdir),
ztest_unit_test(test_fat_open),
ztest_unit_test_setup_teardown(test_nffs_open,
test_setup, test_teardown),
ztest_unit_test(test_littlefs_open),
ztest_unit_test(test_fat_write),
ztest_unit_test_setup_teardown(test_nffs_write,
test_setup, test_teardown),
ztest_unit_test(test_littlefs_write),
ztest_unit_test(test_fat_read),
ztest_unit_test(test_littlefs_read),
ztest_unit_test(test_fat_close),
ztest_unit_test_setup_teardown(test_nffs_read,
test_setup, test_teardown),
ztest_unit_test(test_littlefs_close),
ztest_unit_test(test_fat_unlink),
ztest_unit_test_setup_teardown(test_nffs_unlink,
test_setup, test_teardown),
ztest_unit_test(test_littlefs_unlink),
ztest_unit_test(test_fs_help));
ztest_run_test_suite(multifs_fs_test);
}

View file

@ -1,662 +0,0 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <fs/fs.h>
#include <nffs/queue.h>
#include <nffs/nffs.h>
#include <nffs/os.h>
#include <drivers/flash.h>
#include <ztest_assert.h>
#include "nffs_test_utils.h"
/*
* This should fit the largest area used in test (128K).
*/
#define AREA_BUF_MAX_SIZE (128 * 1024)
static u8_t area_buf[AREA_BUF_MAX_SIZE];
#define NFFS_TEST_BUF_SIZE (24 * 1024)
u8_t nffs_test_buf[NFFS_TEST_BUF_SIZE];
void nffs_test_util_overwrite_data(u8_t *data, u32_t data_len,
u32_t addr)
{
struct device *dev;
struct flash_pages_info info;
off_t off;
/*dev = device_get_binding();*/
flash_get_page_info_by_offs(dev, addr, &info);
nffs_os_flash_read(0, info.start_offset, area_buf, info.size);
/*
* To make this simpler, assume we always overwrite within sector
* boundary (which is the case here).
*/
off = addr - info.start_offset;
memcpy(&area_buf[off], data, data_len);
nffs_os_flash_erase(0, info.start_offset, info.size);
nffs_os_flash_write(0, info.start_offset, area_buf, info.size);
}
void nffs_test_util_assert_ent_name(struct fs_dirent *fs_dirent,
const char *expected_name)
{
zassert_equal(strcmp(fs_dirent->name, expected_name), 0, NULL);
}
void nffs_test_util_assert_file_len(struct nffs_file *file, u32_t expected)
{
uint32_t len;
int rc;
rc = nffs_inode_data_len(file->nf_inode_entry, &len);
zassert_equal(rc, 0, NULL);
zassert_equal(len, expected, NULL);
}
void nffs_test_util_assert_cache_is_sane(const char *filename)
{
struct nffs_cache_inode *cache_inode;
struct nffs_cache_block *cache_block;
struct nffs_file *file;
struct fs_file_t fs_file;
uint32_t cache_start;
uint32_t cache_end;
u32_t block_end;
int rc;
rc = fs_open(&fs_file, filename);
zassert_equal(rc, 0, NULL);
file = fs_file.filep;
rc = nffs_cache_inode_ensure(&cache_inode, file->nf_inode_entry);
zassert_equal(rc, 0, NULL);
nffs_cache_inode_range(cache_inode, &cache_start, &cache_end);
if (TAILQ_EMPTY(&cache_inode->nci_block_list)) {
zassert_equal(cache_start, 0, NULL);
zassert_equal(cache_end, 0, NULL);
} else {
block_end = 0U; /* Pacify gcc. */
TAILQ_FOREACH(cache_block, &cache_inode->nci_block_list,
ncb_link) {
if (cache_block ==
TAILQ_FIRST(&cache_inode->nci_block_list)) {
zassert_equal(cache_block->ncb_file_offset,
cache_start, NULL);
} else {
/* Ensure no gap between this block and its
* predecessor.
*/
zassert_equal(cache_block->ncb_file_offset,
block_end, NULL);
}
block_end = cache_block->ncb_file_offset +
cache_block->ncb_block.nb_data_len;
if (cache_block ==
TAILQ_LAST(&cache_inode->nci_block_list,
nffs_cache_block_list)) {
zassert_equal(block_end, cache_end, NULL);
}
}
}
rc = fs_close(&fs_file);
zassert_equal(rc, 0, NULL);
}
void
nffs_test_util_assert_contents(const char *filename, const char *contents,
int contents_len)
{
struct fs_file_t file;
u32_t bytes_read;
void *buf;
int rc;
rc = fs_open(&file, filename);
zassert_equal(rc, 0, NULL);
zassert_true(contents_len <= AREA_BUF_MAX_SIZE, "contents too large");
buf = area_buf;
bytes_read = fs_read(&file, buf, contents_len);
zassert_equal(bytes_read, contents_len, NULL);
zassert_equal(memcmp(buf, contents, contents_len), 0, NULL);
rc = fs_close(&file);
zassert_equal(rc, 0, NULL);
nffs_test_util_assert_cache_is_sane(filename);
}
int nffs_test_util_block_count(const char *filename)
{
struct nffs_hash_entry *entry;
struct nffs_block block;
struct nffs_file *file;
struct fs_file_t fs_file;
int count;
int rc;
rc = fs_open(&fs_file, filename);
zassert_equal(rc, 0, NULL);
file = fs_file.filep;
count = 0;
entry = file->nf_inode_entry->nie_last_block_entry;
while (entry != NULL) {
count++;
rc = nffs_block_from_hash_entry(&block, entry);
zassert_equal(rc, 0, NULL);
zassert_not_equal(block.nb_prev, entry, NULL);
entry = block.nb_prev;
}
rc = fs_close(&fs_file);
zassert_equal(rc, 0, NULL);
return count;
}
void nffs_test_util_assert_block_count(const char *filename, int expected_count)
{
int actual_count;
actual_count = nffs_test_util_block_count(filename);
zassert_equal(actual_count, expected_count, NULL);
}
void nffs_test_util_assert_cache_range(const char *filename,
u32_t expected_cache_start,
u32_t expected_cache_end)
{
struct nffs_cache_inode *cache_inode;
struct nffs_file *file;
struct fs_file_t fs_file;
uint32_t cache_start;
uint32_t cache_end;
int rc;
rc = fs_open(&fs_file, filename);
zassert_equal(rc, 0, NULL);
file = fs_file.filep;
rc = nffs_cache_inode_ensure(&cache_inode, file->nf_inode_entry);
zassert_equal(rc, 0, NULL);
nffs_cache_inode_range(cache_inode, &cache_start, &cache_end);
zassert_equal(cache_start, expected_cache_start, NULL);
zassert_equal(cache_end, expected_cache_end, NULL);
rc = fs_close(&fs_file);
zassert_equal(rc, 0, NULL);
nffs_test_util_assert_cache_is_sane(filename);
}
void nffs_test_util_create_file_blocks(const char *filename,
const struct nffs_test_block_desc *blks,
int num_blocks)
{
struct fs_file_t file;
u32_t total_len;
u32_t offset;
char *buf;
int num_writes;
int rc;
int i;
/* We do not have 'truncate' flag in fs_open, so unlink here instead */
rc = fs_unlink(filename);
/* Don't fail on -ENOENT or 0, as can't truncate as file doesn't exists
* or 0 on successful, fail on all other error values
*/
zassert_true(((rc == 0) || (rc == -ENOENT)), "unlink/truncate failed");
rc = fs_open(&file, filename);
zassert_equal(rc, 0, NULL);
total_len = 0U;
if (num_blocks <= 0) {
num_writes = 1;
} else {
num_writes = num_blocks;
}
for (i = 0; i < num_writes; i++) {
rc = fs_write(&file, blks[i].data, blks[i].data_len);
zassert_equal(rc, blks[i].data_len, NULL);
total_len += blks[i].data_len;
}
rc = fs_close(&file);
zassert_equal(rc, 0, NULL);
zassert_true(total_len <= AREA_BUF_MAX_SIZE, "contents too large");
buf = area_buf;
offset = 0U;
for (i = 0; i < num_writes; i++) {
memcpy(buf + offset, blks[i].data, blks[i].data_len);
offset += blks[i].data_len;
}
zassert_equal(offset, total_len, NULL);
nffs_test_util_assert_contents(filename, buf, total_len);
if (num_blocks > 0) {
nffs_test_util_assert_block_count(filename, num_blocks);
}
}
void nffs_test_util_create_file(const char *filename, const char *contents,
int contents_len)
{
struct nffs_test_block_desc block;
block.data = contents;
block.data_len = contents_len;
nffs_test_util_create_file_blocks(filename, &block, 0);
}
void nffs_test_util_append_file(const char *filename, const char *contents,
int contents_len)
{
struct fs_file_t file;
int rc;
rc = fs_open(&file, filename);
zassert_equal(rc, 0, NULL);
rc = fs_seek(&file, 0, FS_SEEK_END);
zassert_equal(rc, 0, NULL);
rc = fs_write(&file, contents, contents_len);
zassert_equal(rc, contents_len, NULL);
rc = fs_close(&file);
zassert_equal(rc, 0, NULL);
}
void nffs_test_copy_area(const struct nffs_area_desc *from,
const struct nffs_area_desc *to)
{
int rc;
void *buf;
zassert_equal(from->nad_length, to->nad_length, NULL);
zassert_true(from->nad_length <= AREA_BUF_MAX_SIZE, "area too large");
buf = area_buf;
rc = nffs_os_flash_read(from->nad_flash_id, from->nad_offset, buf,
from->nad_length);
zassert_equal(rc, 0, NULL);
rc = nffs_os_flash_erase(from->nad_flash_id, to->nad_offset,
to->nad_length);
zassert_equal(rc, 0, NULL);
rc = nffs_os_flash_write(to->nad_flash_id, to->nad_offset, buf,
to->nad_length);
zassert_equal(rc, 0, NULL);
}
void nffs_test_util_create_subtree(const char *parent_path,
const struct nffs_test_file_desc *elem)
{
char *path;
int rc;
int i;
if (parent_path == NULL) {
path = k_malloc(1);
zassert_not_null(path, NULL);
path[0] = '\0';
} else {
path = k_malloc(strlen(parent_path) +
strlen(elem->filename) + 2);
zassert_not_null(path, NULL);
sprintf(path, "%s/%s", parent_path, elem->filename);
}
if (elem->is_dir) {
if ((parent_path != NULL) &&
(strlen(parent_path) > strlen(NFFS_MNTP))) {
rc = fs_mkdir(path);
zassert_equal(rc, 0, NULL);
}
if (elem->children != NULL) {
for (i = 0; elem->children[i].filename != NULL; i++) {
nffs_test_util_create_subtree(path,
elem->children + i);
}
}
} else {
nffs_test_util_create_file(path, elem->contents,
elem->contents_len);
}
k_free(path);
}
void nffs_test_util_create_tree(const struct nffs_test_file_desc *root_dir)
{
nffs_test_util_create_subtree(NFFS_MNTP, root_dir);
}
#define NFFS_TEST_TOUCHED_ARR_SZ (16 * 64)
/*#define NFFS_TEST_TOUCHED_ARR_SZ (16 * 1024)*/
struct nffs_hash_entry
*nffs_test_touched_entries[NFFS_TEST_TOUCHED_ARR_SZ];
int nffs_test_num_touched_entries;
/* Recursively descend directory structure */
void nffs_test_assert_file(const struct nffs_test_file_desc *file,
struct nffs_inode_entry *inode_entry,
const char *path)
{
const struct nffs_test_file_desc *child_file;
struct nffs_inode inode;
struct nffs_inode_entry *child_inode_entry;
char *child_path, *abs_path;
int child_filename_len;
int path_len;
int rc;
/*
* track of hash entries that have been examined
*/
zassert_true(nffs_test_num_touched_entries < NFFS_TEST_TOUCHED_ARR_SZ,
NULL);
nffs_test_touched_entries[nffs_test_num_touched_entries] =
&inode_entry->nie_hash_entry;
nffs_test_num_touched_entries++;
path_len = strlen(path);
rc = nffs_inode_from_entry(&inode, inode_entry);
zassert_equal(rc, 0, NULL);
/* recursively examine each child of directory */
if (nffs_hash_id_is_dir(inode_entry->nie_hash_entry.nhe_id)) {
for (child_file = file->children;
child_file != NULL && child_file->filename != NULL;
child_file++) {
/*
* Construct full pathname for file
* Not null terminated
*/
child_filename_len = strlen(child_file->filename);
child_path = k_malloc(path_len +
child_filename_len + 2);
zassert_not_null(child_path, NULL);
memcpy(child_path, path, path_len);
child_path[path_len] = '/';
memcpy(child_path + path_len + 1, child_file->filename,
child_filename_len);
child_path[path_len + 1 + child_filename_len] = '\0';
/*
* Verify child inode can be found using full pathname
*/
rc = nffs_path_find_inode_entry(child_path,
&child_inode_entry);
zassert_equal(rc, 0, NULL);
nffs_test_assert_file(child_file, child_inode_entry,
child_path);
k_free(child_path);
}
} else {
abs_path = k_malloc(strlen(NFFS_MNTP) + path_len + 2);
sprintf(abs_path, "%s%s", NFFS_MNTP, path);
nffs_test_util_assert_contents(abs_path, file->contents,
file->contents_len);
k_free(abs_path);
}
}
void nffs_test_assert_branch_touched(struct nffs_inode_entry *inode_entry)
{
struct nffs_inode_entry *child;
int i;
if (inode_entry == nffs_lost_found_dir) {
return;
}
for (i = 0; i < nffs_test_num_touched_entries; i++) {
if (nffs_test_touched_entries[i] ==
&inode_entry->nie_hash_entry) {
break;
}
}
zassert_true(i < nffs_test_num_touched_entries, NULL);
nffs_test_touched_entries[i] = NULL;
if (nffs_hash_id_is_dir(inode_entry->nie_hash_entry.nhe_id)) {
SLIST_FOREACH(child, &inode_entry->nie_child_list,
nie_sibling_next) {
nffs_test_assert_branch_touched(child);
}
}
}
void nffs_test_assert_child_inode_present(struct nffs_inode_entry *child)
{
const struct nffs_inode_entry *inode_entry;
const struct nffs_inode_entry *parent;
struct nffs_inode inode;
int rc;
/*
* Successfully read inode data from flash
*/
rc = nffs_inode_from_entry(&inode, child);
zassert_equal(rc, 0, NULL);
/*
* Validate parent
*/
parent = inode.ni_parent;
zassert_not_null(parent, NULL);
zassert_true(nffs_hash_id_is_dir(parent->nie_hash_entry.nhe_id), NULL);
/*
* Make sure inode is in parents child list
*/
SLIST_FOREACH(inode_entry, &parent->nie_child_list, nie_sibling_next) {
if (inode_entry == child) {
return;
}
}
zassert_true(0, NULL);
}
void nffs_test_assert_block_present(struct nffs_hash_entry *block_entry)
{
const struct nffs_inode_entry *inode_entry;
struct nffs_hash_entry *cur;
struct nffs_block block;
int rc;
/*
* Successfully read block data from flash
*/
rc = nffs_block_from_hash_entry(&block, block_entry);
zassert_equal(rc, 0, NULL);
/*
* Validate owning inode
*/
inode_entry = block.nb_inode_entry;
zassert_not_null(inode_entry, NULL);
zassert_true(nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id),
NULL);
/*
* Validate that block is in owning inode's block chain
*/
cur = inode_entry->nie_last_block_entry;
while (cur != NULL) {
if (cur == block_entry) {
return;
}
rc = nffs_block_from_hash_entry(&block, cur);
zassert_equal(rc, 0, NULL);
cur = block.nb_prev;
}
zassert_true(0, NULL);
}
/*
* Recursively verify that the children of each directory are sorted
* on the directory children linked list by filename length
*/
void nffs_test_assert_children_sorted(struct nffs_inode_entry *inode_entry)
{
struct nffs_inode_entry *child_entry;
struct nffs_inode_entry *prev_entry;
struct nffs_inode child_inode;
struct nffs_inode prev_inode;
int cmp;
int rc;
prev_entry = NULL;
SLIST_FOREACH(child_entry, &inode_entry->nie_child_list,
nie_sibling_next) {
rc = nffs_inode_from_entry(&child_inode, child_entry);
zassert_equal(rc, 0, NULL);
if (prev_entry != NULL) {
rc = nffs_inode_from_entry(&prev_inode, prev_entry);
zassert_equal(rc, 0, NULL);
rc = nffs_inode_filename_cmp_flash(&prev_inode,
&child_inode, &cmp);
zassert_equal(rc, 0, NULL);
zassert_true(cmp < 0, NULL);
}
if (nffs_hash_id_is_dir(child_entry->nie_hash_entry.nhe_id)) {
nffs_test_assert_children_sorted(child_entry);
}
prev_entry = child_entry;
}
}
void nffs_test_assert_system_once(const struct nffs_test_file_desc *root_dir)
{
struct nffs_inode_entry *inode_entry;
struct nffs_hash_entry *entry;
struct nffs_hash_entry *next;
int i;
nffs_test_num_touched_entries = 0;
nffs_test_assert_file(root_dir, nffs_root_dir, "");
nffs_test_assert_branch_touched(nffs_root_dir);
/* Ensure no orphaned inodes or blocks. */
NFFS_HASH_FOREACH(entry, i, next) {
zassert_true(entry->nhe_flash_loc != NFFS_FLASH_LOC_NONE, NULL);
if (nffs_hash_id_is_inode(entry->nhe_id)) {
inode_entry = (void *)entry;
zassert_equal(inode_entry->nie_refcnt, 1, NULL);
if (entry->nhe_id == NFFS_ID_ROOT_DIR) {
zassert_true(inode_entry == nffs_root_dir,
NULL);
} else {
nffs_test_assert_child_inode_present(
inode_entry);
}
} else {
nffs_test_assert_block_present(entry);
}
}
/* Ensure proper sorting. */
nffs_test_assert_children_sorted(nffs_root_dir);
}
void nffs_test_assert_system(const struct nffs_test_file_desc *root_dir,
const struct nffs_area_desc *area_descs)
{
int rc;
/* Ensure files are as specified, and that there are no other files or
* orphaned inodes / blocks.
*/
nffs_test_assert_system_once(root_dir);
/* Force a garbage collection cycle. */
rc = nffs_gc(NULL);
zassert_equal(rc, 0, NULL);
/* Ensure file system is still as expected. */
nffs_test_assert_system_once(root_dir);
/* Clear cached data and restore from flash (i.e, simulate a reboot). */
rc = nffs_misc_reset();
zassert_equal(rc, 0, NULL);
rc = nffs_restore_full(area_descs);
zassert_equal(rc, 0, NULL);
/* Ensure file system is still as expected. */
nffs_test_assert_system_once(root_dir);
}
void nffs_test_assert_area_seqs(int seq1, int count1, int seq2, int count2)
{
struct nffs_disk_area disk_area;
int cur1;
int cur2;
int rc;
int i;
cur1 = 0;
cur2 = 0;
for (i = 0; i < nffs_num_areas; i++) {
rc = nffs_flash_read(i, 0, &disk_area, sizeof(disk_area));
zassert_equal(rc, 0, NULL);
zassert_true(nffs_area_magic_is_set(&disk_area), NULL);
zassert_equal(disk_area.nda_gc_seq, nffs_areas[i].na_gc_seq,
NULL);
if (i == nffs_scratch_area_idx) {
zassert_equal(disk_area.nda_id, NFFS_AREA_ID_NONE,
NULL);
}
if (nffs_areas[i].na_gc_seq == seq1) {
cur1++;
} else if (nffs_areas[i].na_gc_seq == seq2) {
cur2++;
} else {
zassert_true(0, NULL);
}
}
zassert_equal(cur1, count1, NULL);
zassert_equal(cur2, count2, NULL);
}

View file

@ -1,88 +0,0 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef H_NFFS_TEST_UTILS_
#define H_NFFS_TEST_UTILS_
#include <zephyr/types.h>
#include <nffs/nffs.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NFFS_MNTP "/nffs"
extern struct nffs_area_desc *nffs_default_area_descs;
struct nffs_test_block_desc {
const char *data;
int data_len;
};
struct nffs_test_file_desc {
const char *filename;
int is_dir;
const char *contents;
int contents_len;
struct nffs_test_file_desc *children;
};
extern int nffs_test_num_touched_entries;
extern int flash_native_memset(u32_t offset, uint8_t c, u32_t len);
extern u8_t nffs_test_buf[];
void nffs_test_util_overwrite_data(u8_t *data, u32_t data_len, u32_t addr);
void nffs_test_util_assert_ent_name(struct fs_dirent *dirent,
const char *expected_name);
void nffs_test_util_assert_file_len(struct nffs_file *file, u32_t expected);
void nffs_test_util_assert_cache_is_sane(const char *filename);
void nffs_test_util_assert_contents(const char *filename,
const char *contents, int contents_len);
int nffs_test_util_block_count(const char *filename);
void nffs_test_util_assert_block_count(const char *filename,
int expected_count);
void nffs_test_util_assert_cache_range(const char *filename,
u32_t expected_cache_start,
u32_t expected_cache_end);
void nffs_test_util_create_file_blocks(const char *filename,
const struct nffs_test_block_desc *blks,
int num_blocks);
void nffs_test_util_create_file(const char *filename, const char *contents,
int contents_len);
void nffs_test_util_append_file(const char *filename, const char *contents,
int contents_len);
void nffs_test_copy_area(const struct nffs_area_desc *from,
const struct nffs_area_desc *to);
void nffs_test_util_create_subtree(const char *parent_path,
const struct nffs_test_file_desc *elem);
void nffs_test_util_create_tree(const struct nffs_test_file_desc *root_dir);
/*
* Recursively descend directory structure
*/
void nffs_test_assert_file(const struct nffs_test_file_desc *file,
struct nffs_inode_entry *inode_entry,
const char *path);
void nffs_test_assert_branch_touched(struct nffs_inode_entry *inode_entry);
void nffs_test_assert_child_inode_present(struct nffs_inode_entry *child);
void nffs_test_assert_block_present(struct nffs_hash_entry *block_entry);
/*
* Recursively verify that the children of each directory are sorted
* on the directory children linked list by filename length
*/
void nffs_test_assert_children_sorted(struct nffs_inode_entry *inode_entry);
void nffs_test_assert_system_once(const struct nffs_test_file_desc *root_dir);
void nffs_test_assert_system(const struct nffs_test_file_desc *root_dir,
const struct nffs_area_desc *area_descs);
void nffs_test_assert_area_seqs(int seq1, int count1, int seq2, int count2);
#ifdef __cplusplus
}
#endif
#endif /* H_NFFS_TEST_UTILS_ */

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include <fs/fs.h>
#include <limits.h>
void clear_flash(void);
int check_file_dir_exists(const char *fpath);
int test_file_open(struct fs_file_t *filep, const char *fpath);
int test_file_write(struct fs_file_t *filep, const char *str);
int test_file_read(struct fs_file_t *filep, const char *test_str);
int test_file_close(struct fs_file_t *filep);
int test_file_delete(const char *fpath);
int test_rmdir(const char *dir_path);
int test_mkdir(const char *dir_path, const char *file);
int test_lsdir(const char *path);

View file

@ -0,0 +1,157 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include <stdio.h>
#include <limits.h>
#include <assert.h>
#include <fs/fs.h>
#include "test_common.h"
int test_rmdir(const char *dir_path);
int test_mkdir(const char *dir_path, const char *file)
{
int res;
struct fs_file_t filep;
char file_path[PATH_MAX] = { 0 };
res = sprintf(file_path, "%s/%s", dir_path, file);
assert(res < sizeof(file_path));
if (check_file_dir_exists(dir_path)) {
TC_PRINT("[%s] exists, delete it\n", dir_path);
if (test_rmdir(dir_path)) {
TC_PRINT("Error deleting dir %s\n", dir_path);
return TC_FAIL;
}
} else {
TC_PRINT("Creating new dir %s\n", dir_path);
}
/* Verify fs_mkdir() */
res = fs_mkdir(dir_path);
if (res) {
TC_PRINT("Error creating dir[%d]\n", res);
return res;
}
res = fs_open(&filep, file_path);
if (res) {
TC_PRINT("Failed opening file [%d]\n", res);
return res;
}
TC_PRINT("Testing write to file %s\n", file_path);
res = test_file_write(&filep, "NOTHING");
if (res) {
return res;
}
res = fs_close(&filep);
if (res) {
TC_PRINT("Error closing file [%d]\n", res);
return res;
}
TC_PRINT("Created dir %s!\n", dir_path);
return res;
}
int test_lsdir(const char *path)
{
int res;
struct fs_dir_t dirp;
struct fs_dirent entry;
TC_PRINT("\nlsdir tests:\n");
/* Verify fs_opendir() */
res = fs_opendir(&dirp, path);
if (res) {
TC_PRINT("Error opening dir %s [%d]\n", path, res);
return res;
}
TC_PRINT("\nListing dir %s:\n", path);
for (;;) {
/* Verify fs_readdir() */
res = fs_readdir(&dirp, &entry);
/* entry.name[0] == 0 means end-of-dir */
if (res || entry.name[0] == 0) {
break;
}
if (entry.type == FS_DIR_ENTRY_DIR) {
TC_PRINT("[DIR ] %s\n", entry.name);
} else {
TC_PRINT("[FILE] %s (size = %zu)\n",
entry.name, entry.size);
}
}
/* Verify fs_closedir() */
fs_closedir(&dirp);
return res;
}
int test_rmdir(const char *dir_path)
{
int res;
struct fs_dir_t dirp;
static struct fs_dirent entry;
if (!check_file_dir_exists(dir_path)) {
TC_PRINT("%s doesn't exist\n", dir_path);
return TC_FAIL;
}
res = fs_opendir(&dirp, dir_path);
if (res) {
TC_PRINT("Error opening dir[%d]\n", res);
return res;
}
TC_PRINT("\nRemoving files and sub directories in %s\n", dir_path);
for (;;) {
char file_path[PATH_MAX] = { 0 };
res = fs_readdir(&dirp, &entry);
/* entry.name[0] == 0 means end-of-dir */
if (res || entry.name[0] == 0) {
break;
}
/* Delete file or sub directory */
sprintf(file_path, "%s/%s", dir_path, entry.name);
assert(res < sizeof(file_path));
TC_PRINT("Removing %s\n", file_path);
res = fs_unlink(file_path);
if (res) {
TC_PRINT("Error deleting file/dir [%d]\n", res);
fs_closedir(&dirp);
return res;
}
}
fs_closedir(&dirp);
/* Verify fs_unlink() */
res = fs_unlink(dir_path);
if (res) {
TC_PRINT("Error removing dir [%d]\n", res);
return res;
}
TC_PRINT("Removed dir %s!\n", dir_path);
return res;
}

View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include <string.h>
#include <fs/fs.h>
#include "test_common.h"
int test_file_open(struct fs_file_t *filep, const char *file_path)
{
int res;
TC_PRINT("\nOpen tests:\n");
if (check_file_dir_exists(file_path)) {
TC_PRINT("Opening existing file %s\n", file_path);
} else {
TC_PRINT("Creating new file %s\n", file_path);
}
/* Verify fs_open() */
res = fs_open(filep, file_path);
if (res) {
TC_PRINT("Failed opening file [%d]\n", res);
return res;
}
TC_PRINT("Opened file %s\n", file_path);
return res;
}
int test_file_write(struct fs_file_t *filep, const char *test_str)
{
ssize_t brw;
int res;
TC_PRINT("\nWrite tests:\n");
/* Verify fs_seek() */
res = fs_seek(filep, 0, FS_SEEK_SET);
if (res) {
TC_PRINT("fs_seek failed [%d]\n", res);
fs_close(filep);
return res;
}
TC_PRINT("Data written:\"%s\"\n\n", test_str);
/* Verify fs_write() */
brw = fs_write(filep, (char *)test_str, strlen(test_str));
if (brw < 0) {
TC_PRINT("Failed writing to file [%zd]\n", brw);
fs_close(filep);
return brw;
}
if (brw < strlen(test_str)) {
TC_PRINT("Unable to complete write. Volume full.\n");
TC_PRINT("Number of bytes written: [%zd]\n", brw);
fs_close(filep);
return TC_FAIL;
}
TC_PRINT("Data successfully written!\n");
return res;
}
int test_file_read(struct fs_file_t *filep, const char *test_str)
{
ssize_t brw;
int res;
char read_buff[80];
size_t sz = strlen(test_str);
TC_PRINT("\nRead tests:\n");
res = fs_seek(filep, 0, FS_SEEK_SET);
if (res) {
TC_PRINT("fs_seek failed [%d]\n", res);
fs_close(filep);
return res;
}
/* Verify fs_read() */
brw = fs_read(filep, read_buff, sz);
if (brw < 0) {
TC_PRINT("Failed reading file [%zd]\n", brw);
fs_close(filep);
return brw;
}
read_buff[brw] = 0;
TC_PRINT("Data read:\"%s\"\n\n", read_buff);
if (strcmp(test_str, read_buff)) {
TC_PRINT("Error - Data read does not match data written\n");
TC_PRINT("Data read:\"%s\"\n\n", read_buff);
return TC_FAIL;
}
TC_PRINT("Data read matches data written\n");
return res;
}
int test_file_close(struct fs_file_t *filep)
{
int res;
TC_PRINT("\nClose tests:\n");
res = fs_close(filep);
if (res) {
TC_PRINT("Error closing file [%d]\n", res);
return res;
}
return res;
}
int test_file_delete(const char *file_path)
{
int res;
TC_PRINT("\nDelete tests:\n");
/* Verify fs_unlink() */
res = fs_unlink(file_path);
if (res) {
TC_PRINT("Error deleting file [%d]\n", res);
return res;
}
/* Check if file was deleted */
if (check_file_dir_exists(file_path)) {
TC_PRINT("Failed deleting %s\n", file_path);
return TC_FAIL;
}
TC_PRINT("File (%s) deleted successfully!\n", file_path);
return res;
}

View file

@ -3,21 +3,6 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <ztest.h>
#include <fs/fs.h>
#define FATFS_MNTP "/RAM:"
#define TEST_FILE FATFS_MNTP"/testfile.txt"
#define TEST_DIR FATFS_MNTP"/testdir"
#define TEST_DIR_FILE FATFS_MNTP"/testdir/testfile.txt"
extern struct fs_file_t filep;
extern const char test_str[];
int check_file_dir_exists(const char *path);
void test_fat_mount(void);
void test_fat_open(void);
void test_fat_write(void);

View file

@ -4,163 +4,24 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "test_fat.h"
#include <stdio.h>
#include <fs/fs.h>
#include "test_common.h"
#include "test_fat.h"
#include "test_fat_priv.h"
extern int test_file_write(void);
extern int test_file_close(void);
static int test_rmdir(void);
static int test_mkdir(void)
{
int res;
TC_PRINT("\nmkdir tests:\n");
if (check_file_dir_exists(TEST_DIR)) {
TC_PRINT("[%s] exists, delete it\n", TEST_DIR);
if (test_rmdir()) {
TC_PRINT("Error deleting dir %s\n", TEST_DIR);
return TC_FAIL;
}
} else {
TC_PRINT("Creating new dir %s\n", TEST_DIR);
}
/* Verify fs_mkdir() */
res = fs_mkdir(TEST_DIR);
if (res) {
TC_PRINT("Error creating dir[%d]\n", res);
return res;
}
res = fs_open(&filep, TEST_DIR_FILE);
if (res) {
TC_PRINT("Failed opening file [%d]\n", res);
return res;
}
res = test_file_write();
if (res) {
return res;
}
res = fs_close(&filep);
if (res) {
TC_PRINT("Error closing file [%d]\n", res);
return res;
}
TC_PRINT("Created dir %s!\n", TEST_DIR);
return res;
}
static int test_lsdir(const char *path)
{
int res;
struct fs_dir_t dirp;
struct fs_dirent entry;
TC_PRINT("\nlsdir tests:\n");
/* Verify fs_opendir() */
res = fs_opendir(&dirp, path);
if (res) {
TC_PRINT("Error opening dir %s [%d]\n", path, res);
return res;
}
TC_PRINT("\nListing dir %s:\n", path);
for (;;) {
/* Verify fs_readdir() */
res = fs_readdir(&dirp, &entry);
/* entry.name[0] == 0 means end-of-dir */
if (res || entry.name[0] == 0) {
break;
}
if (entry.type == FS_DIR_ENTRY_DIR) {
TC_PRINT("[DIR ] %s\n", entry.name);
} else {
TC_PRINT("[FILE] %s (size = %zu)\n",
entry.name, entry.size);
}
}
/* Verify fs_closedir() */
fs_closedir(&dirp);
return res;
}
static int test_rmdir(void)
{
int res;
struct fs_dir_t dirp;
static struct fs_dirent entry;
char file_path[80];
TC_PRINT("\nrmdir tests:\n");
if (!check_file_dir_exists(TEST_DIR)) {
TC_PRINT("%s doesn't exist\n", TEST_DIR);
return TC_FAIL;
}
res = fs_opendir(&dirp, TEST_DIR);
if (res) {
TC_PRINT("Error opening dir[%d]\n", res);
return res;
}
TC_PRINT("\nRemoving files and sub directories in %s\n", TEST_DIR);
for (;;) {
res = fs_readdir(&dirp, &entry);
/* entry.name[0] == 0 means end-of-dir */
if (res || entry.name[0] == 0) {
break;
}
/* Delete file or sub directory */
sprintf(file_path, "%s/%s", TEST_DIR, entry.name);
TC_PRINT("Removing %s\n", file_path);
res = fs_unlink(file_path);
if (res) {
TC_PRINT("Error deleting file/dir [%d]\n", res);
fs_closedir(&dirp);
return res;
}
}
fs_closedir(&dirp);
/* Verify fs_unlink() */
res = fs_unlink(TEST_DIR);
if (res) {
TC_PRINT("Error removing dir [%d]\n", res);
return res;
}
TC_PRINT("Removed dir %s!\n", TEST_DIR);
return res;
}
void test_fat_mkdir(void)
{
zassert_true(test_mkdir() == TC_PASS, NULL);
zassert_true(test_mkdir(TEST_DIR_PATH, TEST_FILE) == TC_PASS, NULL);
}
void test_fat_readdir(void)
{
zassert_true(test_lsdir(FATFS_MNTP) == TC_PASS, NULL);
zassert_true(test_lsdir(TEST_DIR_PATH) == TC_PASS, NULL);
}
void test_fat_rmdir(void)
{
zassert_true(test_rmdir() == TC_PASS, NULL);
zassert_true(test_rmdir(TEST_DIR_PATH) == TC_PASS, NULL);
}

View file

@ -4,170 +4,37 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <fs/fs.h>
#include "test_common.h"
#include "test_fat.h"
#include <string.h>
#include "test_fat_priv.h"
static int test_file_open(void)
{
int res;
TC_PRINT("\nOpen tests:\n");
if (check_file_dir_exists(TEST_FILE)) {
TC_PRINT("Opening existing file %s\n", TEST_FILE);
} else {
TC_PRINT("Creating new file %s\n", TEST_FILE);
}
/* Verify fs_open() */
res = fs_open(&filep, TEST_FILE);
if (res) {
TC_PRINT("Failed opening file [%d]\n", res);
return res;
}
TC_PRINT("Opened file %s\n", TEST_FILE);
return res;
}
int test_file_write(void)
{
ssize_t brw;
int res;
TC_PRINT("\nWrite tests:\n");
/* Verify fs_seek() */
res = fs_seek(&filep, 0, FS_SEEK_SET);
if (res) {
TC_PRINT("fs_seek failed [%d]\n", res);
fs_close(&filep);
return res;
}
TC_PRINT("Data written:\"%s\"\n\n", test_str);
/* Verify fs_write() */
brw = fs_write(&filep, (char *)test_str, strlen(test_str));
if (brw < 0) {
TC_PRINT("Failed writing to file [%zd]\n", brw);
fs_close(&filep);
return brw;
}
if (brw < strlen(test_str)) {
TC_PRINT("Unable to complete write. Volume full.\n");
TC_PRINT("Number of bytes written: [%zd]\n", brw);
fs_close(&filep);
return TC_FAIL;
}
TC_PRINT("Data successfully written!\n");
return res;
}
static int test_file_read(void)
{
ssize_t brw;
int res;
char read_buff[80];
size_t sz = strlen(test_str);
TC_PRINT("\nRead tests:\n");
res = fs_seek(&filep, 0, FS_SEEK_SET);
if (res) {
TC_PRINT("fs_seek failed [%d]\n", res);
fs_close(&filep);
return res;
}
/* Verify fs_read() */
brw = fs_read(&filep, read_buff, sz);
if (brw < 0) {
TC_PRINT("Failed reading file [%zd]\n", brw);
fs_close(&filep);
return brw;
}
read_buff[brw] = 0;
TC_PRINT("Data read:\"%s\"\n\n", read_buff);
if (strcmp(test_str, read_buff)) {
TC_PRINT("Error - Data read does not match data written\n");
TC_PRINT("Data read:\"%s\"\n\n", read_buff);
return TC_FAIL;
}
TC_PRINT("Data read matches data written\n");
return res;
}
static int test_file_close(void)
{
int res;
TC_PRINT("\nClose tests:\n");
res = fs_close(&filep);
if (res) {
TC_PRINT("Error closing file [%d]\n", res);
return res;
}
TC_PRINT("Closed file %s\n", TEST_FILE);
return res;
}
static int test_file_delete(void)
{
int res;
TC_PRINT("\nDelete tests:\n");
/* Verify fs_unlink() */
res = fs_unlink(TEST_FILE);
if (res) {
TC_PRINT("Error deleting file [%d]\n", res);
return res;
}
/* Check if file was deleted */
if (check_file_dir_exists(TEST_FILE)) {
TC_PRINT("Failed deleting %s\n", TEST_FILE);
return TC_FAIL;
}
TC_PRINT("File (%s) deleted successfully!\n", TEST_FILE);
return res;
}
static struct fs_file_t test_file;
static const char *test_str = "Hello world FAT";
void test_fat_open(void)
{
zassert_true(test_file_open() == TC_PASS, NULL);
zassert_true(test_file_open(&test_file, TEST_FILE_PATH) == TC_PASS,
NULL);
}
void test_fat_write(void)
{
zassert_true(test_file_write() == TC_PASS, NULL);
TC_PRINT("Write to file %s\n", TEST_FILE_PATH);
zassert_true(test_file_write(&test_file, test_str) == TC_PASS,
NULL);
}
void test_fat_read(void)
{
zassert_true(test_file_read() == TC_PASS, NULL);
zassert_true(test_file_read(&test_file, test_str) == TC_PASS, NULL);
}
void test_fat_close(void)
{
zassert_true(test_file_close() == TC_PASS, NULL);
zassert_true(test_file_close(&test_file) == TC_PASS, NULL);
}
void test_fat_unlink(void)
{
zassert_true(test_file_delete() == TC_PASS, NULL);
zassert_true(test_file_delete(TEST_FILE_PATH) == TC_PASS, NULL);
}

View file

@ -6,7 +6,10 @@
#include "test_fat.h"
#include <ff.h>
#include "test_common.h"
#include "test_fs_shell.h"
#include "test_fat.h"
#include "test_fat_priv.h"
/* for mount using FS api */
#if !defined(CONFIG_FILE_SYSTEM_SHELL)

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2020 Nordic Seminconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#define FATFS_MNTP "/RAM:"
#define TEST_FILE "testfile.txt"
#define TEST_FILE_PATH FATFS_MNTP"/"TEST_FILE
#define TEST_DIR_PATH FATFS_MNTP"/testdir"
#define TEST_DIR_FILE_PATH TEST_DIR"/testfile.txt"

View file

@ -32,7 +32,7 @@ void test_fs_help(void)
test_shell_exec("help", 0);
test_shell_exec("help fs", 0);
test_shell_exec("fs mount fat", -EINVAL);
test_shell_exec("fs mount nffs", -EINVAL);
test_shell_exec("fs mount littlefs", -EINVAL);
#else
ztest_test_skip();
#endif
@ -42,7 +42,7 @@ void test_fs_fat_mount(void)
{
test_shell_exec("fs mount fat /RAM:", 0);
}
void test_fs_nffs_mount(void)
void test_fs_littlefs_mount(void)
{
test_shell_exec("fs mount nffs /nffs", 0);
test_shell_exec("fs mount littlefs /littlefs", 0);
}

View file

@ -8,5 +8,5 @@
void test_fs_help(void);
void test_fs_fat_mount(void);
void test_fs_nffs_mount(void);
void test_fs_littlefs_mount(void);
void test_fs_shell_exit(void);

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
void test_littlefs_mount(void);
void test_littlefs_open(void);
void test_littlefs_write(void);
void test_littlefs_read(void);
void test_littlefs_close(void);
void test_littlefs_unlink(void);
void test_littlefs_mkdir(void);
void test_littlefs_readdir(void);
void test_littlefs_rmdir(void);

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <fs/fs.h>
#include "test_common.h"
#include "test_littlefs.h"
#include "test_littlefs_priv.h"
void test_littlefs_mkdir(void)
{
zassert_true(test_mkdir(TEST_DIR_PATH, TEST_FILE) == TC_PASS, NULL);
}
void test_littlefs_readdir(void)
{
zassert_true(test_lsdir(TEST_DIR_PATH) == TC_PASS, NULL);
}
void test_littlefs_rmdir(void)
{
zassert_true(test_rmdir(TEST_DIR_PATH) == TC_PASS, NULL);
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <fs/fs.h>
#include "test_common.h"
#include "test_littlefs.h"
#include "test_littlefs_priv.h"
static struct fs_file_t test_file;
static const char *test_str = "Hello world LITTLEFS";
void test_littlefs_open(void)
{
zassert_true(test_file_open(&test_file, TEST_FILE_PATH) == TC_PASS,
NULL);
}
void test_littlefs_write(void)
{
TC_PRINT("Write to file %s\n", TEST_FILE_PATH);
zassert_true(test_file_write(&test_file, test_str) == TC_PASS,
NULL);
}
void test_littlefs_read(void)
{
zassert_true(test_file_read(&test_file, test_str) == TC_PASS, NULL);
}
void test_littlefs_close(void)
{
zassert_true(test_file_close(&test_file) == TC_PASS, NULL);
}
void test_littlefs_unlink(void)
{
zassert_true(test_file_delete(TEST_FILE_PATH) == TC_PASS, NULL);
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <device.h>
#include <fs/fs.h>
#include <ztest.h>
#include <fs/littlefs.h>
#include "test_fs_shell.h"
#if !defined(CONFIG_FILE_SYSTEM_SHELL)
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
struct fs_mount_t littlefs_mnt = {
.type = FS_LITTLEFS,
.fs_data = &storage,
.storage_dev = (void *)DT_FLASH_AREA_STORAGE_ID,
.mnt_point = "/littlefs"
};
static int test_mount(void)
{
int res;
res = fs_mount(&littlefs_mnt);
if (res < 0) {
TC_PRINT("Error mounting littlefs [%d]\n", res);
return TC_FAIL;
}
return TC_PASS;
}
#endif
void test_littlefs_mount(void)
{
#ifdef CONFIG_FILE_SYSTEM_SHELL
test_fs_littlefs_mount();
#else
zassert_true(test_mount() == TC_PASS, NULL);
#endif
}

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LFS_MNTP "/littlefs"
#define TEST_FILE "testfile.txt"
#define TEST_FILE_PATH LFS_MNTP"/"TEST_FILE
#define TEST_DIR_PATH LFS_MNTP"/testdir"
#define TEST_DIR_FILE_PATH TEST_DIR"/testfile.txt"

View file

@ -1,18 +0,0 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <ztest.h>
#include <fs/fs.h>
#include <nffs/nffs.h>
void test_nffs_mount(void);
void test_nffs_mkdir(void);
void test_nffs_readdir(void);
void test_nffs_unlink(void);
void test_nffs_open(void);
void test_nffs_write(void);
void test_nffs_read(void);

View file

@ -1,161 +0,0 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <fs/fs.h>
#include <ztest.h>
#include <ztest_assert.h>
#include "nffs_test_utils.h"
void test_nffs_mkdir(void)
{
struct fs_file_t file;
int rc;
rc = nffs_format_full(nffs_current_area_descs);
zassert_equal(rc, 0, "cannot format nffs");
rc = fs_mkdir(NFFS_MNTP"/a");
zassert_equal(rc, 0, "cannot create directory");
rc = fs_open(&file, NFFS_MNTP"/a/myfile.txt");
zassert_equal(rc, 0, "cannot open file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
struct nffs_test_file_desc *expected_system =
(struct nffs_test_file_desc[]) { {
.filename = "",
.is_dir = 1,
.children = (struct nffs_test_file_desc[]) { {
.filename = "a",
.is_dir = 1,
.children = (struct nffs_test_file_desc[]) { {
.filename = "myfile.txt",
.contents = NULL,
.contents_len = 0,
}, {
.filename = NULL,
} },
}, {
.filename = NULL,
} },
} };
nffs_test_assert_system(expected_system, nffs_current_area_descs);
}
void test_nffs_readdir(void)
{
struct fs_dir_t dir;
struct fs_dirent dirent;
int rc;
/* Setup. */
rc = nffs_format_full(nffs_current_area_descs);
zassert_equal(rc, 0, "cannot format nffs");
rc = fs_mkdir(NFFS_MNTP"/mydir");
zassert_equal(rc, 0, "cannot create directory");
nffs_test_util_create_file(NFFS_MNTP"/mydir/b", "bbbb", 4);
nffs_test_util_create_file(NFFS_MNTP"/mydir/a", "aaaa", 4);
rc = fs_mkdir(NFFS_MNTP"/mydir/c");
zassert_equal(rc, 0, "cannot create directory");
/* Nonexistent directory. */
rc = fs_opendir(&dir, NFFS_MNTP"/asdf");
zassert_not_equal(rc, 0, "cannot open nonexistent directory");
/* Fail to opendir a file. */
rc = fs_opendir(&dir, NFFS_MNTP"/mydir/a");
zassert_not_equal(rc, 0, "cannot open directory");
/* Real directory (with trailing slash). */
rc = fs_opendir(&dir, NFFS_MNTP"/mydir/");
zassert_equal(rc, 0, "cannot open dir (trailing slash)");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
nffs_test_util_assert_ent_name(&dirent, "a");
zassert_equal(dirent.type == FS_DIR_ENTRY_DIR, 0,
"invalid directory name");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
nffs_test_util_assert_ent_name(&dirent, "b");
zassert_equal(dirent.type == FS_DIR_ENTRY_DIR, 0,
"invalid directory name");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
nffs_test_util_assert_ent_name(&dirent, "c");
zassert_equal(dirent.type != FS_DIR_ENTRY_DIR, 0,
"invalid directory name");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
rc = fs_closedir(&dir);
zassert_equal(rc, 0, "cannot close directory");
/* Root directory. */
rc = fs_opendir(&dir, NFFS_MNTP"/");
zassert_equal(rc, 0, "cannot open root directory");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read root directory");
nffs_test_util_assert_ent_name(&dirent, "lost+found");
zassert_equal(dirent.type == FS_DIR_ENTRY_DIR, 1, "no lost+found");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
nffs_test_util_assert_ent_name(&dirent, "mydir");
zassert_equal(dirent.type != FS_DIR_ENTRY_DIR, 0,
"no mydir directory");
rc = fs_closedir(&dir);
zassert_equal(rc, 0, "cannot close directory");
/* Delete entries while iterating. */
rc = fs_opendir(&dir, NFFS_MNTP"/mydir");
zassert_equal(rc, 0, "cannot open directory");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
nffs_test_util_assert_ent_name(&dirent, "a");
zassert_equal(dirent.type == FS_DIR_ENTRY_DIR, 0,
"invalid directory name");
rc = fs_unlink(NFFS_MNTP"/mydir/b");
zassert_equal(rc, 0, "cannot delete mydir");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
rc = fs_unlink(NFFS_MNTP"/mydir/c");
zassert_equal(rc, 0, "cannot delete lower directory");
rc = fs_unlink(NFFS_MNTP"/mydir");
zassert_equal(rc, 0, "cannot delete mydir directory");
nffs_test_util_assert_ent_name(&dirent, "c");
zassert_equal(dirent.type == FS_DIR_ENTRY_DIR, 1,
"invalid directory name");
rc = fs_readdir(&dir, &dirent);
zassert_equal(rc, 0, "cannot read directory");
rc = fs_closedir(&dir);
zassert_equal(rc, 0, "cannot close directory");
/* Ensure directory is gone. */
rc = fs_opendir(&dir, NFFS_MNTP"/mydir");
zassert_not_equal(rc, 0, "directory is still present");
}

View file

@ -1,316 +0,0 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <fs/fs.h>
#include <ztest.h>
#include <ztest_assert.h>
#include "nffs_test_utils.h"
extern struct k_mem_slab nffs_block_entry_pool;
extern struct k_mem_slab nffs_inode_entry_pool;
void test_nffs_open(void)
{
struct fs_file_t file;
struct fs_dir_t dir;
int rc;
rc = nffs_format_full(nffs_current_area_descs);
zassert_equal(rc, 0, "cannot format nffs");
/*** Fail to open an invalid path (not rooted). */
rc = fs_open(&file, "file");
zassert_equal(rc, -EINVAL, "failed to detect invalid path");
/*** Fail to open a directory (root directory). */
rc = fs_open(&file, "/");
zassert_equal(rc, -EINVAL, "failed to detect invalid directory");
/*** Fail to open a child of a nonexistent directory. */
rc = fs_open(&file, "/dir/myfile.txt");
zassert_equal(rc, -ENOENT, "failed to detect nonexistent directory");
rc = fs_opendir(&dir, "/dir");
zassert_equal(rc, -ENOENT, "failed to detect nonexistent directory");
rc = fs_mkdir(NFFS_MNTP"/dir");
zassert_equal(rc, 0, "failed to open directory");
/*** Fail to open a directory. */
rc = fs_open(&file, NFFS_MNTP"/dir");
zassert_equal(rc, -EINVAL, "failed to open a directory");
/*** Successfully open an existing file for reading. */
nffs_test_util_create_file(NFFS_MNTP"/dir/file.txt", "1234567890", 10);
rc = fs_open(&file, NFFS_MNTP"/dir/file.txt");
zassert_equal(rc, 0, "failed to open a file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
/*** Successfully open an nonexistent file for writing. */
rc = fs_open(&file, NFFS_MNTP"/dir/file2.txt");
zassert_equal(rc, 0, "cannot open nonexistent file for writing");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
/*** Ensure the file can be reopened. */
rc = fs_open(&file, NFFS_MNTP"/dir/file.txt");
zassert_equal(rc, 0, "cannot reopen file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close reopened file");
}
void test_nffs_read(void)
{
u8_t buf[16];
struct fs_file_t file;
int rc;
rc = nffs_format_full(nffs_current_area_descs);
zassert_equal(rc, 0, "cannot format nffs");
nffs_test_util_create_file(NFFS_MNTP"/myfile.txt", "1234567890", 10);
rc = fs_open(&file, NFFS_MNTP"/myfile.txt");
zassert_equal(rc, 0, "cannot open file");
nffs_test_util_assert_file_len(file.filep, 10);
zassert_equal(fs_tell(&file), 0, "invalid pos in file");
rc = fs_read(&file, &buf, 4);
zassert_equal(rc, 4, "invalid bytes read");
zassert_equal(memcmp(buf, "1234", 4), 0, "invalid buffer size");
zassert_equal(fs_tell(&file), 4, "invalid pos in file");
rc = fs_read(&file, buf + 4, sizeof(buf) - 4);
zassert_equal(rc, 6, "invalid bytes read");
zassert_equal(memcmp(buf, "1234567890", 10), 0, "invalid buffer size");
zassert_equal(fs_tell(&file), 10, "invalid pos in file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
}
void test_nffs_write(void)
{
struct fs_file_t file;
struct nffs_file *nffs_file;
int rc;
/*** Setup. */
rc = nffs_format_full(nffs_current_area_descs);
zassert_equal(rc, 0, "cannot format nffs");
nffs_test_util_append_file(NFFS_MNTP"/myfile.txt", "abcdefgh", 8);
/*** Overwrite within one block (middle). */
rc = fs_open(&file, NFFS_MNTP"/myfile.txt");
nffs_file = file.filep;
zassert_equal(rc, 0, "cannot open file");
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 0, "invalid pos in file");
rc = fs_seek(&file, 3, FS_SEEK_SET);
zassert_equal(rc, 0, "cannot set pos in file");
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 3, "invalid pos in file");
rc = fs_write(&file, "12", 2);
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 5, "cannot get pos in file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
nffs_test_util_assert_contents(NFFS_MNTP"/myfile.txt", "abc12fgh", 8);
nffs_test_util_assert_block_count(NFFS_MNTP"/myfile.txt", 1);
/*** Overwrite within one block (start). */
rc = fs_open(&file, NFFS_MNTP"/myfile.txt");
zassert_equal(rc, 0, "cannot open file");
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 0, "invalid pos in file");
rc = fs_write(&file, "xy", 2);
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 2, "invalid pos in file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
nffs_test_util_assert_contents(NFFS_MNTP"/myfile.txt", "xyc12fgh", 8);
nffs_test_util_assert_block_count(NFFS_MNTP"/myfile.txt", 1);
/*** Overwrite within one block (end). */
rc = fs_open(&file, NFFS_MNTP"/myfile.txt");
zassert_equal(rc, 0, "cannot open file");
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 0, "invalid pos in file");
rc = fs_seek(&file, 6, FS_SEEK_SET);
zassert_equal(rc, 0, "cannot set pos in file");
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 6, "invalid pos in file");
rc = fs_write(&file, "<>", 2);
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 8, "invalid pos in file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
nffs_test_util_assert_contents(NFFS_MNTP"/myfile.txt", "xyc12f<>", 8);
nffs_test_util_assert_block_count(NFFS_MNTP"/myfile.txt", 1);
/*** Overwrite one block middle, extend. */
rc = fs_open(&file, NFFS_MNTP"/myfile.txt");
zassert_equal(rc, 0, "cannot open file");
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 0, "invalid pos in file");
rc = fs_seek(&file, 4, FS_SEEK_SET);
zassert_equal(rc, 0, "cannot set pos in file");
nffs_test_util_assert_file_len(nffs_file, 8);
zassert_equal(fs_tell(&file), 4, "invalid pos in file");
rc = fs_write(&file, "abcdefgh", 8);
nffs_test_util_assert_file_len(nffs_file, 12);
zassert_equal(fs_tell(&file), 12, "invalid pos in file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
nffs_test_util_assert_contents(NFFS_MNTP"/myfile.txt",
"xyc1abcdefgh", 12);
nffs_test_util_assert_block_count(NFFS_MNTP"/myfile.txt", 1);
/*** Overwrite one block start, extend. */
rc = fs_open(&file, NFFS_MNTP"/myfile.txt");
zassert_equal(rc, 0, "cannot open file");
nffs_test_util_assert_file_len(nffs_file, 12);
zassert_equal(fs_tell(&file), 0, "invalid pos in file");
rc = fs_write(&file, "abcdefghijklmnop", 16);
nffs_test_util_assert_file_len(nffs_file, 16);
zassert_equal(fs_tell(&file), 16, "invalid pos in file");
rc = fs_close(&file);
zassert_equal(rc, 0, "cannot close file");
nffs_test_util_assert_contents(NFFS_MNTP"/myfile.txt",
"abcdefghijklmnop", 16);
nffs_test_util_assert_block_count(NFFS_MNTP"/myfile.txt", 1);
struct nffs_test_file_desc *expected_system =
(struct nffs_test_file_desc[]) { {
.filename = "",
.is_dir = 1,
.children = (struct nffs_test_file_desc[]) { {
.filename = "myfile.txt",
.contents = "abcdefghijklmnop",
.contents_len = 16,
}, {
.filename = NULL,
} },
} };
nffs_test_assert_system(expected_system, nffs_current_area_descs);
}
void test_nffs_unlink(void)
{
struct fs_dirent file_stats;
struct fs_file_t file0, file1;
u8_t buf[64];
struct nffs_file *nffs_file;
u32_t bytes_read;
int initial_num_blocks;
int initial_num_inodes;
int rc;
rc = nffs_format_full(nffs_current_area_descs);
zassert_equal(rc, 0, "cannot format nffs");
initial_num_blocks = k_mem_slab_num_free_get(&nffs_block_entry_pool);
initial_num_inodes = k_mem_slab_num_free_get(&nffs_inode_entry_pool);
nffs_test_util_create_file(NFFS_MNTP"/file0.txt", "0", 1);
rc = fs_open(&file0, NFFS_MNTP"/file0.txt");
zassert_equal(rc, 0, "cannot open file");
nffs_file = file0.filep;
zassert_equal(nffs_file->nf_inode_entry->nie_refcnt, 2, "inode error");
rc = fs_unlink(NFFS_MNTP"/file0.txt");
zassert_equal(rc, 0, "");
zassert_equal(nffs_file->nf_inode_entry->nie_refcnt, 1, "inode error");
rc = fs_stat(NFFS_MNTP"/file0.txt", &file_stats);
zassert_not_equal(rc, 0, "no such file");
rc = fs_write(&file0, "00", 2);
rc = fs_seek(&file0, 0, FS_SEEK_SET);
zassert_equal(rc, 0, "cannot set pos in file");
bytes_read = fs_read(&file0, buf, sizeof(buf));
zassert_equal(bytes_read, 2, "invalid bytes read");
zassert_equal(memcmp(buf, "00", 2), 0, "invalid buffer size");
rc = fs_close(&file0);
zassert_equal(rc, 0, "cannot close file");
rc = fs_stat(NFFS_MNTP"/file0.txt", &file_stats);
zassert_not_equal(rc, 0, "no such file");
/* Ensure the file was fully removed from RAM. */
zassert_equal(k_mem_slab_num_free_get(&nffs_inode_entry_pool),
initial_num_inodes, "file not remove entirely");
zassert_equal(k_mem_slab_num_free_get(&nffs_block_entry_pool),
initial_num_blocks, "file not remove entirely");
/*** Nested unlink. */
rc = fs_mkdir(NFFS_MNTP"/mydir");
zassert_equal(rc, 0, "cannot make directory");
nffs_test_util_create_file(NFFS_MNTP"/mydir/file1.txt", "1", 2);
rc = fs_open(&file1, NFFS_MNTP"/mydir/file1.txt");
zassert_equal(rc, 0, "cannot open file");
nffs_file = file1.filep;
zassert_equal(nffs_file->nf_inode_entry->nie_refcnt, 2, "inode error");
rc = fs_unlink(NFFS_MNTP"/mydir");
zassert_equal(rc, 0, "cannot delete directory");
zassert_equal(nffs_file->nf_inode_entry->nie_refcnt, 1, "inode error");
rc = fs_stat(NFFS_MNTP"/mydir/file1.txt", &file_stats);
zassert_not_equal(rc, 0, "unlink failed");
rc = fs_write(&file1, "11", 2);
rc = fs_seek(&file1, 0, FS_SEEK_SET);
zassert_equal(rc, 0, "cannot set pos in file");
bytes_read = fs_read(&file1, buf, sizeof(buf));
zassert_equal(bytes_read, 2, "invalid bytes read");
zassert_equal(memcmp(buf, "11", 2), 0, "invalid buffer size");
rc = fs_close(&file1);
zassert_equal(rc, 0, "cannot close file");
rc = fs_stat(NFFS_MNTP"/mydir/file1.txt", &file_stats);
zassert_not_equal(rc, 0, "unlink failed");
struct nffs_test_file_desc *expected_system =
(struct nffs_test_file_desc[]) { {
.filename = "",
.is_dir = 1,
} };
nffs_test_assert_system(expected_system, nffs_current_area_descs);
/* Ensure the files and directories were fully removed from RAM. */
zassert_equal(k_mem_slab_num_free_get(&nffs_inode_entry_pool),
initial_num_inodes, "not all removed from RAM");
zassert_equal(k_mem_slab_num_free_get(&nffs_block_entry_pool),
initial_num_blocks, "not all removed from RAM");
}

View file

@ -1,57 +0,0 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <device.h>
#include <fs/fs.h>
#include <ztest.h>
#include <ztest_assert.h>
#include "nffs_test_utils.h"
#include "test_fs_shell.h"
#if !defined(CONFIG_FILE_SYSTEM_SHELL)
/* NFFS work area strcut */
static struct nffs_flash_desc flash_desc;
/* mounting info */
static struct fs_mount_t nffs_mnt = {
.type = FS_NFFS,
.mnt_point = "/nffs",
.fs_data = &flash_desc,
};
static int test_mount(void)
{
struct device *flash_dev;
int res;
/*flash_dev = device_get_binding();*/
if (!flash_dev) {
return -ENODEV;
}
/* set backend storage dev */
nffs_mnt.storage_dev = flash_dev;
res = fs_mount(&nffs_mnt);
if (res < 0) {
TC_PRINT("Error mounting nffs [%d]\n", res);
return TC_FAIL;
}
return TC_PASS;
}
#endif
void test_nffs_mount(void)
{
#ifdef CONFIG_FILE_SYSTEM_SHELL
test_fs_nffs_mount();
#else
zassert_true(test_mount() == TC_PASS, NULL);
#endif
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <limits.h>
#include <device.h>
#include <fs/fs.h>
#include <ztest.h>
#include <storage/flash_map.h>
int check_file_dir_exists(const char *fpath)
{
int res;
struct fs_dirent entry;
res = fs_stat(fpath, &entry);
return !res;
}
void clear_flash(void)
{
int rc;
const struct flash_area *fap;
rc = flash_area_open(DT_FLASH_AREA_STORAGE_ID, &fap);
zassert_equal(rc, 0, "Opening flash area for erase [%d]\n", rc);
rc = flash_area_erase(fap, 0, fap->fa_size);
zassert_equal(rc, 0, "Erasing flash area [%d]\n", rc);
}

View file

@ -0,0 +1,8 @@
tests:
filesystem.multifs:
platform_whitelist: native_posix qemu_x86
tags: littlefs fatfs filesystem qemu_x86
filesystem.fs_shell:
extra_args: CONF_FILE="prj_fs_shell.conf"
platform_whitelist: native_posix qemu_x86
tags: littlefs fatfs filesystem