Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

curvebs(client): Fix always get file info from cache #2931

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/client/file_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,5 +276,26 @@ void FileInstance::StopLease() {
}
}

FInfo FileInstance::GetCurrentFileInfo(bool force) {
FInfo info = finfo_;
if (!force) {
return info;
}

FileEpoch fEpoch;
int rc = mdsclient_->GetFileInfo(info.fullPathName, info.userinfo, &info,
&fEpoch);
(void)fEpoch;
if (rc != LIBCURVE_ERROR::OK) {
LOG(WARNING) << "Fail to get current file info from mds, return cached"
"file info, filename: "
<< info.fullPathName;
} else {
finfo_ = info;
}

return info;
}

} // namespace client
} // namespace curve
6 changes: 2 additions & 4 deletions src/client/file_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,10 @@ class CURVE_CACHELINE_ALIGNMENT FileInstance {

/**
* @brief 获取当前instance对应的文件信息
*
* @param force whether force to get file info from mds
* @return 当前instance对应文件的信息
*/
FInfo GetCurrentFileInfo() const {
return finfo_;
}
FInfo GetCurrentFileInfo(bool force = false);

static FileInstance* NewInitedFileInstance(
const FileServiceOption& fileServiceOption,
Expand Down
2 changes: 1 addition & 1 deletion src/client/libcurve_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ int FileClient::StatFile(int fd, FileStatInfo *finfo) {
return -LIBCURVE_ERROR::FAILED;
}
FileInstance *instance = fileserviceMap_[fd];
fi = instance->GetCurrentFileInfo();
fi = instance->GetCurrentFileInfo(/*force=*/true);
}
BuildFileStatInfo(fi, finfo);

Expand Down
1 change: 1 addition & 0 deletions test/client/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ cc_test(
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
"//test/integration/cluster_common:integration_cluster_common",
"//test/client/mock:curve_client_mock",
],
)

Expand Down
153 changes: 151 additions & 2 deletions test/client/file_instance_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,22 @@
* Author: wuhanqing
*/

#include <gtest/gtest.h>
#include <gflags/gflags.h>
#include "src/client/file_instance.h"

#include <brpc/server.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "test/client/mock/mock_namespace_service.h"

namespace curve {
namespace client {

using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::SaveArgPointee;

TEST(FileInstanceTest, CommonTest) {
UserInfo userInfo{"test", "passwd"};
std::shared_ptr<MDSClient> mdsclient = std::make_shared<MDSClient>();
Expand Down Expand Up @@ -72,5 +81,145 @@ TEST(FileInstanceTest, IoAlignmentTest) {
ASSERT_FALSE(CheckAlign(511, 511, 512));
}

constexpr size_t kMiB = 1 << 20;
constexpr size_t kGiB = 1 << 30;

class FileInstanceGetFileInfoTest : public ::testing::Test {
protected:
void SetUp() override {
FileServiceOption opts;
opts.metaServerOpt.mdsAddrs = {kSvrAddr};

ASSERT_EQ(0, mdsclient_->Initialize(opts.metaServerOpt));
ASSERT_EQ(0, server_.AddService(&nameService_,
brpc::SERVER_DOESNT_OWN_SERVICE));
ASSERT_EQ(0, server_.Start(kSvrAddr, nullptr));

UserInfo user("test", "");
instance_.reset(FileInstance::NewInitedFileInstance(
opts, mdsclient_, "/test", user, OpenFlags{},
/*readonly=*/false));

EXPECT_CALL(nameService_, OpenFile(_, _, _, _))
.WillOnce(Invoke([](::google::protobuf::RpcController* cntl,
const curve::mds::OpenFileRequest*,
curve::mds::OpenFileResponse* response,
google::protobuf::Closure* done) {
response->set_statuscode(curve::mds::StatusCode::kOK);
auto* info = response->mutable_fileinfo();
info->set_id(2);
info->set_parentid(1);
info->set_chunksize(16ULL * kMiB);
info->set_segmentsize(1ULL * kGiB);
info->set_length(1ULL * kGiB);
auto* session = response->mutable_protosession();
session->set_sessionid("1");
session->set_leasetime(60);
session->set_createtime(0);
session->set_sessionstatus(
curve::mds::SessionStatus::kSessionOK);
done->Run();
}));

EXPECT_CALL(nameService_, CloseFile(_, _, _, _))
.WillOnce(Invoke([](::google::protobuf::RpcController* cntl,
const curve::mds::CloseFileRequest*,
curve::mds::CloseFileResponse* response,
google::protobuf::Closure* done) {
response->set_statuscode(curve::mds::StatusCode::kOK);
done->Run();
}));

EXPECT_CALL(nameService_, RefreshSession(_, _, _, _))
.WillRepeatedly(
Invoke([](::google::protobuf::RpcController* cntl,
const curve::mds::ReFreshSessionRequest*,
curve::mds::ReFreshSessionResponse* response,
google::protobuf::Closure* done) {
response->set_statuscode(curve::mds::StatusCode::kOK);
response->set_sessionid("");
done->Run();
}));

ASSERT_EQ(0, instance_->Open());
}

void TearDown() override {
ASSERT_EQ(0, instance_->Close());

server_.Stop(0);
server_.Join();
}

protected:
const char* kSvrAddr = "127.0.0.1:9610";

std::shared_ptr<MDSClient> mdsclient_ = std::make_shared<MDSClient>();
std::unique_ptr<FileInstance> instance_;

brpc::Server server_;
curve::mds::MockNameService nameService_;
};

TEST_F(FileInstanceGetFileInfoTest, TestGetInfoFromCache) {
auto info = instance_->GetCurrentFileInfo();
ASSERT_EQ(1ULL * kGiB, info.length);
}

TEST_F(FileInstanceGetFileInfoTest, TestForceGetInfo) {
// get info from mds success, return cached fileinfo
{
EXPECT_CALL(nameService_, GetFileInfo(_, _, _, _))
.WillOnce(Invoke([](::google::protobuf::RpcController* cntl,
const curve::mds::GetFileInfoRequest*,
curve::mds::GetFileInfoResponse* response,
google::protobuf::Closure* done) {
response->set_statuscode(
curve::mds::StatusCode::kFileNotExists);
done->Run();
}));

auto info = instance_->GetCurrentFileInfo(/*force=*/true);
ASSERT_EQ(1ULL * kGiB, info.length);
}

// get info from mds success, return new fileinfo
{
EXPECT_CALL(nameService_, GetFileInfo(_, _, _, _))
.WillOnce(Invoke([](::google::protobuf::RpcController* cntl,
const curve::mds::GetFileInfoRequest*,
curve::mds::GetFileInfoResponse* response,
google::protobuf::Closure* done) {
response->set_statuscode(curve::mds::StatusCode::kOK);
auto* info = response->mutable_fileinfo();
info->set_id(2);
info->set_parentid(1);
info->set_chunksize(16ULL * kMiB);
info->set_segmentsize(1ULL * kGiB);
info->set_length(2ULL * kGiB); // increase file size to 2GiB
done->Run();
}));

auto info = instance_->GetCurrentFileInfo(/*force=*/true);
ASSERT_EQ(2ULL * kGiB, info.length);
}

// get info from mds success, return cached fileinfo
{
EXPECT_CALL(nameService_, GetFileInfo(_, _, _, _))
.WillOnce(Invoke([](::google::protobuf::RpcController* cntl,
const curve::mds::GetFileInfoRequest*,
curve::mds::GetFileInfoResponse* response,
google::protobuf::Closure* done) {
response->set_statuscode(
curve::mds::StatusCode::kFileNotExists);
done->Run();
}));

auto info = instance_->GetCurrentFileInfo(/*force=*/true);
ASSERT_EQ(2ULL * kGiB, info.length);
}
}

} // namespace client
} // namespace curve
11 changes: 11 additions & 0 deletions test/client/mock/mock_namespace_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ class MockNameService : public CurveFSService {
OpenFileResponse* response,
google::protobuf::Closure* done));

MOCK_METHOD4(CloseFile, void(google::protobuf::RpcController* cntl,
const CloseFileRequest* request,
CloseFileResponse* response,
google::protobuf::Closure* done));

MOCK_METHOD4(DeleteFile, void(google::protobuf::RpcController* cntl,
const DeleteFileRequest* request,
DeleteFileResponse* response,
Expand All @@ -64,6 +69,12 @@ class MockNameService : public CurveFSService {
const curve::mds::IncreaseFileEpochRequest* request,
curve::mds::IncreaseFileEpochResponse* response,
::google::protobuf::Closure* done));

MOCK_METHOD4(GetFileInfo,
void(::google::protobuf::RpcController* controller,
const ::curve::mds::GetFileInfoRequest* request,
::curve::mds::GetFileInfoResponse* response,
::google::protobuf::Closure* done));
};

} // namespace mds
Expand Down