mirror of https://github.com/jeelabs/esp-link.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1267 lines
32 KiB
1267 lines
32 KiB
7 years ago
|
/*
|
||
|
* 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>
|
||
|
|
||
|
/* The follow defines control details of how the fuzzer can exercise the API. If you
|
||
|
* undef any of these, then the fuzzer is less brutal. FOr example, if you undef
|
||
|
* HAVE_REMOVE_OPEN, then the fuzzer will not attempt to remove (or rename) an open file
|
||
|
*/
|
||
|
#define HAVE_REMOVE_OPEN
|
||
|
#define HAVE_MULTIPLE_OPEN
|
||
|
#define NO_FORCE_CHECK
|
||
|
|
||
|
SUITE(bug_tests)
|
||
|
static void setup() {
|
||
|
_setup_test_only();
|
||
|
}
|
||
|
static void teardown() {
|
||
|
_teardown();
|
||
|
}
|
||
|
|
||
|
TEST(nodemcu_full_fs_1) {
|
||
|
fs_reset_specific(0, 0, 4096*20, 4096, 4096, 256);
|
||
|
|
||
|
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 < 0);
|
||
|
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED);
|
||
|
res2 = SPIFFS_stat(FS, "test1.txt", &s);
|
||
|
TEST_CHECK(res2 < 0);
|
||
|
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
|
||
|
|
||
|
TEST(nodemcu_full_fs_2) {
|
||
|
fs_reset_specific(0, 0, 4096*22, 4096, 4096, 256);
|
||
|
|
||
|
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
|
||
|
|
||
|
TEST(magic_test) {
|
||
|
// this test only works on default sizes
|
||
|
TEST_ASSERT(sizeof(spiffs_obj_id) == sizeof(u16_t));
|
||
|
|
||
|
// one obj lu page, not full
|
||
|
fs_reset_specific(0, 0, 4096*16, 4096, 4096*1, 128);
|
||
|
TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||
|
// one obj lu page, full
|
||
|
fs_reset_specific(0, 0, 4096*16, 4096, 4096*2, 128);
|
||
|
TEST_CHECK(!SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||
|
// two obj lu pages, not full
|
||
|
fs_reset_specific(0, 0, 4096*16, 4096, 4096*4, 128);
|
||
|
TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(nodemcu_309) {
|
||
|
fs_reset_specific(0, 0, 4096*20, 4096, 4096, 256);
|
||
|
|
||
|
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); // disabled, depends on too many variables
|
||
|
|
||
|
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
|
||
|
|
||
|
|
||
|
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, 0, 1024*1024*2, 65536, 65536, 256);
|
||
|
|
||
|
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(0, 1024*1024*2, 65536, 65536, 256);
|
||
|
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
|
||
|
|
||
|
|
||
|
TEST(spiffs_12) {
|
||
|
fs_reset_specific(0x4024c000, 0x4024c000 + 0, 192*1024, 4096, 4096*2, 256);
|
||
|
|
||
|
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
|
||
|
|
||
|
|
||
|
TEST(zero_sized_file_44) {
|
||
|
fs_reset();
|
||
|
|
||
|
spiffs_file fd = SPIFFS_open(FS, "zero", SPIFFS_RDWR | SPIFFS_CREAT, 0);
|
||
|
TEST_CHECK_GE(fd, 0);
|
||
|
|
||
|
int res = SPIFFS_close(FS, fd);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
fd = SPIFFS_open(FS, "zero", SPIFFS_RDWR, 0);
|
||
|
TEST_CHECK_GE(fd, 0);
|
||
|
|
||
|
u8_t buf[8];
|
||
|
res = SPIFFS_read(FS, fd, buf, 8);
|
||
|
TEST_CHECK_EQ(res, 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_END_OF_OBJECT);
|
||
|
|
||
|
res = SPIFFS_read(FS, fd, buf, 0);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
res = SPIFFS_read(FS, fd, buf, 0);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
buf[0] = 1;
|
||
|
buf[1] = 2;
|
||
|
|
||
|
res = SPIFFS_write(FS, fd, buf, 2);
|
||
|
TEST_CHECK_EQ(res, 2);
|
||
|
|
||
|
res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_SET);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
u8_t b;
|
||
|
res = SPIFFS_read(FS, fd, &b, 1);
|
||
|
TEST_CHECK_EQ(res, 1);
|
||
|
TEST_CHECK_EQ(b, 1);
|
||
|
|
||
|
res = SPIFFS_read(FS, fd, &b, 1);
|
||
|
TEST_CHECK_EQ(res, 1);
|
||
|
TEST_CHECK_EQ(b, 2);
|
||
|
|
||
|
res = SPIFFS_read(FS, fd, buf, 8);
|
||
|
TEST_CHECK_EQ(res, 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_END_OF_OBJECT);
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
#if !SPIFFS_READ_ONLY
|
||
|
TEST(truncate_48) {
|
||
|
fs_reset();
|
||
|
|
||
|
u32_t len = SPIFFS_DATA_PAGE_SIZE(FS)/2;
|
||
|
|
||
|
s32_t res = test_create_and_write_file("small", len, len);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
spiffs_file fd = SPIFFS_open(FS, "small", SPIFFS_RDWR, 0);
|
||
|
TEST_CHECK_GE(fd, 0);
|
||
|
|
||
|
spiffs_fd *desc;
|
||
|
#if SPIFFS_FILEHDL_OFFSET
|
||
|
res = spiffs_fd_get(FS, fd - TEST_SPIFFS_FILEHDL_OFFSET, &desc);
|
||
|
#else
|
||
|
res = spiffs_fd_get(FS, fd, &desc);
|
||
|
#endif
|
||
|
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
TEST_CHECK_EQ(desc->size, len);
|
||
|
|
||
|
u32_t new_len = len/2;
|
||
|
res = spiffs_object_truncate(desc, new_len, 0);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
TEST_CHECK_EQ(desc->size, new_len);
|
||
|
|
||
|
res = SPIFFS_close(FS, fd);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
spiffs_stat s;
|
||
|
res = SPIFFS_stat(FS, "small", &s);
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
TEST_CHECK_EQ(s.size, new_len);
|
||
|
|
||
|
res = SPIFFS_remove(FS, "small");
|
||
|
TEST_CHECK_GE(res, 0);
|
||
|
|
||
|
fd = SPIFFS_open(FS, "small", SPIFFS_RDWR, 0);
|
||
|
TEST_CHECK_LT(fd, 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_NOT_FOUND);
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
#endif
|
||
|
|
||
|
TEST(eof_tell_72) {
|
||
|
fs_reset();
|
||
|
|
||
|
s32_t res;
|
||
|
|
||
|
spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_CREAT | SPIFFS_RDWR | SPIFFS_APPEND, 0);
|
||
|
TEST_CHECK_GT(fd, 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 1);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 0);
|
||
|
|
||
|
res = SPIFFS_write(FS, fd, "test", 4);
|
||
|
TEST_CHECK_EQ(res, 4);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 1);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 4);
|
||
|
|
||
|
res = SPIFFS_fflush(FS, fd);
|
||
|
TEST_CHECK_EQ(res, SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 1);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 4);
|
||
|
|
||
|
res = SPIFFS_lseek(FS, fd, 2, SPIFFS_SEEK_SET);
|
||
|
TEST_CHECK_EQ(res, 2);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 2);
|
||
|
|
||
|
res = SPIFFS_write(FS, fd, "test", 4);
|
||
|
TEST_CHECK_EQ(res, 4);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 1);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 8);
|
||
|
|
||
|
res = SPIFFS_fflush(FS, fd);
|
||
|
TEST_CHECK_EQ(res, SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 1);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 8);
|
||
|
|
||
|
res = SPIFFS_close(FS, fd);
|
||
|
TEST_CHECK_EQ(res, SPIFFS_OK);
|
||
|
TEST_CHECK_LT(SPIFFS_eof(FS, fd), SPIFFS_OK);
|
||
|
TEST_CHECK_LT(SPIFFS_tell(FS, fd), SPIFFS_OK);
|
||
|
|
||
|
fd = SPIFFS_open(FS, "file", SPIFFS_RDWR, 0);
|
||
|
TEST_CHECK_GT(fd, 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 0);
|
||
|
|
||
|
res = SPIFFS_lseek(FS, fd, 2, SPIFFS_SEEK_SET);
|
||
|
TEST_CHECK_EQ(res, 2);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 2);
|
||
|
|
||
|
res = SPIFFS_write(FS, fd, "test", 4);
|
||
|
TEST_CHECK_EQ(res, 4);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 6);
|
||
|
|
||
|
res = SPIFFS_fflush(FS, fd);
|
||
|
TEST_CHECK_EQ(res, SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 6);
|
||
|
|
||
|
res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_END);
|
||
|
TEST_CHECK_EQ(res, 8);
|
||
|
TEST_CHECK_EQ(SPIFFS_eof(FS, fd), 1);
|
||
|
TEST_CHECK_EQ(SPIFFS_tell(FS, fd), 8);
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(spiffs_dup_file_74) {
|
||
|
fs_reset_specific(0, 0, 64*1024, 4096, 4096*2, 256);
|
||
|
{
|
||
|
spiffs_file fd = SPIFFS_open(FS, "/config", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0);
|
||
|
TEST_CHECK(fd >= 0);
|
||
|
char buf[5];
|
||
|
strncpy(buf, "test", sizeof(buf));
|
||
|
SPIFFS_write(FS, fd, buf, 4);
|
||
|
SPIFFS_close(FS, fd);
|
||
|
}
|
||
|
{
|
||
|
spiffs_file fd = SPIFFS_open(FS, "/data", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0);
|
||
|
TEST_CHECK(fd >= 0);
|
||
|
SPIFFS_close(FS, fd);
|
||
|
}
|
||
|
{
|
||
|
spiffs_file fd = SPIFFS_open(FS, "/config", SPIFFS_RDONLY, 0);
|
||
|
TEST_CHECK(fd >= 0);
|
||
|
char buf[5];
|
||
|
int cb = SPIFFS_read(FS, fd, buf, sizeof(buf));
|
||
|
TEST_CHECK(cb > 0 && cb < sizeof(buf));
|
||
|
TEST_CHECK(strncmp("test", buf, cb) == 0);
|
||
|
SPIFFS_close(FS, fd);
|
||
|
}
|
||
|
{
|
||
|
spiffs_file fd = SPIFFS_open(FS, "/data", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0);
|
||
|
TEST_CHECK(fd >= 0);
|
||
|
spiffs_stat stat;
|
||
|
SPIFFS_fstat(FS, fd, &stat);
|
||
|
if (strcmp((const char*) stat.name, "/data") != 0) {
|
||
|
// oops! lets check the list of files...
|
||
|
spiffs_DIR dir;
|
||
|
SPIFFS_opendir(FS, "/", &dir);
|
||
|
struct spiffs_dirent dirent;
|
||
|
while (SPIFFS_readdir(&dir, &dirent)) {
|
||
|
printf("%s\n", dirent.name);
|
||
|
}
|
||
|
// this will print "/config" two times
|
||
|
TEST_CHECK(0);
|
||
|
}
|
||
|
SPIFFS_close(FS, fd);
|
||
|
}
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(temporal_fd_cache) {
|
||
|
fs_reset_specific(0, 0, 1024*1024, 4096, 2*4096, 256);
|
||
|
(FS)->fd_count = 4;
|
||
|
|
||
|
char *fcss = "blaha.css";
|
||
|
|
||
|
char *fhtml[] = {
|
||
|
"index.html", "cykel.html", "bloja.html", "drivmedel.html", "smorgasbord.html",
|
||
|
"ombudsman.html", "fubbick.html", "paragrod.html"
|
||
|
};
|
||
|
|
||
|
const int hit_probabilities[] = {
|
||
|
25, 20, 16, 12, 10, 8, 5, 4
|
||
|
};
|
||
|
|
||
|
const int runs = 10000;
|
||
|
|
||
|
// create our webserver files
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fcss, 2000, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[0], 4000, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[1], 3000, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[2], 2000, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[3], 1000, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[4], 1500, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[5], 3000, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[6], 2000, 256), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(test_create_and_write_file(fhtml[7], 3500, 256), SPIFFS_OK);
|
||
|
|
||
|
clear_flash_ops_log();
|
||
|
|
||
|
int run = 0;
|
||
|
do {
|
||
|
// open & read an html
|
||
|
int dice = rand() % 100;
|
||
|
int probability = 0;
|
||
|
int html_ix = 0;
|
||
|
do {
|
||
|
probability += hit_probabilities[html_ix];
|
||
|
if (dice <= probability) {
|
||
|
break;
|
||
|
}
|
||
|
html_ix++;
|
||
|
} while(probability < 100);
|
||
|
|
||
|
TEST_CHECK_EQ(read_and_verify(fhtml[html_ix]), SPIFFS_OK);
|
||
|
|
||
|
// open & read css
|
||
|
TEST_CHECK_EQ(read_and_verify(fcss), SPIFFS_OK);
|
||
|
} while (run ++ < runs);
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
static int run_fuzz_test(FILE *f, int maxfds, int debuglog) {
|
||
|
// There are a bunch of arbitrary constants in this test case. Changing them will
|
||
|
// almost certainly change the effets of an input file. It *may* be worth
|
||
|
// making some of these constants to come from the input file.
|
||
|
int setup = fgetc(f);
|
||
|
|
||
|
int page_size = 128 << (setup & 3);
|
||
|
setup >>= 2;
|
||
|
int erase_size = 4096 << (setup & 3);
|
||
|
setup >>= 2;
|
||
|
int block_size = erase_size << (setup & 1);
|
||
|
setup >>= 1;
|
||
|
int blocks = 4 + (setup & 7);
|
||
|
fs_reset_specific(0, 0, blocks * block_size, erase_size, block_size, page_size);
|
||
|
int res;
|
||
|
(FS)->fd_count = 4;
|
||
|
|
||
|
int c;
|
||
|
|
||
|
spiffs_file fd[4];
|
||
|
memset(fd, -1, sizeof(fd));
|
||
|
int openindex[4];
|
||
|
memset(openindex, -1, sizeof(openindex));
|
||
|
char *filename[8];
|
||
|
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
char buff[128];
|
||
|
sprintf(buff, "%dfile%d.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasdasdasdadxxxxxxxxxxxxxxxxxxx", i, i);
|
||
|
buff[9 + 2 * i] = 0;
|
||
|
filename[i] = strdup(buff);
|
||
|
}
|
||
|
|
||
|
// The list of 8 modes that are chosen. SPIFFS_EXCL is not present -- it probably ought to be.
|
||
|
int modes[8] = {SPIFFS_RDONLY, SPIFFS_RDWR, SPIFFS_RDWR|SPIFFS_TRUNC, SPIFFS_RDWR|SPIFFS_CREAT, SPIFFS_RDWR|SPIFFS_CREAT|SPIFFS_TRUNC,
|
||
|
SPIFFS_WRONLY|SPIFFS_CREAT|SPIFFS_TRUNC, SPIFFS_RDWR|SPIFFS_CREAT|SPIFFS_TRUNC|SPIFFS_DIRECT, SPIFFS_WRONLY};
|
||
|
|
||
|
char buff[2048];
|
||
|
for (i = 0; i < sizeof(buff); i++) {
|
||
|
buff[i] = i * 19;
|
||
|
}
|
||
|
|
||
|
#define LOGOP if (debuglog) printf
|
||
|
|
||
|
while ((c = fgetc(f)) >= 0) {
|
||
|
int add;
|
||
|
char rbuff[2048];
|
||
|
if (c <= ' ') {
|
||
|
continue;
|
||
|
}
|
||
|
int arg = fgetc(f);
|
||
|
if (arg < 0) {
|
||
|
break;
|
||
|
}
|
||
|
int fdn = ((arg >> 6) & 3) % maxfds;
|
||
|
int rc;
|
||
|
switch(c) {
|
||
|
case 'O':
|
||
|
if (fd[fdn] >= 0) {
|
||
|
LOGOP(" close(%d)\n", fd[fdn]);
|
||
|
SPIFFS_close(FS, fd[fdn]);
|
||
|
openindex[fdn] = -1;
|
||
|
fd[fdn] = -1;
|
||
|
}
|
||
|
#ifndef HAVE_MULTIPLE_OPEN
|
||
|
{
|
||
|
int index = (arg >> 3) & 7;
|
||
|
for (i = 0; i < sizeof(openindex) / sizeof(openindex[0]); i++) {
|
||
|
if (openindex[i] == index) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (i < sizeof(openindex) / sizeof(openindex[0])) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
LOGOP(" open(\"%s\", 0x%x)", filename[(arg>>3) & 7], modes[arg & 7]);
|
||
|
fd[fdn] = SPIFFS_open(FS, filename[(arg>>3) & 7], modes[arg & 7], 0);
|
||
|
if (fd[fdn] >= 0) {
|
||
|
openindex[fdn] = (arg >> 3) & 7;
|
||
|
}
|
||
|
LOGOP(" -> %d\n", fd[fdn]);
|
||
|
break;
|
||
|
|
||
|
case 'S':
|
||
|
if (fd[fdn] >= 0) {
|
||
|
int offset = (14 << (arg & 7)) + arg;
|
||
|
if (arg & 16) {
|
||
|
offset = -offset;
|
||
|
}
|
||
|
int whence = (arg & 63) % 3;
|
||
|
LOGOP(" lseek(%d, %d, %d)\n", fd[fdn], offset, whence);
|
||
|
SPIFFS_lseek(FS, fd[fdn], offset, whence);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'R':
|
||
|
if (fd[fdn] >= 0) {
|
||
|
LOGOP(" read(%d, , %d)", fd[fdn], (15 << (arg & 7)) + (arg & 127));
|
||
|
int rlen = SPIFFS_read(FS, fd[fdn], rbuff, (15 << (arg & 7)) + (arg & 127));
|
||
|
LOGOP(" -> %d\n", rlen);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'W':
|
||
|
if (fd[fdn] >= 0) {
|
||
|
LOGOP(" write(%d, , %d)", fd[fdn], (15 << (arg & 7)) + (arg & 127));
|
||
|
rc = SPIFFS_write(FS, fd[fdn], buff, (15 << (arg & 7)) + (arg & 127));
|
||
|
LOGOP(" -> %d\n", rc);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'C':
|
||
|
if (fd[fdn] >= 0) {
|
||
|
LOGOP(" close(%d)\n", fd[fdn]);
|
||
|
SPIFFS_close(FS, fd[fdn]);
|
||
|
}
|
||
|
fd[fdn] = -1;
|
||
|
openindex[fdn] = -1;
|
||
|
break;
|
||
|
|
||
|
case 'b':
|
||
|
add = fgetc(f);
|
||
|
for (i = 0; i < sizeof(buff); i++) {
|
||
|
buff[i] = add + i * arg;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'f':
|
||
|
if (fd[fdn] >= 0) {
|
||
|
LOGOP(" fflush(%d)\n", fd[fdn]);
|
||
|
SPIFFS_fflush(FS, fd[fdn]);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
#ifdef HAVE_REMOVE_OPEN
|
||
|
case 'D':
|
||
|
if (fd[fdn] >= 0) {
|
||
|
LOGOP(" fremove(%d)\n", fd[fdn]);
|
||
|
SPIFFS_fremove(FS, fd[fdn]);
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
case 'd':
|
||
|
#ifndef HAVE_REMOVE_OPEN
|
||
|
{
|
||
|
int index = arg & 7;
|
||
|
for (i = 0; i < sizeof(openindex) / sizeof(openindex[0]); i++) {
|
||
|
if (openindex[i] == index) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (i < sizeof(openindex) / sizeof(openindex[0])) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
LOGOP(" remove(\"%s\")", filename[arg & 7]);
|
||
|
rc = SPIFFS_remove(FS, filename[arg & 7]);
|
||
|
LOGOP(" -> %d\n", rc);
|
||
|
break;
|
||
|
|
||
|
case 'r':
|
||
|
#ifndef HAVE_REMOVE_OPEN
|
||
|
{
|
||
|
int index = arg & 7;
|
||
|
for (i = 0; i < sizeof(openindex) / sizeof(openindex[0]); i++) {
|
||
|
if (openindex[i] == index) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (i < sizeof(openindex) / sizeof(openindex[0])) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
LOGOP(" rename(\"%s\", \"%s\")", filename[arg & 7], filename[(arg >> 3) & 7]);
|
||
|
rc = SPIFFS_rename(FS, filename[arg & 7], filename[(arg >> 3) & 7]);
|
||
|
LOGOP(" -> %d\n", rc);
|
||
|
break;
|
||
|
|
||
|
case 'U':
|
||
|
ungetc(arg, f);
|
||
|
for (i = 0; i < 4; i++) {
|
||
|
fd[i] = -1;
|
||
|
}
|
||
|
{
|
||
|
#ifdef DO_UNMOUNT
|
||
|
LOGOP(" unmount\n");
|
||
|
SPIFFS_unmount(FS);
|
||
|
#endif
|
||
|
char *tmpfile = strdup("/tmp/fsdump.XXXXXX");
|
||
|
LOGOP(" cycle and remount\n");
|
||
|
close(mkstemp(tmpfile));
|
||
|
fs_store_dump(tmpfile);
|
||
|
fs_mount_dump(tmpfile, 0, 0, blocks * block_size, erase_size, block_size, page_size);
|
||
|
unlink(tmpfile);
|
||
|
free(tmpfile);
|
||
|
#ifndef NO_FORCE_CHECK
|
||
|
LOGOP(" forcecheck()");
|
||
|
rc = SPIFFS_check(FS);
|
||
|
LOGOP(" -> %d\n", rc);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'c':
|
||
|
{
|
||
|
LOGOP(" check()");
|
||
|
rc = SPIFFS_check(FS);
|
||
|
LOGOP(" -> %d\n", rc);
|
||
|
ungetc(arg, f);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
ungetc(arg, f);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < 4; i++) {
|
||
|
if (fd[i] >= 0) {
|
||
|
LOGOP(" close(%d)\n", fd[i]);
|
||
|
SPIFFS_close(FS, fd[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
}
|
||
|
|
||
|
#define FMEMARGS(x) x, sizeof(x) - 1
|
||
|
|
||
|
TEST(fuzzer_found_1) {
|
||
|
return run_fuzz_test(fmemopen(FMEMARGS("\021OlWkd5O4W4W0O5OlWkO5OlW0O5O4W0"), "r"), 4, 1);
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(fuzzer_found_2) {
|
||
|
return run_fuzz_test(fmemopen(FMEMARGS("bO4W6W0d\036O4W6"), "r"), 4, 1);
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(fuzzer_found_3) {
|
||
|
return run_fuzz_test(fmemopen(FMEMARGS("\264O4OqWeWWWWW@O4WWW\027"), "r"), 4, 1);
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(fuzzer_found_4) {
|
||
|
unsigned char smalltest[] = {
|
||
|
0x62, 0x4f, 0x24, 0x57, 0x3f, 0x57, 0x3f, 0x57, 0x3f, 0x57, 0x3f, 0x57,
|
||
|
0x3f, 0x4f, 0x34, 0x57, 0x3f, 0x55, 0x4f, 0x61, 0x57, 0x61, 0x4f, 0x61,
|
||
|
0x57, 0x65, 0x43, 0x61, 0x4f, 0x24, 0x57, 0x30
|
||
|
};
|
||
|
unsigned int smalltest_len = 32;
|
||
|
|
||
|
return run_fuzz_test(fmemopen(smalltest, smalltest_len, "r"), 4, 1);
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(fuzzer_found_single_1) {
|
||
|
return run_fuzz_test(fmemopen(FMEMARGS("\000O\004Odr4d\356Okr0WWUO;WWWWd\035W4"), "r"), 1, 1);
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(log_afl_test) {
|
||
|
u32_t old_val = set_abort_on_error(1);
|
||
|
int rc = run_fuzz_test(stdin, 4, 1);
|
||
|
set_abort_on_error(old_val);
|
||
|
return rc;
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(afl_test) {
|
||
|
u32_t old_val = set_abort_on_error(1);
|
||
|
int rc = run_fuzz_test(stdin, 4, 0);
|
||
|
set_abort_on_error(old_val);
|
||
|
return rc;
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(afl_single) {
|
||
|
u32_t old_val = set_abort_on_error(1);
|
||
|
int rc = run_fuzz_test(stdin, 1, 0);
|
||
|
set_abort_on_error(old_val);
|
||
|
return rc;
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(small_free_space) {
|
||
|
fs_reset_specific(0, 0, 400*1024, 4096, 2*4096, 256);
|
||
|
spiffs_file fd;
|
||
|
int res;
|
||
|
(FS)->fd_count = 4;
|
||
|
|
||
|
int tfd = SPIFFS_open(FS, "testfile", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||
|
TEST_CHECK(tfd > 0);
|
||
|
char *tbuf = "some data";
|
||
|
res = SPIFFS_write(FS, tfd, tbuf, strlen(tbuf));
|
||
|
|
||
|
TEST_CHECK(res == strlen(tbuf));
|
||
|
|
||
|
res = SPIFFS_fflush(FS, tfd);
|
||
|
TEST_CHECK(res >= SPIFFS_OK);
|
||
|
|
||
|
SPIFFS_close(FS, tfd);
|
||
|
|
||
|
const int runs = 1000;
|
||
|
|
||
|
int fileCurrNumber = 0;
|
||
|
int fileDelNumber = 1;
|
||
|
|
||
|
int run = 0;
|
||
|
do {
|
||
|
u8_t buf[1000];
|
||
|
|
||
|
sprintf(buf, "%d", fileCurrNumber);
|
||
|
int i;
|
||
|
for (i = 0; i < 100; i++) {
|
||
|
strcat(buf, " azzaaax");
|
||
|
}
|
||
|
|
||
|
int maxFileNr = 500;
|
||
|
char *filename = "awyn";
|
||
|
char *fileext = ".dat";
|
||
|
|
||
|
u32_t total;
|
||
|
u32_t used;
|
||
|
|
||
|
SPIFFS_info(FS, &total, &used);
|
||
|
|
||
|
if (total - used < 20000) {
|
||
|
maxFileNr = 1;
|
||
|
}
|
||
|
|
||
|
fileCurrNumber++;
|
||
|
int fileCntr = fileCurrNumber + 1 - fileDelNumber;
|
||
|
|
||
|
char fileCurrName[64];
|
||
|
sprintf(fileCurrName, "%s%d%s", filename, fileCurrNumber, fileext);
|
||
|
|
||
|
fd = SPIFFS_open(FS, fileCurrName, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||
|
TEST_CHECK(fd > 0);
|
||
|
|
||
|
//printf("About to write to %s\n", fileCurrName);
|
||
|
res = SPIFFS_write(FS, fd, buf, strlen(buf));
|
||
|
|
||
|
TEST_CHECK(res == strlen(buf));
|
||
|
|
||
|
res = SPIFFS_fflush(FS, fd);
|
||
|
TEST_CHECK_EQ(res, SPIFFS_OK);
|
||
|
|
||
|
SPIFFS_close(FS, fd);
|
||
|
|
||
|
if (fileCntr > maxFileNr) {
|
||
|
char fileDelName[64];
|
||
|
sprintf(fileDelName, "%s%d%s", filename, fileDelNumber, fileext);
|
||
|
//printf("Deleting %s (free space %d)\n", fileDelName, total - used);
|
||
|
|
||
|
res = SPIFFS_remove(FS, fileDelName);
|
||
|
|
||
|
TEST_CHECK(res == SPIFFS_OK);
|
||
|
fileDelNumber++;
|
||
|
}
|
||
|
} while (run ++ < runs);
|
||
|
|
||
|
tfd = SPIFFS_open(FS, "testfile", SPIFFS_RDONLY, 0);
|
||
|
TEST_CHECK(tfd > 0);
|
||
|
char rbuf[32];
|
||
|
res = SPIFFS_read(FS, tfd, rbuf, sizeof(rbuf));
|
||
|
|
||
|
TEST_CHECK(res == strlen(tbuf));
|
||
|
|
||
|
SPIFFS_close(FS, tfd);
|
||
|
|
||
|
TEST_CHECK(memcmp(rbuf, tbuf, strlen(tbuf)) == 0);
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(lots_of_overwrite) {
|
||
|
fs_reset_specific(0, 0, 3000*1024, 4096, 2*4096, 256);
|
||
|
spiffs_file fd;
|
||
|
int res;
|
||
|
(FS)->fd_count = 4;
|
||
|
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < 5; i++) {
|
||
|
|
||
|
char filename[64];
|
||
|
sprintf(filename, "%d-tstfile", i);
|
||
|
int tfd = SPIFFS_open(FS, filename, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||
|
TEST_CHECK(tfd > 0);
|
||
|
char tbuf[1024];
|
||
|
memset(tbuf, 'a', 700);
|
||
|
tbuf[700] = 0;
|
||
|
res = SPIFFS_write(FS, tfd, tbuf, strlen(tbuf));
|
||
|
|
||
|
TEST_CHECK(res == strlen(tbuf));
|
||
|
|
||
|
res = SPIFFS_fflush(FS, tfd);
|
||
|
TEST_CHECK(res >= SPIFFS_OK);
|
||
|
|
||
|
SPIFFS_close(FS, tfd);
|
||
|
}
|
||
|
|
||
|
const int runs = 100000;
|
||
|
|
||
|
int run = 0;
|
||
|
for (run = 0; run < runs; run++) {
|
||
|
u8_t buf[2000];
|
||
|
|
||
|
sprintf(buf, "%d", run);
|
||
|
int i;
|
||
|
for (i = 0; i < 100 + (run % 100); i++) {
|
||
|
strcat(buf, " azzaaax");
|
||
|
}
|
||
|
|
||
|
int tfd = SPIFFS_open(FS, "file.dat", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||
|
TEST_CHECK(tfd > 0);
|
||
|
res = SPIFFS_write(FS, tfd, buf, strlen(buf));
|
||
|
|
||
|
TEST_CHECK(res == strlen(buf));
|
||
|
|
||
|
res = SPIFFS_fflush(FS, tfd);
|
||
|
TEST_CHECK(res >= SPIFFS_OK);
|
||
|
|
||
|
SPIFFS_close(FS, tfd);
|
||
|
|
||
|
tfd = SPIFFS_open(FS, "file.dat", SPIFFS_RDONLY, 0);
|
||
|
TEST_CHECK(tfd > 0);
|
||
|
char rbuf[2000];
|
||
|
res = SPIFFS_read(FS, tfd, rbuf, sizeof(rbuf));
|
||
|
|
||
|
TEST_CHECK(res == strlen(buf));
|
||
|
|
||
|
SPIFFS_close(FS, tfd);
|
||
|
|
||
|
TEST_CHECK(memcmp(rbuf, buf, strlen(buf)) == 0);
|
||
|
|
||
|
char filename[64];
|
||
|
sprintf(filename, "%d-tstfile", run % 5);
|
||
|
tfd = SPIFFS_open(FS, filename, SPIFFS_RDONLY, 0);
|
||
|
TEST_CHECK(tfd > 0);
|
||
|
char tbuf[1024];
|
||
|
memset(tbuf, 'a', 700);
|
||
|
tbuf[700] = 0;
|
||
|
res = SPIFFS_read(FS, tfd, rbuf, sizeof(rbuf));
|
||
|
|
||
|
TEST_CHECK(res == strlen(tbuf));
|
||
|
|
||
|
SPIFFS_close(FS, tfd);
|
||
|
TEST_CHECK(memcmp(rbuf, tbuf, strlen(tbuf)) == 0);
|
||
|
}
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
|
||
|
#if 0
|
||
|
TEST(spiffs_hidden_file_90) {
|
||
|
fs_mount_dump("imgs/90.hidden_file.spiffs", 0, 0, 1*1024*1024, 4096, 4096, 128);
|
||
|
|
||
|
SPIFFS_vis(FS);
|
||
|
|
||
|
dump_page(FS, 1);
|
||
|
dump_page(FS, 0x8fe);
|
||
|
dump_page(FS, 0x8ff);
|
||
|
|
||
|
{
|
||
|
spiffs_DIR dir;
|
||
|
SPIFFS_opendir(FS, "/", &dir);
|
||
|
struct spiffs_dirent dirent;
|
||
|
while (SPIFFS_readdir(&dir, &dirent)) {
|
||
|
printf("%-32s sz:%-7i obj_id:%08x pix:%08x\n", dirent.name, dirent.size, dirent.obj_id, dirent.pix);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("remove cli.bin res %i\n", SPIFFS_remove(FS, "cli.bin"));
|
||
|
|
||
|
{
|
||
|
spiffs_DIR dir;
|
||
|
SPIFFS_opendir(FS, "/", &dir);
|
||
|
struct spiffs_dirent dirent;
|
||
|
while (SPIFFS_readdir(&dir, &dirent)) {
|
||
|
printf("%-32s sz:%-7i obj_id:%08x pix:%08x\n", dirent.name, dirent.size, dirent.obj_id, dirent.pix);
|
||
|
}
|
||
|
}
|
||
|
return TEST_RES_OK;
|
||
|
|
||
|
} TEST_END
|
||
|
#endif
|
||
|
#if 0
|
||
|
TEST(null_deref_check_93) {
|
||
|
fs_mount_dump("imgs/93.dump.bin", 0, 0, 2*1024*1024, 4096, 4096, 256);
|
||
|
|
||
|
//int res = SPIFFS_open(FS, "d43.fw", SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_WRONLY, 0);
|
||
|
//TEST_CHECK_GE(res, SPIFFS_OK);
|
||
|
|
||
|
SPIFFS_vis(FS);
|
||
|
|
||
|
printf("\n\n-------------------------------------------------\n\n");
|
||
|
|
||
|
SPIFFS_check(FS);
|
||
|
//fs_store_dump("imgs/93.dump.checked.bin");
|
||
|
|
||
|
SPIFFS_vis(FS);
|
||
|
|
||
|
printf("\n\n-------------------------------------------------\n\n");
|
||
|
|
||
|
SPIFFS_check(FS);
|
||
|
|
||
|
SPIFFS_vis(FS);
|
||
|
printf("\n\n-------------------------------------------------\n\n");
|
||
|
|
||
|
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
#endif
|
||
|
|
||
|
TEST(spiffs_145) {
|
||
|
int res;
|
||
|
fs_reset_specific(0, 0, 1024*1024, 65536, 65536, 1024);
|
||
|
{
|
||
|
spiffs_file fd = SPIFFS_open(FS, "biggie", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0);
|
||
|
TEST_CHECK(fd >= 0);
|
||
|
char buf[1024*512];
|
||
|
memset(buf, 0xee, sizeof(buf));
|
||
|
TEST_CHECK_GT(SPIFFS_write(FS, fd, buf, sizeof(buf)), 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_close(FS, fd), SPIFFS_OK);
|
||
|
}
|
||
|
const int runs = 1000;
|
||
|
int run = 0;
|
||
|
while (run++ < runs) {
|
||
|
spiffs_file fd = SPIFFS_open(FS, "clobber", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0);
|
||
|
TEST_CHECK(fd >= 0);
|
||
|
char buf[8192];
|
||
|
memset(buf, 0xee, sizeof(buf));
|
||
|
TEST_CHECK_GT(SPIFFS_write(FS, fd, buf, sizeof(buf)), 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_close(FS, fd), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(SPIFFS_remove(FS, "clobber"), SPIFFS_OK);
|
||
|
}
|
||
|
|
||
|
// below stolen from SPIFFS_vis
|
||
|
spiffs *fs = FS;
|
||
|
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
|
||
|
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
|
||
|
spiffs_block_ix bix = 0;
|
||
|
|
||
|
while (bix < fs->block_count) {
|
||
|
// check each object lookup page
|
||
|
spiffs_obj_id erase_count;
|
||
|
TEST_CHECK_EQ(_spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0,
|
||
|
SPIFFS_ERASE_COUNT_PADDR(fs, bix),
|
||
|
sizeof(spiffs_obj_id), (u8_t *)&erase_count), SPIFFS_OK);
|
||
|
TEST_CHECK_NEQ(erase_count, (spiffs_obj_id)-1);
|
||
|
TEST_CHECK_NEQ(erase_count, 0);
|
||
|
bix++;
|
||
|
} // per block
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
|
||
|
TEST(seek_bug_148) {
|
||
|
int res;
|
||
|
#define MAGIC_SIZE_THAT_FAILS 26355 // happens to be SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_OBJ_HDR_IX_LEN(FS)
|
||
|
fs_reset_specific(0, 0, 64*1024, 4096, 4096, 256);
|
||
|
u8_t buf[MAGIC_SIZE_THAT_FAILS];
|
||
|
spiffs_file fd = SPIFFS_open(FS, "EVENT", SPIFFS_O_CREAT | SPIFFS_O_RDWR, 0);
|
||
|
TEST_CHECK_GT(fd, 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_write(FS, fd, &buf, sizeof(buf)), sizeof(buf));
|
||
|
TEST_CHECK_EQ(SPIFFS_close(FS, fd), SPIFFS_OK);
|
||
|
fd = SPIFFS_open(FS, "EVENT", SPIFFS_O_RDONLY, 0);
|
||
|
TEST_CHECK_GT(fd, 0);
|
||
|
TEST_CHECK_EQ(SPIFFS_lseek(FS, fd, 0, SEEK_END), MAGIC_SIZE_THAT_FAILS);
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
|
||
|
TEST(remove_release_fd_152) {
|
||
|
int res;
|
||
|
fs_reset_specific(0, 0, 64*1024, 4096, 4096, 256);
|
||
|
u8_t buf[1024];
|
||
|
memrand(buf, sizeof(buf));
|
||
|
TEST_CHECK_EQ(count_taken_fds(FS), 0);
|
||
|
spiffs_file fd1 = SPIFFS_open(FS, "removemeandloseafd", SPIFFS_O_CREAT | SPIFFS_O_RDWR, 0);
|
||
|
TEST_CHECK_GT(fd1, 0);
|
||
|
TEST_CHECK_EQ(count_taken_fds(FS), 1);
|
||
|
TEST_CHECK_EQ(SPIFFS_write(FS, fd1, &buf, sizeof(buf)), sizeof(buf));
|
||
|
TEST_CHECK_EQ(SPIFFS_close(FS, fd1), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(count_taken_fds(FS), 0);
|
||
|
spiffs_file fd2 = SPIFFS_open(FS, "removemeandloseafd", SPIFFS_O_RDWR, 0);
|
||
|
TEST_CHECK_GT(fd2, 0);
|
||
|
TEST_CHECK_EQ(count_taken_fds(FS), 1);
|
||
|
spiffs_file fd3 = SPIFFS_open(FS, "removemeandloseafd", SPIFFS_O_RDWR, 0);
|
||
|
TEST_CHECK_GT(fd3, 0);
|
||
|
TEST_CHECK_EQ(count_taken_fds(FS), 2);
|
||
|
TEST_CHECK_EQ(SPIFFS_remove(FS, "removemeandloseafd"), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(count_taken_fds(FS), 0);
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
TEST(certain_file_size_fail_165) {
|
||
|
fs_reset_specific(0, 0, 512*1024, 4*1024, 64*1024, 256);
|
||
|
const int NUM = 134;
|
||
|
const int SIZ = 200;
|
||
|
u8_t buf[SIZ];
|
||
|
|
||
|
TEST_CHECK_EQ(SPIFFS_creat(FS, "test", 0), SPIFFS_OK);
|
||
|
spiffs_file fd = SPIFFS_open(FS, "test", SPIFFS_O_CREAT | SPIFFS_O_WRONLY, 0);
|
||
|
TEST_CHECK_GT(fd, 0);
|
||
|
|
||
|
int i;
|
||
|
for (i = 0; i < NUM; i++) {
|
||
|
TEST_CHECK_EQ(SPIFFS_write(FS, fd, buf, SIZ), SIZ);
|
||
|
}
|
||
|
TEST_CHECK_EQ(SPIFFS_close(FS, fd), SPIFFS_OK);
|
||
|
fd = SPIFFS_open(FS, "test", SPIFFS_O_RDONLY, 0);
|
||
|
TEST_CHECK_GT(fd, 0);
|
||
|
|
||
|
spiffs_stat s;
|
||
|
TEST_CHECK_EQ(SPIFFS_fstat(FS, fd, &s), SPIFFS_OK);
|
||
|
TEST_CHECK_EQ(s.size, NUM*SIZ);
|
||
|
|
||
|
int size = 0;
|
||
|
for (i = 0; i < NUM; i++) {
|
||
|
size += SPIFFS_read(FS, fd, buf, SIZ);
|
||
|
}
|
||
|
TEST_CHECK_EQ(size, NUM*SIZ);
|
||
|
|
||
|
return TEST_RES_OK;
|
||
|
} TEST_END
|
||
|
|
||
|
|
||
|
SUITE_TESTS(bug_tests)
|
||
|
ADD_TEST(nodemcu_full_fs_1)
|
||
|
ADD_TEST(nodemcu_full_fs_2)
|
||
|
ADD_TEST(magic_test)
|
||
|
ADD_TEST(nodemcu_309)
|
||
|
ADD_TEST(robert)
|
||
|
ADD_TEST(spiffs_12)
|
||
|
ADD_TEST(zero_sized_file_44)
|
||
|
ADD_TEST(truncate_48)
|
||
|
ADD_TEST(eof_tell_72)
|
||
|
ADD_TEST(spiffs_dup_file_74)
|
||
|
ADD_TEST(temporal_fd_cache)
|
||
|
ADD_TEST(spiffs_145)
|
||
|
ADD_TEST(seek_bug_148)
|
||
|
//ADD_TEST(small_free_space)
|
||
|
ADD_TEST(lots_of_overwrite)
|
||
|
ADD_TEST(fuzzer_found_1)
|
||
|
ADD_TEST(fuzzer_found_2)
|
||
|
ADD_TEST(fuzzer_found_3)
|
||
|
ADD_TEST(fuzzer_found_4)
|
||
|
ADD_TEST(remove_release_fd_152)
|
||
|
ADD_TEST(certain_file_size_fail_165)
|
||
|
ADD_TEST_NON_DEFAULT(fuzzer_found_single_1)
|
||
|
ADD_TEST_NON_DEFAULT(log_afl_test)
|
||
|
ADD_TEST_NON_DEFAULT(afl_test)
|
||
|
ADD_TEST_NON_DEFAULT(afl_single)
|
||
|
#if 0
|
||
|
ADD_TEST(spiffs_hidden_file_90)
|
||
|
#endif
|
||
|
#if 0
|
||
|
ADD_TEST(null_deref_check_93)
|
||
|
#endif
|
||
|
SUITE_END(bug_tests)
|