tests: add filesystem api test
This commit verifies below FS APIs: fs_open() fs_close() fs_read() fs_write() fs_truncate() fs_seek() fs_tell() fs_sync() fs_unlink() fs_mkdir() fs_opendir() fs_closedir() fs_readdir() fs_stat() fs_statvfs() Change-Id: I1a48b9e960b62a1c4986cc577f658199da7a28cd Signed-off-by: Qiu Peiyang <peiyangx.qiu@intel.com>
This commit is contained in:
parent
4e5fa0ede2
commit
8a119a4319
13 changed files with 621 additions and 555 deletions
|
@ -1 +0,0 @@
|
|||
obj-y += main.o
|
|
@ -1,520 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <misc/printk.h>
|
||||
#include <fs.h>
|
||||
|
||||
static void file_tests(void);
|
||||
static void dir_tests(void);
|
||||
static void vol_tests(void);
|
||||
|
||||
#define TEST_SUB_DIR "sub1"
|
||||
#define TEST_FILE "testfile.txt"
|
||||
|
||||
/*
|
||||
* @file
|
||||
* @brief File system demo
|
||||
* Demonstrates the ZEPHYR File System APIs
|
||||
*/
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printk("File System Demo!\n\n");
|
||||
|
||||
file_tests();
|
||||
dir_tests();
|
||||
vol_tests();
|
||||
}
|
||||
|
||||
static int check_file_dir_exists(const char *path)
|
||||
{
|
||||
int res;
|
||||
struct fs_dirent entry;
|
||||
|
||||
res = fs_stat(path, &entry);
|
||||
|
||||
return !res;
|
||||
}
|
||||
|
||||
static int open_file(fs_file_t *fp, const char *path)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (check_file_dir_exists(path)) {
|
||||
printk("Opening existing file %s\n", path);
|
||||
} else {
|
||||
printk("Creating new file %s\n", path);
|
||||
}
|
||||
|
||||
res = fs_open(fp, path);
|
||||
if (res) {
|
||||
printk("Failed opening file [%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
printk("Opened file %s\n", path);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static const char test_str[] = "hello world!";
|
||||
|
||||
static int write_test(fs_file_t *fp, off_t ofs, const char *str)
|
||||
{
|
||||
ssize_t brw;
|
||||
int res;
|
||||
|
||||
res = fs_seek(fp, ofs, FS_SEEK_SET);
|
||||
if (res) {
|
||||
printk("fs_seek failed [%d]\n", res);
|
||||
fs_close(fp);
|
||||
return res;
|
||||
}
|
||||
|
||||
brw = fs_write(fp, (char *)str, strlen(str));
|
||||
if (brw < 0) {
|
||||
printk("Failed writing to file [%zd]\n", brw);
|
||||
fs_close(fp);
|
||||
return brw;
|
||||
}
|
||||
if (brw < strlen(str)) {
|
||||
printk("Unable to complete write. Volume full.\n");
|
||||
printk("Number of bytes written: [%zd]\n", brw);
|
||||
fs_close(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("Data successfully written!\n");
|
||||
printk("Data written:\"%s\"\n\n", str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int read_test(fs_file_t *fp, off_t ofs, size_t sz, char *read_buff)
|
||||
{
|
||||
ssize_t brw;
|
||||
int res;
|
||||
|
||||
res = fs_seek(fp, ofs, FS_SEEK_SET);
|
||||
if (res) {
|
||||
printk("fs_seek failed [%d]\n", res);
|
||||
fs_close(fp);
|
||||
return res;
|
||||
}
|
||||
|
||||
brw = fs_read(fp, read_buff, sz);
|
||||
if (brw < 0) {
|
||||
printk("Failed reading file [%zd]\n", brw);
|
||||
fs_close(fp);
|
||||
return brw;
|
||||
}
|
||||
|
||||
printk("Data successfully read!\n");
|
||||
read_buff[brw] = 0;
|
||||
printk("Data read:\"%s\"\n\n", read_buff);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int close_file(fs_file_t *fp, const char *path)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = fs_close(fp);
|
||||
if (res) {
|
||||
printk("Error closing file [%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
printk("Closed file %s\n", path);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int delete_test(const char *path)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* Delete the file and verify checking its status */
|
||||
res = fs_unlink(path);
|
||||
if (res) {
|
||||
printk("Error deleting file [%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Check if file was deleted */
|
||||
if (check_file_dir_exists(path)) {
|
||||
printk("Failed deleting %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("File (%s) deleted successfully!\n", path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int truncate_test(fs_file_t *fp)
|
||||
{
|
||||
int res;
|
||||
off_t pos;
|
||||
char read_buff[80];
|
||||
|
||||
printk("\nTruncate tests:\n");
|
||||
|
||||
/* Test truncating to 0 size */
|
||||
printk("Testing shrink to 0 size\n");
|
||||
res = fs_truncate(fp, 0);
|
||||
if (res) {
|
||||
printk("fs_truncate failed [%d]\n", res);
|
||||
fs_close(fp);
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(fp, 0, FS_SEEK_END);
|
||||
if (fs_tell(fp) > 0) {
|
||||
printk("Failed truncating to size 0\n");
|
||||
fs_close(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("Testing write after truncating\n");
|
||||
res = write_test(fp, 0, test_str);
|
||||
if (res) {
|
||||
printk("Write failed after truncating\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(fp, 0, FS_SEEK_END);
|
||||
pos = fs_tell(fp);
|
||||
|
||||
printk("Original size of file = %ld\n", pos);
|
||||
|
||||
/* Test shrinking */
|
||||
|
||||
res = fs_truncate(fp, pos - 5);
|
||||
if (res) {
|
||||
printk("fs_truncate failed [%d]\n", res);
|
||||
fs_close(fp);
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(fp, 0, FS_SEEK_END);
|
||||
printk("File size after shrinking by 5 bytes = %ld\n", fs_tell(fp));
|
||||
if (fs_tell(fp) != (pos - 5)) {
|
||||
printk("File size after fs_truncate not as expected\n");
|
||||
fs_close(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check original contents */
|
||||
|
||||
printk("Check original contents after shrinking file\n");
|
||||
res = read_test(fp, 0, strlen(test_str) - 5, read_buff);
|
||||
if (res) {
|
||||
printk("Read failed after truncating\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (strncmp(test_str, read_buff, strlen(test_str) - 5)) {
|
||||
printk("Data corruption after shrink\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test expanding file */
|
||||
|
||||
fs_seek(fp, 0, FS_SEEK_END);
|
||||
pos = fs_tell(fp);
|
||||
res = fs_truncate(fp, pos + 10);
|
||||
if (res) {
|
||||
printk("fs_truncate failed [%d]\n", res);
|
||||
fs_close(fp);
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(fp, 0, FS_SEEK_END);
|
||||
printk("File size after expanding by 10 bytes = %ld\n", fs_tell(fp));
|
||||
|
||||
if (fs_tell(fp) != (pos + 10)) {
|
||||
printk("File size after fs_truncate not as expected\n");
|
||||
fs_close(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check the original contents */
|
||||
|
||||
printk("Check original contents after expanding file\n");
|
||||
res = read_test(fp, 0, strlen(test_str) - 5, read_buff);
|
||||
if (res) {
|
||||
printk("Read failed after truncating\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (strncmp(test_str, read_buff, strlen(test_str) - 5)) {
|
||||
printk("Data corruption after expand\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if expanded regions are zeroed */
|
||||
|
||||
fs_seek(fp, -5, FS_SEEK_END);
|
||||
|
||||
printk("Testing for zeroes in expanded region\n");
|
||||
|
||||
ssize_t brw = fs_read(fp, read_buff, 5);
|
||||
|
||||
if (brw < 5) {
|
||||
printk("Read failed after truncating\n");
|
||||
fs_close(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (read_buff[i]) {
|
||||
printk("Expanded regions are not zeroed\n");
|
||||
fs_close(fp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void file_tests(void)
|
||||
{
|
||||
fs_file_t fp;
|
||||
int res;
|
||||
char read_buff[80];
|
||||
|
||||
res = open_file(&fp, TEST_FILE);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = write_test(&fp, 0, test_str);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = read_test(&fp, 0, strlen(test_str), read_buff);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(test_str, read_buff)) {
|
||||
printk("Error - Data read does not match data written\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Data read matches data written!\n");
|
||||
|
||||
res = truncate_test(&fp);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = close_file(&fp, TEST_FILE);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = delete_test(TEST_FILE);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int create_dir(const char *path)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = fs_mkdir(path);
|
||||
if (res) {
|
||||
printk("Error creating dir[%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
printk("Created dir %s!\n", path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deletes files and sub directories one level deep */
|
||||
static int remove_dir(const char *path)
|
||||
{
|
||||
int res;
|
||||
fs_dir_t dp;
|
||||
static struct fs_dirent entry;
|
||||
char file_path[80];
|
||||
|
||||
if (!check_file_dir_exists(path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = fs_opendir(&dp, path);
|
||||
if (res) {
|
||||
printk("Error opening dir[%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
printk("\nRemoving files and sub directories in %s\n", path);
|
||||
for (;;) {
|
||||
res = fs_readdir(&dp, &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", path, entry.name);
|
||||
printk("Removing %s\n", file_path);
|
||||
|
||||
res = fs_unlink(file_path);
|
||||
if (res) {
|
||||
printk("Error deleting file/dir [%d]\n", res);
|
||||
fs_closedir(&dp);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
fs_closedir(&dp);
|
||||
|
||||
/* Remove the sub directory */
|
||||
res = fs_unlink(path);
|
||||
if (res) {
|
||||
printk("Error removing dir [%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
printk("Removed dir %s!\n", path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int list_dir(const char *path)
|
||||
{
|
||||
int res;
|
||||
fs_dir_t dp;
|
||||
static struct fs_dirent entry;
|
||||
|
||||
res = fs_opendir(&dp, path);
|
||||
if (res) {
|
||||
printk("Error opening dir[%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
printk("\nListing dir %s:\n", path);
|
||||
for (;;) {
|
||||
res = fs_readdir(&dp, &entry);
|
||||
|
||||
/* entry.name[0] == 0 means end-of-dir */
|
||||
if (res || entry.name[0] == 0) {
|
||||
break;
|
||||
}
|
||||
if (entry.type == FS_DIR_ENTRY_DIR) {
|
||||
printk("[DIR ] %s\n", entry.name);
|
||||
} else {
|
||||
printk("[FILE] %s (size = %zu)\n",
|
||||
entry.name, entry.size);
|
||||
}
|
||||
}
|
||||
|
||||
fs_closedir(&dp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dir_tests(void)
|
||||
{
|
||||
fs_file_t fp[2];
|
||||
int res;
|
||||
|
||||
/* Remove sub dir if already exists */
|
||||
res = remove_dir(TEST_SUB_DIR);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a sub directory */
|
||||
res = create_dir(TEST_SUB_DIR);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Open or create files */
|
||||
|
||||
res = open_file(&fp[0], TEST_FILE);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = open_file(&fp[1], TEST_SUB_DIR "/" TEST_FILE);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write to files to check size info */
|
||||
res = write_test(&fp[0], 0, "1");
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = write_test(&fp[1], 0, "12");
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Close the files in the directories */
|
||||
|
||||
res = close_file(&fp[0], TEST_FILE);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = close_file(&fp[1], TEST_SUB_DIR "/" TEST_FILE);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* List the files in root and sub dir */
|
||||
res = list_dir("/");
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = list_dir(TEST_SUB_DIR);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove sub dir */
|
||||
res = remove_dir(TEST_SUB_DIR);
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void vol_tests(void)
|
||||
{
|
||||
struct fs_statvfs stat;
|
||||
int res;
|
||||
|
||||
res = fs_statvfs(&stat);
|
||||
if (res) {
|
||||
printk("Error getting volume stats [%d]\n", res);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("\n");
|
||||
printk("Optimal transfer block size = %lu\n", stat.f_bsize);
|
||||
printk("Allocation unit size = %lu\n", stat.f_frsize);
|
||||
printk("Volume size in f_frsize units = %lu\n", stat.f_blocks);
|
||||
printk("Free space in f_frsize units = %lu\n", stat.f_bfree);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
BOARD ?= arduino_101
|
||||
CONF_FILE = prj.conf
|
||||
CONF_FILE ?= prj.conf
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.test
|
|
@ -28,64 +28,96 @@ or
|
|||
|
||||
Sample Output:
|
||||
|
||||
File System Demo!
|
||||
***** BOOTING ZEPHYR OS v1.6.99 - BUILD: Feb 8 2017 07:33:07 *****
|
||||
Running test suite fat_fs_basic_test
|
||||
tc_start() - test_fat_file
|
||||
|
||||
Open tests:
|
||||
Creating new file testfile.txt
|
||||
Opened file testfile.txt
|
||||
Data successfully written!
|
||||
|
||||
Write tests:
|
||||
Data written:"hello world!"
|
||||
|
||||
Data successfully read!
|
||||
Data successfully written!
|
||||
|
||||
Sync tests:
|
||||
|
||||
Read tests:
|
||||
Data read:"hello world!"
|
||||
|
||||
Data read matches data written!
|
||||
Data read matches data written
|
||||
|
||||
Truncate tests:
|
||||
|
||||
Testing shrink to 0 size
|
||||
Testing write after truncating
|
||||
Data successfully written!
|
||||
|
||||
Write tests:
|
||||
Data written:"hello world!"
|
||||
|
||||
Data successfully written!
|
||||
Original size of file = 12
|
||||
|
||||
Testing shrinking
|
||||
File size after shrinking by 5 bytes = 7
|
||||
Check original contents after shrinking file
|
||||
Data successfully read!
|
||||
Data read:"hello w"
|
||||
|
||||
Testing expanding
|
||||
File size after expanding by 10 bytes = 17
|
||||
Check original contents after expanding file
|
||||
Data successfully read!
|
||||
Data read:"hello w"
|
||||
|
||||
Testing for zeroes in expanded region
|
||||
|
||||
Close tests:
|
||||
Closed file testfile.txt
|
||||
|
||||
Delete tests:
|
||||
File (testfile.txt) deleted successfully!
|
||||
Created dir sub1!
|
||||
Creating new file testfile.txt
|
||||
Opened file testfile.txt
|
||||
Creating new file sub1/testfile.txt
|
||||
Opened file sub1/testfile.txt
|
||||
Data successfully written!
|
||||
Data written:"1"
|
||||
===================================================================
|
||||
PASS - test_fat_file.
|
||||
tc_start() - test_fat_dir
|
||||
|
||||
mkdir tests:
|
||||
Creating new dir testdir
|
||||
|
||||
Write tests:
|
||||
Data written:"hello world!"
|
||||
|
||||
Data successfully written!
|
||||
Data written:"12"
|
||||
Created dir testdir!
|
||||
|
||||
Closed file testfile.txt
|
||||
Closed file sub1/testfile.txt
|
||||
lsdir tests:
|
||||
|
||||
Listing dir /:
|
||||
[DIR ] SUB1
|
||||
[FILE] TESTFILE.TXT (size = 1)
|
||||
[DIR ] FATFILE
|
||||
[FILE] TEST.C (size = 10)
|
||||
[DIR ] TESTDIR
|
||||
[DIR ] 1
|
||||
|
||||
Listing dir sub1:
|
||||
[FILE] TESTFILE.TXT (size = 2)
|
||||
lsdir tests:
|
||||
|
||||
Removing files and sub directories in sub1
|
||||
Removing sub1/TESTFILE.TXT
|
||||
Removed dir sub1!
|
||||
Listing dir testdir:
|
||||
[FILE] TESTFILE.TXT (size = 12)
|
||||
|
||||
rmdir tests:
|
||||
|
||||
Removing testdir/TESTFILE.TXT
|
||||
Removed dir testdir!
|
||||
|
||||
lsdir tests:
|
||||
|
||||
Listing dir /:
|
||||
[DIR ] FATFILE
|
||||
[FILE] TEST.C (size = 10)
|
||||
[DIR ] 1
|
||||
|
||||
===================================================================
|
||||
PASS - test_fat_dir.
|
||||
tc_start() - test_fat_fs
|
||||
|
||||
Optimal transfer block size = 512
|
||||
Allocation unit size = 512
|
||||
Volume size in f_frsize units = 152
|
||||
Free space in f_frsize units = 151
|
||||
Allocation unit size = 1024
|
||||
Volume size in f_frsize units = 2028
|
||||
Free space in f_frsize units = 2025
|
||||
===================================================================
|
||||
PASS - test_fat_fs.
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
|
@ -3,5 +3,5 @@ CONFIG_FILE_SYSTEM_FAT=y
|
|||
CONFIG_DISK_ACCESS_FLASH=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_GPIO=y
|
||||
#CONFIG_DISK_ACCESS_RAM=y
|
||||
|
||||
CONFIG_ZTEST=y
|
3
tests/fs/fat_fs_api/src/Makefile
Normal file
3
tests/fs/fat_fs_api/src/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
include $(ZEPHYR_BASE)/tests/Makefile.test
|
||||
|
||||
obj-y += main.o common.o test_fat_file.o test_fat_dir.o test_fat_fs.o
|
21
tests/fs/fat_fs_api/src/common.c
Normal file
21
tests/fs/fat_fs_api/src/common.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <test_fat.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
23
tests/fs/fat_fs_api/src/main.c
Normal file
23
tests/fs/fat_fs_api/src/main.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup t_fat_fs
|
||||
* @{
|
||||
* @defgroup t_fat_fs_basic test_fat_fs_basic_operations
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <test_fat.h>
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(fat_fs_basic_test,
|
||||
ztest_unit_test(test_fat_file),
|
||||
ztest_unit_test(test_fat_dir),
|
||||
ztest_unit_test(test_fat_fs));
|
||||
ztest_run_test_suite(fat_fs_basic_test);
|
||||
}
|
21
tests/fs/fat_fs_api/src/test_fat.h
Normal file
21
tests/fs/fat_fs_api/src/test_fat.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <ztest.h>
|
||||
#include <fs.h>
|
||||
|
||||
#define TEST_FILE "testfile.txt"
|
||||
#define TEST_DIR "testdir"
|
||||
fs_file_t filep;
|
||||
extern const char test_str[];
|
||||
|
||||
int check_file_dir_exists(const char *path);
|
||||
|
||||
void test_fat_file(void);
|
||||
void test_fat_dir(void);
|
||||
void test_fat_fs(void);
|
||||
|
166
tests/fs/fat_fs_api/src/test_fat_dir.c
Normal file
166
tests/fs/fat_fs_api/src/test_fat_dir.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* @filesystem
|
||||
* @brief test_filesystem
|
||||
* Demonstrates the ZEPHYR File System APIs
|
||||
*/
|
||||
|
||||
#include <test_fat.h>
|
||||
#include <stdio.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 "/" TEST_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;
|
||||
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;
|
||||
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_dir(void)
|
||||
{
|
||||
assert_true(test_mkdir() == TC_PASS, NULL);
|
||||
assert_true(test_lsdir("/") == TC_PASS, NULL);
|
||||
assert_true(test_lsdir(TEST_DIR) == TC_PASS, NULL);
|
||||
assert_true(test_rmdir() == TC_PASS, NULL);
|
||||
assert_true(test_lsdir("/") == TC_PASS, NULL);
|
||||
}
|
282
tests/fs/fat_fs_api/src/test_fat_file.c
Normal file
282
tests/fs/fat_fs_api/src/test_fat_file.c
Normal file
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* @filesystem
|
||||
* @brief test_filesystem
|
||||
* Demonstrates the ZEPHYR File System APIs
|
||||
*/
|
||||
|
||||
#include <test_fat.h>
|
||||
#include <string.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_sync(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
TC_PRINT("\nSync tests:\n");
|
||||
|
||||
/* Verify fs_sync() */
|
||||
res = fs_sync(&filep);
|
||||
if (res) {
|
||||
TC_PRINT("Error syncing file [%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
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_truncate(void)
|
||||
{
|
||||
int res;
|
||||
off_t orig_pos;
|
||||
char read_buff[80];
|
||||
ssize_t brw;
|
||||
|
||||
TC_PRINT("\nTruncate tests:\n");
|
||||
|
||||
/* Verify fs_truncate() */
|
||||
/* Test truncating to 0 size */
|
||||
TC_PRINT("\nTesting shrink to 0 size\n");
|
||||
res = fs_truncate(&filep, 0);
|
||||
if (res) {
|
||||
TC_PRINT("fs_truncate failed [%d]\n", res);
|
||||
fs_close(&filep);
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(&filep, 0, FS_SEEK_END);
|
||||
/* Verify fs_tell() */
|
||||
if (fs_tell(&filep) > 0) {
|
||||
TC_PRINT("Failed truncating to size 0\n");
|
||||
fs_close(&filep);
|
||||
return TC_FAIL;
|
||||
}
|
||||
|
||||
TC_PRINT("Testing write after truncating\n");
|
||||
res = test_file_write();
|
||||
if (res) {
|
||||
TC_PRINT("Write failed after truncating\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(&filep, 0, FS_SEEK_END);
|
||||
|
||||
orig_pos = fs_tell(&filep);
|
||||
TC_PRINT("Original size of file = %ld\n", orig_pos);
|
||||
|
||||
/* Test shrinking file */
|
||||
TC_PRINT("\nTesting shrinking\n");
|
||||
res = fs_truncate(&filep, orig_pos - 5);
|
||||
if (res) {
|
||||
TC_PRINT("fs_truncate failed [%d]\n", res);
|
||||
fs_close(&filep);
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(&filep, 0, FS_SEEK_END);
|
||||
TC_PRINT("File size after shrinking by 5 bytes = %ld\n",
|
||||
fs_tell(&filep));
|
||||
if (fs_tell(&filep) != (orig_pos - 5)) {
|
||||
TC_PRINT("File size after fs_truncate not as expected\n");
|
||||
fs_close(&filep);
|
||||
return TC_FAIL;
|
||||
}
|
||||
|
||||
/* Test expanding file */
|
||||
TC_PRINT("\nTesting expanding\n");
|
||||
fs_seek(&filep, 0, FS_SEEK_END);
|
||||
orig_pos = fs_tell(&filep);
|
||||
res = fs_truncate(&filep, orig_pos + 10);
|
||||
if (res) {
|
||||
TC_PRINT("fs_truncate failed [%d]\n", res);
|
||||
fs_close(&filep);
|
||||
return res;
|
||||
}
|
||||
|
||||
fs_seek(&filep, 0, FS_SEEK_END);
|
||||
TC_PRINT("File size after expanding by 10 bytes = %ld\n",
|
||||
fs_tell(&filep));
|
||||
if (fs_tell(&filep) != (orig_pos + 10)) {
|
||||
TC_PRINT("File size after fs_truncate not as expected\n");
|
||||
fs_close(&filep);
|
||||
return TC_FAIL;
|
||||
}
|
||||
|
||||
/* Check if expanded regions are zeroed */
|
||||
TC_PRINT("Testing for zeroes in expanded region\n");
|
||||
fs_seek(&filep, -5, FS_SEEK_END);
|
||||
|
||||
brw = fs_read(&filep, read_buff, 5);
|
||||
|
||||
if (brw < 5) {
|
||||
TC_PRINT("Read failed after truncating\n");
|
||||
fs_close(&filep);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (read_buff[i]) {
|
||||
TC_PRINT("Expanded regions are not zeroed\n");
|
||||
fs_close(&filep);
|
||||
return TC_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return TC_PASS;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void test_fat_file(void)
|
||||
{
|
||||
assert_true(test_file_open() == TC_PASS, NULL);
|
||||
assert_true(test_file_write() == TC_PASS, NULL);
|
||||
assert_true(test_file_sync() == TC_PASS, NULL);
|
||||
assert_true(test_file_read() == TC_PASS, NULL);
|
||||
assert_true(test_file_truncate() == TC_PASS, NULL);
|
||||
assert_true(test_file_close() == TC_PASS, NULL);
|
||||
assert_true(test_file_delete() == TC_PASS, NULL);
|
||||
}
|
39
tests/fs/fat_fs_api/src/test_fat_fs.c
Normal file
39
tests/fs/fat_fs_api/src/test_fat_fs.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* @filesystem
|
||||
* @brief test Zephyr file system generic features
|
||||
* to demonstrates the ZEPHYR File System APIs
|
||||
*/
|
||||
|
||||
#include <test_fat.h>
|
||||
|
||||
static int test_statvfs(void)
|
||||
{
|
||||
struct fs_statvfs stat;
|
||||
int res;
|
||||
|
||||
/* Verify fs_statvfs() */
|
||||
res = fs_statvfs(&stat);
|
||||
if (res) {
|
||||
TC_PRINT("Error getting volume stats [%d]\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
TC_PRINT("\n");
|
||||
TC_PRINT("Optimal transfer block size = %lu\n", stat.f_bsize);
|
||||
TC_PRINT("Allocation unit size = %lu\n", stat.f_frsize);
|
||||
TC_PRINT("Volume size in f_frsize units = %lu\n", stat.f_blocks);
|
||||
TC_PRINT("Free space in f_frsize units = %lu\n", stat.f_bfree);
|
||||
|
||||
return TC_PASS;
|
||||
}
|
||||
|
||||
void test_fat_fs(void)
|
||||
{
|
||||
assert_true(test_statvfs() == TC_PASS, NULL);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue