forked from caoXF/curve
356 lines
11 KiB
C++
356 lines
11 KiB
C++
/*
|
|
* 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: Monday, 24th December 2018 10:41:03 am
|
|
* Author: tongguangxun
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <gmock/gmock.h>
|
|
#include <gflags/gflags.h>
|
|
#include <glog/logging.h>
|
|
#include <brpc/server.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
|
|
#include <mutex> // NOLINT
|
|
#include <chrono> // NOLINT
|
|
#include <atomic>
|
|
#include <functional>
|
|
#include <condition_variable> // NOLINT
|
|
#include <string>
|
|
|
|
#include "src/client/client_config.h"
|
|
#include "test/client/fake/fakeMDS.h"
|
|
#include "src/client/file_instance.h"
|
|
#include "src/client/iomanager4file.h"
|
|
#include "src/client/libcurve_file.h"
|
|
#include "test/client/fake/fakeChunkserver.h"
|
|
#include "test/integration/cluster_common/cluster.h"
|
|
#include "test/util/config_generator.h"
|
|
|
|
extern std::string mdsMetaServerAddr;
|
|
extern std::string configpath;
|
|
DECLARE_string(chunkserver_list);
|
|
|
|
namespace curve {
|
|
namespace client {
|
|
|
|
#define SLEEP_TIME_S 5
|
|
|
|
uint64_t ioSleepTime = 0;
|
|
|
|
bool sessionFlag = false;
|
|
std::mutex sessionMtx;
|
|
std::condition_variable sessionCV;
|
|
|
|
void sessioncallback(CurveAioContext* aioctx) {
|
|
uint64_t ioEndTime = TimeUtility::GetTimeofDayUs();
|
|
|
|
ASSERT_GT(ioEndTime - ioSleepTime, SLEEP_TIME_S * 1000000);
|
|
|
|
sessionFlag = true;
|
|
}
|
|
|
|
TEST(ClientSession, LeaseTaskTest) {
|
|
FLAGS_chunkserver_list =
|
|
"127.0.0.1:9176:0,127.0.0.1:9177:0,127.0.0.1:9178:0";
|
|
|
|
std::string filename = "/1";
|
|
|
|
/*** init mds service ***/
|
|
FakeMDS mds(filename);
|
|
mds.Initialize();
|
|
mds.StartService();
|
|
// 设置leaderid
|
|
curve::client::EndPoint ep;
|
|
butil::str2endpoint("127.0.0.1", 9176, &ep);
|
|
PeerId pd(ep);
|
|
mds.StartCliService(pd);
|
|
mds.CreateCopysetNode(true);
|
|
ClientConfig cc;
|
|
cc.Init(configpath.c_str());
|
|
|
|
FileInstance fileinstance;
|
|
|
|
UserInfo_t userinfo;
|
|
userinfo.owner = "userinfo";
|
|
|
|
std::shared_ptr<MDSClient> mdsclient = std::make_shared<MDSClient>();
|
|
mdsclient->Initialize(cc.GetFileServiceOption().metaServerOpt);
|
|
ASSERT_TRUE(fileinstance.Initialize(
|
|
filename, mdsclient, userinfo, OpenFlags{}, cc.GetFileServiceOption()));
|
|
|
|
brpc::Server server;
|
|
FakeMDSCurveFSService* curvefsservice = mds.GetMDSService();
|
|
|
|
// set openfile response
|
|
::curve::mds::OpenFileResponse openresponse;
|
|
curve::mds::FileInfo * finfo = new curve::mds::FileInfo;
|
|
::curve::mds::ProtoSession* se = new ::curve::mds::ProtoSession;
|
|
se->set_sessionid("1");
|
|
se->set_createtime(12345);
|
|
se->set_leasetime(100000);
|
|
se->set_sessionstatus(::curve::mds::SessionStatus::kSessionOK);
|
|
|
|
finfo->set_filename(filename);
|
|
finfo->set_id(1);
|
|
openresponse.set_statuscode(::curve::mds::StatusCode::kOK);
|
|
openresponse.set_allocated_protosession(se);
|
|
openresponse.set_allocated_fileinfo(finfo);
|
|
|
|
FakeReturn* openfakeret
|
|
= new FakeReturn(nullptr, static_cast<void*>(&openresponse));
|
|
curvefsservice->SetOpenFile(openfakeret);
|
|
|
|
// 2. set refresh response
|
|
std::mutex mtx;
|
|
std::condition_variable refreshcv;
|
|
auto refresht = [&mtx, &refreshcv]() {
|
|
LOG(INFO) << "get refresh session request!";
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.notify_one();
|
|
};
|
|
curve::mds::FileInfo * info = new curve::mds::FileInfo;
|
|
info->set_filename(filename);
|
|
info->set_seqnum(2);
|
|
info->set_id(1);
|
|
info->set_parentid(0);
|
|
info->set_filetype(curve::mds::FileType::INODE_PAGEFILE);
|
|
info->set_chunksize(4 * 1024 * 1024);
|
|
info->set_length(4 * 1024 * 1024 * 1024ul);
|
|
info->set_ctime(12345678);
|
|
|
|
::curve::mds::ReFreshSessionResponse refreshresp;
|
|
refreshresp.set_statuscode(::curve::mds::StatusCode::kOK);
|
|
refreshresp.set_sessionid("1234");
|
|
refreshresp.set_allocated_fileinfo(info);
|
|
FakeReturn* refreshfakeret
|
|
= new FakeReturn(nullptr, static_cast<void*>(&refreshresp));
|
|
curvefsservice->SetRefreshSession(refreshfakeret, refresht);
|
|
|
|
// 3. open the file
|
|
int openret = fileinstance.Open();
|
|
ASSERT_EQ(openret, LIBCURVE_ERROR::OK);
|
|
|
|
// 4. wait for refresh
|
|
for (int i = 0; i < 4; i++) {
|
|
{
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.wait(lk);
|
|
}
|
|
}
|
|
|
|
curve::client::LeaseExecutor* lease = fileinstance.GetLeaseExecutor();
|
|
|
|
// 5. set refresh AuthFail
|
|
refreshresp.set_statuscode(::curve::mds::kOwnerAuthFail);
|
|
FakeReturn* refreshFakeRetAuthFail =
|
|
new FakeReturn(nullptr, static_cast<void*>(&refreshresp));
|
|
curvefsservice->SetRefreshSession(refreshFakeRetAuthFail, refresht);
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
{
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.wait(lk);
|
|
}
|
|
}
|
|
|
|
char* buf3 = new char[8 * 1024];
|
|
CurveAioContext aioctx2;
|
|
aioctx2.offset = 0;
|
|
aioctx2.length = 4 * 1024;
|
|
aioctx2.ret = LIBCURVE_ERROR::OK;
|
|
aioctx2.cb = sessioncallback;
|
|
aioctx2.buf = buf3;
|
|
|
|
ioSleepTime = TimeUtility::GetTimeofDayUs();
|
|
|
|
ASSERT_EQ(0, fileinstance.AioRead(&aioctx2, UserDataType::RawBuffer));
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(SLEEP_TIME_S));
|
|
|
|
// 6. set refresh success
|
|
refreshresp.set_statuscode(::curve::mds::StatusCode::kOK);
|
|
FakeReturn* refreshfakeretOK2 =
|
|
new FakeReturn(nullptr, static_cast<void*>(&refreshresp));
|
|
curvefsservice->SetRefreshSession(refreshfakeretOK2, refresht);
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
{
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.wait(lk);
|
|
}
|
|
}
|
|
ASSERT_TRUE(lease->LeaseValid());
|
|
|
|
// 7. set refresh kFileNotExists
|
|
refreshresp.set_statuscode(::curve::mds::kFileNotExists);
|
|
FakeReturn* refreshFakeRetFileNotExists =
|
|
new FakeReturn(nullptr, static_cast<void*>(&refreshresp));
|
|
curvefsservice->SetRefreshSession(refreshFakeRetFileNotExists, refresht);
|
|
|
|
{
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.wait(lk);
|
|
}
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
lease = fileinstance.GetLeaseExecutor();
|
|
ASSERT_FALSE(lease->LeaseValid());
|
|
|
|
// 8. set refresh success
|
|
refreshresp.set_statuscode(::curve::mds::StatusCode::kOK);
|
|
FakeReturn* refreshfakeretOK3 =
|
|
new FakeReturn(nullptr, static_cast<void*>(&refreshresp));
|
|
curvefsservice->SetRefreshSession(refreshfakeretOK3, refresht);
|
|
fileinstance.GetLeaseExecutor()->ResetRefreshSessionTask();
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
{
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.wait(lk);
|
|
}
|
|
}
|
|
ASSERT_TRUE(lease->LeaseValid());
|
|
|
|
{
|
|
std::unique_lock<std::mutex> lk(sessionMtx);
|
|
sessionCV.wait(lk, [&]() { return sessionFlag; });
|
|
}
|
|
|
|
// 9. set inode id changed
|
|
refreshresp.set_allocated_fileinfo(nullptr); // clear existing file info
|
|
|
|
curve::mds::FileInfo* newFileInfo = new curve::mds::FileInfo;
|
|
newFileInfo->set_filename(filename);
|
|
newFileInfo->set_seqnum(2);
|
|
newFileInfo->set_id(100);
|
|
newFileInfo->set_parentid(0);
|
|
newFileInfo->set_filetype(curve::mds::FileType::INODE_PAGEFILE);
|
|
newFileInfo->set_chunksize(4 * 1024 * 1024);
|
|
newFileInfo->set_length(4 * 1024 * 1024 * 1024ul);
|
|
newFileInfo->set_ctime(12345678);
|
|
|
|
refreshresp.set_allocated_fileinfo(newFileInfo);
|
|
refreshresp.set_statuscode(::curve::mds::StatusCode::kOK);
|
|
|
|
FakeReturn* refreshFakeRetWithNewInodeId = new FakeReturn(
|
|
nullptr, static_cast<void*>(&refreshresp));
|
|
curvefsservice->SetRefreshSession(
|
|
refreshFakeRetWithNewInodeId, refresht);
|
|
|
|
{
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.wait(lk);
|
|
}
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
lease = fileinstance.GetLeaseExecutor();
|
|
ASSERT_FALSE(lease->LeaseValid());
|
|
|
|
// 10. set refresh success
|
|
refreshresp.set_allocated_fileinfo(nullptr); // clear existing file info
|
|
|
|
newFileInfo = new curve::mds::FileInfo;
|
|
newFileInfo->set_filename(filename);
|
|
newFileInfo->set_seqnum(2);
|
|
newFileInfo->set_id(1);
|
|
newFileInfo->set_parentid(0);
|
|
newFileInfo->set_filetype(curve::mds::FileType::INODE_PAGEFILE);
|
|
newFileInfo->set_chunksize(4 * 1024 * 1024);
|
|
newFileInfo->set_length(4 * 1024 * 1024 * 1024ul);
|
|
newFileInfo->set_ctime(12345678);
|
|
|
|
refreshresp.set_allocated_fileinfo(newFileInfo);
|
|
refreshresp.set_statuscode(::curve::mds::StatusCode::kOK);
|
|
|
|
FakeReturn* refreshfakeretOK4 =
|
|
new FakeReturn(nullptr, static_cast<void*>(&refreshresp));
|
|
curvefsservice->SetRefreshSession(refreshfakeretOK4, refresht);
|
|
fileinstance.GetLeaseExecutor()->ResetRefreshSessionTask();
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
{
|
|
std::unique_lock<std::mutex> lk(mtx);
|
|
refreshcv.wait(lk);
|
|
}
|
|
}
|
|
ASSERT_TRUE(lease->LeaseValid());
|
|
|
|
std::unique_lock<std::mutex> lk(sessionMtx);
|
|
sessionCV.wait(lk, [&]() { return sessionFlag; });
|
|
|
|
// 11. set fake close return
|
|
::curve::mds::CloseFileResponse closeresp;
|
|
closeresp.set_statuscode(::curve::mds::StatusCode::kOK);
|
|
FakeReturn* closefileret
|
|
= new FakeReturn(nullptr, static_cast<void*>(&closeresp));
|
|
curvefsservice->SetCloseFile(closefileret);
|
|
|
|
LOG(INFO) << "uninit fileinstance";
|
|
fileinstance.Close();
|
|
fileinstance.UnInitialize();
|
|
|
|
LOG(INFO) << "stop server";
|
|
server.Stop(0);
|
|
server.Join();
|
|
|
|
LOG(INFO) << "uninit mds";
|
|
mds.UnInitialize();
|
|
}
|
|
|
|
} // namespace client
|
|
} // namespace curve
|
|
|
|
std::string mdsMetaServerAddr = "127.0.0.1:9101"; // NOLINT
|
|
uint32_t segment_size = 1 * 1024 * 1024 * 1024ul; // NOLINT
|
|
uint32_t chunk_size = 4 * 1024 * 1024; // NOLINT
|
|
std::string configpath = "./test/client/configs/client_session.conf"; // NOLINT
|
|
|
|
const std::vector<std::string> clientConf {
|
|
std::string("mds.listen.addr=127.0.0.1:9101,127.0.0.1:9102"),
|
|
std::string("global.logPath=./runlog/"),
|
|
std::string("chunkserver.rpcTimeoutMS=1000"),
|
|
std::string("chunkserver.opMaxRetry=3"),
|
|
std::string("metacache.getLeaderRetry=3"),
|
|
std::string("metacache.getLeaderTimeOutMS=1000"),
|
|
std::string("global.fileMaxInFlightRPCNum=2048"),
|
|
std::string("metacache.rpcRetryIntervalUS=500"),
|
|
std::string("mds.rpcRetryIntervalUS=500"),
|
|
std::string("schedule.threadpoolSize=2"),
|
|
std::string("mds.maxRetryMS=5000")
|
|
};
|
|
|
|
int main(int argc, char ** argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
::testing::InitGoogleMock(&argc, argv);
|
|
google::ParseCommandLineFlags(&argc, &argv, false);
|
|
|
|
curve::CurveCluster* cluster = new curve::CurveCluster();
|
|
|
|
cluster->PrepareConfig<curve::ClientConfigGenerator>(
|
|
configpath, clientConf);
|
|
|
|
int ret = RUN_ALL_TESTS();
|
|
return ret;
|
|
}
|