curve/test/tools/namespace_tool_test.cpp

397 lines
13 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2020 NetEase Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Project: curve
* File Created: 2019-09-29
* Author: charisu
* Copyright (c) 2018 netease
*/
#include <gtest/gtest.h>
#include "src/tools/namespace_tool.h"
#include "test/tools/mock/mock_namespace_tool_core.h"
using ::testing::_;
using ::testing::Return;
using ::testing::DoAll;
using ::testing::SetArgPointee;
DECLARE_bool(isTest);
DECLARE_string(fileName);
DECLARE_uint64(offset);
DECLARE_bool(showAllocSize);
DECLARE_bool(showFileSize);
DECLARE_bool(showAllocMap);
class NameSpaceToolTest : public ::testing::Test {
protected:
NameSpaceToolTest() {
FLAGS_isTest = true;
}
void SetUp() {
core_ = std::make_shared<curve::tool::MockNameSpaceToolCore>();
}
void TearDown() {
core_ = nullptr;
FLAGS_showFileSize = true;
FLAGS_showAllocSize = true;
}
void GetFileInfoForTest(FileInfo* fileInfo) {
fileInfo->set_id(1);
fileInfo->set_filename("test");
fileInfo->set_parentid(0);
fileInfo->set_filetype(curve::mds::FileType::INODE_PAGEFILE);
fileInfo->set_segmentsize(segmentSize);
fileInfo->set_length(5 * segmentSize);
fileInfo->set_originalfullpathname("/cinder/test");
fileInfo->set_ctime(1573546993000000);
}
void GetCsLocForTest(ChunkServerLocation* csLoc, uint64_t csId) {
csLoc->set_chunkserverid(csId);
csLoc->set_hostip("127.0.0.1");
csLoc->set_port(9191 + csId);
}
void GetSegmentForTest(PageFileSegment* segment) {
segment->set_logicalpoolid(1);
segment->set_segmentsize(segmentSize);
segment->set_chunksize(chunkSize);
segment->set_startoffset(0);
for (int i = 0; i < 10; ++i) {
auto chunk = segment->add_chunks();
chunk->set_copysetid(1000 + i);
chunk->set_chunkid(2000 + i);
}
}
uint64_t segmentSize = 1 * 1024 * 1024 * 1024ul;
uint64_t chunkSize = 16 * 1024 * 1024;
std::shared_ptr<curve::tool::MockNameSpaceToolCore> core_;
};
TEST_F(NameSpaceToolTest, SupportCommand) {
curve::tool::NameSpaceTool namespaceTool(core_);
ASSERT_TRUE(namespaceTool.SupportCommand("get"));
ASSERT_TRUE(namespaceTool.SupportCommand("list"));
ASSERT_TRUE(namespaceTool.SupportCommand("seginfo"));
ASSERT_TRUE(namespaceTool.SupportCommand("delete"));
ASSERT_TRUE(namespaceTool.SupportCommand("clean-recycle"));
ASSERT_TRUE(namespaceTool.SupportCommand("create"));
ASSERT_TRUE(namespaceTool.SupportCommand("chunk-location"));
ASSERT_TRUE(namespaceTool.SupportCommand("update-throttle"));
ASSERT_FALSE(namespaceTool.SupportCommand("none"));
}
TEST_F(NameSpaceToolTest, GetFile) {
curve::tool::NameSpaceTool namespaceTool(core_);
namespaceTool.PrintHelp("abc");
namespaceTool.PrintHelp("get");
FileInfo fileInfo;
GetFileInfoForTest(&fileInfo);
PageFileSegment segment;
GetSegmentForTest(&segment);
FLAGS_fileName = "/test/";
// 0、Init失败
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("get"));
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(0));
ASSERT_EQ(-1, namespaceTool.RunCommand("abc"));
// 1、正常情况
FLAGS_showAllocMap = true;
EXPECT_CALL(*core_, GetFileInfo(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(fileInfo),
Return(0)));
curve::tool::AllocMap allocMap = {{1, segmentSize}, {2, 9 * segmentSize}};
EXPECT_CALL(*core_, GetAllocatedSize(_, _, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(10 * segmentSize),
SetArgPointee<2>(allocMap),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("get"));
// 2、获取fileInfo失败
EXPECT_CALL(*core_, GetFileInfo(_, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("get"));
// 3、计算大小失败
EXPECT_CALL(*core_, GetFileInfo(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(fileInfo),
Return(0)));
EXPECT_CALL(*core_, GetAllocatedSize(_, _, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("get"));
// 4、get的是目录的话还要计算file size
FileInfo fileInfo2;
GetFileInfoForTest(&fileInfo2);
fileInfo2.set_filetype(curve::mds::FileType::INODE_DIRECTORY);
EXPECT_CALL(*core_, GetFileInfo(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(fileInfo2),
Return(0)));
EXPECT_CALL(*core_, GetAllocatedSize(_, _, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(10 * segmentSize),
Return(0)));
EXPECT_CALL(*core_, GetFileSize(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(10 * segmentSize),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("get"));
// 5、指定了-showAllocSize=false的话不计算分配大小
FLAGS_showAllocSize = false;
EXPECT_CALL(*core_, GetFileInfo(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(fileInfo),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("get"));
// 6、对目录指定了-showFileSize=false的话不计算文件大小
FLAGS_showFileSize = false;
FLAGS_showAllocSize = false;
EXPECT_CALL(*core_, GetFileInfo(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(fileInfo2),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("get"));
}
TEST_F(NameSpaceToolTest, ListDir) {
curve::tool::NameSpaceTool namespaceTool(core_);
namespaceTool.PrintHelp("list");
FileInfo fileInfo;
GetFileInfoForTest(&fileInfo);
PageFileSegment segment;
GetSegmentForTest(&segment);
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(0));
// 1、正常情况
std::vector<FileInfo> files;
for (uint64_t i = 0; i < 3; ++i) {
files.emplace_back(fileInfo);
}
EXPECT_CALL(*core_, ListDir(_, _))
.Times(2)
.WillRepeatedly(DoAll(SetArgPointee<1>(files),
Return(0)));
EXPECT_CALL(*core_, GetAllocatedSize(_, _, _))
.Times(6)
.WillRepeatedly(DoAll(SetArgPointee<1>(10 * segmentSize),
Return(0)));
FLAGS_fileName = "/";
ASSERT_EQ(0, namespaceTool.RunCommand("list"));
FLAGS_fileName = "/test/";
ASSERT_EQ(0, namespaceTool.RunCommand("list"));
// 2、listDir失败
EXPECT_CALL(*core_, ListDir(_, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("list"));
// 3、计算大小失败,个别的文件计算大小失败会继续计算,但是返回-1
EXPECT_CALL(*core_, ListDir(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(files),
Return(0)));
EXPECT_CALL(*core_, GetAllocatedSize(_, _, _))
.Times(3)
.WillOnce(Return(-1))
.WillRepeatedly(DoAll(SetArgPointee<1>(10 * segmentSize),
Return(0)));
ASSERT_EQ(-1, namespaceTool.RunCommand("list"));
// 4、指定了-showAllocSize=false的话不计算分配大小
FLAGS_showAllocSize = false;
EXPECT_CALL(*core_, ListDir(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(files),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("list"));
// 4、list的时候有目录的话计算fileSize
FileInfo fileInfo2;
GetFileInfoForTest(&fileInfo2);
fileInfo2.set_filetype(curve::mds::FileType::INODE_DIRECTORY);
files.emplace_back(fileInfo2);
EXPECT_CALL(*core_, ListDir(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(files),
Return(0)));
EXPECT_CALL(*core_, GetFileSize(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(10 * segmentSize),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("list"));
// 5、指定了-showFileSize=false的话不计算文件大小
FLAGS_showFileSize = false;
EXPECT_CALL(*core_, ListDir(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(files),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("list"));
}
TEST_F(NameSpaceToolTest, SegInfo) {
curve::tool::NameSpaceTool namespaceTool(core_);
namespaceTool.PrintHelp("seginfo");
std::vector<PageFileSegment> segments;
for (int i = 0; i < 3; ++i) {
PageFileSegment segment;
GetSegmentForTest(&segment);
segments.emplace_back(segment);
}
FLAGS_fileName = "/test";
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(0));
// 1、正常情况
EXPECT_CALL(*core_, GetFileSegments(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(segments),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("seginfo"));
// 2、GetFileSegment失败
EXPECT_CALL(*core_, GetFileSegments(_, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("seginfo"));
}
TEST_F(NameSpaceToolTest, CreateFile) {
curve::tool::NameSpaceTool namespaceTool(core_);
namespaceTool.PrintHelp("create");
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(0));
// 1、正常情况
EXPECT_CALL(*core_, CreateFile(_, _))
.Times(1)
.WillOnce(Return(0));
ASSERT_EQ(0, namespaceTool.RunCommand("create"));
// 2、创建失败
EXPECT_CALL(*core_, CreateFile(_, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("create"));
}
TEST_F(NameSpaceToolTest, DeleteFile) {
curve::tool::NameSpaceTool namespaceTool(core_);
namespaceTool.PrintHelp("delete");
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(0));
// 1、正常情况
EXPECT_CALL(*core_, DeleteFile(_, _))
.Times(1)
.WillOnce(Return(0));
ASSERT_EQ(0, namespaceTool.RunCommand("delete"));
// 2、创建失败
EXPECT_CALL(*core_, DeleteFile(_, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("delete"));
}
TEST_F(NameSpaceToolTest, CleanRecycle) {
curve::tool::NameSpaceTool namespaceTool(core_);
namespaceTool.PrintHelp("clean-recycle");
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(0));
// 1、正常情况
EXPECT_CALL(*core_, CleanRecycleBin(_, _))
.Times(1)
.WillOnce(Return(0));
ASSERT_EQ(0, namespaceTool.RunCommand("clean-recycle"));
// 2、失败
EXPECT_CALL(*core_, CleanRecycleBin(_, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("clean-recycle"));
}
TEST_F(NameSpaceToolTest, PrintChunkLocation) {
curve::tool::NameSpaceTool namespaceTool(core_);
namespaceTool.PrintHelp("chunk-location");
std::vector<ChunkServerLocation> csLocs;
for (uint64_t i = 0; i < 3; ++i) {
ChunkServerLocation csLoc;
GetCsLocForTest(&csLoc, i);
csLocs.emplace_back(csLoc);
}
uint64_t chunkId = 2001;
std::pair<uint32_t, uint32_t> copyset = {1, 101};
EXPECT_CALL(*core_, Init(_))
.Times(1)
.WillOnce(Return(0));
// 1、正常情况
EXPECT_CALL(*core_, QueryChunkCopyset(_, _, _, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<2>(chunkId),
SetArgPointee<3>(copyset),
Return(0)));
EXPECT_CALL(*core_, GetChunkServerListInCopySet(_, _, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<2>(csLocs),
Return(0)));
ASSERT_EQ(0, namespaceTool.RunCommand("chunk-location"));
// 2、QueryChunkCopyset失败
EXPECT_CALL(*core_, QueryChunkCopyset(_, _, _, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("chunk-location"));
// 3、GetChunkServerListInCopySet失败
EXPECT_CALL(*core_, QueryChunkCopyset(_, _, _, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<2>(chunkId),
SetArgPointee<3>(copyset),
Return(0)));
EXPECT_CALL(*core_, GetChunkServerListInCopySet(_, _, _))
.Times(1)
.WillOnce(Return(-1));
ASSERT_EQ(-1, namespaceTool.RunCommand("chunk-location"));
}