spiffs: Add host test for generated spiffs image

This commit is contained in:
Renz Christian Bagaporo
2019-01-15 09:59:09 +08:00
parent 8ba10bf3dc
commit ca06f73a51
2 changed files with 175 additions and 30 deletions

View File

@@ -68,7 +68,7 @@ $(BUILD_DIR)/$(COMPONENT_LIB): $(OBJ_FILES) $(SDKCONFIG)
clean: clean:
$(MAKE) -C $(STUBS_LIB_DIR) clean $(MAKE) -C $(STUBS_LIB_DIR) clean
$(MAKE) -C $(SPI_FLASH_SIM_DIR) clean $(MAKE) -C $(SPI_FLASH_SIM_DIR) clean
rm -f $(OBJ_FILES) $(TEST_OBJ_FILES) $(TEST_PROGRAM) $(COMPONENT_LIB) partition_table.bin rm -f $(OBJ_FILES) $(TEST_OBJ_FILES) $(TEST_PROGRAM) $(COMPONENT_LIB) partition_table.bin image.bin
lib: $(BUILD_DIR)/$(COMPONENT_LIB) lib: $(BUILD_DIR)/$(COMPONENT_LIB)
@@ -86,7 +86,11 @@ TEST_OBJ_FILES = $(filter %.o, $(TEST_SOURCE_FILES:.cpp=.o) $(TEST_SOURCE_FILES:
$(TEST_PROGRAM): lib $(TEST_OBJ_FILES) $(SPI_FLASH_SIM_BUILD_DIR)/$(SPI_FLASH_SIM_LIB) $(STUBS_LIB_BUILD_DIR)/$(STUBS_LIB) partition_table.bin $(SDKCONFIG) $(TEST_PROGRAM): lib $(TEST_OBJ_FILES) $(SPI_FLASH_SIM_BUILD_DIR)/$(SPI_FLASH_SIM_LIB) $(STUBS_LIB_BUILD_DIR)/$(STUBS_LIB) partition_table.bin $(SDKCONFIG)
g++ $(LDFLAGS) $(CXXFLAGS) -o $@ $(TEST_OBJ_FILES) -L$(BUILD_DIR) -l:$(COMPONENT_LIB) -L$(SPI_FLASH_SIM_BUILD_DIR) -l:$(SPI_FLASH_SIM_LIB) -L$(STUBS_LIB_BUILD_DIR) -l:$(STUBS_LIB) g++ $(LDFLAGS) $(CXXFLAGS) -o $@ $(TEST_OBJ_FILES) -L$(BUILD_DIR) -l:$(COMPONENT_LIB) -L$(SPI_FLASH_SIM_BUILD_DIR) -l:$(SPI_FLASH_SIM_LIB) -L$(STUBS_LIB_BUILD_DIR) -l:$(STUBS_LIB)
test: $(TEST_PROGRAM) # Use spiffs source directory as the test image
spiffs_image: ../spiffs $(shell find ../spiffs -type d) $(shell find ../spiffs -type -f -name '*')
../spiffsgen.py 2097152 ../spiffs image.bin
test: $(TEST_PROGRAM) spiffs_image
./$(TEST_PROGRAM) ./$(TEST_PROGRAM)
# Create other necessary targets # Create other necessary targets

View File

@@ -1,6 +1,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <sys/mman.h>
#include <dirent.h>
#include <limits.h>
#include "esp_partition.h" #include "esp_partition.h"
#include "spiffs.h" #include "spiffs.h"
@@ -11,19 +14,18 @@
extern "C" void init_spi_flash(const char* chip_size, size_t block_size, size_t sector_size, size_t page_size, const char* partition_bin); extern "C" void init_spi_flash(const char* chip_size, size_t block_size, size_t sector_size, size_t page_size, const char* partition_bin);
TEST_CASE("format disk, open file, write and read file", "[spiffs]") static void init_spiffs(spiffs *fs, uint32_t max_files)
{ {
init_spi_flash(CONFIG_ESPTOOLPY_FLASHSIZE, CONFIG_WL_SECTOR_SIZE * 16, CONFIG_WL_SECTOR_SIZE, CONFIG_WL_SECTOR_SIZE, "partition_table.bin");
spiffs fs;
spiffs_config cfg; spiffs_config cfg;
s32_t spiffs_res;
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "storage"); const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "storage");
REQUIRE(partition);
// Configure objects needed by SPIFFS // Configure objects needed by SPIFFS
esp_spiffs_t esp_user_data; esp_spiffs_t *user_data = (esp_spiffs_t*) calloc(1, sizeof(*user_data));
esp_user_data.partition = partition; user_data->partition = partition;
fs.user_data = (void*)&esp_user_data; fs->user_data = (void*)user_data;
cfg.hal_erase_f = spiffs_api_erase; cfg.hal_erase_f = spiffs_api_erase;
cfg.hal_read_f = spiffs_api_read; cfg.hal_read_f = spiffs_api_read;
@@ -34,31 +36,128 @@ TEST_CASE("format disk, open file, write and read file", "[spiffs]")
cfg.phys_erase_block = CONFIG_WL_SECTOR_SIZE; cfg.phys_erase_block = CONFIG_WL_SECTOR_SIZE;
cfg.phys_size = partition->size; cfg.phys_size = partition->size;
uint32_t max_files = 5; uint32_t work_sz = cfg.log_page_size * 2;
uint8_t *work = (uint8_t*) malloc(work_sz);
uint32_t fds_sz = max_files * sizeof(spiffs_fd); uint32_t fds_sz = max_files * sizeof(spiffs_fd);
uint32_t work_sz = cfg.log_page_size * 2; uint8_t *fds = (uint8_t*) malloc(fds_sz);
#if CONFIG_SPIFFS_CACHE
uint32_t cache_sz = sizeof(spiffs_cache) + max_files * (sizeof(spiffs_cache_page) uint32_t cache_sz = sizeof(spiffs_cache) + max_files * (sizeof(spiffs_cache_page)
+ cfg.log_page_size); + cfg.log_page_size);
uint8_t *work = (uint8_t*) malloc(work_sz);
uint8_t *fds = (uint8_t*) malloc(fds_sz);
uint8_t *cache = (uint8_t*) malloc(cache_sz); uint8_t *cache = (uint8_t*) malloc(cache_sz);
#else
s32_t spiffs_res; uint32_t cache_sz = 0;
uint8_t cache = NULL;
#endif
// Special mounting procedure: mount, format, mount as per // Special mounting procedure: mount, format, mount as per
// https://github.com/pellepl/spiffs/wiki/Using-spiffs // https://github.com/pellepl/spiffs/wiki/Using-spiffs
spiffs_res = SPIFFS_mount(&fs, &cfg, work, fds, fds_sz, spiffs_res = SPIFFS_mount(fs, &cfg, work, fds, fds_sz,
cache, cache_sz, spiffs_api_check); cache, cache_sz, spiffs_api_check);
REQUIRE(spiffs_res == SPIFFS_ERR_NOT_A_FS);
spiffs_res = SPIFFS_format(&fs); if (spiffs_res == SPIFFS_ERR_NOT_A_FS) {
REQUIRE(spiffs_res >= SPIFFS_OK); spiffs_res = SPIFFS_format(fs);
REQUIRE(spiffs_res >= SPIFFS_OK);
spiffs_res = SPIFFS_mount(fs, &cfg, work, fds, fds_sz,
cache, cache_sz, spiffs_api_check);
}
spiffs_res = SPIFFS_mount(&fs, &cfg, work, fds, fds_sz,
cache, cache_sz, spiffs_api_check);
REQUIRE(spiffs_res >= SPIFFS_OK); REQUIRE(spiffs_res >= SPIFFS_OK);
}
static void deinit_spiffs(spiffs *fs)
{
SPIFFS_unmount(fs);
free(fs->work);
free(fs->user_data);
free(fs->fd_space);
#if CONFIG_SPIFFS_CACHE
free(fs->cache);
#endif
}
static void check_spiffs_files(spiffs *fs, const char *base_path, char* cur_path)
{
DIR *dir;
struct dirent *entry;
size_t len = strlen(cur_path);
if (len == 0) {
strcpy(cur_path, base_path);
len = strlen(base_path);
}
dir = opendir(cur_path);
REQUIRE(dir != 0);
while ((entry = readdir(dir)) != NULL) {
char *name = entry->d_name;
if (entry->d_type == DT_DIR) {
if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
cur_path[len] = '/';
strcpy(cur_path + len + 1, name);
check_spiffs_files(fs, base_path, cur_path);
cur_path[len] = '\0';
} else {
char path[PATH_MAX];
// Read the file from host FS
strcpy(path, cur_path);
strcat(path, "/");
strcat(path, name);
FILE* f = fopen(path , "r");
REQUIRE(f);
fseek(f, 0, SEEK_END);
long sz = ftell(f);
fseek(f, 0, SEEK_SET);
char *f_contents = (char*) malloc(sz);
fread(f_contents, 1, sz, f);
fclose(f);
s32_t spiffs_res;
// Read the file from SPIFFS
char *spiffs_path = path + strlen(base_path);
spiffs_res = SPIFFS_open(fs, spiffs_path, SPIFFS_RDONLY, 0);
REQUIRE(spiffs_res > SPIFFS_OK);
spiffs_file fd = spiffs_res;
spiffs_stat stat;
spiffs_res = SPIFFS_stat(fs, spiffs_path, &stat);
char *spiffs_f_contents = (char*) malloc(stat.size);
spiffs_res = SPIFFS_read(fs, fd, spiffs_f_contents, stat.size);
REQUIRE(spiffs_res == stat.size);
// Compare the contents
REQUIRE(sz == stat.size);
bool same = memcmp(f_contents, spiffs_f_contents, sz) == 0;
REQUIRE(same);
free(f_contents);
free(spiffs_f_contents);
}
}
closedir(dir);
}
TEST_CASE("format disk, open file, write and read file", "[spiffs]")
{
init_spi_flash(CONFIG_ESPTOOLPY_FLASHSIZE, CONFIG_WL_SECTOR_SIZE * 16, CONFIG_WL_SECTOR_SIZE, CONFIG_WL_SECTOR_SIZE, "partition_table.bin");
spiffs fs;
s32_t spiffs_res;
init_spiffs(&fs, 5);
// Open test file // Open test file
spiffs_res = SPIFFS_open(&fs, "test.txt", SPIFFS_O_CREAT | SPIFFS_O_RDWR, 0); spiffs_res = SPIFFS_open(&fs, "test.txt", SPIFFS_O_CREAT | SPIFFS_O_RDWR, 0);
@@ -77,8 +176,6 @@ TEST_CASE("format disk, open file, write and read file", "[spiffs]")
*((uint32_t*)(data + i)) = i; *((uint32_t*)(data + i)) = i;
} }
s32_t bw;
// Write data to file // Write data to file
spiffs_res = SPIFFS_write(&fs, file, (void*)data, data_size); spiffs_res = SPIFFS_write(&fs, file, (void*)data, data_size);
REQUIRE(spiffs_res >= SPIFFS_OK); REQUIRE(spiffs_res >= SPIFFS_OK);
@@ -99,9 +196,53 @@ TEST_CASE("format disk, open file, write and read file", "[spiffs]")
REQUIRE(memcmp(data, read, data_size) == 0); REQUIRE(memcmp(data, read, data_size) == 0);
// Unmount deinit_spiffs(&fs);
SPIFFS_unmount(&fs);
free(read); free(read);
free(data); free(data);
} }
TEST_CASE("can read spiffs image", "[spiffs]")
{
init_spi_flash(CONFIG_ESPTOOLPY_FLASHSIZE, CONFIG_WL_SECTOR_SIZE * 16, CONFIG_WL_SECTOR_SIZE, CONFIG_WL_SECTOR_SIZE, "partition_table.bin");
spiffs fs;
s32_t spiffs_res;
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "storage");
// Write the contents of the image file to partition
FILE* img_file = fopen("image.bin", "r");
REQUIRE(img_file);
fseek(img_file, 0, SEEK_END);
long img_size = ftell(img_file);
fseek(img_file, 0, SEEK_SET);
char *img = (char*) malloc(img_size);
fread(img, 1, img_size, img_file);
fclose(img_file);
REQUIRE(partition->size == img_size);
esp_partition_erase_range(partition, 0, partition->size);
esp_partition_write(partition, 0, img, img_size);
free(img);
// Mount the spiffs partition and init filesystem, using the contents of
// the image file
init_spiffs(&fs, 1024);
// Check spiffs consistency
spiffs_res = SPIFFS_check(&fs);
REQUIRE(spiffs_res == SPIFFS_OK);
char path_buf[PATH_MAX];
// The image is created from the spiffs source directory. Compare the files in that
// directory to the files read from the SPIFFS image.
check_spiffs_files(&fs, "../spiffs", path_buf);
deinit_spiffs(&fs);
}