]> granicus.if.org Git - esp-idf/commitdiff
spiffs: Add host test for generated spiffs image
authorRenz Christian Bagaporo <renz@espressif.com>
Tue, 15 Jan 2019 01:59:09 +0000 (09:59 +0800)
committerRenz Christian Bagaporo <renz@espressif.com>
Mon, 25 Mar 2019 04:51:52 +0000 (12:51 +0800)
components/spiffs/test_spiffs_host/Makefile
components/spiffs/test_spiffs_host/test_spiffs.cpp

index b0e694f29c41ce04274e89904cddf11798a33d87..4d016f7b4d8e7306c7d4f5baa04f56fcdfe8bfd3 100644 (file)
@@ -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
index fa3936c2f44e6f87a1123a7ccdf87cf4d4a30c4a..a523f06a734dd64f8c38da09677a857d5dcffcb0 100644 (file)
@@ -1,6 +1,9 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
+#include <sys/mman.h>
+#include <dirent.h>
+#include <limits.h>
 
 #include "esp_partition.h"
 #include "spiffs.h"
 
 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