This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 3ff50ac  apps: fs_test: Add filesystem testing application
     new 617b9c3  Merge pull request #2527 from utzig/apps-fs-test
3ff50ac is described below

commit 3ff50ac1b58121d4598354c135c8562dad2131b6
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Fri Mar 12 07:18:46 2021 -0300

    apps: fs_test: Add filesystem testing application
    
    The fs_test app exercises all defined `fs/fs` interfaces, and is useful
    when adding new filesystems' support or debugging filesystem issues.
    
    Signed-off-by: Fabio Utzig <ut...@apache.org>
---
 apps/fs_test/pkg.yml        |  38 ++++
 apps/fs_test/src/littlefs.c |  51 +++++
 apps/fs_test/src/main.c     | 452 ++++++++++++++++++++++++++++++++++++++++++++
 apps/fs_test/src/nffs.c     |  39 ++++
 apps/fs_test/syscfg.yml     |  41 ++++
 5 files changed, 621 insertions(+)

diff --git a/apps/fs_test/pkg.yml b/apps/fs_test/pkg.yml
new file mode 100644
index 0000000..af1d493
--- /dev/null
+++ b/apps/fs_test/pkg.yml
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: apps/fs_test
+pkg.type: app
+pkg.description: "Exercise an FS using the standard FS interface."
+pkg.author: "Apache Mynewt <d...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+
+pkg.deps.FS_TEST_NFFS:
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/fs/nffs"
+
+pkg.deps.FS_TEST_LITTLEFS:
+    - "@apache-mynewt-core/fs/littlefs"
diff --git a/apps/fs_test/src/littlefs.c b/apps/fs_test/src/littlefs.c
new file mode 100644
index 0000000..74604d1
--- /dev/null
+++ b/apps/fs_test/src/littlefs.c
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/mynewt.h"
+
+#if MYNEWT_VAL(FS_TEST_LITTLEFS)
+
+#if !MYNEWT_VAL(LITTLEFS_FLASH_AREA)
+#error "No LITTLEFS_FLASH_AREA defined"
+#endif
+
+#include "littlefs/lfs.h"
+
+int littlefs_reformat(void);
+int littlefs_init(void);
+
+int
+fs_lowlevel_init(void)
+{
+    int rc;
+
+    (void)rc;
+
+    /* always force format before starting */
+#if MYNEWT_VAL(FS_TEST_FORCE_REFORMAT)
+    rc = littlefs_reformat();
+    if (rc) {
+        return rc;
+    }
+#endif
+
+    return littlefs_init();
+}
+
+#endif
diff --git a/apps/fs_test/src/main.c b/apps/fs_test/src/main.c
new file mode 100644
index 0000000..7246a94
--- /dev/null
+++ b/apps/fs_test/src/main.c
@@ -0,0 +1,452 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/mynewt.h"
+#include <bsp/bsp.h>
+#include <hal/hal_flash.h>
+#include <console/console.h>
+#include <log/log.h>
+#include "flash_map/flash_map.h"
+#include <fs/fs.h>
+#include <hal/hal_gpio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+#define BLINKY_PRIO          (8)
+#define BLINKY_STACK_SIZE    OS_STACK_ALIGN(64)
+static struct os_task blinky_task;
+
+#define FS_TEST_PRIO         (9)
+#define FS_TEST_STACK_SIZE   OS_STACK_ALIGN(2048)
+static struct os_task fs_test_task;
+
+#if !MYNEWT_VAL(FS_TEST_LITTLEFS) && !MYNEWT_VAL(FS_TEST_NFFS)
+#error "No filesystem selected, or unsupported FS!"
+#endif
+
+static char *random_strings[] = {
+    "Q4qrwYFQIzCj8JsjxIVQIywAWkkFo2kk",
+    "sEIdSP7uG6XkJr3ZkOCYPL8Rj80gGPVe2w",
+    "idZNVRMBuaYP3E8CSL36NXYpGPj5ED",
+    "000o2PHKjvxfV4AuvDaqye2QPJK7269",
+    "R3Xg4daYGr",
+};
+
+/* Root directory where files will be created */
+static const char *dirformat = "fs_test_%d";
+
+#define STARTUP_DELAY MYNEWT_VAL(FS_TEST_STARTUP_DELAY)
+#define MAX_TEST_FILES MYNEWT_VAL(FS_TEST_MAX_FILES)
+
+#define BLINK_NORMAL (OS_TICKS_PER_SEC)
+#define BLINK_SLOW (OS_TICKS_PER_SEC * 2)
+#define BLINK_FAST (OS_TICKS_PER_SEC / 2)
+static uint32_t g_blink_freq = BLINK_NORMAL;
+
+static int
+fs_test_create_directory(char *dirname)
+{
+    char name[20];
+    int i;
+    int rc;
+
+    i = 0;
+    while (true) {
+        sprintf(name, dirformat, i);
+        rc = fs_mkdir(name);
+        if (rc != FS_EEXIST) {
+            break;
+        }
+        i++;
+    }
+
+    if (rc == FS_EOK) {
+        printf("Created new test directory (%s)\n", name);
+        strcpy(dirname, name);
+    } else {
+        printf("Failed creating test directory (%d)\n", rc);
+    }
+
+    return rc;
+}
+
+static int
+fs_test_write_files(char *root)
+{
+    int i;
+    char name[30];
+    struct fs_file *file = NULL;
+    char *string;
+    uint32_t len;
+    int rc;
+
+    for (i = 0; i < MAX_TEST_FILES; i++) {
+        sprintf(name, "%s/test_%d", root, i);
+        string = random_strings[i % ARRAY_SIZE(random_strings)];
+        len = strlen(string);
+
+        printf("Opening new file (%s) for writing... ", name);
+        rc = fs_open(name, FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE, &file);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            return -1;
+        }
+        printf("ok\n");
+
+        printf("Writing data to new file... ");
+        rc = fs_write(file, string, len);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            fs_close(file);
+            return -1;
+        }
+        printf("ok\n");
+
+        fs_close(file);
+    }
+
+    return 0;
+}
+
+static int
+fs_test_read_files(char *root)
+{
+    int i;
+    char name[30];
+    char buf[45];
+    struct fs_file *file = NULL;
+    char *string;
+    uint32_t len;
+    uint32_t outlen;
+    uint32_t pos;
+    int rc;
+
+    for (i = 0; i < MAX_TEST_FILES; i++) {
+        sprintf(name, "%s/test_%d", root, i);
+        string = random_strings[i % ARRAY_SIZE(random_strings)];
+        len = strlen(string);
+
+        printf("Opening new file (%s) for reading... ", name);
+        rc = fs_open(name, FS_ACCESS_READ, &file);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            printf("Failed opening for reading: %d\n", rc);
+            return rc;
+        }
+        printf("ok\n");
+
+        printf("Getting file length... ");
+        rc = fs_filelen(file, &outlen);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            fs_close(file);
+            return rc;
+        }
+        printf("ok (%ld)\n", outlen);
+
+        if (len != outlen) {
+            printf("%s has an unexpected length (%lu!=%lu)\n", name, len, 
outlen);
+            fs_close(file);
+            return -1;
+        }
+
+        pos = fs_getpos(file);
+        if (pos != 0) {
+            printf("Invalid position (%lu), should be (0)\n", pos);
+            fs_close(file);
+            return -1;
+        }
+
+        printf("Reading from file... ");
+        memset(buf, 0, sizeof(buf));
+        rc = fs_read(file, len, buf, &outlen);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            fs_close(file);
+            return rc;
+        }
+        printf("ok\n");
+
+        printf("Compare read results... ");
+        if (strncmp(buf, string, len) != 0) {
+            printf("fail\n");
+            fs_close(file);
+            return -1;
+        }
+        printf("ok\n");
+
+        pos = fs_getpos(file);
+        if (pos != len) {
+            printf("Invalid position (%lu), should be (%lu)\n", pos, len);
+            fs_close(file);
+            return -1;
+        }
+
+        printf("Seek to middle position of file... ");
+        rc = fs_seek(file, len / 2);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            fs_close(file);
+            return rc;
+        }
+        printf("ok\n");
+
+        pos = fs_getpos(file);
+        if (pos != len / 2) {
+            printf("Invalid position (%lu), should be (%lu)\n", pos, len / 2);
+            fs_close(file);
+            return -1;
+        }
+
+        printf("Reading again... ");
+        memset(buf, 0, sizeof(buf));
+        rc = fs_read(file, len / 2, buf, &outlen);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            fs_close(file);
+            return -1;
+        }
+        printf("ok\n");
+
+        printf("Comparing read results... ");
+        if (strncmp(buf, &string[len / 2], len / 2) != 0) {
+            printf("fail\n");
+            fs_close(file);
+            return -1;
+        }
+        printf("ok\n");
+
+        fs_close(file);
+    }
+
+    return 0;
+}
+
+static int
+fs_test_rename_files(char *root)
+{
+    int i;
+    char name[30];
+    char new_name[30];
+    int rc;
+
+    for (i = 0; i < MAX_TEST_FILES; i++) {
+        sprintf(name, "%s/test_%d", root, i);
+        sprintf(new_name, "%s/tested_%d", root, i);
+
+        printf("Renaming (%s) to (%s)... ", name, new_name);
+        rc = fs_rename(name, new_name);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            return -1;
+        }
+        printf("ok\n");
+    }
+
+    return 0;
+}
+
+static int
+fs_test_read_directory(char *root)
+{
+    struct fs_dir *dir;
+    struct fs_dirent *dirent;
+    char name[40];
+    uint8_t out_len;
+    int rc;
+
+    printf("Opening (%s) directory... ", root);
+    rc = fs_opendir(root, &dir);
+    if (rc != 0) {
+        printf("fail (%d)\n", rc);
+        return -1;
+    }
+    printf("ok\n");
+
+    do {
+        printf("Reading directory entry... ");
+        rc = fs_readdir(dir, &dirent);
+        if (rc == FS_ENOENT) {
+            printf("ok\n");
+            rc = 0;
+            break;
+        } else if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            rc = -1;
+            goto out;
+        }
+        printf("ok\n");
+
+        printf("Getting dirent information... ");
+        rc = fs_dirent_name(dirent, 40, name, &out_len);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            rc = -1;
+            goto out;
+        }
+        printf("ok\n");
+
+        if (fs_dirent_is_dir(dirent)) {
+            printf("Found directory (%s)\n", name);
+        } else {
+            printf("Found file (%s)\n", name);
+        }
+    } while (1);
+
+out:
+    fs_closedir(dir);
+
+    return rc;
+}
+
+static int
+fs_test_cleanup(char *root)
+{
+    int i;
+    char name[30];
+    int rc;
+
+    memset(name, 0, sizeof(name));
+
+    for (i = 0; i < MAX_TEST_FILES; i++) {
+        sprintf(name, "%s/tested_%d", root, i);
+
+        printf("Removing file (%s)... ", name);
+        rc = fs_unlink(name);
+        if (rc != 0) {
+            printf("fail (%d)\n", rc);
+            return -1;
+        }
+        printf("ok\n");
+    }
+
+    printf("Remove directory (%s)... ", root);
+    rc = fs_unlink(root);
+    if (rc < 0) {
+        printf("fail (%d)\n", rc);
+        return -1;
+    }
+    printf("ok\n");
+
+    return 0;
+}
+
+extern int fs_lowlevel_init(void);
+
+static void
+fs_test_handler(void *arg)
+{
+    int rc;
+    char root[30];
+
+    g_blink_freq = BLINK_SLOW;
+
+    printf("Will start test in %d secs...\n", STARTUP_DELAY);
+    os_time_delay(STARTUP_DELAY * OS_TICKS_PER_SEC);
+
+    rc = fs_lowlevel_init();
+    if (rc == 0) {
+        rc = fs_test_create_directory(root);
+    }
+    if (rc == 0) {
+        rc = fs_test_write_files(root);
+    }
+    if (rc == 0) {
+        rc = fs_test_read_files(root);
+    }
+    if (rc == 0) {
+        rc = fs_test_rename_files(root);
+    }
+    if (rc == 0) {
+        rc = fs_test_read_directory(root);
+    }
+    if (rc == 0) {
+        rc = fs_test_cleanup(root);
+    }
+
+    if (rc) {
+        printf("Filesystem testing has failed\n");
+        g_blink_freq = BLINK_FAST;
+    } else {
+        printf("Filesystem testing was successful\n");
+        g_blink_freq = BLINK_NORMAL;
+    }
+
+    while (1) {
+        os_time_delay(1);
+    }
+}
+
+static void
+blinky_handler(void *arg)
+{
+    int led_pin;
+
+    led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(led_pin, 1);
+
+    while (1) {
+        os_time_delay(g_blink_freq);
+        hal_gpio_toggle(led_pin);
+    }
+}
+
+static void
+init_tasks(void)
+{
+    os_stack_t *pstack;
+
+    pstack = malloc(sizeof(*pstack) * FS_TEST_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&fs_test_task, "fs_test", fs_test_handler, NULL,
+                 FS_TEST_PRIO, OS_WAIT_FOREVER, pstack, FS_TEST_STACK_SIZE);
+
+    pstack = malloc(sizeof(*pstack) * BLINKY_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&blinky_task, "blinky", blinky_handler, NULL,
+                 BLINKY_PRIO, OS_WAIT_FOREVER, pstack, BLINKY_STACK_SIZE);
+}
+
+int
+main(int argc, char **argv)
+{
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    init_tasks();
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}
diff --git a/apps/fs_test/src/nffs.c b/apps/fs_test/src/nffs.c
new file mode 100644
index 0000000..6fdb502
--- /dev/null
+++ b/apps/fs_test/src/nffs.c
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/mynewt.h"
+
+#if MYNEWT_VAL(FS_TEST_NFFS)
+
+#if !MYNEWT_VAL(NFFS_FLASH_AREA)
+#error "No NFFS_FLASH_AREA defined"
+#endif
+
+#include "nffs/nffs.h"
+
+/*
+ * TODO: NFFS currently only supports formatting while mounting on sysinit
+ */
+int
+fs_lowlevel_init(void)
+{
+    return 0;
+}
+
+#endif
diff --git a/apps/fs_test/syscfg.yml b/apps/fs_test/syscfg.yml
new file mode 100644
index 0000000..596a8e5
--- /dev/null
+++ b/apps/fs_test/syscfg.yml
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    FS_TEST_NFFS:
+        description: 'Run tests on an NFFS partition'
+        value: 0
+        restrictions:
+            - '!FS_TEST_LITTLEFS'
+    FS_TEST_LITTLEFS:
+        description: 'Run tests on a LittleFS partition'
+        value: 0
+        restrictions:
+            - '!FS_TEST_NFFS'
+    FS_TEST_MAX_FILES:
+        description: 'Amount of files to create for read/write test'
+        value: 4
+    FS_TEST_FORCE_REFORMAT:
+        description: 'Always format the flash area before running'
+        value: 0
+    FS_TEST_STARTUP_DELAY:
+        description: 'Time to wait before starting the tests in seconds'
+        value: 0
+
+syscfg.vals.FS_TEST_LITTLEFS:
+    LITTLEFS_DISABLE_SYSINIT: 1

Reply via email to