blob: 9c4e05449677a07c349559901080f256383b5538 [file] [log] [blame]
/*
* Copyright (c) 2019 Peter Bigot Consulting, LLC
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Basic littlefs operations:
* * create
* * write
* * stat
* * read
* * seek
* * tell
* * truncate
* * unlink
* * sync
*/
#include <string.h>
#include <zephyr/ztest.h>
#include "testfs_tests.h"
#include "testfs_lfs.h"
#include <lfs.h>
#include <zephyr/fs/littlefs.h>
static int mount(struct fs_mount_t *mp)
{
TC_PRINT("mounting %s\n", mp->mnt_point);
zassert_equal(fs_mount(mp), 0,
"mount failed");
return TC_PASS;
}
static int clear_partition(struct fs_mount_t *mp)
{
TC_PRINT("clearing partition %s\n", mp->mnt_point);
zassert_equal(testfs_lfs_wipe_partition(mp),
TC_PASS,
"failed to wipe partition");
return TC_PASS;
}
static int clean_statvfs(const struct fs_mount_t *mp)
{
struct fs_statvfs stat;
TC_PRINT("checking clean statvfs of %s\n", mp->mnt_point);
zassert_equal(fs_statvfs(mp->mnt_point, &stat), 0,
"statvfs failed");
TC_PRINT("%s: bsize %lu ; frsize %lu ; blocks %lu ; bfree %lu\n",
mp->mnt_point,
stat.f_bsize, stat.f_frsize, stat.f_blocks, stat.f_bfree);
zassert_equal(stat.f_bsize, 16,
"bsize fail");
zassert_equal(stat.f_frsize, 4096,
"frsize fail");
zassert_equal(stat.f_blocks, 16,
"blocks fail");
zassert_equal(stat.f_bfree, stat.f_blocks - 2U,
"bfree fail");
return TC_PASS;
}
static int check_medium(void)
{
struct fs_mount_t *mp = &testfs_medium_mnt;
struct fs_statvfs stat;
zassert_equal(clear_partition(mp), TC_PASS,
"clear partition failed");
zassert_equal(fs_mount(mp), 0,
"medium mount failed");
zassert_equal(fs_statvfs(mp->mnt_point, &stat), 0,
"statvfs failed");
TC_PRINT("%s: bsize %lu ; frsize %lu ; blocks %lu ; bfree %lu\n",
mp->mnt_point,
stat.f_bsize, stat.f_frsize, stat.f_blocks, stat.f_bfree);
zassert_equal(stat.f_bsize, MEDIUM_IO_SIZE,
"bsize fail");
zassert_equal(stat.f_frsize, 4096,
"frsize fail");
zassert_equal(stat.f_blocks, 240,
"blocks fail");
zassert_equal(stat.f_bfree, stat.f_blocks - 2U,
"bfree fail");
zassert_equal(fs_unmount(mp), 0,
"medium unmount failed");
return TC_PASS;
}
static int check_large(void)
{
struct fs_mount_t *mp = &testfs_large_mnt;
struct fs_statvfs stat;
zassert_equal(clear_partition(mp), TC_PASS,
"clear partition failed");
zassert_equal(fs_mount(mp), 0,
"large mount failed");
zassert_equal(fs_statvfs(mp->mnt_point, &stat), 0,
"statvfs failed");
TC_PRINT("%s: bsize %lu ; frsize %lu ; blocks %lu ; bfree %lu\n",
mp->mnt_point,
stat.f_bsize, stat.f_frsize, stat.f_blocks, stat.f_bfree);
zassert_equal(stat.f_bsize, LARGE_IO_SIZE,
"bsize fail");
zassert_equal(stat.f_frsize, 32768,
"frsize fail");
zassert_equal(stat.f_blocks, 96,
"blocks fail");
zassert_equal(stat.f_bfree, stat.f_blocks - 2U,
"bfree fail");
zassert_equal(fs_unmount(mp), 0,
"large unmount failed");
return TC_PASS;
}
static int num_files(struct fs_mount_t *mp)
{
struct testfs_path path;
char name[2] = { 0 };
const char *pstr;
struct fs_file_t files[CONFIG_FS_LITTLEFS_NUM_FILES];
size_t fi = 0;
int rc;
memset(files, 0, sizeof(files));
TC_PRINT("CONFIG_FS_LITTLEFS_NUM_FILES=%u\n", CONFIG_FS_LITTLEFS_NUM_FILES);
while (fi < ARRAY_SIZE(files)) {
struct fs_file_t *const file = &files[fi];
name[0] = 'A' + fi;
pstr = testfs_path_init(&path, mp,
name,
TESTFS_PATH_END);
TC_PRINT("opening %s\n", pstr);
rc = fs_open(file, pstr, FS_O_CREATE | FS_O_RDWR);
zassert_equal(rc, 0, "open %s failed: %d", pstr, rc);
rc = testfs_write_incrementing(file, 0, TESTFS_BUFFER_SIZE);
zassert_equal(rc, TESTFS_BUFFER_SIZE, "write %s failed: %d", pstr, rc);
++fi;
}
while (fi-- != 0) {
struct fs_file_t *const file = &files[fi];
name[0] = 'A' + fi;
pstr = testfs_path_init(&path, mp,
name,
TESTFS_PATH_END);
TC_PRINT("Close and unlink %s\n", pstr);
rc = fs_close(file);
zassert_equal(rc, 0, "close %s failed: %d", pstr, rc);
rc = fs_unlink(pstr);
zassert_equal(rc, 0, "unlink %s failed: %d", pstr, rc);
}
return TC_PASS;
}
static int num_dirs(struct fs_mount_t *mp)
{
struct testfs_path path;
char name[3] = "Dx";
const char *pstr;
struct fs_dir_t dirs[CONFIG_FS_LITTLEFS_NUM_DIRS];
size_t di = 0;
int rc;
memset(dirs, 0, sizeof(dirs));
TC_PRINT("CONFIG_FS_LITTLEFS_NUM_DIRS=%u\n", CONFIG_FS_LITTLEFS_NUM_DIRS);
while (di < ARRAY_SIZE(dirs)) {
struct fs_dir_t *const dir = &dirs[di];
name[1] = 'A' + di;
pstr = testfs_path_init(&path, mp,
name,
TESTFS_PATH_END);
TC_PRINT("making and opening directory %s\n", pstr);
rc = fs_mkdir(pstr);
zassert_equal(rc, 0, "mkdir %s failed: %d", pstr, rc);
rc = fs_opendir(dir, pstr);
zassert_equal(rc, 0, "opendir %s failed: %d", name, rc);
++di;
}
while (di-- != 0) {
struct fs_dir_t *const dir = &dirs[di];
name[1] = 'A' + di;
pstr = testfs_path_init(&path, mp,
name,
TESTFS_PATH_END);
TC_PRINT("Close and rmdir %s\n", pstr);
rc = fs_closedir(dir);
zassert_equal(rc, 0, "closedir %s failed: %d", name, rc);
rc = fs_unlink(pstr);
zassert_equal(rc, 0, "unlink %s failed: %d", name, rc);
}
return TC_PASS;
}
void test_fs_basic(void);
/* Mount structure needed by test_fs_basic tests. */
struct fs_mount_t *fs_basic_test_mp = &testfs_small_mnt;
ZTEST(littlefs, test_lfs_basic)
{
struct fs_mount_t *mp = &testfs_small_mnt;
zassert_equal(clear_partition(mp), TC_PASS,
"clear partition failed");
/* Common basic tests.
* (File system is mounted and unmounted during that test.)
*/
test_fs_basic();
/* LittleFS specific tests */
zassert_equal(mount(mp), TC_PASS,
"clean mount failed");
zassert_equal(clean_statvfs(mp), TC_PASS,
"clean statvfs failed");
zassert_equal(num_files(mp), TC_PASS,
"num_files failed");
zassert_equal(num_dirs(mp), TC_PASS,
"num_dirs failed");
TC_PRINT("unmounting %s\n", mp->mnt_point);
zassert_equal(fs_unmount(mp), 0,
"unmount small failed");
if (IS_ENABLED(CONFIG_APP_TEST_CUSTOM)) {
zassert_equal(check_medium(), TC_PASS,
"check medium failed");
zassert_equal(check_large(), TC_PASS,
"check large failed");
}
}