* 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 "test_bucket_group.h"
#define private public
#include "lsm_store/file/file_store_impl.h"
#include "slice_table/bucket_group.h"
#include "slice_table/bucket_group_manager.h"
#include "slice_table/bucket_group_range.h"
#undef private
using namespace ock::bss;
const std::string testFilePath = "test_output.txt";
auto fileInput = std::make_shared<FileInputView>();
auto fileOutput = std::make_shared<FileOutputView>();
class TestBucketGroup : public ::testing::Test {
public:
void SetUp() override
{
fileStoreId = std::make_shared<FileStoreID>();
config = std::make_shared<Config>();
memManager = std::make_shared<MemManager>(AllocatorType::DIRECT);
stateIdProvider = std::make_shared<StateIdProvider>(1, 1, memManager);
tableFactory = std::make_shared<FileFactory>(config, memManager);
fileCache = std::make_shared<FileCacheManager>();
stateFilterManager = std::make_shared<StateFilterManager>(stateIdProvider, config, 1, 1);
sliceIndex = std::make_shared<SliceBucketIndex>();
Uri uri(testFilePath);
PathRef path = std::make_shared<Path>(uri);
ASSERT_EQ(fileOutput->Init(path, config, FileOutputView::WriteMode::OVERWRITE), BSS_OK);
ASSERT_EQ(fileInput->Init(FileSystemType::LOCAL, path), BSS_OK);
}
void TearDown() override
{
fileOutput->Close();
fileInput->Close();
}
std::shared_ptr<FileStoreID> fileStoreId;
std::shared_ptr<Config> config;
std::shared_ptr<StateIdProvider> stateIdProvider;
std::shared_ptr<FileFactory> tableFactory;
std::shared_ptr<FileCacheManager> fileCache;
std::shared_ptr<StateFilterManager> stateFilterManager;
std::shared_ptr<MemManager> memManager;
SliceBucketIndexRef sliceIndex;
};
* @tc.name : Initialize_ShouldReturnError_WhenSliceIndexIsNull
* @tc.number: 001
* @tc.desc : Test scenario where sliceIndex is null.
*/
TEST_F(TestBucketGroup, Initialize_ShouldReturnError_WhenSliceIndexIsNull)
{
uint32_t bucketGroupId = 1;
LsmStoreRef lsmStore;
SliceBucketIndexRef sliceIndex = nullptr;
uint32_t startBucket = 1;
uint32_t endBucket = 10;
BucketGroup bucketGroup;
BResult result = bucketGroup.Initialize(bucketGroupId, lsmStore, sliceIndex, startBucket, endBucket);
EXPECT_EQ(result, BSS_ERR);
}
* @tc.name : Initialize_ShouldReturnError_WhenFileStoreIsNull
* @tc.number: 002
* @tc.desc : Test scenario where fileStore is null.
*/
TEST_F(TestBucketGroup, Initialize_ShouldReturnError_WhenFileStoreIsNull)
{
uint32_t bucketGroupId = 1;
LsmStoreRef lsmStore = nullptr;
SliceBucketIndexRef sliceIndex = std::make_shared<SliceBucketIndex>();
uint32_t startBucket = 1;
uint32_t endBucket = 10;
BucketGroup bucketGroup;
BResult result = bucketGroup.Initialize(bucketGroupId, lsmStore, sliceIndex, startBucket, endBucket);
EXPECT_EQ(result, BSS_ERR);
}
* @tc.name : Initialize_ShouldReturnSuccess_WhenAllParamsAreValid
* @tc.number: 003
* @tc.desc : Test scenario where all parameters are valid.
*/
TEST_F(TestBucketGroup, Initialize_ShouldReturnSuccess_WhenAllParamsAreValid)
{
uint32_t bucketGroupId = 1;
LsmStoreRef lsmStore = std::make_shared<LsmStore>(fileStoreId, config, tableFactory, fileCache, stateFilterManager,
memManager);
SliceBucketIndexRef sliceIndex = std::make_shared<SliceBucketIndex>();
uint32_t startBucket = 1;
uint32_t endBucket = 10;
BucketGroup bucketGroup;
BResult result = bucketGroup.Initialize(bucketGroupId, lsmStore, sliceIndex, startBucket, endBucket);
EXPECT_EQ(result, BSS_OK);
}
* @tc.name : Restore_ShouldReturnError_WhenReadStartBucketFails
* @tc.number: BucketGroup_Restore_001
* @tc.desc : Test that Restore returns an error when reading startBucket fails
*/
TEST_F(TestBucketGroup, Restore_ShouldReturnError_WhenReadStartBucketFails)
{
uint32_t totalBucketNum = 10;
BucketGroupRangeRef bucketGroupRange;
fileInput->Seek(0);
BResult result = BucketGroup::Restore(fileInput, totalBucketNum, bucketGroupRange);
EXPECT_NE(result, BSS_OK);
}
* @tc.name : Restore_ShouldReturnError_WhenReadEndBucketFails
* @tc.number: BucketGroup_Restore_002
* @tc.desc : Test that Restore returns an error when reading endBucket fails
*/
TEST_F(TestBucketGroup, Restore_ShouldReturnError_WhenReadEndBucketFails)
{
uint32_t startBucket = 1;
uint32_t totalBucketNum = 10;
ASSERT_EQ(fileOutput->WriteUint32(startBucket), BSS_OK);
BucketGroupRangeRef bucketGroupRange;
fileInput->Seek(0);
BResult result = BucketGroup::Restore(fileInput, totalBucketNum, bucketGroupRange);
EXPECT_NE(result, BSS_OK);
}
* @tc.name : Restore_ShouldReturnError_WhenReadBucketGroupIdFails
* @tc.number: BucketGroup_Restore_003
* @tc.desc : Test that Restore returns an error when reading bucketGroupId fails
*/
TEST_F(TestBucketGroup, Restore_ShouldReturnError_WhenReadBucketGroupIdFails)
{
uint32_t startBucket = 1;
uint32_t endBucket = 2;
uint32_t totalBucketNum = 10;
ASSERT_EQ(fileOutput->WriteUint32(startBucket), BSS_OK);
ASSERT_EQ(fileOutput->WriteUint32(endBucket), BSS_OK);
BucketGroupRangeRef bucketGroupRange;
fileInput->Seek(0);
BResult result = BucketGroup::Restore(fileInput, totalBucketNum, bucketGroupRange);
EXPECT_NE(result, BSS_OK);
}
* @tc.name : Restore_ShouldReturnSuccess_WhenAllReadsSucceed
* @tc.number: BucketGroup_Restore_004
* @tc.desc : Test that Restore returns success when all reads succeed
*/
TEST_F(TestBucketGroup, Restore_ShouldReturnSuccess_WhenAllReadsSucceed)
{
uint32_t startBucket = 1;
uint32_t endBucket = 2;
uint32_t bucketGroupId = 3;
uint32_t totalBucketNum = 10;
ASSERT_EQ(fileOutput->WriteUint32(startBucket), BSS_OK);
ASSERT_EQ(fileOutput->WriteUint32(endBucket), BSS_OK);
ASSERT_EQ(fileOutput->WriteUint32(bucketGroupId), BSS_OK);
BucketGroupRangeRef bucketGroupRange;
fileInput->Seek(0);
BResult result = BucketGroup::Restore(fileInput, totalBucketNum, bucketGroupRange);
EXPECT_EQ(result, BSS_OK);
EXPECT_NE(bucketGroupRange, nullptr);
EXPECT_EQ(bucketGroupRange->GetStartBucket(), startBucket);
EXPECT_EQ(bucketGroupRange->GetEndBucket(), endBucket);
EXPECT_EQ(bucketGroupRange->GetTotalBucket(), totalBucketNum);
EXPECT_EQ(bucketGroupRange->GetBucketGroupId(), bucketGroupId);
}
* @tc.name : Initialize_ShouldReturnBSS_ERR_WhenConfigIsNullptr
* @tc.number: Initialize_Test_001
* @tc.desc : Test Initialize function when config is nullptr
*/
TEST_F(TestBucketGroup, Initialize_ShouldReturnBSS_ERR_WhenConfigIsNullptr)
{
BucketGroupManager manager;
BResult result = manager.Initialize(nullptr, sliceIndex, fileCache, 1, 1, memManager, nullptr);
EXPECT_EQ(result, BSS_ERR);
}
* @tc.name : Initialize_ShouldReturnBSS_ERR_WhenSliceIndexIsNullptr
* @tc.number: Initialize_Test_002
* @tc.desc : Test Initialize function when sliceIndex is nullptr
*/
TEST_F(TestBucketGroup, Initialize_ShouldReturnBSS_ERR_WhenSliceIndexIsNullptr)
{
BucketGroupManager manager;
BResult result = manager.Initialize(config, nullptr, fileCache, 1, 1, memManager, nullptr);
EXPECT_EQ(result, BSS_ERR);
}
* @tc.name : RestoreMeta_ShouldReturnError_WhenReadBucketGroupNumFails
* @tc.number: 001
* @tc.desc : Test that RestoreMeta returns error when reading bucketGroupNum fails.
*/
TEST_F(TestBucketGroup, RestoreMeta_ShouldReturnError_WhenReadBucketGroupNumFails)
{
FileInputViewRef reader = std::make_shared<FileInputView>();
std::vector<BucketGroupRangeRef> bucketGroupRanges;
uint32_t totalBucketNum = 10;
fileInput->Seek(0);
BResult result = BucketGroupManager::RestoreMeta(fileInput, totalBucketNum, bucketGroupRanges);
EXPECT_NE(result, BSS_OK);
}
* @tc.name : RestoreMeta_ShouldReturnSuccess_WhenReadBucketGroupNumSucceeds
* @tc.number: 002
* @tc.desc : Test that RestoreMeta returns success when reading bucketGroupNum succeeds.
*/
TEST_F(TestBucketGroup, RestoreMeta_ShouldReturnSuccess_WhenReadBucketGroupNumSucceeds)
{
std::vector<BucketGroupRangeRef> bucketGroupRanges;
uint32_t bucketGroupNum = 0;
uint32_t totalBucketNum = 10;
ASSERT_EQ(fileOutput->WriteUint32(bucketGroupNum), BSS_OK);
fileInput->Seek(0);
BResult result = BucketGroupManager::RestoreMeta(fileInput, totalBucketNum, bucketGroupRanges);
EXPECT_EQ(result, BSS_OK);
EXPECT_EQ(bucketGroupRanges.size(), bucketGroupNum);
}
* @tc.name : RestoreMeta_ShouldReturnError_WhenBucketGroupRestoreFails
* @tc.number: 003
* @tc.desc : Test that RestoreMeta returns error when BucketGroup::Restore fails.
*/
TEST_F(TestBucketGroup, RestoreMeta_ShouldReturnError_WhenBucketGroupRestoreFails)
{
std::vector<BucketGroupRangeRef> bucketGroupRanges;
uint32_t bucketGroupNum = 2;
uint32_t totalBucketNum = 10;
ASSERT_EQ(fileOutput->WriteUint32(bucketGroupNum), BSS_OK);
fileInput->Seek(0);
BResult result = BucketGroupManager::RestoreMeta(fileInput, totalBucketNum, bucketGroupRanges);
EXPECT_NE(result, BSS_OK);
}
* @tc.name : RestoreMeta_ShouldReturnSuccess_WhenBucketGroupRestoreSucceeds
* @tc.number: 004
* @tc.desc : Test that RestoreMeta returns success when BucketGroup::Restore succeeds.
*/
TEST_F(TestBucketGroup, RestoreMeta_ShouldReturnSuccess_WhenBucketGroupRestoreSucceeds)
{
std::vector<BucketGroupRangeRef> bucketGroupRanges;
uint32_t bucketGroupNum = 2;
uint32_t startBucket = 1;
uint32_t endBucket = 2;
uint32_t bucketGroupId = 3;
uint32_t totalBucketNum = 10;
ASSERT_EQ(fileOutput->WriteUint32(bucketGroupNum), BSS_OK);
for (uint32_t i = 0; i < bucketGroupNum; i++) {
ASSERT_EQ(fileOutput->WriteUint32(startBucket), BSS_OK);
ASSERT_EQ(fileOutput->WriteUint32(endBucket), BSS_OK);
ASSERT_EQ(fileOutput->WriteUint32(bucketGroupId), BSS_OK);
}
fileInput->Seek(0);
BResult result = BucketGroupManager::RestoreMeta(fileInput, totalBucketNum, bucketGroupRanges);
EXPECT_EQ(result, BSS_OK);
EXPECT_EQ(bucketGroupRanges.size(), bucketGroupNum);
}
* @tc.name : RestoreFileStore_ShouldReturnBSS_OK_WhenNoBucketGroups
* @tc.number: 001
* @tc.desc : 测试当没有BucketGroup时,RestoreFileStore函数返回BSS_OK
*/
TEST_F(TestBucketGroup, RestoreFileStore_ShouldReturnBSS_OK_WhenNoBucketGroups)
{
BucketGroupManager manager;
manager.mBucketGroups.clear();
std::vector<SliceTableRestoreMetaRef> sliceTableRestoreMetaList;
std::unordered_map<std::string, std::string> pathMap;
std::unordered_map<std::string, uint32_t> pathFileIdMap;
BResult result = manager.RestoreFileStore(sliceTableRestoreMetaList, pathMap, pathFileIdMap, false);
EXPECT_EQ(result, BSS_OK);
}