* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "include/boost_state_db.h"
#include "include/boost_state_table.h"
#include "snapshot/savepoint_data_view.h"
#include "test_utils.h"
namespace ock {
namespace bss {
BoostStateDB *mDB;
inline std::vector<uint8_t> GetRandomData()
{
std::random_device rd;
std::mt19937 gen(rd());
uint32_t lenBegin = 1;
uint32_t lenEnd = 300;
uint32_t byteBegin = 0;
uint32_t byteEnd = 255;
std::uniform_int_distribution<> LenDist(lenBegin, lenEnd);
std::uniform_int_distribution<> byteDist(byteBegin, byteEnd);
uint32_t length = LenDist(gen);
std::vector<uint8_t> data(length);
for (uint32_t i = 0; i < length; ++i) {
data[i] = static_cast<uint8_t>(byteDist(gen));
}
return data;
}
TableRef CreateFromDB(StateType keyedStateType, std::string tableName, BoostStateDB *db)
{
auto tblDesc = std::make_shared<TableDescription>(keyedStateType, tableName, -1, TableSerializer{},
db->GetConfig());
return db->GetTableOrCreate(tblDesc);
}
class TestSavepoint : public ::testing::Test {
public:
TestSavepoint() = default;
void SetUp() override;
void TearDown() override;
};
void TestSavepoint::SetUp()
{
ConfigRef config = std::make_shared<Config>();
config->mMemorySegmentSize = IO_SIZE_4M;
config->SetEvictMinSize(IO_SIZE_4M);
config->Init(NO_0, NO_15, NO_16);
mDB = BoostStateDBFactory::Create();
mDB->Open(config);
}
void TestSavepoint::TearDown()
{
mDB->Close();
delete mDB;
}
TEST_F(TestSavepoint, TestSavePoint)
{
std::map<std::vector<uint8_t>, std::vector<uint8_t>> expectedEntrySet;
KVTableRef kVTable = std::dynamic_pointer_cast<KVTable>(CreateFromDB(StateType::VALUE, "kVTable", mDB));
uint32_t size = NO_10000;
for (uint32_t j = 0; j < size; j++) {
std::vector<uint8_t> key = GetRandomData();
std::vector<uint8_t> value = GetRandomData();
auto tempEntry = std::make_pair(key, value);
if (expectedEntrySet.find(key) != expectedEntrySet.end()) {
continue;
}
expectedEntrySet.emplace(key, value);
uint32_t keyHashCode = test::HashForTest(key.data(), key.size());
BinaryData priKey(key.data(), key.size());
BinaryData val(value.data(), value.size());
kVTable->Put(keyHashCode, priKey, val);
}
sleep(NO_10);
SavepointDataView *dataView = mDB->TriggerSavepoint();
auto iterator = dataView->SavepointIterator();
ASSERT_EQ(dataView != nullptr, true);
std::set<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> tempEntrySet;
uint32_t count = 0;
while (iterator->HasNext()) {
count++;
BinaryKeyValueItemRef item = iterator->Next();
auto serializedKey = item->mKey;
auto serializedValue = item->mValue;
std::vector<uint8_t> key(serializedKey, serializedKey + item->mKeyLength);
std::vector<uint8_t> value(serializedValue, serializedValue + item->mValueLength);
auto it = expectedEntrySet.find(key);
ASSERT_EQ(it != expectedEntrySet.end(), true);
ASSERT_EQ(it->second == value, true);
}
ASSERT_EQ(count, expectedEntrySet.size());
}
}
}