From 02f090b756cb6b5088d2ba937c6723e936fef284 Mon Sep 17 00:00:00 2001 From: Laczen JMS Date: Thu, 10 Oct 2024 13:30:59 +0200 Subject: [PATCH] storage: add tests Add tests for storage area and storage area store Signed-off-by: Laczen JMS --- .../storage_area_api/CMakeLists.txt | 12 + .../boards/native_sim.overlay | 22 + .../boards/qemu_cortex_m3.overlay | 15 + .../storage_area_api/cfg_disk.conf | 2 + .../storage_area_api/cfg_eeprom.conf | 1 + .../storage_area_api/cfg_flash.conf | 1 + .../storage_area_api/cfg_ram.conf | 1 + .../storage_area/storage_area_api/prj.conf | 6 + .../storage_area/storage_area_api/src/main.c | 196 +++++++++ .../storage_area_api/testcase.yaml | 23 + .../storage_area_store/CMakeLists.txt | 12 + .../boards/native_sim.overlay | 22 + .../boards/qemu_cortex_m3.overlay | 15 + .../storage_area_store/cfg_disk.conf | 2 + .../storage_area_store/cfg_eeprom.conf | 1 + .../storage_area_store/cfg_flash.conf | 2 + .../storage_area_store/cfg_ram.conf | 1 + .../storage_area/storage_area_store/prj.conf | 6 + .../storage_area_store/src/main.c | 397 ++++++++++++++++++ .../storage_area_store/testcase.yaml | 23 + 20 files changed, 760 insertions(+) create mode 100644 tests/subsys/storage/storage_area/storage_area_api/CMakeLists.txt create mode 100644 tests/subsys/storage/storage_area/storage_area_api/boards/native_sim.overlay create mode 100644 tests/subsys/storage/storage_area/storage_area_api/boards/qemu_cortex_m3.overlay create mode 100644 tests/subsys/storage/storage_area/storage_area_api/cfg_disk.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_api/cfg_eeprom.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_api/cfg_flash.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_api/cfg_ram.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_api/prj.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_api/src/main.c create mode 100644 tests/subsys/storage/storage_area/storage_area_api/testcase.yaml create mode 100644 tests/subsys/storage/storage_area/storage_area_store/CMakeLists.txt create mode 100644 tests/subsys/storage/storage_area/storage_area_store/boards/native_sim.overlay create mode 100644 tests/subsys/storage/storage_area/storage_area_store/boards/qemu_cortex_m3.overlay create mode 100644 tests/subsys/storage/storage_area/storage_area_store/cfg_disk.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_store/cfg_eeprom.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_store/cfg_flash.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_store/cfg_ram.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_store/prj.conf create mode 100644 tests/subsys/storage/storage_area/storage_area_store/src/main.c create mode 100644 tests/subsys/storage/storage_area/storage_area_store/testcase.yaml diff --git a/tests/subsys/storage/storage_area/storage_area_api/CMakeLists.txt b/tests/subsys/storage/storage_area/storage_area_api/CMakeLists.txt new file mode 100644 index 00000000000000..1677fb33854823 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 Laczen +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(storage_area_test) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/storage/storage_area/storage_area_api/boards/native_sim.overlay b/tests/subsys/storage/storage_area/storage_area_api/boards/native_sim.overlay new file mode 100644 index 00000000000000..50aa2d710c81d0 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/boards/native_sim.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Laczen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &eeprom0; + +/ { + eeprom0: eeprom { + status = "okay"; + compatible = "zephyr,sim-eeprom"; + size = ; + }; + + ramdisk0: ramdisk { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <32>; + }; +}; diff --git a/tests/subsys/storage/storage_area/storage_area_api/boards/qemu_cortex_m3.overlay b/tests/subsys/storage/storage_area/storage_area_api/boards/qemu_cortex_m3.overlay new file mode 100644 index 00000000000000..eaa83b4a1544bf --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/boards/qemu_cortex_m3.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Laczen + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + storage_sram: sram@2000C000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2000C000 0x4000>; + zephyr,memory-region = "STORAGE_SRAM"; + status = "okay"; + }; +}; diff --git a/tests/subsys/storage/storage_area/storage_area_api/cfg_disk.conf b/tests/subsys/storage/storage_area/storage_area_api/cfg_disk.conf new file mode 100644 index 00000000000000..fd34c12feff7ce --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/cfg_disk.conf @@ -0,0 +1,2 @@ +CONFIG_STORAGE_AREA_DISK=y +CONFIG_DISK_DRIVER_RAM=y diff --git a/tests/subsys/storage/storage_area/storage_area_api/cfg_eeprom.conf b/tests/subsys/storage/storage_area/storage_area_api/cfg_eeprom.conf new file mode 100644 index 00000000000000..9e1e18a4af6acf --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/cfg_eeprom.conf @@ -0,0 +1 @@ +CONFIG_STORAGE_AREA_EEPROM=y diff --git a/tests/subsys/storage/storage_area/storage_area_api/cfg_flash.conf b/tests/subsys/storage/storage_area/storage_area_api/cfg_flash.conf new file mode 100644 index 00000000000000..3287eb5a1007e6 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/cfg_flash.conf @@ -0,0 +1 @@ +CONFIG_STORAGE_AREA_FLASH=y diff --git a/tests/subsys/storage/storage_area/storage_area_api/cfg_ram.conf b/tests/subsys/storage/storage_area/storage_area_api/cfg_ram.conf new file mode 100644 index 00000000000000..64344d93082123 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/cfg_ram.conf @@ -0,0 +1 @@ +CONFIG_STORAGE_AREA_RAM=y diff --git a/tests/subsys/storage/storage_area/storage_area_api/prj.conf b/tests/subsys/storage/storage_area/storage_area_api/prj.conf new file mode 100644 index 00000000000000..e888be4a79069f --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/prj.conf @@ -0,0 +1,6 @@ +CONFIG_ZTEST=y +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y + +CONFIG_STORAGE_AREA=y +CONFIG_STORAGE_AREA_VERIFY=y diff --git a/tests/subsys/storage/storage_area/storage_area_api/src/main.c b/tests/subsys/storage/storage_area/storage_area_api/src/main.c new file mode 100644 index 00000000000000..ff1d52e9b306f6 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/src/main.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2024 Laczen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Test for the storage_area API */ + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(sa_api_test); + +#ifdef CONFIG_STORAGE_AREA_FLASH +#include +#define FLASH_AREA_NODE DT_NODELABEL(storage_partition) +#define FLASH_AREA_OFFSET DT_REG_ADDR(FLASH_AREA_NODE) +#define FLASH_AREA_DEVICE \ + DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(FLASH_AREA_NODE)) +#define FLASH_AREA_XIP FLASH_AREA_OFFSET + \ + DT_REG_ADDR(DT_MTD_FROM_FIXED_PARTITION(FLASH_AREA_NODE)) +#define AREA_SIZE DT_REG_SIZE(FLASH_AREA_NODE) +#define AREA_ERASE_SIZE 4096 +#define AREA_WRITE_SIZE 512 + +STORAGE_AREA_FLASH_RW_DEFINE(test, FLASH_AREA_DEVICE, FLASH_AREA_OFFSET, + FLASH_AREA_XIP, AREA_WRITE_SIZE, AREA_ERASE_SIZE, AREA_SIZE, + STORAGE_AREA_PROP_LOVRWRITE); +#endif /* CONFIG_STORAGE_AREA_FLASH */ + +#ifdef CONFIG_STORAGE_AREA_EEPROM +#include +#define EEPROM_NODE DT_ALIAS(eeprom_0) +#define EEPROM_AREA_DEVICE DEVICE_DT_GET(EEPROM_NODE) +#define AREA_SIZE DT_PROP(EEPROM_NODE, size) +#define AREA_ERASE_SIZE 1024 +#define AREA_WRITE_SIZE 4 + +STORAGE_AREA_EEPROM_RW_DEFINE(test, EEPROM_AREA_DEVICE, 0U, AREA_WRITE_SIZE, + AREA_ERASE_SIZE, AREA_SIZE, 0); +#endif /* CONFIG_STORAGE_AREA_EEPROM */ + +#ifdef CONFIG_STORAGE_AREA_RAM +#include +#define RAM_NODE DT_NODELABEL(storage_sram) +#define AREA_SIZE DT_REG_SIZE(RAM_NODE) +#define AREA_ERASE_SIZE 4096 +#define AREA_WRITE_SIZE 4 + +STORAGE_AREA_RAM_RW_DEFINE(test, DT_REG_ADDR(RAM_NODE), AREA_WRITE_SIZE, + AREA_ERASE_SIZE, AREA_SIZE, 0); +#endif /* CONFIG_STORAGE_AREA_RAM */ + +#ifdef CONFIG_STORAGE_AREA_DISK +#include +#define DISK_NODE DT_NODELABEL(ramdisk0) +#define DISK_NAME DT_PROP(DISK_NODE, disk_name) +#define DISK_SSIZE DT_PROP(DISK_NODE, sector_size) +#define DISK_SCNT DT_PROP(DISK_NODE, sector_count) +#define AREA_SIZE DISK_SCNT * DISK_SSIZE / 2 +#define AREA_ERASE_SIZE DISK_SSIZE +#define AREA_WRITE_SIZE DISK_SSIZE + +STORAGE_AREA_DISK_RW_DEFINE(test, DISK_NAME, DISK_SCNT / 2, DISK_SSIZE, + AREA_WRITE_SIZE, AREA_ERASE_SIZE, AREA_SIZE, 0); +#endif /* CONFIG_STORAGE_AREA_DISK */ + +static void *storage_area_api_setup(void) +{ + return NULL; +} + +static void storage_area_api_before(void *fixture) +{ + ARG_UNUSED(fixture); + + const struct storage_area *sa = GET_STORAGE_AREA(test); + int rc = storage_area_erase(sa, 0, 1); + + zassert_ok(rc, "erase returned [%d]", rc); +} + +ZTEST_USER(storage_area_api, test_read_write_simple) +{ + const struct storage_area *sa = GET_STORAGE_AREA(test); + uint8_t wr[STORAGE_AREA_WRITESIZE(sa)]; + uint8_t rd[STORAGE_AREA_WRITESIZE(sa)]; + struct storage_area_iovec rdvec = { + .data = &rd, + .len = sizeof(rd), + }; + struct storage_area_iovec wrvec = { + .data = &wr, + .len = sizeof(wr), + }; + int rc; + + + memset(wr, 'T', sizeof(wr)); + memset(rd, 0, sizeof(rd)); + + rc = storage_area_writev(sa, 0U, &wrvec, 1U); + zassert_ok(rc, "prog returned [%d]", rc); + + rc = storage_area_readv(sa, 0U, &rdvec, 1U); + zassert_ok(rc, "read returned [%d]", rc); + + zassert_mem_equal(rd, wr, sizeof(wr), 0, "data mismatch"); +} + +ZTEST_USER(storage_area_api, test_read_write_direct) +{ + const struct storage_area *sa = GET_STORAGE_AREA(test); + uint8_t wr[STORAGE_AREA_WRITESIZE(sa)]; + uint8_t rd[STORAGE_AREA_WRITESIZE(sa)]; + int rc; + + memset(wr, 'T', sizeof(wr)); + memset(rd, 0, sizeof(rd)); + + rc = storage_area_write(sa, 0U, wr, sizeof(wr)); + zassert_ok(rc, "prog returned [%d]", rc); + + rc = storage_area_read(sa, 0U, rd, sizeof(rd)); + zassert_ok(rc, "read returned [%d]", rc); + + zassert_mem_equal(rd, wr, sizeof(wr), 0, "data mismatch"); +} + +ZTEST_USER(storage_area_api, test_read_write_blocks) +{ + const struct storage_area *sa = GET_STORAGE_AREA(test); + uint8_t magic = 0xA0; + uint8_t wr[STORAGE_AREA_WRITESIZE(sa)]; + uint8_t rd[STORAGE_AREA_WRITESIZE(sa)]; + uint8_t fill[STORAGE_AREA_WRITESIZE(sa) - 1]; + struct storage_area_iovec rdvec[] = { + { + .data = (void *)&magic, + .len = sizeof(magic), + }, + { + .data = (void *)&rd, + .len = sizeof(rd), + }, + }; + struct storage_area_iovec wrvec[] = { + { + .data = (void *)&magic, + .len = sizeof(magic), + }, + { + .data = (void *)&wr, + .len = sizeof(wr), + }, + { + .data = (void *)&fill, + .len = sizeof(fill), + }, + }; + int rc; + + memset(fill, 0xff, sizeof(fill)); + memset(wr, 'T', sizeof(wr)); + memset(rd, 0, sizeof(rd)); + + rc = storage_area_writev(sa, 0U, wrvec, ARRAY_SIZE(wrvec)); + zassert_ok(rc, "prog returned [%d]", rc); + + rc = storage_area_readv(sa, 0U, rdvec, ARRAY_SIZE(rdvec)); + zassert_ok(rc, "read returned [%d]", rc); + + zassert_equal(magic, 0xA0, "magic has changed"); + zassert_mem_equal(rd, wr, sizeof(wr), 0, "data mismatch"); +} + +ZTEST_USER(storage_area_api, test_ioctl) +{ + const struct storage_area *sa = GET_STORAGE_AREA(test); + uintptr_t xip; + + int rc = storage_area_ioctl(sa, STORAGE_AREA_IOCTL_XIPADDRESS, &xip); + + if ((IS_ENABLED(CONFIG_STORAGE_AREA_DISK)) || + (IS_ENABLED(CONFIG_STORAGE_AREA_EEPROM))) { + zassert_equal(rc, -ENOTSUP, "xip returned invalid address"); + } else { + zassert_ok(rc, "xip returned no address"); + } +} + +ZTEST_SUITE(storage_area_api, NULL, storage_area_api_setup, + storage_area_api_before, NULL, NULL); diff --git a/tests/subsys/storage/storage_area/storage_area_api/testcase.yaml b/tests/subsys/storage/storage_area/storage_area_api/testcase.yaml new file mode 100644 index 00000000000000..e58248620d3748 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_api/testcase.yaml @@ -0,0 +1,23 @@ +common: + tags: storage_area_api +tests: + storage.storage_area.api.flash: + platform_allow: + - native_sim + extra_args: + - EXTRA_CONF_FILE=cfg_flash.conf + storage.storage_area.api.eeprom: + platform_allow: + - native_sim + extra_args: + - EXTRA_CONF_FILE=cfg_eeprom.conf + storage.storage_area.api.ram: + platform_allow: + - qemu_cortex_m3 + extra_args: + - EXTRA_CONF_FILE=cfg_ram.conf + storage.storage_area.api.disk: + platform_allow: + - native_sim + extra_args: + - EXTRA_CONF_FILE=cfg_disk.conf diff --git a/tests/subsys/storage/storage_area/storage_area_store/CMakeLists.txt b/tests/subsys/storage/storage_area/storage_area_store/CMakeLists.txt new file mode 100644 index 00000000000000..7008f970ef06ce --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2019 Peter Bigot Consulting, LLC +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(sastest) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/storage/storage_area/storage_area_store/boards/native_sim.overlay b/tests/subsys/storage/storage_area/storage_area_store/boards/native_sim.overlay new file mode 100644 index 00000000000000..b89b41d3a4aaf6 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/boards/native_sim.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Laczen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &eeprom0; + +/ { + eeprom0: eeprom { + status = "okay"; + compatible = "zephyr,sim-eeprom"; + size = ; + }; + + ramdisk0: ramdisk { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <64>; + }; +}; diff --git a/tests/subsys/storage/storage_area/storage_area_store/boards/qemu_cortex_m3.overlay b/tests/subsys/storage/storage_area/storage_area_store/boards/qemu_cortex_m3.overlay new file mode 100644 index 00000000000000..eaa83b4a1544bf --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/boards/qemu_cortex_m3.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Laczen + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + storage_sram: sram@2000C000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2000C000 0x4000>; + zephyr,memory-region = "STORAGE_SRAM"; + status = "okay"; + }; +}; diff --git a/tests/subsys/storage/storage_area/storage_area_store/cfg_disk.conf b/tests/subsys/storage/storage_area/storage_area_store/cfg_disk.conf new file mode 100644 index 00000000000000..fd34c12feff7ce --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/cfg_disk.conf @@ -0,0 +1,2 @@ +CONFIG_STORAGE_AREA_DISK=y +CONFIG_DISK_DRIVER_RAM=y diff --git a/tests/subsys/storage/storage_area/storage_area_store/cfg_eeprom.conf b/tests/subsys/storage/storage_area/storage_area_store/cfg_eeprom.conf new file mode 100644 index 00000000000000..9e1e18a4af6acf --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/cfg_eeprom.conf @@ -0,0 +1 @@ +CONFIG_STORAGE_AREA_EEPROM=y diff --git a/tests/subsys/storage/storage_area/storage_area_store/cfg_flash.conf b/tests/subsys/storage/storage_area/storage_area_store/cfg_flash.conf new file mode 100644 index 00000000000000..40e2faa1239220 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/cfg_flash.conf @@ -0,0 +1,2 @@ +CONFIG_STORAGE_AREA_FLASH=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y diff --git a/tests/subsys/storage/storage_area/storage_area_store/cfg_ram.conf b/tests/subsys/storage/storage_area/storage_area_store/cfg_ram.conf new file mode 100644 index 00000000000000..64344d93082123 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/cfg_ram.conf @@ -0,0 +1 @@ +CONFIG_STORAGE_AREA_RAM=y diff --git a/tests/subsys/storage/storage_area/storage_area_store/prj.conf b/tests/subsys/storage/storage_area/storage_area_store/prj.conf new file mode 100644 index 00000000000000..7f93e55c0fd7a4 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/prj.conf @@ -0,0 +1,6 @@ +CONFIG_ZTEST=y +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y + +CONFIG_STORAGE_AREA=y +CONFIG_STORAGE_AREA_STORE=y diff --git a/tests/subsys/storage/storage_area/storage_area_store/src/main.c b/tests/subsys/storage/storage_area/storage_area_store/src/main.c new file mode 100644 index 00000000000000..cf12a1742777a7 --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/src/main.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2024 Laczen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Test for the storage_area_store API */ + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(sas_test); + +#ifdef CONFIG_STORAGE_AREA_FLASH +#include +#define FLASH_AREA_NODE DT_NODELABEL(storage_partition) +#define FLASH_AREA_OFFSET DT_REG_ADDR(FLASH_AREA_NODE) +#define FLASH_AREA_DEVICE \ + DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(FLASH_AREA_NODE)) +#define FLASH_AREA_XIP FLASH_AREA_OFFSET + \ + DT_REG_ADDR(DT_MTD_FROM_FIXED_PARTITION(FLASH_AREA_NODE)) +#define AREA_SIZE DT_REG_SIZE(FLASH_AREA_NODE) +#define AREA_ERASE_SIZE 8192 +#define AREA_WRITE_SIZE 8 + +STORAGE_AREA_FLASH_RW_DEFINE(test, FLASH_AREA_DEVICE, FLASH_AREA_OFFSET, + FLASH_AREA_XIP, AREA_WRITE_SIZE, AREA_ERASE_SIZE, AREA_SIZE, + STORAGE_AREA_PROP_LOVRWRITE | STORAGE_AREA_PROP_AUTOERASE); +#endif /* CONFIG_STORAGE_AREA_FLASH */ + +#ifdef CONFIG_STORAGE_AREA_EEPROM +#include +#define EEPROM_NODE DT_ALIAS(eeprom_0) +#define EEPROM_AREA_DEVICE DEVICE_DT_GET(EEPROM_NODE) +#define AREA_SIZE DT_PROP(EEPROM_NODE, size) +#define AREA_ERASE_SIZE 4096 +#define AREA_WRITE_SIZE 4 + +STORAGE_AREA_EEPROM_RW_DEFINE(test, EEPROM_AREA_DEVICE, 0U, AREA_WRITE_SIZE, + AREA_ERASE_SIZE, AREA_SIZE, 0); +#endif /* CONFIG_STORAGE_AREA_EEPROM */ + +#ifdef CONFIG_STORAGE_AREA_RAM +#include +#define RAM_NODE DT_NODELABEL(storage_sram) +#define AREA_SIZE DT_REG_SIZE(RAM_NODE) +#define AREA_ERASE_SIZE 4096 +#define AREA_WRITE_SIZE 4 + +STORAGE_AREA_RAM_RW_DEFINE(test, DT_REG_ADDR(RAM_NODE), AREA_WRITE_SIZE, + AREA_ERASE_SIZE, AREA_SIZE, 0); +#endif /* CONFIG_STORAGE_AREA_RAM */ + +#ifdef CONFIG_STORAGE_AREA_DISK +#include +#define DISK_NODE DT_NODELABEL(ramdisk0) +#define DISK_NAME DT_PROP(DISK_NODE, disk_name) +#define DISK_SSIZE DT_PROP(DISK_NODE, sector_size) +#define DISK_SCNT DT_PROP(DISK_NODE, sector_count) +#define AREA_SIZE DISK_SCNT * DISK_SSIZE / 2 +#define AREA_ERASE_SIZE 4096 +#define AREA_WRITE_SIZE DISK_SSIZE + +STORAGE_AREA_DISK_RW_DEFINE(test, DISK_NAME, DISK_SCNT / 2, DISK_SSIZE, + AREA_WRITE_SIZE, AREA_ERASE_SIZE, AREA_SIZE, 0); +#endif /* CONFIG_STORAGE_AREA_DISK */ + +static const char cookie[] = "!NVS"; + +bool move(const struct storage_area_record *record) +{ + uint8_t nsz; + + if (storage_area_record_read(record, 0U, &nsz, sizeof(nsz)) != 0) { + return false; + } + + if (record->size == (nsz + sizeof(nsz))) { + return false; + } + + char name[nsz]; + + if (storage_area_record_read(record, sizeof(nsz), &name, nsz) != 0) { + return false; + } + + struct storage_area_record walk = { + .store = record->store, + .sector = record->sector, + .loc = record->loc, + .size = record->size, + }; + + while (true) { + int rc; + + rc = storage_area_record_next(record->store, &walk); + if (rc != 0) { + break; + } + + rc = storage_area_record_read(&walk, 0U, &nsz, sizeof(nsz)); + if (rc != 0) { + break; + } + + if (nsz != sizeof(name)) { + continue; + } + + char wname[nsz]; + + rc = storage_area_record_read(&walk, sizeof(nsz), wname, nsz); + if (rc != 0) { + break; + } + + if (memcmp(name, wname, nsz) != 0) { + continue; + } + + break; + } + + if (walk.size == 0U) { + return true; + } + + return false; +} + +void move_cb(const struct storage_area_record *src, + const struct storage_area_record *dst) +{ + LOG_INF("Moved %d-%d to %d-%d", src->sector, src->loc, dst->sector, + dst->loc); +} + +const struct storage_area_store_compact_cb compact_cb = { + .move = move, + .move_cb = move_cb, +}; + +#define SECTOR_SIZE 4096 +STORAGE_AREA_STORE_DEFINE(test, GET_STORAGE_AREA(test), (void *)cookie, + sizeof(cookie), SECTOR_SIZE, AREA_SIZE / SECTOR_SIZE, + AREA_ERASE_SIZE / SECTOR_SIZE, 0U); + +static void *storage_area_store_api_setup(void) +{ + return NULL; +} + +static void storage_area_store_api_before(void *fixture) +{ + ARG_UNUSED(fixture); + + int rc = storage_area_store_wipe(GET_STORAGE_AREA_STORE(test)); + + zassert_ok(rc, "wipe returned [%d]", rc); +} + +void storage_area_store_report_state(char *tag, + const struct storage_area_store *store) +{ + struct storage_area_store_data *data = store->data; + + LOG_INF("%s: sector: %d - loc:%d - wrapcnt:%d", tag, data->sector, + data->loc, data->wrapcnt); +} + +int write_data(const struct storage_area_store *store, char *name, + uint32_t value) +{ + uint8_t nsz = strlen(name); + struct storage_area_iovec wr[] = { + { + .data = &nsz, + .len = sizeof(nsz), + }, + { + .data = name, + .len = nsz, + }, + { + .data = &value, + .len = sizeof(uint32_t), + } + }; + + return storage_area_store_writev(store, wr, ARRAY_SIZE(wr)); +} + +int read_data(const struct storage_area_store *store, char *name, + uint32_t *value) +{ + uint8_t nsz = strlen(name); + struct storage_area_record walk, match; + int rc = 0; + + walk.store = NULL; + while (storage_area_record_next(store, &walk) == 0) { + uint8_t nlen; + + rc = storage_area_record_read(&walk, 0U, &nlen, sizeof(nlen)); + if (rc != 0) { + break; + } + + if (nlen != nsz) { + continue; + } + + char rdname[nlen]; + + rc = storage_area_record_read(&walk, 1U, rdname, nlen); + if (rc != 0) { + break; + } + + if (memcmp(name, rdname, nlen) != 0) { + continue; + } + + memcpy(&match, &walk, sizeof(walk)); + } + + if ((rc != 0) || (match.store != walk.store) || + ((match.size - nsz - 1U) != sizeof(uint32_t))) { + rc = -ENOENT; + goto end; + } + + rc = storage_area_record_read(&match, 1U + nsz, value, sizeof(uint32_t)); +end: + return rc; +} + +ZTEST_USER(storage_area_store_api, test_store) +{ + struct storage_area_store *store = GET_STORAGE_AREA_STORE(test); + uint32_t wvalue1, wvalue2, wvalue3, rvalue; + int rc; + + rc = storage_area_store_mount(store, &compact_cb); + zassert_ok(rc, "mount returned [%d]", rc); + storage_area_store_report_state("Mount", store); + + wvalue1 = 0U; + rc = write_data(store, "data1", wvalue1); + zassert_ok(rc, "write returned [%d]", rc); + storage_area_store_report_state("Write", store); + + rvalue = 0xFFFF; + rc = read_data(store, "data1", &rvalue); + zassert_ok(rc, "read returned [%d]", rc); + zassert_equal(rvalue, wvalue1, "bad data read"); + + rc = storage_area_store_unmount(store); + zassert_ok(rc, "unmount returned [%d]", rc); + storage_area_store_report_state("Unmount", store); + + rc = storage_area_store_mount(store, &compact_cb); + zassert_ok(rc, "mount returned [%d]", rc); + storage_area_store_report_state("Mount", store); + + rvalue = 0xFFFF; + rc = read_data(store, "data1", &rvalue); + zassert_ok(rc, "read returned [%d]", rc); + zassert_equal(rvalue, wvalue1, "bad data read"); + + wvalue2 = 0x00C0FFEE; + rc = write_data(store, "mydata/test", wvalue2); + zassert_ok(rc, "write returned [%d]", rc); + storage_area_store_report_state("Write", store); + + rvalue = 0xFFFF; + rc = read_data(store, "mydata/test", &rvalue); + zassert_ok(rc, "read returned [%d]", rc); + zassert_equal(rvalue, wvalue2, "bad data read"); + + wvalue3 = 0U; + for (int i = 0; i < store->sector_cnt; i++) { + while (write_data(store, "data2", wvalue3) == 0) { + wvalue3++; + } + + wvalue3--; + storage_area_store_report_state("Write", store); + rc = storage_area_store_compact(store, &compact_cb); + zassert_ok(rc, "compact returned [%d]", rc); + storage_area_store_report_state("Compact", store); + } + + rvalue = 0xFFFF; + rc = read_data(store, "data1", &rvalue); + zassert_ok(rc, "read returned [%d]", rc); + zassert_equal(rvalue, wvalue1, "bad data read"); + + rc = storage_area_store_unmount(store); + zassert_ok(rc, "unmount returned [%d]", rc); + storage_area_store_report_state("Unmount", store); + + size_t wroff; + uint8_t bad[STORAGE_AREA_WRITESIZE(store->area)]; + + wroff = store->data->sector * store->sector_size + store->data->loc; + wroff -= STORAGE_AREA_WRITESIZE(store->area); + memset(bad, 0x0, sizeof(bad)); + rc = storage_area_write(store->area, wroff, bad, sizeof(bad)); + zassert_ok(rc, "write returned [%d]", rc); + + rc = storage_area_store_mount(store, &compact_cb); + zassert_ok(rc, "mount returned [%d]", rc); + storage_area_store_report_state("Mount", store); + + rvalue = 0xFFFF; + rc = read_data(store, "data1", &rvalue); + zassert_ok(rc, "read returned [%d]", rc); + zassert_equal(rvalue, wvalue1, "bad data read"); + + rvalue = 0xFFFF; + rc = read_data(store, "mydata/test", &rvalue); + zassert_ok(rc, "read returned [%d]", rc); + zassert_equal(rvalue, wvalue2, "bad data read"); + + rvalue = 0xFFFF; + rc = read_data(store, "data2", &rvalue); + zassert_ok(rc, "read returned [%d]", rc); + zassert_equal(rvalue, wvalue3, "bad data read"); +} + +STORAGE_AREA_STORE_DEFINE(testupdate, GET_STORAGE_AREA(test), (void *)cookie, + sizeof(cookie), SECTOR_SIZE, AREA_SIZE / SECTOR_SIZE, + AREA_ERASE_SIZE / SECTOR_SIZE, 1U); + +ZTEST_USER(storage_area_store_api, test_record_update) +{ + struct storage_area_store *store = GET_STORAGE_AREA_STORE(testupdate); + + if ((!STORAGE_AREA_FOVRWRITE(store->area)) && + (!STORAGE_AREA_LOVRWRITE(store->area))) { + /* record update not supported */ + return; + } + + struct storage_area_record walk; + uint8_t status; + uint32_t value; + struct storage_area_iovec wr[] = { + { + .data = &status, + .len = sizeof(status), + }, + { + .data = &value, + .len = sizeof(value), + }, + }; + uint8_t rdstatus; + int rc; + + rc = storage_area_store_mount(store, NULL); + zassert_ok(rc, "mount returned [%d]", rc); + storage_area_store_report_state("Mount", store); + + status = 0xff; + value = 0xdeadbeef; + rc = storage_area_store_writev(store, wr, ARRAY_SIZE(wr)); + zassert_ok(rc, "write returned [%d]", rc); + storage_area_store_report_state("write", store); + + walk.store = NULL; + rc = storage_area_record_next(store, &walk); + zassert_ok(rc, "retrieve record failed [%d]", rc); + zassert_equal(walk.size, sizeof(status) + sizeof(value), "wrong record"); + zassert_true(storage_area_record_valid(&walk), "bad record"); + rc = storage_area_record_read(&walk, 0, &rdstatus, sizeof(rdstatus)); + zassert_ok(rc, "read from record failed [%d]", rc); + zassert_equal(status, rdstatus, "bad status"); + + status = 0x0; + rc = storage_area_record_update(&walk, &status, sizeof(status)); + zassert_ok(rc, "record update failed [%d]", rc); + zassert_true(storage_area_record_valid(&walk), "bad record"); + rc = storage_area_record_read(&walk, 0, &rdstatus, sizeof(rdstatus)); + zassert_ok(rc, "read from record failed [%d]", rc); + zassert_equal(status, rdstatus, "bad status"); +} + +ZTEST_SUITE(storage_area_store_api, NULL, storage_area_store_api_setup, + storage_area_store_api_before, NULL, NULL); diff --git a/tests/subsys/storage/storage_area/storage_area_store/testcase.yaml b/tests/subsys/storage/storage_area/storage_area_store/testcase.yaml new file mode 100644 index 00000000000000..77ae3ff99c1bbb --- /dev/null +++ b/tests/subsys/storage/storage_area/storage_area_store/testcase.yaml @@ -0,0 +1,23 @@ +common: + tags: storage_area_store +tests: + storage.storage_area.store.flash: + platform_allow: + - native_sim + extra_args: + - EXTRA_CONF_FILE=cfg_flash.conf + storage.storage_area.store.eeprom: + platform_allow: + - native_sim + extra_args: + - EXTRA_CONF_FILE=cfg_eeprom.conf + storage.storage_area.store.ram: + platform_allow: + - qemu_cortex_m3 + extra_args: + - EXTRA_CONF_FILE=cfg_ram.conf + storage.storage_area.store.disk: + platform_allow: + - native_sim + extra_args: + - EXTRA_CONF_FILE=cfg_disk.conf