|
|
@@ -14,6 +14,9 @@
|
|
|
#include "catch.hpp"
|
|
|
#include "nvs.hpp"
|
|
|
#include "nvs_test_api.h"
|
|
|
+#ifdef CONFIG_NVS_ENCRYPTION
|
|
|
+#include "nvs_encr.hpp"
|
|
|
+#endif
|
|
|
#include "spi_flash_emulation.h"
|
|
|
#include <sstream>
|
|
|
#include <iostream>
|
|
|
@@ -382,10 +385,10 @@ TEST_CASE("storage can find items on second page if first is not fully written a
|
|
|
ESP_ERROR_CHECK(storage.writeItem(0, ItemType::BLOB, "1", bigdata, sizeof(bigdata)));
|
|
|
// write another big chunk of data
|
|
|
ESP_ERROR_CHECK(storage.writeItem(0, ItemType::BLOB, "2", bigdata, sizeof(bigdata)));
|
|
|
-
|
|
|
+
|
|
|
// write third one; it will not fit into the first page
|
|
|
ESP_ERROR_CHECK(storage.writeItem(0, ItemType::BLOB, "3", bigdata, sizeof(bigdata)));
|
|
|
-
|
|
|
+
|
|
|
size_t size;
|
|
|
ESP_ERROR_CHECK(storage.getItemDataSize(0, ItemType::BLOB, "1", size));
|
|
|
CHECK(size == sizeof(bigdata));
|
|
|
@@ -505,7 +508,7 @@ TEST_CASE("nvs api tests", "[nvs]")
|
|
|
{
|
|
|
SpiFlashEmulator emu(10);
|
|
|
emu.randomize(100);
|
|
|
-
|
|
|
+
|
|
|
nvs_handle handle_1;
|
|
|
const uint32_t NVS_FLASH_SECTOR = 6;
|
|
|
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
|
|
|
@@ -547,11 +550,11 @@ TEST_CASE("nvs api tests", "[nvs]")
|
|
|
size_t buf_len_needed;
|
|
|
TEST_ESP_OK(nvs_get_str(handle_2, "key", NULL, &buf_len_needed));
|
|
|
CHECK(buf_len_needed == buf_len);
|
|
|
-
|
|
|
+
|
|
|
size_t buf_len_short = buf_len - 1;
|
|
|
TEST_ESP_ERR(ESP_ERR_NVS_INVALID_LENGTH, nvs_get_str(handle_2, "key", buf, &buf_len_short));
|
|
|
CHECK(buf_len_short == buf_len);
|
|
|
-
|
|
|
+
|
|
|
size_t buf_len_long = buf_len + 1;
|
|
|
TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len_long));
|
|
|
CHECK(buf_len_long == buf_len);
|
|
|
@@ -559,19 +562,21 @@ TEST_CASE("nvs api tests", "[nvs]")
|
|
|
TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len));
|
|
|
|
|
|
CHECK(0 == strcmp(buf, str));
|
|
|
+ nvs_close(handle_1);
|
|
|
+ nvs_close(handle_2);
|
|
|
}
|
|
|
|
|
|
TEST_CASE("wifi test", "[nvs]")
|
|
|
{
|
|
|
SpiFlashEmulator emu(10);
|
|
|
emu.randomize(10);
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
const uint32_t NVS_FLASH_SECTOR = 5;
|
|
|
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
|
|
|
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
|
|
-
|
|
|
+
|
|
|
nvs_handle misc_handle;
|
|
|
TEST_ESP_OK(nvs_open("nvs.net80211", NVS_READWRITE, &misc_handle));
|
|
|
char log[33];
|
|
|
@@ -579,31 +584,31 @@ TEST_CASE("wifi test", "[nvs]")
|
|
|
TEST_ESP_ERR(nvs_get_str(misc_handle, "log", log, &log_size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
strcpy(log, "foobarbazfizzz");
|
|
|
TEST_ESP_OK(nvs_set_str(misc_handle, "log", log));
|
|
|
-
|
|
|
+
|
|
|
nvs_handle net80211_handle;
|
|
|
TEST_ESP_OK(nvs_open("nvs.net80211", NVS_READWRITE, &net80211_handle));
|
|
|
-
|
|
|
+
|
|
|
uint8_t opmode = 2;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "wifi.opmode", &opmode), ESP_ERR_NVS_NOT_FOUND);
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "wifi.opmode", opmode));
|
|
|
-
|
|
|
+
|
|
|
uint8_t country = 0;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "wifi.country", &opmode), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "wifi.country", opmode));
|
|
|
-
|
|
|
+
|
|
|
char ssid[36];
|
|
|
size_t size = sizeof(ssid);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "sta.ssid", ssid, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
strcpy(ssid, "my android AP");
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "sta.ssid", ssid, size));
|
|
|
-
|
|
|
+
|
|
|
char mac[6];
|
|
|
size = sizeof(mac);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "sta.mac", mac, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
memset(mac, 0xab, 6);
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "sta.mac", mac, size));
|
|
|
-
|
|
|
+
|
|
|
uint8_t authmode = 1;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "sta.authmode", &authmode), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "sta.authmode", authmode));
|
|
|
@@ -619,11 +624,11 @@ TEST_CASE("wifi test", "[nvs]")
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "sta.pmk", pmk, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
memset(pmk, 1, size);
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "sta.pmk", pmk, size));
|
|
|
-
|
|
|
+
|
|
|
uint8_t chan = 1;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "sta.chan", &chan), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "sta.chan", chan));
|
|
|
-
|
|
|
+
|
|
|
uint8_t autoconn = 1;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "auto.conn", &autoconn), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "auto.conn", autoconn));
|
|
|
@@ -641,43 +646,43 @@ TEST_CASE("wifi test", "[nvs]")
|
|
|
uint8_t phym = 3;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "sta.phym", &phym), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "sta.phym", phym));
|
|
|
-
|
|
|
+
|
|
|
uint8_t phybw = 2;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "sta.phybw", &phybw), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "sta.phybw", phybw));
|
|
|
-
|
|
|
+
|
|
|
char apsw[2];
|
|
|
size = sizeof(apsw);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "sta.apsw", apsw, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
memset(apsw, 0x2, size);
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "sta.apsw", apsw, size));
|
|
|
-
|
|
|
+
|
|
|
char apinfo[700];
|
|
|
size = sizeof(apinfo);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "sta.apinfo", apinfo, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
memset(apinfo, 0, size);
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "sta.apinfo", apinfo, size));
|
|
|
-
|
|
|
+
|
|
|
size = sizeof(ssid);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "ap.ssid", ssid, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
strcpy(ssid, "ESP_A2F340");
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "ap.ssid", ssid, size));
|
|
|
-
|
|
|
+
|
|
|
size = sizeof(mac);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "ap.mac", mac, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
memset(mac, 0xac, 6);
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "ap.mac", mac, size));
|
|
|
-
|
|
|
+
|
|
|
size = sizeof(pswd);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "ap.passwd", pswd, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
strcpy(pswd, "");
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "ap.passwd", pswd, size));
|
|
|
-
|
|
|
+
|
|
|
size = sizeof(pmk);
|
|
|
TEST_ESP_ERR(nvs_get_blob(net80211_handle, "ap.pmk", pmk, &size), ESP_ERR_NVS_NOT_FOUND);
|
|
|
memset(pmk, 1, size);
|
|
|
TEST_ESP_OK(nvs_set_blob(net80211_handle, "ap.pmk", pmk, size));
|
|
|
-
|
|
|
+
|
|
|
chan = 6;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "ap.chan", &chan), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "ap.chan", chan));
|
|
|
@@ -685,19 +690,19 @@ TEST_CASE("wifi test", "[nvs]")
|
|
|
authmode = 0;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "ap.authmode", &authmode), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "ap.authmode", authmode));
|
|
|
-
|
|
|
+
|
|
|
uint8_t hidden = 0;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "ap.hidden", &hidden), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "ap.hidden", hidden));
|
|
|
-
|
|
|
+
|
|
|
uint8_t max_conn = 4;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "ap.max.conn", &max_conn), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "ap.max.conn", max_conn));
|
|
|
-
|
|
|
+
|
|
|
uint8_t bcn_interval = 2;
|
|
|
TEST_ESP_ERR(nvs_get_u8(net80211_handle, "bcn_interval", &bcn_interval), ESP_ERR_NVS_NOT_FOUND);
|
|
|
TEST_ESP_OK(nvs_set_u8(net80211_handle, "bcn_interval", bcn_interval));
|
|
|
-
|
|
|
+
|
|
|
s_perf << "Time to simulate nvs init with wifi libs: " << emu.getTotalTime() << " us (" << emu.getEraseOps() << "E " << emu.getWriteOps() << "W " << emu.getReadOps() << "R " << emu.getWriteBytes() << "Wb " << emu.getReadBytes() << "Rb)" << std::endl;
|
|
|
|
|
|
}
|
|
|
@@ -707,15 +712,15 @@ TEST_CASE("can init storage from flash with random contents", "[nvs]")
|
|
|
{
|
|
|
SpiFlashEmulator emu(10);
|
|
|
emu.randomize(42);
|
|
|
-
|
|
|
+
|
|
|
nvs_handle handle;
|
|
|
const uint32_t NVS_FLASH_SECTOR = 5;
|
|
|
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
|
|
|
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_OK(nvs_open("nvs.net80211", NVS_READWRITE, &handle));
|
|
|
-
|
|
|
+
|
|
|
uint8_t opmode = 2;
|
|
|
if (nvs_get_u8(handle, "wifi.opmode", &opmode) != ESP_OK) {
|
|
|
TEST_ESP_OK(nvs_set_u8(handle, "wifi.opmode", opmode));
|
|
|
@@ -735,16 +740,16 @@ TEST_CASE("nvs api tests, starting with random data in flash", "[nvs][long]")
|
|
|
}
|
|
|
SpiFlashEmulator emu(10);
|
|
|
emu.randomize(static_cast<uint32_t>(count));
|
|
|
-
|
|
|
+
|
|
|
const uint32_t NVS_FLASH_SECTOR = 6;
|
|
|
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
|
|
|
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
|
|
-
|
|
|
+
|
|
|
nvs_handle handle_1;
|
|
|
TEST_ESP_ERR(nvs_open("namespace1", NVS_READONLY, &handle_1), ESP_ERR_NVS_NOT_FOUND);
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle_1));
|
|
|
TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678));
|
|
|
for (size_t i = 0; i < 500; ++i) {
|
|
|
@@ -756,20 +761,20 @@ TEST_CASE("nvs api tests, starting with random data in flash", "[nvs][long]")
|
|
|
char str_buf[128];
|
|
|
snprintf(str_buf, sizeof(str_buf), str, i + count * 1024);
|
|
|
TEST_ESP_OK(nvs_set_str(handle_2, "key", str_buf));
|
|
|
-
|
|
|
+
|
|
|
int32_t v1;
|
|
|
TEST_ESP_OK(nvs_get_i32(handle_1, "foo", &v1));
|
|
|
CHECK(0x23456789 % (i + 1) == v1);
|
|
|
-
|
|
|
+
|
|
|
int32_t v2;
|
|
|
TEST_ESP_OK(nvs_get_i32(handle_2, "foo", &v2));
|
|
|
CHECK(static_cast<int32_t>(i) == v2);
|
|
|
-
|
|
|
+
|
|
|
char buf[128];
|
|
|
size_t buf_len = sizeof(buf);
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len));
|
|
|
-
|
|
|
+
|
|
|
CHECK(0 == strcmp(buf, str_buf));
|
|
|
nvs_close(handle_2);
|
|
|
}
|
|
|
@@ -789,7 +794,7 @@ class RandomTest {
|
|
|
char v5[strBufLen], v6[strBufLen], v7[strBufLen], v8[strBufLen], v9[strBufLen];
|
|
|
uint8_t v10[smallBlobLen], v11[largeBlobLen];
|
|
|
bool written[nKeys];
|
|
|
-
|
|
|
+
|
|
|
public:
|
|
|
RandomTest()
|
|
|
{
|
|
|
@@ -807,7 +812,7 @@ public:
|
|
|
const size_t nKeys = sizeof(keys) / sizeof(keys[0]);
|
|
|
static_assert(nKeys == sizeof(types) / sizeof(types[0]), "");
|
|
|
static_assert(nKeys == sizeof(values) / sizeof(values[0]), "");
|
|
|
-
|
|
|
+
|
|
|
auto randomRead = [&](size_t index) -> esp_err_t {
|
|
|
switch (types[index]) {
|
|
|
case ItemType::I32:
|
|
|
@@ -826,7 +831,7 @@ public:
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
case ItemType::U64:
|
|
|
{
|
|
|
uint64_t val;
|
|
|
@@ -843,7 +848,7 @@ public:
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
case ItemType::SZ:
|
|
|
{
|
|
|
char buf[strBufLen];
|
|
|
@@ -895,13 +900,13 @@ public:
|
|
|
}
|
|
|
return ESP_OK;
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
auto randomWrite = [&](size_t index) -> esp_err_t {
|
|
|
switch (types[index]) {
|
|
|
case ItemType::I32:
|
|
|
{
|
|
|
int32_t val = static_cast<int32_t>(gen());
|
|
|
-
|
|
|
+
|
|
|
auto err = nvs_set_i32(handle, keys[index], val);
|
|
|
if (err == ESP_ERR_FLASH_OP_FAIL) {
|
|
|
return err;
|
|
|
@@ -916,11 +921,11 @@ public:
|
|
|
*reinterpret_cast<int32_t*>(values[index]) = val;
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
case ItemType::U64:
|
|
|
{
|
|
|
uint64_t val = static_cast<uint64_t>(gen());
|
|
|
-
|
|
|
+
|
|
|
auto err = nvs_set_u64(handle, keys[index], val);
|
|
|
if (err == ESP_ERR_FLASH_OP_FAIL) {
|
|
|
return err;
|
|
|
@@ -935,19 +940,19 @@ public:
|
|
|
*reinterpret_cast<uint64_t*>(values[index]) = val;
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
case ItemType::SZ:
|
|
|
{
|
|
|
char buf[strBufLen];
|
|
|
size_t len = strBufLen;
|
|
|
-
|
|
|
+
|
|
|
size_t strLen = gen() % (strBufLen - 1);
|
|
|
std::generate_n(buf, strLen, [&]() -> char {
|
|
|
const char c = static_cast<char>(gen() % 127);
|
|
|
return (c < 32) ? 32 : c;
|
|
|
});
|
|
|
buf[strLen] = 0;
|
|
|
-
|
|
|
+
|
|
|
auto err = nvs_set_str(handle, keys[index], buf);
|
|
|
if (err == ESP_ERR_FLASH_OP_FAIL) {
|
|
|
return err;
|
|
|
@@ -998,8 +1003,8 @@ public:
|
|
|
}
|
|
|
return ESP_OK;
|
|
|
};
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
for (; count != 0; --count) {
|
|
|
size_t index = gen() % (nKeys);
|
|
|
switch (gen() % 3) {
|
|
|
@@ -1008,7 +1013,7 @@ public:
|
|
|
return ESP_ERR_FLASH_OP_FAIL;
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
default: // write, 2/3
|
|
|
if (randomWrite(index) == ESP_ERR_FLASH_OP_FAIL) {
|
|
|
return ESP_ERR_FLASH_OP_FAIL;
|
|
|
@@ -1039,7 +1044,7 @@ TEST_CASE("monkey test", "[nvs][monkey]")
|
|
|
std::mt19937 gen(rd());
|
|
|
uint32_t seed = 3;
|
|
|
gen.seed(seed);
|
|
|
-
|
|
|
+
|
|
|
SpiFlashEmulator emu(10);
|
|
|
emu.randomize(seed);
|
|
|
emu.clearStats();
|
|
|
@@ -1047,15 +1052,15 @@ TEST_CASE("monkey test", "[nvs][monkey]")
|
|
|
const uint32_t NVS_FLASH_SECTOR = 2;
|
|
|
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 8;
|
|
|
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
|
|
-
|
|
|
+
|
|
|
nvs_handle handle;
|
|
|
TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
|
|
|
RandomTest test;
|
|
|
size_t count = 1000;
|
|
|
CHECK(test.doRandomThings(handle, gen, count) == ESP_OK);
|
|
|
-
|
|
|
+
|
|
|
s_perf << "Monkey test: nErase=" << emu.getEraseOps() << " nWrite=" << emu.getWriteOps() << std::endl;
|
|
|
}
|
|
|
|
|
|
@@ -1066,13 +1071,14 @@ TEST_CASE("test recovery from sudden poweroff", "[long][nvs][recovery][monkey]")
|
|
|
uint32_t seed = 3;
|
|
|
gen.seed(seed);
|
|
|
const size_t iter_count = 2000;
|
|
|
-
|
|
|
+
|
|
|
SpiFlashEmulator emu(10);
|
|
|
|
|
|
const uint32_t NVS_FLASH_SECTOR = 2;
|
|
|
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 8;
|
|
|
- emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
|
|
|
+ emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
+
|
|
|
size_t totalOps = 0;
|
|
|
int lastPercent = -1;
|
|
|
for (uint32_t errDelay = 0; ; ++errDelay) {
|
|
|
@@ -1081,7 +1087,7 @@ TEST_CASE("test recovery from sudden poweroff", "[long][nvs][recovery][monkey]")
|
|
|
emu.clearStats();
|
|
|
emu.failAfter(errDelay);
|
|
|
RandomTest test;
|
|
|
-
|
|
|
+
|
|
|
if (totalOps != 0) {
|
|
|
int percent = errDelay * 100 / totalOps;
|
|
|
if (percent > lastPercent) {
|
|
|
@@ -1089,7 +1095,7 @@ TEST_CASE("test recovery from sudden poweroff", "[long][nvs][recovery][monkey]")
|
|
|
lastPercent = percent;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
nvs_handle handle;
|
|
|
size_t count = iter_count;
|
|
|
@@ -1103,7 +1109,7 @@ TEST_CASE("test recovery from sudden poweroff", "[long][nvs][recovery][monkey]")
|
|
|
nvs_close(handle);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
|
|
TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
|
|
|
auto res = test.doRandomThings(handle, gen, count);
|
|
|
@@ -1122,7 +1128,7 @@ TEST_CASE("test for memory leaks in open/set", "[leaks]")
|
|
|
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
|
|
|
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
|
|
-
|
|
|
+
|
|
|
for (int i = 0; i < 100000; ++i) {
|
|
|
nvs_handle light_handle = 0;
|
|
|
char lightbulb[1024] = {12, 13, 14, 15, 16};
|
|
|
@@ -1178,12 +1184,12 @@ TEST_CASE("recovery after failure to write data", "[nvs]")
|
|
|
{
|
|
|
Storage storage;
|
|
|
TEST_ESP_OK(storage.init(0, 3));
|
|
|
-
|
|
|
+
|
|
|
TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_FLASH_OP_FAIL);
|
|
|
-
|
|
|
+
|
|
|
// check that repeated operations cause an error
|
|
|
TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_NVS_INVALID_STATE);
|
|
|
-
|
|
|
+
|
|
|
uint8_t val;
|
|
|
TEST_ESP_ERR(storage.readItem(1, ItemType::U8, "key", &val, sizeof(val)), ESP_ERR_NVS_NOT_FOUND);
|
|
|
}
|
|
|
@@ -1193,7 +1199,7 @@ TEST_CASE("recovery after failure to write data", "[nvs]")
|
|
|
p.load(0);
|
|
|
CHECK(p.getErasedEntryCount() == 3);
|
|
|
CHECK(p.getUsedEntryCount() == 0);
|
|
|
-
|
|
|
+
|
|
|
// try to write again
|
|
|
TEST_ESP_OK(p.writeItem(1, ItemType::SZ, "key", str, strlen(str)));
|
|
|
}
|
|
|
@@ -1208,18 +1214,18 @@ TEST_CASE("crc errors in item header are handled", "[nvs]")
|
|
|
TEST_ESP_OK(storage.writeItem(0, "ns1", static_cast<uint8_t>(1)));
|
|
|
TEST_ESP_OK(storage.writeItem(1, "value1", static_cast<uint32_t>(1)));
|
|
|
TEST_ESP_OK(storage.writeItem(1, "value2", static_cast<uint32_t>(2)));
|
|
|
-
|
|
|
+
|
|
|
// corrupt item header
|
|
|
uint32_t val = 0;
|
|
|
emu.write(32 * 3, &val, 4);
|
|
|
-
|
|
|
+
|
|
|
// check that storage can recover
|
|
|
TEST_ESP_OK(storage.init(0, 3));
|
|
|
TEST_ESP_OK(storage.readItem(1, "value2", val));
|
|
|
CHECK(val == 2);
|
|
|
// check that the corrupted item is no longer present
|
|
|
TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, storage.readItem(1, "value1", val));
|
|
|
-
|
|
|
+
|
|
|
// add more items to make the page full
|
|
|
for (size_t i = 0; i < Page::ENTRY_COUNT; ++i) {
|
|
|
char item_name[Item::MAX_KEY_LENGTH + 1];
|
|
|
@@ -1230,7 +1236,7 @@ TEST_CASE("crc errors in item header are handled", "[nvs]")
|
|
|
// corrupt another item on the full page
|
|
|
val = 0;
|
|
|
emu.write(32 * 4, &val, 4);
|
|
|
-
|
|
|
+
|
|
|
// check that storage can recover
|
|
|
TEST_ESP_OK(storage.init(0, 3));
|
|
|
// check that the corrupted item is no longer present
|
|
|
@@ -1284,7 +1290,7 @@ TEST_CASE("read/write failure (TW8406)", "[nvs]")
|
|
|
char data[76] = {12, 13, 14, 15, 16};
|
|
|
uint8_t number = 20;
|
|
|
size_t data_len = sizeof(data);
|
|
|
-
|
|
|
+
|
|
|
ESP_ERROR_CHECK(nvs_open("LIGHT", NVS_READWRITE, &light_handle));
|
|
|
ESP_ERROR_CHECK(nvs_set_u8(light_handle, "RecordNum", number));
|
|
|
for (i = 0; i < number; ++i) {
|
|
|
@@ -1292,7 +1298,7 @@ TEST_CASE("read/write failure (TW8406)", "[nvs]")
|
|
|
ESP_ERROR_CHECK(nvs_set_blob(light_handle, key, data, sizeof(data)));
|
|
|
}
|
|
|
nvs_commit(light_handle);
|
|
|
-
|
|
|
+
|
|
|
uint8_t get_number = 0;
|
|
|
ESP_ERROR_CHECK(nvs_get_u8(light_handle, "RecordNum", &get_number));
|
|
|
REQUIRE(number == get_number);
|
|
|
@@ -1988,8 +1994,6 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo
|
|
|
TEST_ESP_ERR(p3.findItem(1, ItemType::BLOB, "singlepage"), ESP_ERR_NVS_NOT_FOUND);
|
|
|
}
|
|
|
|
|
|
-/* Add new tests above */
|
|
|
-/* This test has to be the final one */
|
|
|
|
|
|
TEST_CASE("check partition generation utility with multipage blob support disabled", "[nvs_part_gen]")
|
|
|
{
|
|
|
@@ -2067,7 +2071,7 @@ TEST_CASE("read data from partition generated via partition generation utility w
|
|
|
CHECK(memcmp(bin_data, binfiledata, bin_len) == 0);
|
|
|
|
|
|
file.close();
|
|
|
-
|
|
|
+ nvs_close(handle);
|
|
|
}
|
|
|
|
|
|
TEST_CASE("check partition generation utility with multipage blob support enabled", "[nvs_part_gen]")
|
|
|
@@ -2149,6 +2153,242 @@ TEST_CASE("read data from partition generated via partition generation utility w
|
|
|
|
|
|
}
|
|
|
|
|
|
+#if CONFIG_NVS_ENCRYPTION
|
|
|
+TEST_CASE("check underlying xts code for 32-byte size sector encryption", "[nvs]")
|
|
|
+{
|
|
|
+ auto toHex = [](char ch) {
|
|
|
+ if(ch >= '0' && ch <= '9')
|
|
|
+ return ch - '0';
|
|
|
+ else if(ch >= 'a' && ch <= 'f')
|
|
|
+ return ch - 'a' + 10;
|
|
|
+ else if(ch >= 'A' && ch <= 'F')
|
|
|
+ return ch - 'A' + 10;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ auto toHexByte = [toHex](char* c) {
|
|
|
+ return 16 * toHex(c[0]) + toHex(c[1]);
|
|
|
+ };
|
|
|
+
|
|
|
+ auto toHexStream = [toHexByte](char* src, uint8_t* dest) {
|
|
|
+ uint32_t cnt =0;
|
|
|
+ char* p = src;
|
|
|
+ while(*p != '\0' && *(p + 1) != '\0')
|
|
|
+ {
|
|
|
+ dest[cnt++] = toHexByte(p); p += 2;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ uint8_t eky_hex[2 * NVS_KEY_SIZE];
|
|
|
+ uint8_t ptxt_hex[Page::ENTRY_SIZE], ctxt_hex[Page::ENTRY_SIZE], ba_hex[16];
|
|
|
+ mbedtls_aes_xts_context ectx[1];
|
|
|
+ mbedtls_aes_xts_context dctx[1];
|
|
|
+
|
|
|
+ char eky[][2 * NVS_KEY_SIZE + 1] = {
|
|
|
+ "0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
+ "1111111111111111111111111111111111111111111111111111111111111111"
|
|
|
+ };
|
|
|
+ char tky[][2 * NVS_KEY_SIZE + 1] = {
|
|
|
+ "0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
+ "2222222222222222222222222222222222222222222222222222222222222222"
|
|
|
+ };
|
|
|
+ char blk_addr[][2*16 + 1] = {
|
|
|
+ "00000000000000000000000000000000",
|
|
|
+ "33333333330000000000000000000000"
|
|
|
+ };
|
|
|
+
|
|
|
+ char ptxt[][2 * Page::ENTRY_SIZE + 1] = {
|
|
|
+ "0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
+ "4444444444444444444444444444444444444444444444444444444444444444"
|
|
|
+ };
|
|
|
+ char ctxt[][2 * Page::ENTRY_SIZE + 1] = {
|
|
|
+ "d456b4fc2e620bba6ffbed27b956c9543454dd49ebd8d8ee6f94b65cbe158f73",
|
|
|
+ "e622334f184bbce129a25b2ac76b3d92abf98e22df5bdd15af471f3db8946a85"
|
|
|
+ };
|
|
|
+
|
|
|
+ mbedtls_aes_xts_init(ectx);
|
|
|
+ mbedtls_aes_xts_init(dctx);
|
|
|
+
|
|
|
+ for(uint8_t cnt = 0; cnt < sizeof(eky)/sizeof(eky[0]); cnt++) {
|
|
|
+ toHexStream(eky[cnt], eky_hex);
|
|
|
+ toHexStream(tky[cnt], &eky_hex[NVS_KEY_SIZE]);
|
|
|
+ toHexStream(ptxt[cnt], ptxt_hex);
|
|
|
+ toHexStream(ctxt[cnt], ctxt_hex);
|
|
|
+ toHexStream(blk_addr[cnt], ba_hex);
|
|
|
+
|
|
|
+ CHECK(!mbedtls_aes_xts_setkey_enc(ectx, eky_hex, 2 * NVS_KEY_SIZE * 8));
|
|
|
+ CHECK(!mbedtls_aes_xts_setkey_enc(dctx, eky_hex, 2 * NVS_KEY_SIZE * 8));
|
|
|
+
|
|
|
+ CHECK(!mbedtls_aes_crypt_xts(ectx, MBEDTLS_AES_ENCRYPT, Page::ENTRY_SIZE, ba_hex, ptxt_hex, ptxt_hex));
|
|
|
+
|
|
|
+ CHECK(!memcmp(ptxt_hex, ctxt_hex, Page::ENTRY_SIZE));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+TEST_CASE("test nvs apis with encryption enabled", "[nvs]")
|
|
|
+{
|
|
|
+ SpiFlashEmulator emu(10);
|
|
|
+ emu.randomize(100);
|
|
|
+
|
|
|
+ nvs_handle handle_1;
|
|
|
+ const uint32_t NVS_FLASH_SECTOR = 6;
|
|
|
+ const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
|
|
|
+ emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
|
|
|
+
|
|
|
+ nvs_sec_cfg_t xts_cfg;
|
|
|
+ for(int count = 0; count < NVS_KEY_SIZE; count++) {
|
|
|
+ xts_cfg.eky[count] = 0x11;
|
|
|
+ xts_cfg.tky[count] = 0x22;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (uint16_t i = NVS_FLASH_SECTOR; i <NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN; ++i) {
|
|
|
+ spi_flash_erase_sector(i);
|
|
|
+ }
|
|
|
+ TEST_ESP_OK(nvs_flash_secure_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN, &xts_cfg));
|
|
|
+
|
|
|
+ TEST_ESP_ERR(nvs_open("namespace1", NVS_READONLY, &handle_1), ESP_ERR_NVS_NOT_FOUND);
|
|
|
+
|
|
|
+
|
|
|
+ TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle_1));
|
|
|
+ TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678));
|
|
|
+ TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x23456789));
|
|
|
+
|
|
|
+ nvs_handle handle_2;
|
|
|
+ TEST_ESP_OK(nvs_open("namespace2", NVS_READWRITE, &handle_2));
|
|
|
+ TEST_ESP_OK(nvs_set_i32(handle_2, "foo", 0x3456789a));
|
|
|
+ const char* str = "value 0123456789abcdef0123456789abcdef";
|
|
|
+ TEST_ESP_OK(nvs_set_str(handle_2, "key", str));
|
|
|
+
|
|
|
+ int32_t v1;
|
|
|
+ TEST_ESP_OK(nvs_get_i32(handle_1, "foo", &v1));
|
|
|
+ CHECK(0x23456789 == v1);
|
|
|
+
|
|
|
+ int32_t v2;
|
|
|
+ TEST_ESP_OK(nvs_get_i32(handle_2, "foo", &v2));
|
|
|
+ CHECK(0x3456789a == v2);
|
|
|
+
|
|
|
+ char buf[strlen(str) + 1];
|
|
|
+ size_t buf_len = sizeof(buf);
|
|
|
+
|
|
|
+ size_t buf_len_needed;
|
|
|
+ TEST_ESP_OK(nvs_get_str(handle_2, "key", NULL, &buf_len_needed));
|
|
|
+ CHECK(buf_len_needed == buf_len);
|
|
|
+
|
|
|
+ size_t buf_len_short = buf_len - 1;
|
|
|
+ TEST_ESP_ERR(ESP_ERR_NVS_INVALID_LENGTH, nvs_get_str(handle_2, "key", buf, &buf_len_short));
|
|
|
+ CHECK(buf_len_short == buf_len);
|
|
|
+
|
|
|
+ size_t buf_len_long = buf_len + 1;
|
|
|
+ TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len_long));
|
|
|
+ CHECK(buf_len_long == buf_len);
|
|
|
+
|
|
|
+ TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len));
|
|
|
+
|
|
|
+ CHECK(0 == strcmp(buf, str));
|
|
|
+ nvs_close(handle_1);
|
|
|
+ nvs_close(handle_2);
|
|
|
+ TEST_ESP_OK(nvs_flash_deinit());
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled", "[nvs_part_gen]")
|
|
|
+{
|
|
|
+ int childpid = fork();
|
|
|
+ if (childpid == 0) {
|
|
|
+ exit(execlp("python", "python",
|
|
|
+ "../nvs_partition_generator/nvs_partition_gen.py",
|
|
|
+ "../nvs_partition_generator/sample_multipage_blob.csv",
|
|
|
+ "../nvs_partition_generator/partition_encrypted.bin",
|
|
|
+ "12KB",
|
|
|
+ "--encrypt",
|
|
|
+ "True",
|
|
|
+ "--keyfile",
|
|
|
+ "../nvs_partition_generator/testdata/encryption_keys.txt",NULL));
|
|
|
+ } else {
|
|
|
+ CHECK(childpid > 0);
|
|
|
+ int status;
|
|
|
+ waitpid(childpid, &status, 0);
|
|
|
+ CHECK(WEXITSTATUS(status) != -1);
|
|
|
+ }
|
|
|
+
|
|
|
+ SpiFlashEmulator emu("../nvs_partition_generator/partition_encrypted.bin");
|
|
|
+ nvs_handle handle;
|
|
|
+
|
|
|
+ nvs_sec_cfg_t xts_cfg;
|
|
|
+
|
|
|
+ for(int count = 0; count < NVS_KEY_SIZE; count++) {
|
|
|
+ xts_cfg.eky[count] = 0x11;
|
|
|
+ xts_cfg.tky[count] = 0x22;
|
|
|
+ }
|
|
|
+
|
|
|
+ TEST_ESP_OK(nvs_flash_secure_init_custom(NVS_DEFAULT_PART_NAME, 0, 3, &xts_cfg));
|
|
|
+
|
|
|
+ TEST_ESP_OK(nvs_open_from_partition(NVS_DEFAULT_PART_NAME, "dummyNamespace", NVS_READONLY, &handle));
|
|
|
+
|
|
|
+ uint8_t u8v;
|
|
|
+ TEST_ESP_OK( nvs_get_u8(handle, "dummyU8Key", &u8v));
|
|
|
+ CHECK(u8v == 127);
|
|
|
+ int8_t i8v;
|
|
|
+ TEST_ESP_OK( nvs_get_i8(handle, "dummyI8Key", &i8v));
|
|
|
+ CHECK(i8v == -128);
|
|
|
+ uint16_t u16v;
|
|
|
+ TEST_ESP_OK( nvs_get_u16(handle, "dummyU16Key", &u16v));
|
|
|
+ CHECK(u16v == 32768);
|
|
|
+ uint32_t u32v;
|
|
|
+ TEST_ESP_OK( nvs_get_u32(handle, "dummyU32Key", &u32v));
|
|
|
+ CHECK(u32v == 4294967295);
|
|
|
+ int32_t i32v;
|
|
|
+ TEST_ESP_OK( nvs_get_i32(handle, "dummyI32Key", &i32v));
|
|
|
+ CHECK(i32v == -2147483648);
|
|
|
+
|
|
|
+ char buf[64] = {0};
|
|
|
+ size_t buflen = 64;
|
|
|
+ TEST_ESP_OK( nvs_get_str(handle, "dummyStringKey", buf, &buflen));
|
|
|
+ CHECK(strncmp(buf, "0A:0B:0C:0D:0E:0F", buflen) == 0);
|
|
|
+
|
|
|
+ uint8_t hexdata[] = {0x01, 0x02, 0x03, 0xab, 0xcd, 0xef};
|
|
|
+ buflen = 64;
|
|
|
+ TEST_ESP_OK( nvs_get_blob(handle, "dummyHex2BinKey", buf, &buflen));
|
|
|
+ CHECK(memcmp(buf, hexdata, buflen) == 0);
|
|
|
+
|
|
|
+ uint8_t base64data[] = {'1', '2', '3', 'a', 'b', 'c'};
|
|
|
+ buflen = 64;
|
|
|
+ TEST_ESP_OK( nvs_get_blob(handle, "dummyBase64Key", buf, &buflen));
|
|
|
+ CHECK(memcmp(buf, base64data, buflen) == 0);
|
|
|
+
|
|
|
+ uint8_t hexfiledata[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
|
|
|
+ buflen = 64;
|
|
|
+ TEST_ESP_OK( nvs_get_blob(handle, "hexFileKey", buf, &buflen));
|
|
|
+ CHECK(memcmp(buf, hexfiledata, buflen) == 0);
|
|
|
+
|
|
|
+ uint8_t base64filedata[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xab, 0xcd, 0xef};
|
|
|
+ buflen = 64;
|
|
|
+ TEST_ESP_OK( nvs_get_blob(handle, "base64FileKey", buf, &buflen));
|
|
|
+ CHECK(memcmp(buf, base64filedata, buflen) == 0);
|
|
|
+
|
|
|
+ uint8_t strfiledata[64] = "abcdefghijklmnopqrstuvwxyz\0";
|
|
|
+ buflen = 64;
|
|
|
+ TEST_ESP_OK( nvs_get_str(handle, "stringFileKey", buf, &buflen));
|
|
|
+ CHECK(memcmp(buf, strfiledata, buflen) == 0);
|
|
|
+
|
|
|
+ char bin_data[5120];
|
|
|
+ size_t bin_len = sizeof(bin_data);
|
|
|
+ char binfiledata[5200];
|
|
|
+ ifstream file;
|
|
|
+ file.open("../nvs_partition_generator/testdata/sample_multipage_blob.bin");
|
|
|
+ file.read(binfiledata,5120);
|
|
|
+ TEST_ESP_OK( nvs_get_blob(handle, "binFileKey", bin_data, &bin_len));
|
|
|
+ CHECK(memcmp(bin_data, binfiledata, bin_len) == 0);
|
|
|
+
|
|
|
+ nvs_close(handle);
|
|
|
+ TEST_ESP_OK(nvs_flash_deinit());
|
|
|
+
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Add new tests above */
|
|
|
+/* This test has to be the final one */
|
|
|
|
|
|
TEST_CASE("dump all performance data", "[nvs]")
|
|
|
{
|