From ca06f73a514a9c31377b84d00d6bdd4af2537985 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Tue, 15 Jan 2019 09:59:09 +0800 Subject: [PATCH] spiffs: Add host test for generated spiffs image --- components/spiffs/test_spiffs_host/Makefile | 8 +- .../spiffs/test_spiffs_host/test_spiffs.cpp | 197 +++++++++++++++--- 2 files changed, 175 insertions(+), 30 deletions(-) diff --git a/components/spiffs/test_spiffs_host/Makefile b/components/spiffs/test_spiffs_host/Makefile index b0e694f29c..4d016f7b4d 100644 --- a/components/spiffs/test_spiffs_host/Makefile +++ b/components/spiffs/test_spiffs_host/Makefile @@ -68,7 +68,7 @@ $(BUILD_DIR)/$(COMPONENT_LIB): $(OBJ_FILES) $(SDKCONFIG) clean: $(MAKE) -C $(STUBS_LIB_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) @@ -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) 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) # Create other necessary targets diff --git a/components/spiffs/test_spiffs_host/test_spiffs.cpp b/components/spiffs/test_spiffs_host/test_spiffs.cpp index fa3936c2f4..a523f06a73 100644 --- a/components/spiffs/test_spiffs_host/test_spiffs.cpp +++ b/components/spiffs/test_spiffs_host/test_spiffs.cpp @@ -1,6 +1,9 @@ #include #include #include +#include +#include +#include #include "esp_partition.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); -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; + s32_t spiffs_res; 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 - esp_spiffs_t esp_user_data; - esp_user_data.partition = partition; - fs.user_data = (void*)&esp_user_data; + esp_spiffs_t *user_data = (esp_spiffs_t*) calloc(1, sizeof(*user_data)); + user_data->partition = partition; + fs->user_data = (void*)user_data; cfg.hal_erase_f = spiffs_api_erase; cfg.hal_read_f = spiffs_api_read; @@ -34,34 +36,131 @@ TEST_CASE("format disk, open file, write and read file", "[spiffs]") cfg.phys_erase_block = CONFIG_WL_SECTOR_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 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) + 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); - - s32_t spiffs_res; + uint8_t *cache = (uint8_t*) malloc(cache_sz); +#else + uint32_t cache_sz = 0; + uint8_t cache = NULL; +#endif // Special mounting procedure: mount, format, mount as per // 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); - REQUIRE(spiffs_res == SPIFFS_ERR_NOT_A_FS); - spiffs_res = SPIFFS_format(&fs); - REQUIRE(spiffs_res >= SPIFFS_OK); + if (spiffs_res == SPIFFS_ERR_NOT_A_FS) { + 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); +} + +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 - 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); REQUIRE(spiffs_res >= SPIFFS_OK); // Generate data @@ -77,17 +176,15 @@ TEST_CASE("format disk, open file, write and read file", "[spiffs]") *((uint32_t*)(data + i)) = i; } - s32_t bw; - // 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 == data_size); // Set the file object pointer to the beginning spiffs_res = SPIFFS_lseek(&fs, file, 0, SPIFFS_SEEK_SET); REQUIRE(spiffs_res >= SPIFFS_OK); - + // Read the file spiffs_res = SPIFFS_read(&fs, file, (void*)read, data_size); 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); - // Unmount - SPIFFS_unmount(&fs); + deinit_spiffs(&fs); free(read); 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); +} \ No newline at end of file