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:
Dong Heng
2018-12-28 20:15:59 +08:00
13 changed files with 0 additions and 3835 deletions

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}
}

View File

@ -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_ */

View File

@ -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)
}