mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-07-15 08:32:42 +08:00
Merge branch 'feature/remove_spiffs_example' into 'master'
Remove SPIFFS example because it is not support See merge request sdk/ESP8266_RTOS_SDK!683
This commit is contained in:
@ -1,9 +0,0 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := spiffs
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
@ -1,9 +0,0 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
CFLAGS += -Wno-error=implicit-function-declaration \
|
||||
-Wno-error=unused-label \
|
||||
-Wno-implicit-function-declaration \
|
||||
-Wno-unused-label
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* spiffs_test_params.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SPIFFS_TEST_PARAMS_H__
|
||||
#define __SPIFFS_TEST_PARAMS_H__
|
||||
|
||||
#define FS1_FLASH_SIZE (128*1024)
|
||||
#define FS2_FLASH_SIZE (128*1024)
|
||||
|
||||
#define FS1_FLASH_ADDR (1024*1024)
|
||||
#define FS2_FLASH_ADDR (1280*1024)
|
||||
|
||||
#define SECTOR_SIZE (4*1024)
|
||||
#define LOG_BLOCK (SECTOR_SIZE)
|
||||
#define LOG_PAGE (128)
|
||||
|
||||
#define FD_BUF_SIZE 32*4
|
||||
#define CACHE_BUF_SIZE (LOG_PAGE + 32)*8
|
||||
|
||||
#endif /* __SPIFFS_TEST_PARAMS_H__ */
|
@ -1,329 +0,0 @@
|
||||
/*
|
||||
* test_bugreports.c
|
||||
*
|
||||
* Created on: Mar 8, 2015
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "testrunner.h"
|
||||
#include "test_spiffs.h"
|
||||
#include "spiffs_nucleus.h"
|
||||
#include "spiffs.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
//#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
SUITE(bug_tests)
|
||||
void setup() {
|
||||
_setup_test_only();
|
||||
}
|
||||
void teardown() {
|
||||
_teardown();
|
||||
}
|
||||
|
||||
TEST(nodemcu_full_fs_1) {
|
||||
fs_reset_specific(0, 1280*1024, 4096*20, 4096, 4096, 128);
|
||||
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
|
||||
printf(" fill up system by writing one byte a lot\n");
|
||||
fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
int i;
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_OK;
|
||||
for (i = 0; i < 100*1000; i++) {
|
||||
u8_t buf = 'x';
|
||||
res = SPIFFS_write(FS, fd, &buf, 1);
|
||||
}
|
||||
|
||||
int errno = SPIFFS_errno(FS);
|
||||
int res2 = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res2 == SPIFFS_OK);
|
||||
printf(" >>> file %s size: %i\n", s.name, s.size);
|
||||
|
||||
TEST_CHECK(errno == SPIFFS_ERR_FULL);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
printf(" remove big file\n");
|
||||
res = SPIFFS_remove(FS, "test1.txt");
|
||||
|
||||
printf("res:%i errno:%i\n",res, SPIFFS_errno(FS));
|
||||
|
||||
TEST_CHECK(res == SPIFFS_OK);
|
||||
res2 = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res2 == -1);
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED);
|
||||
res2 = SPIFFS_stat(FS, "test1.txt", &s);
|
||||
TEST_CHECK(res2 == -1);
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND);
|
||||
|
||||
printf(" create small file\n");
|
||||
fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
res = SPIFFS_OK;
|
||||
for (i = 0; res >= 0 && i < 1000; i++) {
|
||||
u8_t buf = 'x';
|
||||
res = SPIFFS_write(FS, fd, &buf, 1);
|
||||
}
|
||||
TEST_CHECK(res >= SPIFFS_OK);
|
||||
|
||||
res2 = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res2 == SPIFFS_OK);
|
||||
printf(" >>> file %s size: %i\n", s.name, s.size);
|
||||
|
||||
TEST_CHECK(s.size == 1000);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(nodemcu_full_fs_1)
|
||||
|
||||
TEST(nodemcu_full_fs_2) {
|
||||
fs_reset_specific(0, 1280*1024, 4096*22, 4096, 4096, 128);
|
||||
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
|
||||
printf(" fill up system by writing one byte a lot\n");
|
||||
fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
int i;
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_OK;
|
||||
for (i = 0; i < 100*1000; i++) {
|
||||
u8_t buf = 'x';
|
||||
res = SPIFFS_write(FS, fd, &buf, 1);
|
||||
}
|
||||
|
||||
int errno = SPIFFS_errno(FS);
|
||||
int res2 = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res2 == SPIFFS_OK);
|
||||
printf(" >>> file %s size: %i\n", s.name, s.size);
|
||||
|
||||
TEST_CHECK(errno == SPIFFS_ERR_FULL);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
res2 = SPIFFS_stat(FS, "test1.txt", &s);
|
||||
TEST_CHECK(res2 == SPIFFS_OK);
|
||||
|
||||
SPIFFS_clearerr(FS);
|
||||
printf(" create small file\n");
|
||||
fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
#if 0
|
||||
// before gc in v3.1
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK);
|
||||
TEST_CHECK(fd > 0);
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
u8_t buf = 'x';
|
||||
res = SPIFFS_write(FS, fd, &buf, 1);
|
||||
}
|
||||
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FULL);
|
||||
res2 = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res2 == SPIFFS_OK);
|
||||
printf(" >>> file %s size: %i\n", s.name, s.size);
|
||||
TEST_CHECK(s.size == 0);
|
||||
SPIFFS_clearerr(FS);
|
||||
#else
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FULL);
|
||||
SPIFFS_clearerr(FS);
|
||||
#endif
|
||||
printf(" remove files\n");
|
||||
res = SPIFFS_remove(FS, "test1.txt");
|
||||
TEST_CHECK(res == SPIFFS_OK);
|
||||
#if 0
|
||||
res = SPIFFS_remove(FS, "test2.txt");
|
||||
TEST_CHECK(res == SPIFFS_OK);
|
||||
#endif
|
||||
|
||||
printf(" create medium file\n");
|
||||
fd = SPIFFS_open(FS, "test3.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK);
|
||||
TEST_CHECK(fd > 0);
|
||||
|
||||
for (i = 0; i < 20*1000; i++) {
|
||||
u8_t buf = 'x';
|
||||
res = SPIFFS_write(FS, fd, &buf, 1);
|
||||
}
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK);
|
||||
|
||||
res2 = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res2 == SPIFFS_OK);
|
||||
printf(" >>> file %s size: %i\n", s.name, s.size);
|
||||
TEST_CHECK(s.size == 20*1000);
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(nodemcu_full_fs_2)
|
||||
|
||||
TEST(magic_test) {
|
||||
// one obj lu page, not full
|
||||
fs_reset_specific(0, 1280*1024, 4096*16, 4096, 4096*1, 128);
|
||||
TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||||
// one obj lu page, full
|
||||
fs_reset_specific(0, 1280*1024, 4096*16, 4096, 4096*2, 128);
|
||||
TEST_CHECK(!SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||||
// two obj lu pages, not full
|
||||
fs_reset_specific(0, 1280*1024, 4096*16, 4096, 4096*4, 128);
|
||||
TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(magic_test)
|
||||
|
||||
TEST(nodemcu_309) {
|
||||
fs_reset_specific(0, 1280*1024, 4096*20, 4096, 4096, 128);
|
||||
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
int j;
|
||||
|
||||
for (j = 1; j <= 3; j++) {
|
||||
char fname[32];
|
||||
sprintf(fname, "20K%i.txt", j);
|
||||
fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_DIRECT, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
int i;
|
||||
res = SPIFFS_OK;
|
||||
u8_t err = 0;
|
||||
for (i = 1; i <= 1280; i++) {
|
||||
char *buf = "0123456789ABCDE\n";
|
||||
res = SPIFFS_write(FS, fd, buf, strlen(buf));
|
||||
if (!err && res < 0) {
|
||||
printf("err @ %i,%i\n", i, j);
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int errno = SPIFFS_errno(FS);
|
||||
TEST_CHECK(errno == SPIFFS_ERR_FULL);
|
||||
|
||||
u32_t total;
|
||||
u32_t used;
|
||||
|
||||
SPIFFS_info(FS, &total, &used);
|
||||
printf("total:%i\nused:%i\nremain:%i\nerrno:%i\n", total, used, total-used, errno);
|
||||
TEST_CHECK(total-used < 11000);
|
||||
|
||||
spiffs_DIR d;
|
||||
struct spiffs_dirent e;
|
||||
struct spiffs_dirent *pe = &e;
|
||||
|
||||
SPIFFS_opendir(FS, "/", &d);
|
||||
int spoon_guard = 0;
|
||||
while ((pe = SPIFFS_readdir(&d, pe))) {
|
||||
printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size);
|
||||
TEST_CHECK(spoon_guard++ < 3);
|
||||
}
|
||||
TEST_CHECK(spoon_guard == 3);
|
||||
SPIFFS_closedir(&d);
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(nodemcu_309)
|
||||
|
||||
|
||||
TEST(robert) {
|
||||
// create a clean file system starting at address 0, 2 megabytes big,
|
||||
// sector size 65536, block size 65536, page size 256
|
||||
fs_reset_specific(0, 1280*1024, 128*1024, 4096, 4096, 128);
|
||||
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
char fname[32];
|
||||
|
||||
sprintf(fname, "test.txt");
|
||||
fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
res = SPIFFS_OK;
|
||||
char buf[500];
|
||||
memset(buf, 0xaa, 500);
|
||||
res = SPIFFS_write(FS, fd, buf, 500);
|
||||
TEST_CHECK(res >= SPIFFS_OK);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
int errno = SPIFFS_errno(FS);
|
||||
TEST_CHECK(errno == SPIFFS_OK);
|
||||
|
||||
//SPIFFS_vis(FS);
|
||||
// unmount
|
||||
SPIFFS_unmount(FS);
|
||||
|
||||
// remount
|
||||
res = fs_mount_specific(1280*1024, 256*1024, 4096, 4096, 128);
|
||||
TEST_CHECK(res== SPIFFS_OK);
|
||||
|
||||
//SPIFFS_vis(FS);
|
||||
|
||||
spiffs_stat s;
|
||||
TEST_CHECK(SPIFFS_stat(FS, fname, &s) == SPIFFS_OK);
|
||||
printf("file %s stat size %i\n", s.name, s.size);
|
||||
TEST_CHECK(s.size == 500);
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(robert)
|
||||
|
||||
|
||||
TEST(spiffs_12) {
|
||||
fs_reset_specific(0, 1280*1024, 128*1024, 4096, 4096, 128);
|
||||
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
int j = 1;
|
||||
|
||||
while (1) {
|
||||
char fname[32];
|
||||
sprintf(fname, "file%i.txt", j);
|
||||
fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_DIRECT, 0);
|
||||
if (fd <=0) break;
|
||||
|
||||
int i;
|
||||
res = SPIFFS_OK;
|
||||
for (i = 1; i <= 100; i++) {
|
||||
char *buf = "0123456789ABCDE\n";
|
||||
res = SPIFFS_write(FS, fd, buf, strlen(buf));
|
||||
if (res < 0) break;
|
||||
}
|
||||
SPIFFS_close(FS, fd);
|
||||
j++;
|
||||
}
|
||||
|
||||
int errno = SPIFFS_errno(FS);
|
||||
TEST_CHECK(errno == SPIFFS_ERR_FULL);
|
||||
|
||||
u32_t total;
|
||||
u32_t used;
|
||||
|
||||
SPIFFS_info(FS, &total, &used);
|
||||
printf("total:%i (%iK)\nused:%i (%iK)\nremain:%i (%iK)\nerrno:%i\n", total, total/1024, used, used/1024, total-used, (total-used)/1024, errno);
|
||||
|
||||
spiffs_DIR d;
|
||||
struct spiffs_dirent e;
|
||||
struct spiffs_dirent *pe = &e;
|
||||
|
||||
SPIFFS_opendir(FS, "/", &d);
|
||||
while ((pe = SPIFFS_readdir(&d, pe))) {
|
||||
printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size);
|
||||
}
|
||||
SPIFFS_closedir(&d);
|
||||
|
||||
//SPIFFS_vis(FS);
|
||||
|
||||
//dump_page(FS, 0);
|
||||
//dump_page(FS, 1);
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(spiffs_12)
|
||||
|
||||
|
||||
SUITE_END(bug_tests)
|
@ -1,419 +0,0 @@
|
||||
/*
|
||||
* test_dev.c
|
||||
*
|
||||
* Created on: Jul 14, 2013
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
|
||||
#include "testrunner.h"
|
||||
#include "test_spiffs.h"
|
||||
#include "spiffs_nucleus.h"
|
||||
#include "spiffs.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
//#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
SUITE(check_tests)
|
||||
void setup() {
|
||||
_setup();
|
||||
}
|
||||
void teardown() {
|
||||
_teardown();
|
||||
}
|
||||
|
||||
TEST(evil_write) {
|
||||
fs_set_validate_flashing(0);
|
||||
printf("writing corruption to block 1 data range (leaving lu intact)\n");
|
||||
u32_t data_range = SPIFFS_CFG_LOG_BLOCK_SZ(FS) -
|
||||
SPIFFS_CFG_LOG_PAGE_SZ(FS) * (SPIFFS_OBJ_LOOKUP_PAGES(FS));
|
||||
u8_t *corruption = malloc(data_range);
|
||||
MALLOC_CHECK(corruption != NULL, data_range);
|
||||
memrand(corruption, data_range);
|
||||
u32_t addr = 0 * SPIFFS_CFG_LOG_PAGE_SZ(FS) * SPIFFS_OBJ_LOOKUP_PAGES(FS) + SPIFFS_CFG_PHYS_ADDR(FS);
|
||||
area_write(addr, corruption, data_range);
|
||||
free(corruption);
|
||||
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
|
||||
printf("CHECK1-----------------\n");
|
||||
SPIFFS_check(FS);
|
||||
printf("CHECK2-----------------\n");
|
||||
SPIFFS_check(FS);
|
||||
printf("CHECK3-----------------\n");
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = test_create_and_write_file("file2", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(evil_write)
|
||||
|
||||
|
||||
TEST(lu_check1) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify lu entry data page index 1
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
// reset lu entry to being erased, but keep page data
|
||||
spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED;
|
||||
spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
|
||||
int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
|
||||
u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry*sizeof(spiffs_obj_id);
|
||||
|
||||
area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
|
||||
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
SPIFFS_check(FS);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(lu_check1)
|
||||
|
||||
|
||||
TEST(page_cons1) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify object index, find object index header
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
// set object index entry 2 to a bad page
|
||||
u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 0 * sizeof(spiffs_page_ix);
|
||||
spiffs_page_ix bad_pix_ref = 0x55;
|
||||
area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
|
||||
area_write(addr+2, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
|
||||
|
||||
// delete all cache
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(page_cons1)
|
||||
|
||||
|
||||
TEST(page_cons2) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify object index, find object index header
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
// find data page span index 0
|
||||
spiffs_page_ix dpix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &dpix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
// set object index entry 1+2 to a data page 0
|
||||
u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix);
|
||||
spiffs_page_ix bad_pix_ref = dpix;
|
||||
area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
|
||||
area_write(addr+sizeof(spiffs_page_ix), (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
|
||||
|
||||
// delete all cache
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(page_cons2)
|
||||
|
||||
|
||||
|
||||
TEST(page_cons3) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify object index, find object index header
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
// set object index entry 1+2 lookup page
|
||||
u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix);
|
||||
spiffs_page_ix bad_pix_ref = SPIFFS_PAGES_PER_BLOCK(FS) * (*FS.block_count - 2);
|
||||
area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
|
||||
area_write(addr+sizeof(spiffs_page_ix), (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix));
|
||||
|
||||
// delete all cache
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(page_cons3)
|
||||
|
||||
|
||||
TEST(page_cons_final) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify page header, make unfinalized
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
// set page span ix 1 as unfinalized
|
||||
u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags);
|
||||
u8_t flags;
|
||||
area_read(addr, (u8_t*)&flags, 1);
|
||||
flags |= SPIFFS_PH_FLAG_FINAL;
|
||||
area_write(addr, (u8_t*)&flags, 1);
|
||||
|
||||
// delete all cache
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(page_cons_final)
|
||||
|
||||
|
||||
TEST(index_cons1) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify lu entry data page index header
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
printf(" deleting lu entry pix %04x\n", pix);
|
||||
// reset lu entry to being erased, but keep page data
|
||||
spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED;
|
||||
spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
|
||||
int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
|
||||
u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id);
|
||||
|
||||
area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
|
||||
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(index_cons1)
|
||||
|
||||
|
||||
TEST(index_cons2) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify lu entry data page index header
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
printf(" writing lu entry for index page, ix %04x, as data page\n", pix);
|
||||
spiffs_obj_id obj_id = 0x1234;
|
||||
spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
|
||||
int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
|
||||
u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id);
|
||||
|
||||
area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
|
||||
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(index_cons2)
|
||||
|
||||
|
||||
TEST(index_cons3) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify lu entry data page index header
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
printf(" setting lu entry pix %04x to another index page\n", pix);
|
||||
// reset lu entry to being erased, but keep page data
|
||||
spiffs_obj_id obj_id = 1234 | SPIFFS_OBJ_ID_IX_FLAG;
|
||||
spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix);
|
||||
int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix);
|
||||
u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id);
|
||||
|
||||
area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id));
|
||||
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
SPIFFS_check(FS);
|
||||
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(index_cons3)
|
||||
|
||||
TEST(index_cons4) {
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS);
|
||||
int res = test_create_and_write_file("file", size, size);
|
||||
TEST_CHECK(res >= 0);
|
||||
res = read_and_verify("file");
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
// modify lu entry data page index header, flags
|
||||
spiffs_page_ix pix;
|
||||
res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
printf(" cue objix hdr deletion in page %04x\n", pix);
|
||||
// set flags as deleting ix header
|
||||
u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags);
|
||||
u8_t flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE);
|
||||
|
||||
area_write(addr, (u8_t*)&flags, 1);
|
||||
|
||||
#if SPIFFS_CACHE
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
SPIFFS_check(FS);
|
||||
|
||||
return TEST_RES_OK;
|
||||
} TEST_END(index_cons4)
|
||||
|
||||
|
||||
|
||||
SUITE_END(check_tests)
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* test_dev.c
|
||||
*
|
||||
* Created on: Jul 14, 2013
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
|
||||
#include "testrunner.h"
|
||||
#include "test_spiffs.h"
|
||||
#include "spiffs_nucleus.h"
|
||||
#include "spiffs.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
//#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
SUITE(dev_tests)
|
||||
void setup() {
|
||||
_setup();
|
||||
}
|
||||
void teardown() {
|
||||
_teardown();
|
||||
}
|
||||
|
||||
TEST(interrupted_write) {
|
||||
char *name = "interrupt";
|
||||
char *name2 = "interrupt2";
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
|
||||
const u32_t sz = SPIFFS_CFG_LOG_PAGE_SZ(FS)*8;
|
||||
u8_t *buf = malloc(sz);
|
||||
MALLOC_CHECK(buf != NULL, sz);
|
||||
memrand(buf, sz);
|
||||
|
||||
printf(" create reference file\n");
|
||||
fd = SPIFFS_open(FS, name, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
clear_flash_ops_log();
|
||||
res = SPIFFS_write(FS, fd, buf, sz);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
u32_t written = get_flash_ops_log_write_bytes();
|
||||
printf(" written bytes: %i\n", written);
|
||||
|
||||
|
||||
printf(" create error file\n");
|
||||
fd = SPIFFS_open(FS, name2, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
clear_flash_ops_log();
|
||||
invoke_error_after_write_bytes(written/2, 0);
|
||||
res = SPIFFS_write(FS, fd, buf, sz);
|
||||
SPIFFS_close(FS, fd);
|
||||
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_TEST);
|
||||
|
||||
clear_flash_ops_log();
|
||||
|
||||
#if SPIFFS_CACHE
|
||||
// delete all cache
|
||||
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||
cache->cpage_use_map = 0;
|
||||
#endif
|
||||
|
||||
|
||||
printf(" read error file\n");
|
||||
fd = SPIFFS_open(FS, name2, SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
printf(" file size: %i\n", s.size);
|
||||
|
||||
if (s.size > 0) {
|
||||
u8_t *buf2 = malloc(s.size);
|
||||
MALLOC_CHECK(buf2 != NULL, s.size);
|
||||
res = SPIFFS_read(FS, fd, buf2, s.size);
|
||||
TEST_CHECK(res >= 0);
|
||||
|
||||
u32_t ix = 0;
|
||||
for (ix = 0; ix < s.size; ix += 16) {
|
||||
int i;
|
||||
printf(" ");
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%02x", buf[ix+i]);
|
||||
}
|
||||
printf(" ");
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%02x", buf2[ix+i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
free(buf2);
|
||||
}
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
|
||||
printf(" FS check\n");
|
||||
SPIFFS_check(FS);
|
||||
|
||||
printf(" read error file again\n");
|
||||
fd = SPIFFS_open(FS, name2, SPIFFS_APPEND | SPIFFS_RDWR, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
TEST_CHECK(res >= 0);
|
||||
printf(" file size: %i\n", s.size);
|
||||
printf(" write file\n");
|
||||
res = SPIFFS_write(FS, fd, buf, sz);
|
||||
TEST_CHECK(res >= 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
|
||||
free(buf);
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(interrupted_write)
|
||||
|
||||
SUITE_END(dev_tests)
|
File diff suppressed because it is too large
Load Diff
@ -1,73 +0,0 @@
|
||||
/* SPIFFS test example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "esp_spiffs.h"
|
||||
#include "esp_ssc.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
#include "testrunner.h"
|
||||
|
||||
#include "spiffs_test_params.h"
|
||||
|
||||
enum {
|
||||
CMD_SPIFFS,
|
||||
CMD_END,
|
||||
};
|
||||
|
||||
#define SSC_CMD_N (CMD_END + 1)
|
||||
|
||||
static void spiffs_test_init(void);
|
||||
|
||||
static ssc_cmd_t sscCmdSet[SSC_CMD_N] = {
|
||||
{"fs", CMD_T_SYNC, CMD_SPIFFS, spiffs_test_init, NULL},
|
||||
{"", CMD_T_ASYNC, CMD_END, NULL, NULL}
|
||||
};
|
||||
|
||||
void spiffs_test_init(void)
|
||||
{
|
||||
char* argv[10], pLine[128];
|
||||
int argc;
|
||||
|
||||
strcpy(pLine, ssc_param_str());
|
||||
argc = ssc_parse_param(pLine, argv);
|
||||
|
||||
run_tests(argc, argv);
|
||||
}
|
||||
|
||||
void spiffs_test_help(void)
|
||||
{
|
||||
printf("\nhelp:\n");
|
||||
printf("$ fs \n");
|
||||
}
|
||||
|
||||
void spiffs_fs1_init(void)
|
||||
{
|
||||
struct esp_spiffs_config config;
|
||||
|
||||
config.phys_size = FS1_FLASH_SIZE;
|
||||
config.phys_addr = FS1_FLASH_ADDR;
|
||||
config.phys_erase_block = SECTOR_SIZE;
|
||||
config.log_block_size = LOG_BLOCK;
|
||||
config.log_page_size = LOG_PAGE;
|
||||
config.fd_buf_size = FD_BUF_SIZE * 2;
|
||||
config.cache_buf_size = CACHE_BUF_SIZE;
|
||||
|
||||
esp_spiffs_init(&config);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
spiffs_fs1_init();
|
||||
|
||||
ssc_attach(SSC_BR_74880);
|
||||
ssc_register(sscCmdSet, SSC_CMD_N, spiffs_test_help);
|
||||
}
|
||||
|
@ -1,909 +0,0 @@
|
||||
/*
|
||||
* test_spiffs.c
|
||||
*
|
||||
* Created on: Jun 19, 2013
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "spiffs.h"
|
||||
#include "spiffs_nucleus.h"
|
||||
|
||||
#include "testrunner.h"
|
||||
|
||||
#include "test_spiffs.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
//#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include "spiffs_test_params.h"
|
||||
|
||||
//#define AREA(x) area[(x) - addr_offset]
|
||||
|
||||
//static unsigned char area[PHYS_FLASH_SIZE];
|
||||
static u32_t addr_offset = 0;
|
||||
|
||||
static int erases[FS2_FLASH_SIZE/SECTOR_SIZE];
|
||||
static char _path[256];
|
||||
static u32_t bytes_rd = 0;
|
||||
static u32_t bytes_wr = 0;
|
||||
static u32_t reads = 0;
|
||||
static u32_t writes = 0;
|
||||
static u32_t error_after_bytes_written = 0;
|
||||
static u32_t error_after_bytes_read = 0;
|
||||
static char error_after_bytes_written_once_only = 0;
|
||||
static char error_after_bytes_read_once_only = 0;
|
||||
static char log_flash_ops = 1;
|
||||
static u32_t fs_check_fixes = 0;
|
||||
|
||||
spiffs __fs;
|
||||
static u8_t _work[LOG_PAGE * 2];
|
||||
static u8_t _fds[FD_BUF_SIZE * 2];
|
||||
static u8_t _cache[CACHE_BUF_SIZE];
|
||||
|
||||
static int check_valid_flash = 1;
|
||||
|
||||
#define TEST_PATH "test_data/"
|
||||
|
||||
char *make_test_fname(const char *name) {
|
||||
sprintf(_path, "%s%s", TEST_PATH, name);
|
||||
return _path;
|
||||
}
|
||||
|
||||
void clear_test_path() {
|
||||
//TODO: need to add later
|
||||
#if 0
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
dp = opendir(TEST_PATH);
|
||||
|
||||
if (dp != NULL) {
|
||||
while ((ep = readdir(dp))) {
|
||||
if (ep->d_name[0] != '.') {
|
||||
sprintf(_path, "%s%s", TEST_PATH, ep->d_name);
|
||||
remove(_path);
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define FLASH_UNIT_SIZE 4
|
||||
|
||||
static s32_t esp_spiffs_readwrite(u32_t addr, u32_t size, u8_t *p, int write)
|
||||
{
|
||||
/*
|
||||
* With proper configurarion spiffs never reads or writes more than
|
||||
* LOG_PAGE_SIZE
|
||||
*/
|
||||
|
||||
if (size > __fs.cfg.log_page_size) {
|
||||
printf("Invalid size provided to read/write (%d)\n\r", (int) size);
|
||||
return SPIFFS_ERR_NOT_CONFIGURED;
|
||||
}
|
||||
|
||||
char tmp_buf[__fs.cfg.log_page_size + FLASH_UNIT_SIZE * 2];
|
||||
u32_t aligned_addr = addr & (-FLASH_UNIT_SIZE);
|
||||
u32_t aligned_size =
|
||||
((size + (FLASH_UNIT_SIZE - 1)) & -FLASH_UNIT_SIZE) + FLASH_UNIT_SIZE;
|
||||
|
||||
int res = spi_flash_read(aligned_addr, (u32_t *) tmp_buf, aligned_size);
|
||||
|
||||
if (res != 0) {
|
||||
printf("spi_flash_read failed: %d (%d, %d)\n\r", res, (int) aligned_addr,
|
||||
(int) aligned_size);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!write) {
|
||||
memcpy(p, tmp_buf + (addr - aligned_addr), size);
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
memcpy(tmp_buf + (addr - aligned_addr), p, size);
|
||||
|
||||
res = spi_flash_write(aligned_addr, (u32_t *) tmp_buf, aligned_size);
|
||||
|
||||
if (res != 0) {
|
||||
// printf("spi_flash_write failed: %d (%d, %d)\n\r", res,
|
||||
// (int) aligned_addr, (int) aligned_size);
|
||||
return res;
|
||||
}
|
||||
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst)
|
||||
{
|
||||
return esp_spiffs_readwrite(addr, size, dst, 0);
|
||||
}
|
||||
|
||||
static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src)
|
||||
{
|
||||
return esp_spiffs_readwrite(addr, size, src, 1);
|
||||
}
|
||||
|
||||
static s32_t esp_spiffs_erase(u32_t addr, u32_t size)
|
||||
{
|
||||
/*
|
||||
* With proper configurarion spiffs always
|
||||
* provides here sector address & sector size
|
||||
*/
|
||||
if (size != __fs.cfg.phys_erase_block || addr % __fs.cfg.phys_erase_block != 0) {
|
||||
printf("Invalid size provided to esp_spiffs_erase (%d, %d)\n\r",
|
||||
(int) addr, (int) size);
|
||||
return SPIFFS_ERR_NOT_CONFIGURED;
|
||||
}
|
||||
|
||||
return spi_flash_erase_sector(addr / __fs.cfg.phys_erase_block);
|
||||
}
|
||||
|
||||
|
||||
static s32_t _read(u32_t addr, u32_t size, u8_t *dst) {
|
||||
if (log_flash_ops) {
|
||||
bytes_rd += size;
|
||||
reads++;
|
||||
if (error_after_bytes_read > 0 && bytes_rd >= error_after_bytes_read) {
|
||||
if (error_after_bytes_read_once_only) {
|
||||
error_after_bytes_read = 0;
|
||||
}
|
||||
return SPIFFS_ERR_TEST;
|
||||
}
|
||||
}
|
||||
if (addr < __fs.cfg.phys_addr) {
|
||||
printf("FATAL read addr too low %08x < %08x\n", addr, FS2_FLASH_ADDR);
|
||||
exit(0);
|
||||
}
|
||||
if (addr + size > __fs.cfg.phys_addr + __fs.cfg.phys_size) {
|
||||
printf("FATAL read addr too high %08x + %08x > %08x\n", addr, size, FS2_FLASH_ADDR + FS2_FLASH_SIZE);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return esp_spiffs_read(addr, size, dst);
|
||||
}
|
||||
|
||||
static s32_t _write(u32_t addr, u32_t size, u8_t *src) {
|
||||
//printf("wr %08x %i\n", addr, size);
|
||||
if (log_flash_ops) {
|
||||
bytes_wr += size;
|
||||
writes++;
|
||||
if (error_after_bytes_written > 0 && bytes_wr >= error_after_bytes_written) {
|
||||
if (error_after_bytes_written_once_only) {
|
||||
error_after_bytes_written = 0;
|
||||
}
|
||||
return SPIFFS_ERR_TEST;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr < __fs.cfg.phys_addr) {
|
||||
printf("FATAL write addr too low %08x < %08x\n", addr, FS2_FLASH_ADDR);
|
||||
exit(0);
|
||||
}
|
||||
if (addr + size > __fs.cfg.phys_addr + __fs.cfg.phys_size) {
|
||||
printf("FATAL write addr too high %08x + %08x > %08x\n", addr, size, FS2_FLASH_ADDR + FS2_FLASH_SIZE);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < size; i++) {
|
||||
if (((addr + i) & (__fs.cfg.log_page_size-1)) != offsetof(spiffs_page_header, flags)) {
|
||||
if (check_valid_flash && ((AREA(addr + i) ^ src[i]) & src[i])) {
|
||||
printf("trying to write %02x to %02x at addr %08x\n", src[i], AREA(addr + i), addr+i);
|
||||
spiffs_page_ix pix = (addr + i) / LOG_PAGE;
|
||||
dump_page(&__fs, pix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
AREA(addr + i) &= src[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
return esp_spiffs_write(addr, size, src);
|
||||
}
|
||||
|
||||
static s32_t _erase(u32_t addr, u32_t size) {
|
||||
if (addr & (__fs.cfg.phys_erase_block-1)) {
|
||||
printf("trying to erase at addr %08x, out of boundary\n", addr);
|
||||
return -1;
|
||||
}
|
||||
if (size & (__fs.cfg.phys_erase_block-1)) {
|
||||
printf("trying to erase at with size %08x, out of boundary\n", size);
|
||||
return -1;
|
||||
}
|
||||
erases[(addr-__fs.cfg.phys_addr)/__fs.cfg.phys_erase_block]++;
|
||||
return esp_spiffs_erase(addr, size);
|
||||
}
|
||||
|
||||
void hexdump_mem(u8_t *b, u32_t len) {
|
||||
while (len--) {
|
||||
if ((((int)b)&0x1f) == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("%02x", *b++);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void hexdump(u32_t addr, u32_t len) {
|
||||
//TODO: need to add later
|
||||
#if 0
|
||||
int remainder = (addr % 32) == 0 ? 0 : 32 - (addr % 32);
|
||||
u32_t a;
|
||||
for (a = addr - remainder; a < addr+len; a++) {
|
||||
if ((a & 0x1f) == 0) {
|
||||
if (a != addr) {
|
||||
printf(" ");
|
||||
int j;
|
||||
for (j = 0; j < 32; j++) {
|
||||
if (a-32+j < addr)
|
||||
printf(" ");
|
||||
else {
|
||||
printf("%c", (AREA(a-32+j) < 32 || AREA(a-32+j) >= 0x7f) ? '.' : AREA(a-32+j));
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%s %08x: ", a<=addr ? "":"\n", a);
|
||||
}
|
||||
if (a < addr) {
|
||||
printf(" ");
|
||||
} else {
|
||||
printf("%02x", AREA(a));
|
||||
}
|
||||
}
|
||||
int j;
|
||||
printf(" ");
|
||||
for (j = 0; j < 32; j++) {
|
||||
if (a-32+j < addr)
|
||||
printf(" ");
|
||||
else {
|
||||
printf("%c", (AREA(a-32+j) < 32 || AREA(a-32+j) >= 0x7f) ? '.' : AREA(a-32+j));
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void dump_page(spiffs *fs, spiffs_page_ix p) {
|
||||
//TODO: need to add later
|
||||
#if 0
|
||||
printf("page %04x ", p);
|
||||
u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, p);
|
||||
if (p % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
|
||||
// obj lu page
|
||||
printf("OBJ_LU");
|
||||
} else {
|
||||
u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs , p)) +
|
||||
SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, p) * sizeof(spiffs_obj_id);
|
||||
spiffs_obj_id obj_id = *((spiffs_obj_id *)&AREA(obj_id_addr));
|
||||
// data page
|
||||
spiffs_page_header *ph = (spiffs_page_header *)&AREA(addr);
|
||||
printf("DATA %04x:%04x ", obj_id, ph->span_ix);
|
||||
printf("%s", ((ph->flags & SPIFFS_PH_FLAG_FINAL) == 0) ? "FIN " : "fin ");
|
||||
printf("%s", ((ph->flags & SPIFFS_PH_FLAG_DELET) == 0) ? "DEL " : "del ");
|
||||
printf("%s", ((ph->flags & SPIFFS_PH_FLAG_INDEX) == 0) ? "IDX " : "idx ");
|
||||
printf("%s", ((ph->flags & SPIFFS_PH_FLAG_USED) == 0) ? "USD " : "usd ");
|
||||
printf("%s ", ((ph->flags & SPIFFS_PH_FLAG_IXDELE) == 0) ? "IDL " : "idl ");
|
||||
if (obj_id & SPIFFS_OBJ_ID_IX_FLAG) {
|
||||
// object index
|
||||
printf("OBJ_IX");
|
||||
if (ph->span_ix == 0) {
|
||||
printf("_HDR ");
|
||||
spiffs_page_object_ix_header *oix_hdr = (spiffs_page_object_ix_header *)&AREA(addr);
|
||||
printf("'%s' %i bytes type:%02x", oix_hdr->name, oix_hdr->size, oix_hdr->type);
|
||||
}
|
||||
} else {
|
||||
// data page
|
||||
printf("CONTENT");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
u32_t len = fs->cfg.log_page_size;
|
||||
hexdump(addr, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
void area_write(u32_t addr, u8_t *buf, u32_t size) {
|
||||
u32_t phys_erase_block = __fs.cfg.phys_erase_block;
|
||||
u32_t addr_align = addr & ~(phys_erase_block - 1);
|
||||
u8_t sec_num = (addr + size - addr_align - 1) / phys_erase_block + 1;
|
||||
u32_t buf_index = 0;
|
||||
u8_t *bbuf = malloc(phys_erase_block);
|
||||
|
||||
MALLOC_CHECK_RETURN(bbuf != NULL, phys_erase_block);
|
||||
|
||||
int i, j;
|
||||
for (i = 0; i < sec_num; i++) {
|
||||
spi_flash_read(addr_align + i * phys_erase_block, (u32_t *)bbuf, phys_erase_block);
|
||||
spi_flash_erase_sector((addr_align + i * phys_erase_block) / phys_erase_block);
|
||||
|
||||
for (j = buf_index;
|
||||
((addr - i * phys_erase_block) % phys_erase_block + j) < phys_erase_block && j < size;
|
||||
j++) {
|
||||
bbuf[addr % phys_erase_block + j] = buf[j];
|
||||
}
|
||||
|
||||
buf_index = j;
|
||||
spi_flash_write(addr_align + i * phys_erase_block, (u32_t *)bbuf, phys_erase_block);
|
||||
}
|
||||
|
||||
free(bbuf);
|
||||
}
|
||||
|
||||
void area_read(u32_t addr, u8_t *buf, u32_t size) {
|
||||
u32_t addr_align = addr & ~(3);
|
||||
u8_t read_num = (addr + size - addr_align - 1) / 4 + 1;
|
||||
u8_t *bbuf = malloc(read_num * 4);
|
||||
|
||||
MALLOC_CHECK_RETURN(bbuf != NULL, read_num * 4);
|
||||
|
||||
spi_flash_read(addr, (u32_t *)bbuf, read_num * 4);
|
||||
memcpy(buf, &bbuf[addr & 3], size);
|
||||
free(bbuf);
|
||||
}
|
||||
|
||||
void dump_erase_counts(spiffs *fs) {
|
||||
spiffs_block_ix bix;
|
||||
printf(" BLOCK |\n");
|
||||
printf(" AGE COUNT|\n");
|
||||
for (bix = 0; bix < fs->block_count; bix++) {
|
||||
printf("----%3i ----|", bix);
|
||||
}
|
||||
printf("\n");
|
||||
for (bix = 0; bix < fs->block_count; bix++) {
|
||||
spiffs_obj_id erase_mark;
|
||||
_spiffs_rd(fs, 0, 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), sizeof(spiffs_obj_id), (u8_t *)&erase_mark);
|
||||
if (erases[bix] == 0) {
|
||||
printf(" |");
|
||||
} else {
|
||||
printf("%7i %4i|", (fs->max_erase_count - erase_mark), erases[bix]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void dump_flash_access_stats() {
|
||||
printf(" RD: %10i reads %10i bytes %10i avg bytes/read\n", reads, bytes_rd, reads == 0 ? 0 : (bytes_rd / reads));
|
||||
printf(" WR: %10i writes %10i bytes %10i avg bytes/write\n", writes, bytes_wr, writes == 0 ? 0 : (bytes_wr / writes));
|
||||
}
|
||||
|
||||
|
||||
//static u32_t old_perc = 999;
|
||||
static void spiffs_check_cb_f(spiffs_check_type type, spiffs_check_report report,
|
||||
u32_t arg1, u32_t arg2) {
|
||||
/* if (report == SPIFFS_CHECK_PROGRESS && old_perc != arg1) {
|
||||
old_perc = arg1;
|
||||
printf("CHECK REPORT: ");
|
||||
switch(type) {
|
||||
case SPIFFS_CHECK_LOOKUP:
|
||||
printf("LU "); break;
|
||||
case SPIFFS_CHECK_INDEX:
|
||||
printf("IX "); break;
|
||||
case SPIFFS_CHECK_PAGE:
|
||||
printf("PA "); break;
|
||||
}
|
||||
printf("%i%%\n", arg1 * 100 / 256);
|
||||
}*/
|
||||
if (report != SPIFFS_CHECK_PROGRESS) {
|
||||
if (report != SPIFFS_CHECK_ERROR) fs_check_fixes++;
|
||||
printf(" check: ");
|
||||
switch (type) {
|
||||
case SPIFFS_CHECK_INDEX:
|
||||
printf("INDEX "); break;
|
||||
case SPIFFS_CHECK_LOOKUP:
|
||||
printf("LOOKUP "); break;
|
||||
case SPIFFS_CHECK_PAGE:
|
||||
printf("PAGE "); break;
|
||||
default:
|
||||
printf("???? "); break;
|
||||
}
|
||||
if (report == SPIFFS_CHECK_ERROR) {
|
||||
printf("ERROR %i", arg1);
|
||||
} else if (report == SPIFFS_CHECK_DELETE_BAD_FILE) {
|
||||
printf("DELETE BAD FILE %04x", arg1);
|
||||
} else if (report == SPIFFS_CHECK_DELETE_ORPHANED_INDEX) {
|
||||
printf("DELETE ORPHANED INDEX %04x", arg1);
|
||||
} else if (report == SPIFFS_CHECK_DELETE_PAGE) {
|
||||
printf("DELETE PAGE %04x", arg1);
|
||||
} else if (report == SPIFFS_CHECK_FIX_INDEX) {
|
||||
printf("FIX INDEX %04x:%04x", arg1, arg2);
|
||||
} else if (report == SPIFFS_CHECK_FIX_LOOKUP) {
|
||||
printf("FIX INDEX %04x:%04x", arg1, arg2);
|
||||
} else {
|
||||
printf("??");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void fs_set_addr_offset(u32_t offset) {
|
||||
addr_offset = offset;
|
||||
}
|
||||
|
||||
s32_t fs_mount_specific(u32_t phys_addr, u32_t phys_size,
|
||||
u32_t phys_sector_size,
|
||||
u32_t log_block_size, u32_t log_page_size) {
|
||||
spiffs_config c;
|
||||
c.hal_erase_f = _erase;
|
||||
c.hal_read_f = _read;
|
||||
c.hal_write_f = _write;
|
||||
c.log_block_size = log_block_size;
|
||||
c.log_page_size = log_page_size;
|
||||
c.phys_addr = phys_addr;
|
||||
c.phys_erase_block = phys_sector_size;
|
||||
c.phys_size = phys_size;
|
||||
|
||||
return SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);
|
||||
}
|
||||
|
||||
void fs_reset_specific(u32_t addr_offset, u32_t phys_addr, u32_t phys_size,
|
||||
u32_t phys_sector_size,
|
||||
u32_t log_block_size, u32_t log_page_size) {
|
||||
fs_set_addr_offset(addr_offset);
|
||||
|
||||
u8_t i;
|
||||
for (i = 0; i < phys_size / phys_sector_size; i++) {
|
||||
spi_flash_erase_sector(phys_addr / phys_sector_size + i);
|
||||
}
|
||||
|
||||
memset(&__fs, 0, sizeof(__fs));
|
||||
|
||||
memset(erases,0,sizeof(erases));
|
||||
memset(_cache,0,sizeof(_cache));
|
||||
|
||||
#if SPIFFS_USE_MAGIC
|
||||
s32_t res = fs_mount_specific(phys_addr, phys_size, phys_sector_size, log_block_size, log_page_size);
|
||||
#else
|
||||
fs_mount_specific(phys_addr, phys_size, phys_sector_size, log_block_size, log_page_size);
|
||||
#endif
|
||||
|
||||
#if SPIFFS_USE_MAGIC
|
||||
if (res == SPIFFS_OK) {
|
||||
SPIFFS_unmount(&__fs);
|
||||
}
|
||||
res = SPIFFS_format(&__fs);
|
||||
if (res != SPIFFS_OK) {
|
||||
printf("format failed, %i\n", SPIFFS_errno(&__fs));
|
||||
}
|
||||
res = fs_mount_specific(phys_addr, phys_size, phys_sector_size, log_block_size, log_page_size);
|
||||
if (res != SPIFFS_OK) {
|
||||
printf("mount failed, %i\n", SPIFFS_errno(&__fs));
|
||||
}
|
||||
#endif
|
||||
|
||||
clear_flash_ops_log();
|
||||
log_flash_ops = 1;
|
||||
fs_check_fixes = 0;
|
||||
}
|
||||
|
||||
void fs_reset() {
|
||||
esp_spiffs_deinit(1);
|
||||
spiffs_fs1_init();
|
||||
fs_reset_specific(0, FS2_FLASH_ADDR, FS2_FLASH_SIZE, SECTOR_SIZE, SECTOR_SIZE, LOG_PAGE);
|
||||
}
|
||||
|
||||
void fs_load_dump(char *fname) {
|
||||
int pfd = open(fname, O_RDONLY, S_IRUSR | S_IWUSR);
|
||||
|
||||
//too large
|
||||
#if 0
|
||||
read(pfd, area, sizeof(area));
|
||||
#endif
|
||||
|
||||
close(pfd);
|
||||
}
|
||||
|
||||
void set_flash_ops_log(int enable) {
|
||||
log_flash_ops = enable;
|
||||
}
|
||||
|
||||
void clear_flash_ops_log() {
|
||||
bytes_rd = 0;
|
||||
bytes_wr = 0;
|
||||
reads = 0;
|
||||
writes = 0;
|
||||
error_after_bytes_read = 0;
|
||||
error_after_bytes_written = 0;
|
||||
}
|
||||
|
||||
u32_t get_flash_ops_log_read_bytes() {
|
||||
return bytes_rd;
|
||||
}
|
||||
|
||||
u32_t get_flash_ops_log_write_bytes() {
|
||||
return bytes_wr;
|
||||
}
|
||||
|
||||
void invoke_error_after_read_bytes(u32_t b, char once_only) {
|
||||
error_after_bytes_read = b;
|
||||
error_after_bytes_read_once_only = once_only;
|
||||
}
|
||||
void invoke_error_after_write_bytes(u32_t b, char once_only) {
|
||||
error_after_bytes_written = b;
|
||||
error_after_bytes_written_once_only = once_only;
|
||||
}
|
||||
|
||||
void fs_set_validate_flashing(int i) {
|
||||
check_valid_flash = i;
|
||||
}
|
||||
|
||||
void real_assert(int c, const char *n, const char *file, int l) {
|
||||
if (c == 0) {
|
||||
printf("ASSERT: %s %s @ %i\n", (n ? n : ""), file, l);
|
||||
printf("fs errno:%i\n", __fs.err_code);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int read_and_verify(char *name) {
|
||||
int fd = SPIFFS_open(&__fs, name, SPIFFS_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
printf(" read_and_verify: could not open file %s\n", name);
|
||||
return fd;
|
||||
}
|
||||
return read_and_verify_fd(fd, name);
|
||||
}
|
||||
|
||||
int read_and_verify_fd(spiffs_file fd, char *name) {
|
||||
s32_t res;
|
||||
int pfd = open(make_test_fname(name), O_RDONLY);
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_fstat(&__fs, fd, &s);
|
||||
if (res < 0) {
|
||||
printf(" read_and_verify: could not stat file %s\n", name);
|
||||
return res;
|
||||
}
|
||||
if (s.size == 0) {
|
||||
SPIFFS_close(&__fs, fd);
|
||||
close(pfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//printf("verifying %s, len %i\n", name, s.size);
|
||||
int offs = 0;
|
||||
u8_t buf_d[256];
|
||||
u8_t buf_v[256];
|
||||
while (offs < s.size) {
|
||||
int read_len = MIN(s.size - offs, sizeof(buf_d));
|
||||
res = SPIFFS_read(&__fs, fd, buf_d, read_len);
|
||||
if (res < 0) {
|
||||
printf(" read_and_verify: could not read file %s offs:%i len:%i filelen:%i\n", name, offs, read_len, s.size);
|
||||
return res;
|
||||
}
|
||||
int pres = read(pfd, buf_v, read_len);
|
||||
(void)pres;
|
||||
//printf("reading offs:%i len:%i spiffs_res:%i posix_res:%i\n", offs, read_len, res, pres);
|
||||
int i;
|
||||
int veri_ok = 1;
|
||||
for (i = 0; veri_ok && i < read_len; i++) {
|
||||
if (buf_d[i] != buf_v[i]) {
|
||||
printf("file verification mismatch @ %i, %02x %c != %02x %c\n", offs+i, buf_d[i], buf_d[i], buf_v[i], buf_v[i]);
|
||||
int j = MAX(0, i-16);
|
||||
int k = MIN(sizeof(buf_d), i+16);
|
||||
k = MIN(s.size-offs, k);
|
||||
int l;
|
||||
for (l = j; l < k; l++) {
|
||||
printf("%c", buf_d[l] > 31 ? buf_d[l] : '.');
|
||||
}
|
||||
printf("\n");
|
||||
for (l = j; l < k; l++) {
|
||||
printf("%c", buf_v[l] > 31 ? buf_v[l] : '.');
|
||||
}
|
||||
printf("\n");
|
||||
veri_ok = 0;
|
||||
}
|
||||
}
|
||||
if (!veri_ok) {
|
||||
SPIFFS_close(&__fs, fd);
|
||||
close(pfd);
|
||||
printf("data mismatch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
offs += read_len;
|
||||
}
|
||||
|
||||
SPIFFS_close(&__fs, fd);
|
||||
close(pfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_on_stop(test *t) {
|
||||
printf(" spiffs errno:%i\n", SPIFFS_errno(&__fs));
|
||||
#if SPIFFS_TEST_VISUALISATION
|
||||
SPIFFS_vis(FS);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void memrand(u8_t *b, int len) {
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
b[i] = rand();
|
||||
}
|
||||
}
|
||||
|
||||
int test_create_file(char *name) {
|
||||
spiffs_stat s;
|
||||
spiffs_file fd;
|
||||
int res = SPIFFS_creat(FS, name, 0);
|
||||
CHECK_RES(res);
|
||||
fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0);
|
||||
CHECK(fd >= 0);
|
||||
res = SPIFFS_fstat(FS, fd, &s);
|
||||
CHECK_RES(res);
|
||||
CHECK(strcmp((char*)s.name, name) == 0);
|
||||
CHECK(s.size == 0);
|
||||
SPIFFS_close(FS, fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_create_and_write_file(char *name, int size, int chunk_size) {
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
printf(" create and write %s", name);
|
||||
res = test_create_file(name);
|
||||
if (res < 0) {
|
||||
printf(" failed creation, %i\n",res);
|
||||
}
|
||||
CHECK(res >= 0);
|
||||
fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0);
|
||||
if (res < 0) {
|
||||
printf(" failed open, %i\n",res);
|
||||
}
|
||||
CHECK(fd >= 0);
|
||||
int pfd = open(make_test_fname(name), O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
int offset = 0;
|
||||
int mark = 0;
|
||||
while (offset < size) {
|
||||
int len = MIN(size-offset, chunk_size);
|
||||
if (offset > mark) {
|
||||
mark += size/16;
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
}
|
||||
u8_t *buf = malloc(len);
|
||||
MALLOC_CHECK_RETURN_1(buf != NULL, len);
|
||||
memrand(buf, len);
|
||||
res = SPIFFS_write(FS, fd, buf, len);
|
||||
write(pfd, buf, len);
|
||||
free(buf);
|
||||
if (res < 0) {
|
||||
printf("\n error @ offset %i, res %i\n", offset, res);
|
||||
}
|
||||
offset += len;
|
||||
CHECK(res >= 0);
|
||||
}
|
||||
printf("\n");
|
||||
close(pfd);
|
||||
|
||||
spiffs_stat stat;
|
||||
res = SPIFFS_fstat(FS, fd, &stat);
|
||||
if (res < 0) {
|
||||
printf(" failed fstat, %i\n",res);
|
||||
}
|
||||
CHECK(res >= 0);
|
||||
if (stat.size != size) {
|
||||
printf(" failed size, %i != %i\n", stat.size, size);
|
||||
}
|
||||
CHECK(stat.size == size);
|
||||
|
||||
SPIFFS_close(FS, fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if SPIFFS_CACHE
|
||||
#if SPIFFS_CACHE_STATS
|
||||
static u32_t chits_tot = 0;
|
||||
static u32_t cmiss_tot = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void _setup_test_only() {
|
||||
fs_set_validate_flashing(1);
|
||||
test_init(test_on_stop);
|
||||
}
|
||||
|
||||
void _setup() {
|
||||
fs_reset();
|
||||
_setup_test_only();
|
||||
}
|
||||
|
||||
void _teardown() {
|
||||
printf(" free blocks : %i of %i\n", (FS)->free_blocks, (FS)->block_count);
|
||||
printf(" pages allocated : %i\n", (FS)->stats_p_allocated);
|
||||
printf(" pages deleted : %i\n", (FS)->stats_p_deleted);
|
||||
#if SPIFFS_GC_STATS
|
||||
printf(" gc runs : %i\n", (FS)->stats_gc_runs);
|
||||
#endif
|
||||
#if SPIFFS_CACHE
|
||||
#if SPIFFS_CACHE_STATS
|
||||
chits_tot += (FS)->cache_hits;
|
||||
cmiss_tot += (FS)->cache_misses;
|
||||
printf(" cache hits : %i (sum %i)\n", (FS)->cache_hits, chits_tot);
|
||||
printf(" cache misses : %i (sum %i)\n", (FS)->cache_misses, cmiss_tot);
|
||||
printf(" cache utiliz : %f\n", ((float)chits_tot/(float)(chits_tot + cmiss_tot)));
|
||||
chits_tot = 0;
|
||||
cmiss_tot = 0;
|
||||
#endif
|
||||
#endif
|
||||
dump_flash_access_stats();
|
||||
clear_flash_ops_log();
|
||||
#if SPIFFS_GC_STATS
|
||||
if ((FS)->stats_gc_runs > 0)
|
||||
#endif
|
||||
dump_erase_counts(FS);
|
||||
printf(" fs consistency check:\n");
|
||||
SPIFFS_check(FS);
|
||||
clear_test_path();
|
||||
|
||||
//hexdump_mem(&AREA(SPIFFS_PHYS_ADDR - 16), 32);
|
||||
//hexdump_mem(&AREA(SPIFFS_PHYS_ADDR + SPIFFS_FLASH_SIZE - 16), 32);
|
||||
}
|
||||
|
||||
u32_t tfile_get_size(tfile_size s) {
|
||||
switch (s) {
|
||||
case EMPTY:
|
||||
return 0;
|
||||
case SMALL:
|
||||
return SPIFFS_DATA_PAGE_SIZE(FS)/2;
|
||||
case MEDIUM:
|
||||
return (SPIFFS_DATA_PAGE_SIZE(FS) * (SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS)))/2;
|
||||
case LARGE:
|
||||
return (FS)->cfg.phys_size/40;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int run_file_config(int cfg_count, tfile_conf* cfgs, int max_runs, int max_concurrent_files, int dbg) {
|
||||
int res;
|
||||
tfile *tfiles = malloc(sizeof(tfile) * max_concurrent_files);
|
||||
MALLOC_CHECK_RETURN_1(tfiles != NULL, sizeof(tfile) * max_concurrent_files);
|
||||
memset(tfiles, 0, sizeof(tfile) * max_concurrent_files);
|
||||
int run = 0;
|
||||
int cur_config_ix = 0;
|
||||
char name[32];
|
||||
while (run < max_runs) {
|
||||
if (dbg) printf(" run %i/%i\n", run, max_runs);
|
||||
int i;
|
||||
for (i = 0; i < max_concurrent_files; i++) {
|
||||
sprintf(name, "file%i_%i", (1+run), i);
|
||||
tfile *tf = &tfiles[i];
|
||||
if (tf->state == 0 && cur_config_ix < cfg_count) {
|
||||
// create a new file
|
||||
strcpy(tf->name, name);
|
||||
tf->state = 1;
|
||||
tf->cfg = cfgs[cur_config_ix];
|
||||
int size = tfile_get_size(tf->cfg.tsize);
|
||||
if (dbg) printf(" create new %s with cfg %i/%i, size %i\n", name, (1+cur_config_ix), cfg_count, size);
|
||||
|
||||
if (tf->cfg.tsize == EMPTY) {
|
||||
res = SPIFFS_creat(FS, name, 0);
|
||||
CHECK_RES(res);
|
||||
int pfd = open(make_test_fname(name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
close(pfd);
|
||||
int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0;
|
||||
spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_RDWR, 0);
|
||||
CHECK(fd > 0);
|
||||
tf->fd = fd;
|
||||
} else {
|
||||
int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0;
|
||||
spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0);
|
||||
CHECK(fd > 0);
|
||||
extra_flags = tf->cfg.ttype == APPENDED ? O_APPEND : 0;
|
||||
int pfd = open(make_test_fname(name), extra_flags | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
tf->fd = fd;
|
||||
u8_t *buf = malloc(size);
|
||||
MALLOC_CHECK_RETURN_1(buf != NULL, size);
|
||||
memrand(buf, size);
|
||||
res = SPIFFS_write(FS, fd, buf, size);
|
||||
CHECK_RES(res);
|
||||
write(pfd, buf, size);
|
||||
close(pfd);
|
||||
free(buf);
|
||||
res = read_and_verify(name);
|
||||
CHECK_RES(res);
|
||||
}
|
||||
|
||||
cur_config_ix++;
|
||||
} else if (tf->state > 0) {
|
||||
// hande file lifecycle
|
||||
switch (tf->cfg.ttype) {
|
||||
case UNTAMPERED: {
|
||||
break;
|
||||
}
|
||||
case APPENDED: {
|
||||
if (dbg) printf(" appending %s\n", tf->name);
|
||||
int size = SPIFFS_DATA_PAGE_SIZE(FS)*3;
|
||||
u8_t *buf = malloc(size);
|
||||
MALLOC_CHECK_RETURN_1(buf != NULL, size);
|
||||
memrand(buf, size);
|
||||
res = SPIFFS_write(FS, tf->fd, buf, size);
|
||||
CHECK_RES(res);
|
||||
int pfd = open(make_test_fname(tf->name), O_APPEND | O_RDWR);
|
||||
write(pfd, buf, size);
|
||||
close(pfd);
|
||||
free(buf);
|
||||
res = read_and_verify(tf->name);
|
||||
CHECK_RES(res);
|
||||
break;
|
||||
}
|
||||
case MODIFIED: {
|
||||
if (dbg) printf(" modify %s\n", tf->name);
|
||||
spiffs_stat stat;
|
||||
res = SPIFFS_fstat(FS, tf->fd, &stat);
|
||||
CHECK_RES(res);
|
||||
int size = stat.size / tf->cfg.tlife + SPIFFS_DATA_PAGE_SIZE(FS)/3;
|
||||
int offs = (stat.size / tf->cfg.tlife) * tf->state;
|
||||
res = SPIFFS_lseek(FS, tf->fd, offs, SPIFFS_SEEK_SET);
|
||||
CHECK_RES(res);
|
||||
u8_t *buf = malloc(size);
|
||||
MALLOC_CHECK_RETURN_1(buf != NULL, size);
|
||||
memrand(buf, size);
|
||||
res = SPIFFS_write(FS, tf->fd, buf, size);
|
||||
CHECK_RES(res);
|
||||
int pfd = open(make_test_fname(tf->name), O_RDWR);
|
||||
lseek(pfd, offs, SEEK_SET);
|
||||
write(pfd, buf, size);
|
||||
close(pfd);
|
||||
free(buf);
|
||||
res = read_and_verify(tf->name);
|
||||
CHECK_RES(res);
|
||||
break;
|
||||
}
|
||||
case REWRITTEN: {
|
||||
if (tf->fd > 0) {
|
||||
SPIFFS_close(FS, tf->fd);
|
||||
}
|
||||
if (dbg) printf(" rewriting %s\n", tf->name);
|
||||
spiffs_file fd = SPIFFS_open(FS, tf->name, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0);
|
||||
CHECK(fd > 0);
|
||||
int pfd = open(make_test_fname(tf->name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
tf->fd = fd;
|
||||
int size = tfile_get_size(tf->cfg.tsize);
|
||||
u8_t *buf = malloc(size);
|
||||
MALLOC_CHECK_RETURN_1(buf != NULL, size);
|
||||
memrand(buf, size);
|
||||
res = SPIFFS_write(FS, fd, buf, size);
|
||||
CHECK_RES(res);
|
||||
write(pfd, buf, size);
|
||||
close(pfd);
|
||||
free(buf);
|
||||
res = read_and_verify(tf->name);
|
||||
CHECK_RES(res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
tf->state++;
|
||||
if (tf->state > tf->cfg.tlife) {
|
||||
// file outlived its time, kill it
|
||||
if (tf->fd > 0) {
|
||||
SPIFFS_close(FS, tf->fd);
|
||||
}
|
||||
if (dbg) printf(" removing %s\n", tf->name);
|
||||
res = read_and_verify(tf->name);
|
||||
CHECK_RES(res);
|
||||
res = SPIFFS_remove(FS, tf->name);
|
||||
CHECK_RES(res);
|
||||
remove(make_test_fname(tf->name));
|
||||
memset(tf, 0, sizeof(*tf));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
run++;
|
||||
}
|
||||
free(tfiles);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* test_spiffs.h
|
||||
*
|
||||
* Created on: Jun 19, 2013
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
#ifndef TEST_SPIFFS_H_
|
||||
#define TEST_SPIFFS_H_
|
||||
|
||||
#include "spiffs.h"
|
||||
|
||||
#define FS &__fs
|
||||
|
||||
extern spiffs __fs;
|
||||
|
||||
|
||||
#define CHECK(r) if (!(r)) return -1;
|
||||
#define CHECK_RES(r) if (r < 0) return -1;
|
||||
#define FS_PURE_DATA_PAGES(fs) \
|
||||
((fs)->cfg.phys_size / (fs)->cfg.log_page_size - (fs)->block_count * SPIFFS_OBJ_LOOKUP_PAGES(fs))
|
||||
#define FS_PURE_DATA_SIZE(fs) \
|
||||
FS_PURE_DATA_PAGES(fs) * SPIFFS_DATA_PAGE_SIZE(fs)
|
||||
|
||||
typedef enum {
|
||||
EMPTY,
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE,
|
||||
} tfile_size;
|
||||
|
||||
typedef enum {
|
||||
UNTAMPERED,
|
||||
APPENDED,
|
||||
MODIFIED,
|
||||
REWRITTEN,
|
||||
} tfile_type;
|
||||
|
||||
typedef enum {
|
||||
SHORT = 4,
|
||||
NORMAL = 20,
|
||||
LONG = 100,
|
||||
} tfile_life;
|
||||
|
||||
typedef struct {
|
||||
tfile_size tsize;
|
||||
tfile_type ttype;
|
||||
tfile_life tlife;
|
||||
} tfile_conf;
|
||||
|
||||
typedef struct {
|
||||
int state;
|
||||
spiffs_file fd;
|
||||
tfile_conf cfg;
|
||||
char name[32];
|
||||
} tfile;
|
||||
|
||||
|
||||
void fs_reset();
|
||||
void fs_reset_specific(u32_t addr_offset, u32_t phys_addr, u32_t phys_size,
|
||||
u32_t phys_sector_size,
|
||||
u32_t log_block_size, u32_t log_page_size);
|
||||
s32_t fs_mount_specific(u32_t phys_addr, u32_t phys_size,
|
||||
u32_t phys_sector_size,
|
||||
u32_t log_block_size, u32_t log_page_size);
|
||||
void fs_set_addr_offset(u32_t offset);
|
||||
int read_and_verify(char *name);
|
||||
int read_and_verify_fd(spiffs_file fd, char *name);
|
||||
void dump_page(spiffs *fs, spiffs_page_ix p);
|
||||
void hexdump(u32_t addr, u32_t len);
|
||||
char *make_test_fname(const char *name);
|
||||
void clear_test_path();
|
||||
void area_write(u32_t addr, u8_t *buf, u32_t size);
|
||||
void area_read(u32_t addr, u8_t *buf, u32_t size);
|
||||
void dump_erase_counts(spiffs *fs);
|
||||
void dump_flash_access_stats();
|
||||
void set_flash_ops_log(int enable);
|
||||
void clear_flash_ops_log();
|
||||
u32_t get_flash_ops_log_read_bytes();
|
||||
u32_t get_flash_ops_log_write_bytes();
|
||||
void invoke_error_after_read_bytes(u32_t b, char once_only);
|
||||
void invoke_error_after_write_bytes(u32_t b, char once_only);
|
||||
|
||||
void memrand(u8_t *b, int len);
|
||||
int test_create_file(char *name);
|
||||
int test_create_and_write_file(char *name, int size, int chunk_size);
|
||||
void _setup();
|
||||
void _setup_test_only();
|
||||
void _teardown();
|
||||
u32_t tfile_get_size(tfile_size s);
|
||||
int run_file_config(int cfg_count, tfile_conf* cfgs, int max_runs, int max_concurrent_files, int dbg);
|
||||
|
||||
|
||||
#endif /* TEST_SPIFFS_H_ */
|
@ -1,214 +0,0 @@
|
||||
/*
|
||||
* testrunner.c
|
||||
*
|
||||
* Created on: Jun 18, 2013
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
//#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "testrunner.h"
|
||||
|
||||
static struct {
|
||||
test *tests;
|
||||
test *_last_test;
|
||||
int test_count;
|
||||
void (*on_stop)(test *t);
|
||||
test_res *failed;
|
||||
test_res *failed_last;
|
||||
test_res *stopped;
|
||||
test_res *stopped_last;
|
||||
FILE *spec;
|
||||
char incl_filter[256];
|
||||
char excl_filter[256];
|
||||
} test_main;
|
||||
|
||||
void test_init(void (*on_stop)(test *t)) {
|
||||
test_main.on_stop = on_stop;
|
||||
}
|
||||
|
||||
static char check_spec(char *name) {
|
||||
if (test_main.spec) {
|
||||
fseek(test_main.spec, 0, SEEK_SET);
|
||||
char *line = NULL;
|
||||
size_t sz;
|
||||
ssize_t read;
|
||||
while ((read = __getline(&line, &sz, test_main.spec)) != -1) {
|
||||
if (strncmp(line, name, strlen(line)-1) == 0) {
|
||||
free(line);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static char check_incl_filter(char *name) {
|
||||
if (strlen(test_main.incl_filter)== 0) return 1;
|
||||
return strstr(name, test_main.incl_filter) == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
static char check_excl_filter(char *name) {
|
||||
if (strlen(test_main.excl_filter)== 0) return 1;
|
||||
return strstr(name, test_main.excl_filter) == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
void add_test(test_f f, char *name, void (*setup)(test *t), void (*teardown)(test *t)) {
|
||||
if (f == 0) return;
|
||||
if (!check_spec(name)) return;
|
||||
if (!check_incl_filter(name)) return;
|
||||
if (!check_excl_filter(name)) return;
|
||||
DBGT("adding test %s\n", name);
|
||||
test *t = malloc(sizeof(test));
|
||||
MALLOC_CHECK_RETURN(t != NULL, sizeof(test));
|
||||
memset(t, 0, sizeof(test));
|
||||
t->f = f;
|
||||
strcpy(t->name, name);
|
||||
t->setup = setup;
|
||||
t->teardown = teardown;
|
||||
if (test_main.tests == 0) {
|
||||
test_main.tests = t;
|
||||
} else {
|
||||
test_main._last_test->_next = t;
|
||||
}
|
||||
test_main._last_test = t;
|
||||
test_main.test_count++;
|
||||
}
|
||||
|
||||
static void add_res(test *t, test_res **head, test_res **last) {
|
||||
test_res *tr = malloc(sizeof(test_res));
|
||||
MALLOC_CHECK_RETURN(t != NULL, sizeof(test));
|
||||
memset(tr,0,sizeof(test_res));
|
||||
strcpy(tr->name, t->name);
|
||||
if (*head == 0) {
|
||||
*head = tr;
|
||||
} else {
|
||||
(*last)->_next = tr;
|
||||
}
|
||||
*last = tr;
|
||||
}
|
||||
|
||||
static void dump_res(test_res **head) {
|
||||
test_res *tr = (*head);
|
||||
while (tr) {
|
||||
test_res *next_tr = tr->_next;
|
||||
printf(" %s\n", tr->name);
|
||||
free(tr);
|
||||
tr = next_tr;
|
||||
}
|
||||
}
|
||||
|
||||
int run_tests(int argc, char **args) {
|
||||
memset(&test_main, 0, sizeof(test_main));
|
||||
int arg;
|
||||
int incl_filter = 0;
|
||||
int excl_filter = 0;
|
||||
for (arg = 0; arg < argc; arg++) {
|
||||
if (strlen(args[arg]) == 0) continue;
|
||||
if (0 == strcmp("-f", args[arg])) {
|
||||
incl_filter = 1;
|
||||
continue;
|
||||
}
|
||||
if (0 == strcmp("-e", args[arg])) {
|
||||
excl_filter = 1;
|
||||
continue;
|
||||
}
|
||||
if (incl_filter) {
|
||||
strcpy(test_main.incl_filter, args[arg]);
|
||||
incl_filter = 0;
|
||||
} else if (excl_filter) {
|
||||
strcpy(test_main.excl_filter, args[arg]);
|
||||
excl_filter = 0;
|
||||
} else {
|
||||
printf("running tests from %s\n", args[arg]);
|
||||
FILE *fd = fopen(args[1], "r");
|
||||
if (fd == NULL) {
|
||||
printf("%s not found\n", args[arg]);
|
||||
return -2;
|
||||
}
|
||||
test_main.spec = fd;
|
||||
}
|
||||
}
|
||||
|
||||
DBGT("adding suites...\n");
|
||||
add_suites();
|
||||
DBGT("%i tests added\n", test_main.test_count);
|
||||
if (test_main.spec) {
|
||||
fclose(test_main.spec);
|
||||
}
|
||||
|
||||
if (test_main.test_count == 0) {
|
||||
printf("No tests to run\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd_success = open("_tests_ok", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
int fd_bad = open("_tests_fail", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
|
||||
DBGT("running tests...\n");
|
||||
int ok = 0;
|
||||
int failed = 0;
|
||||
int stopped = 0;
|
||||
test *cur_t = test_main.tests;
|
||||
int i = 1;
|
||||
while (cur_t) {
|
||||
cur_t->setup(cur_t);
|
||||
test *next_test = cur_t->_next;
|
||||
DBGT("TEST %i/%i : running test %s\n", i, test_main.test_count, cur_t->name);
|
||||
i++;
|
||||
int res = cur_t->f(cur_t);
|
||||
cur_t->test_result = res;
|
||||
cur_t->teardown(cur_t);
|
||||
int fd = res == TEST_RES_OK ? fd_success : fd_bad;
|
||||
write(fd, cur_t->name, strlen(cur_t->name));
|
||||
write(fd, "\n", 1);
|
||||
switch (res) {
|
||||
case TEST_RES_OK:
|
||||
ok++;
|
||||
printf(" .. ok\n");
|
||||
break;
|
||||
case TEST_RES_FAIL:
|
||||
failed++;
|
||||
printf(" .. FAILED\n");
|
||||
if (test_main.on_stop) test_main.on_stop(cur_t);
|
||||
add_res(cur_t, &test_main.failed, &test_main.failed_last);
|
||||
break;
|
||||
case TEST_RES_ASSERT:
|
||||
stopped++;
|
||||
printf(" .. ABORTED\n");
|
||||
if (test_main.on_stop) test_main.on_stop(cur_t);
|
||||
add_res(cur_t, &test_main.stopped, &test_main.stopped_last);
|
||||
break;
|
||||
}
|
||||
free(cur_t);
|
||||
cur_t = next_test;
|
||||
}
|
||||
close(fd_success);
|
||||
close(fd_bad);
|
||||
DBGT("ran %i tests\n", test_main.test_count);
|
||||
printf("Test report, %i tests\n", test_main.test_count);
|
||||
printf("%i succeeded\n", ok);
|
||||
printf("%i failed\n", failed);
|
||||
dump_res(&test_main.failed);
|
||||
printf("%i stopped\n", stopped);
|
||||
dump_res(&test_main.stopped);
|
||||
if (ok < test_main.test_count) {
|
||||
printf("\nFAILED\n");
|
||||
return -1;
|
||||
} else {
|
||||
printf("\nALL TESTS OK\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* testrunner.h
|
||||
*
|
||||
* Created on: Jun 19, 2013
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
SUITE(mysuite)
|
||||
|
||||
void setup(test *t) {}
|
||||
|
||||
void teardown(test *t) {}
|
||||
|
||||
TEST(mytest) {
|
||||
printf("mytest runs now..\n");
|
||||
return 0;
|
||||
} TEST_END(mytest)
|
||||
|
||||
SUITE_END(mysuite)
|
||||
|
||||
|
||||
|
||||
SUITE(mysuite2)
|
||||
|
||||
void setup(test *t) {}
|
||||
|
||||
void teardown(test *t) {}
|
||||
|
||||
TEST(mytest2a) {
|
||||
printf("mytest2a runs now..\n");
|
||||
return 0;
|
||||
} TEST_END(mytest2a)
|
||||
|
||||
TEST(mytest2b) {
|
||||
printf("mytest2b runs now..\n");
|
||||
return 0;
|
||||
} TEST_END(mytest2b)
|
||||
|
||||
SUITE_END(mysuite2)
|
||||
|
||||
|
||||
|
||||
void add_suites() {
|
||||
ADD_SUITE(mysuite);
|
||||
ADD_SUITE(mysuite2);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifndef TESTRUNNER_H_
|
||||
#define TESTRUNNER_H_
|
||||
|
||||
#define TEST_RES_OK 0
|
||||
#define TEST_RES_FAIL -1
|
||||
#define TEST_RES_ASSERT -2
|
||||
|
||||
struct test_s;
|
||||
|
||||
typedef int (*test_f)(struct test_s *t);
|
||||
|
||||
typedef struct test_s {
|
||||
test_f f;
|
||||
char name[64];
|
||||
void *data;
|
||||
void (*setup)(struct test_s *t);
|
||||
void (*teardown)(struct test_s *t);
|
||||
struct test_s *_next;
|
||||
unsigned char test_result;
|
||||
} test;
|
||||
|
||||
typedef struct test_res_s {
|
||||
char name[256];
|
||||
struct test_res_s *_next;
|
||||
} test_res;
|
||||
|
||||
#define MALLOC_CHECK(x, y) if (!(x)) { \
|
||||
printf(" MALLOC %i FAIL %s:%i, FREE %i\n", y, __FILE__, __LINE__, esp_get_free_heap_size()); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
|
||||
#define MALLOC_CHECK_RETURN(x, y) if (!(x)) { \
|
||||
printf(" MALLOC %i FAIL %s:%i, FREE %i\n", y, __FILE__, __LINE__, esp_get_free_heap_size()); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define MALLOC_CHECK_RETURN_1(x, y) if (!(x)) { \
|
||||
printf(" MALLOC %i FAIL %s:%i, FREE %i\n", y, __FILE__, __LINE__, esp_get_free_heap_size()); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
#define TEST_CHECK(x) if (!(x)) { \
|
||||
printf(" TEST FAIL %s:%i\n", __FILE__, __LINE__); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
#define TEST_CHECK_EQ(x, y) if ((x) != (y)) { \
|
||||
printf(" TEST FAIL %s:%i, %i != %i\n", __FILE__, __LINE__, (x), (y)); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
#define TEST_CHECK_NEQ(x, y) if ((x) == (y)) { \
|
||||
printf(" TEST FAIL %s:%i, %i == %i\n", __FILE__, __LINE__, (x), (y)); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
#define TEST_CHECK_GT(x, y) if ((x) <= (y)) { \
|
||||
printf(" TEST FAIL %s:%i, %i <= %i\n", __FILE__, __LINE__, (x), (y)); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
#define TEST_CHECK_LT(x, y) if ((x) >= (y)) { \
|
||||
printf(" TEST FAIL %s:%i, %i >= %i\n", __FILE__, __LINE__, (x), (y)); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
#define TEST_CHECK_GE(x, y) if ((x) < (y)) { \
|
||||
printf(" TEST FAIL %s:%i, %i < %i\n", __FILE__, __LINE__, (x), (y)); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
#define TEST_CHECK_LE(x, y) if ((x) > (y)) { \
|
||||
printf(" TEST FAIL %s:%i, %i > %i\n", __FILE__, __LINE__, (x), (y)); \
|
||||
goto __fail_stop; \
|
||||
}
|
||||
#define TEST_ASSERT(x) if (!(x)) { \
|
||||
printf(" TEST ASSERT %s:%i\n", __FILE__, __LINE__); \
|
||||
goto __fail_assert; \
|
||||
}
|
||||
|
||||
#define DBGT(...) printf(__VA_ARGS__)
|
||||
|
||||
#define str(s) #s
|
||||
|
||||
#define SUITE(sui) \
|
||||
extern void __suite_##sui() {
|
||||
#define SUITE_END(sui) \
|
||||
}
|
||||
#define ADD_SUITE(sui) \
|
||||
__suite_##sui();
|
||||
#define TEST(tf) \
|
||||
int tf(struct test_s *t) { do
|
||||
#define TEST_END(tf) \
|
||||
while(0); \
|
||||
__fail_stop: return TEST_RES_FAIL; \
|
||||
__fail_assert: return TEST_RES_ASSERT; \
|
||||
} \
|
||||
add_test(tf, str(tf), setup, teardown);
|
||||
|
||||
|
||||
void add_suites();
|
||||
void test_init(void (*on_stop)(test *t));
|
||||
void add_test(test_f f, char *name, void (*setup)(test *t), void (*teardown)(test *t));
|
||||
// returns 0 if all tests ok, -1 if any test failed, -2 on badness
|
||||
int run_tests(int argc, char **args);
|
||||
|
||||
#endif /* TESTRUNNER_H_ */
|
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* testsuites.c
|
||||
*
|
||||
* Created on: Jun 19, 2013
|
||||
* Author: petera
|
||||
*/
|
||||
|
||||
#include "testrunner.h"
|
||||
|
||||
void add_suites() {
|
||||
//ADD_SUITE(dev_tests);
|
||||
ADD_SUITE(check_tests);
|
||||
ADD_SUITE(hydrogen_tests)
|
||||
ADD_SUITE(bug_tests)
|
||||
}
|
Reference in New Issue
Block a user