forked from caoXF/curve
191 lines
6.6 KiB
C++
191 lines
6.6 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
|
|
* Date: Sun Dec 20 10:25:08 CST 2020
|
|
*/
|
|
|
|
#include <gflags/gflags.h>
|
|
#include <glog/logging.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <chrono> // NOLINT
|
|
#include <string>
|
|
#include <thread> // NOLINT
|
|
|
|
#include "test/client/mock/mock_mdsclient.h"
|
|
#include "test/client/mock/mock_meta_cache.h"
|
|
|
|
namespace curve {
|
|
namespace client {
|
|
|
|
using ::testing::AllOf;
|
|
using ::testing::Ge;
|
|
using ::testing::Le;
|
|
using ::testing::Matcher;
|
|
using ::testing::Return;
|
|
|
|
class IOTrackerTest : public ::testing::Test {
|
|
public:
|
|
void SetUp() override {
|
|
opt_.taskDelayMs = 100;
|
|
IOTracker::InitDiscardOption(opt_);
|
|
|
|
metric.reset(new DiscardMetric("IOTrackerTest"));
|
|
discardTaskManager_.reset(new DiscardTaskManager(metric.get()));
|
|
|
|
mockMDSClient_.reset(new MockMDSClient());
|
|
mockMetaCache_.reset(new MockMetaCache());
|
|
|
|
MetaCacheOption metaCacheOpt;
|
|
metaCacheOpt.discardGranularity = discardGranularity_;
|
|
mockMetaCache_->Init(metaCacheOpt, mockMDSClient_.get());
|
|
|
|
fileInfo_.fullPathName = "/IOTrackerTest";
|
|
fileInfo_.length = 100 * GiB;
|
|
fileInfo_.segmentsize = segmentSize_;
|
|
fileInfo_.chunksize = 16 * MiB;
|
|
|
|
mockMetaCache_->UpdateFileInfo(fileInfo_);
|
|
}
|
|
|
|
void TearDown() override {
|
|
discardTaskManager_->Stop();
|
|
}
|
|
|
|
protected:
|
|
DiscardOption opt_;
|
|
FInfo fileInfo_;
|
|
std::unique_ptr<DiscardMetric> metric;
|
|
std::unique_ptr<MockMetaCache> mockMetaCache_;
|
|
std::unique_ptr<MockMDSClient> mockMDSClient_;
|
|
std::unique_ptr<DiscardTaskManager> discardTaskManager_;
|
|
uint64_t segmentSize_ = 1 * GiB;
|
|
uint32_t discardGranularity_ = 4 * KiB;
|
|
};
|
|
|
|
TEST_F(IOTrackerTest, TestDiscardNotSatisfyOneSegment) {
|
|
IOTracker iotracker(nullptr, mockMetaCache_.get(), nullptr);
|
|
uint64_t offset = 50 * GiB;
|
|
uint32_t length = 512 * MiB;
|
|
|
|
EXPECT_CALL(*mockMDSClient_, DeAllocateSegment(_, _)).Times(0);
|
|
EXPECT_CALL(*mockMetaCache_, CleanChunksInSegment(_)).Times(0);
|
|
|
|
iotracker.StartDiscard(offset, length, mockMDSClient_.get(), &fileInfo_,
|
|
discardTaskManager_.get());
|
|
ASSERT_EQ(0, iotracker.Wait());
|
|
|
|
// check bitmap
|
|
Bitmap& bitmap = mockMetaCache_->GetFileSegment(50)->GetBitmap();
|
|
std::vector<curve::common::BitRange> clearRanges;
|
|
std::vector<curve::common::BitRange> setRanges;
|
|
bitmap.Divide(0, bitmap.Size(), &clearRanges, &setRanges);
|
|
ASSERT_EQ(1, clearRanges.size());
|
|
ASSERT_EQ(1, setRanges.size());
|
|
|
|
ASSERT_EQ(0, setRanges[0].beginIndex);
|
|
ASSERT_EQ(segmentSize_ / discardGranularity_ / 2 - 1,
|
|
setRanges[0].endIndex); // NOLINT
|
|
ASSERT_EQ(segmentSize_ / discardGranularity_ / 2,
|
|
clearRanges[0].beginIndex); // NOLINT
|
|
ASSERT_EQ(segmentSize_ / discardGranularity_ - 1, clearRanges[0].endIndex);
|
|
}
|
|
|
|
TEST_F(IOTrackerTest, TestDiscardOneSegment) {
|
|
IOTracker iotracker(nullptr, mockMetaCache_.get(), nullptr);
|
|
uint64_t offset = 50 * GiB;
|
|
uint32_t length = 1 * GiB;
|
|
|
|
EXPECT_CALL(*mockMDSClient_, DeAllocateSegment(_, 50 * GiB))
|
|
.WillOnce(Return(LIBCURVE_ERROR::OK));
|
|
EXPECT_CALL(*mockMetaCache_, CleanChunksInSegment(50)).Times(1);
|
|
|
|
iotracker.StartDiscard(offset, length, mockMDSClient_.get(), &fileInfo_,
|
|
discardTaskManager_.get());
|
|
ASSERT_EQ(0, iotracker.Wait());
|
|
|
|
// check bitmap
|
|
Bitmap& bitmap = mockMetaCache_->GetFileSegment(50)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap.NextClearBit(0));
|
|
|
|
std::this_thread::sleep_for(
|
|
std::chrono::milliseconds(5 * opt_.taskDelayMs));
|
|
|
|
// check bitmap after discard
|
|
bitmap = mockMetaCache_->GetFileSegment(50)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap.NextSetBit(0));
|
|
}
|
|
|
|
TEST_F(IOTrackerTest, TestDiscardMultiSegment) {
|
|
// discard three times
|
|
IOTracker iotracker1(nullptr, mockMetaCache_.get(), nullptr);
|
|
uint64_t offset1 = 50 * GiB;
|
|
uint32_t length1 = 512 * MiB;
|
|
|
|
IOTracker iotracker2(nullptr, mockMetaCache_.get(), nullptr);
|
|
uint64_t offset2 = 52 * GiB + 512 * MiB;
|
|
uint32_t length2 = 512 * MiB;
|
|
|
|
IOTracker iotracker3(nullptr, mockMetaCache_.get(), nullptr);
|
|
uint64_t offset3 = 50 * GiB + 512 * MiB;
|
|
uint32_t length3 = 2 * GiB;
|
|
|
|
Matcher<uint64_t> offsetRange = AllOf(Ge(50 * GiB), Le(52 * GiB));
|
|
EXPECT_CALL(*mockMDSClient_, DeAllocateSegment(_, offsetRange))
|
|
.Times(3)
|
|
.WillRepeatedly(Return(LIBCURVE_ERROR::OK));
|
|
|
|
Matcher<SegmentIndex> segmentIndexRange = AllOf(Ge(50), Le(52));
|
|
EXPECT_CALL(*mockMetaCache_, CleanChunksInSegment(segmentIndexRange))
|
|
.Times(3);
|
|
|
|
iotracker1.StartDiscard(offset1, length1, mockMDSClient_.get(), &fileInfo_,
|
|
discardTaskManager_.get());
|
|
ASSERT_EQ(0, iotracker1.Wait());
|
|
|
|
iotracker2.StartDiscard(offset2, length2, mockMDSClient_.get(), &fileInfo_,
|
|
discardTaskManager_.get());
|
|
ASSERT_EQ(0, iotracker2.Wait());
|
|
|
|
iotracker3.StartDiscard(offset3, length3, mockMDSClient_.get(), &fileInfo_,
|
|
discardTaskManager_.get());
|
|
ASSERT_EQ(0, iotracker3.Wait());
|
|
|
|
// check bitmap
|
|
Bitmap& bitmap1 = mockMetaCache_->GetFileSegment(50)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap1.NextClearBit(0));
|
|
Bitmap& bitmap2 = mockMetaCache_->GetFileSegment(51)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap2.NextClearBit(0));
|
|
Bitmap& bitmap3 = mockMetaCache_->GetFileSegment(52)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap3.NextClearBit(0));
|
|
|
|
std::this_thread::sleep_for(
|
|
std::chrono::milliseconds(5 * opt_.taskDelayMs));
|
|
|
|
// check bitmap after discard
|
|
bitmap1 = mockMetaCache_->GetFileSegment(50)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap1.NextSetBit(0));
|
|
bitmap2 = mockMetaCache_->GetFileSegment(51)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap2.NextSetBit(0));
|
|
bitmap3 = mockMetaCache_->GetFileSegment(52)->GetBitmap();
|
|
ASSERT_EQ(Bitmap::NO_POS, bitmap3.NextSetBit(0));
|
|
}
|
|
|
|
} // namespace client
|
|
} // namespace curve
|