1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "catch.hpp"
7 #include <algorithm>
8 #include <cstring>
9 #include "nvs_test_api.h"
10 #include "nvs_handle_simple.hpp"
11 #include "nvs_partition_manager.hpp"
12 #include "spi_flash_emulation.h"
13 #include "nvs_test_api.h"
14 
15 #include "test_fixtures.hpp"
16 
17 using namespace nvs;
18 
19 TEST_CASE("Partition manager initializes storage", "[partition_mgr]")
20 {
21     const uint32_t NVS_FLASH_SECTOR = 6;
22     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
23     PartitionEmulationFixture f(0, 10, "test");
24 
25     REQUIRE(NVSPartitionManager::get_instance()->init_custom(&f.part, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN) == ESP_OK);
26     CHECK(NVSPartitionManager::get_instance()->lookup_storage_from_name("test") != nullptr);
27     REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(f.part.get_partition_name()) == ESP_OK);
28 }
29 
30 TEST_CASE("Partition manager de-initializes storage", "[partition_mgr]")
31 {
32     const uint32_t NVS_FLASH_SECTOR = 6;
33     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
34     PartitionEmulationFixture f(0, 10, "test");
35 
36     REQUIRE(NVSPartitionManager::get_instance()->init_custom(&f.part, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN) == ESP_OK);
37     CHECK(NVSPartitionManager::get_instance()->lookup_storage_from_name("test") != nullptr);
38     CHECK(NVSPartitionManager::get_instance()->deinit_partition("test") == ESP_OK);
39     CHECK(NVSPartitionManager::get_instance()->lookup_storage_from_name("test") == nullptr);
40 }
41 
42 TEST_CASE("Partition manager initializes multiple partitions", "[partition_mgr]")
43 {
44     const uint32_t NVS_FLASH_SECTOR = 6;
45     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
46     SpiFlashEmulator emu(10);
47     PartitionEmulation part_0(&emu, NVS_FLASH_SECTOR * SPI_FLASH_SEC_SIZE, NVS_FLASH_SECTOR_COUNT_MIN * SPI_FLASH_SEC_SIZE, "test1");
48     PartitionEmulation part_1(&emu, NVS_FLASH_SECTOR * SPI_FLASH_SEC_SIZE, NVS_FLASH_SECTOR_COUNT_MIN * SPI_FLASH_SEC_SIZE, "test2");
49 
50     REQUIRE(NVSPartitionManager::get_instance()->init_custom(&part_0, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
51             == ESP_OK);
52     // TODO: why does this work, actually? same sectors used as above
53     REQUIRE(NVSPartitionManager::get_instance()->init_custom(&part_1, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
54             == ESP_OK);
55     Storage *storage1 = NVSPartitionManager::get_instance()->lookup_storage_from_name("test1");
56     REQUIRE(storage1 != nullptr);
57     Storage *storage2 = NVSPartitionManager::get_instance()->lookup_storage_from_name("test2");
58     REQUIRE(storage2 != nullptr);
59 
60     CHECK(storage1 != storage2);
61     REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(part_0.get_partition_name()) == ESP_OK);
62     REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(part_1.get_partition_name()) == ESP_OK);
63 }
64 
65 TEST_CASE("Partition manager open fails on null handle", "[partition_mgr]")
66 {
67     const uint32_t NVS_FLASH_SECTOR = 6;
68     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
69     PartitionEmulationFixture f(0, 10, "test");
70 
71     REQUIRE(NVSPartitionManager::get_instance()->init_custom(&f.part, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
72             == ESP_OK);
73 
74     CHECK(NVSPartitionManager::get_instance()->open_handle("test", "ns_1", NVS_READWRITE, nullptr)
75             == ESP_ERR_INVALID_ARG);
76 
77     NVSPartitionManager::get_instance()->deinit_partition("test");
78 }
79 
80 TEST_CASE("Partition manager invalidates handle on partition de-init", "[partition_mgr]")
81 {
82     const uint32_t NVS_FLASH_SECTOR = 6;
83     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
84     PartitionEmulationFixture f(0, 10, "test");
85 
86     REQUIRE(NVSPartitionManager::get_instance()->init_custom(&f.part, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
87             == ESP_OK);
88 
89     NVSHandleSimple *handle;
90     REQUIRE(NVSPartitionManager::get_instance()->open_handle("test", "ns_1", NVS_READWRITE, &handle) == ESP_OK);
91     CHECK(handle->erase_all() == ESP_OK);
92 
93     REQUIRE(NVSPartitionManager::get_instance()->deinit_partition("test") == ESP_OK);
94 
95     CHECK(handle->erase_all() == ESP_ERR_NVS_INVALID_HANDLE);
96 
97     delete handle;
98 }
99