This is an automated email from the ASF dual-hosted git repository.
airborne pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new c5ee28b0e90 [feat](test) add ut case for inverted index file writer
(#44213)
c5ee28b0e90 is described below
commit c5ee28b0e90d39cd6270e610f5fd158f99ca3604
Author: airborne12 <[email protected]>
AuthorDate: Tue Nov 19 10:28:34 2024 +0800
[feat](test) add ut case for inverted index file writer (#44213)
### What problem does this PR solve?
Related PR: #44084
Problem Summary:
add UT case for #44084 fix
---
.../rowset/segment_v2/inverted_index_file_writer.h | 4 +-
.../segment_v2/inverted_index_fs_directory.cpp | 33 ---
.../segment_v2/inverted_index_fs_directory.h | 33 +++
.../segment_v2/inverted_index_file_writer_test.cpp | 233 ++++++++++++++++++++-
4 files changed, 267 insertions(+), 36 deletions(-)
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_file_writer.h
b/be/src/olap/rowset/segment_v2/inverted_index_file_writer.h
index 3a2fcc1e6ac..ddb22975d68 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_file_writer.h
+++ b/be/src/olap/rowset/segment_v2/inverted_index_file_writer.h
@@ -112,14 +112,14 @@ private:
// Helper functions specific to write_v1
std::pair<int64_t, int32_t> calculate_header_length(const
std::vector<FileInfo>& sorted_files,
lucene::store::Directory* directory);
- std::pair<lucene::store::Directory*,
std::unique_ptr<lucene::store::IndexOutput>>
+ virtual std::pair<lucene::store::Directory*,
std::unique_ptr<lucene::store::IndexOutput>>
create_output_stream_v1(int64_t index_id, const std::string& index_suffix);
virtual void write_header_and_data_v1(lucene::store::IndexOutput* output,
const std::vector<FileInfo>&
sorted_files,
lucene::store::Directory* directory,
int64_t header_length, int32_t
header_file_count);
// Helper functions specific to write_v2
- std::pair<lucene::store::Directory*,
std::unique_ptr<lucene::store::IndexOutput>>
+ virtual std::pair<lucene::store::Directory*,
std::unique_ptr<lucene::store::IndexOutput>>
create_output_stream_v2();
void write_version_and_indices_count(lucene::store::IndexOutput* output);
struct FileMetadata {
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.cpp
b/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.cpp
index 29caf29936d..fe0a81c41a6 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.cpp
+++ b/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.cpp
@@ -83,39 +83,6 @@ namespace doris::segment_v2 {
const char* const DorisFSDirectory::WRITE_LOCK_FILE = "write.lock";
-class DorisFSDirectory::FSIndexOutput : public
lucene::store::BufferedIndexOutput {
-protected:
- void flushBuffer(const uint8_t* b, const int32_t size) override;
-
-public:
- FSIndexOutput() = default;
- void init(const io::FileSystemSPtr& fs, const char* path);
- ~FSIndexOutput() override;
- void close() override;
- int64_t length() const override;
-
- void set_file_writer_opts(const io::FileWriterOptions& opts) { _opts =
opts; }
-
-private:
- io::FileWriterPtr _writer;
- io::FileWriterOptions _opts;
-};
-
-class DorisFSDirectory::FSIndexOutputV2 : public
lucene::store::BufferedIndexOutput {
-private:
- io::FileWriter* _index_v2_file_writer = nullptr;
-
-protected:
- void flushBuffer(const uint8_t* b, const int32_t size) override;
-
-public:
- FSIndexOutputV2() = default;
- void init(io::FileWriter* file_writer);
- ~FSIndexOutputV2() override;
- void close() override;
- int64_t length() const override;
-};
-
bool DorisFSDirectory::FSIndexInput::open(const io::FileSystemSPtr& fs, const
char* path,
IndexInput*& ret, CLuceneError&
error,
int32_t buffer_size, int64_t
file_size) {
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.h
b/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.h
index fd92873c970..dde436054cd 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.h
+++ b/be/src/olap/rowset/segment_v2/inverted_index_fs_directory.h
@@ -210,6 +210,39 @@ protected:
void readInternal(uint8_t* b, const int32_t len) override;
};
+class DorisFSDirectory::FSIndexOutput : public
lucene::store::BufferedIndexOutput {
+protected:
+ void flushBuffer(const uint8_t* b, const int32_t size) override;
+
+public:
+ FSIndexOutput() = default;
+ void init(const io::FileSystemSPtr& fs, const char* path);
+ ~FSIndexOutput() override;
+ void close() override;
+ int64_t length() const override;
+
+ void set_file_writer_opts(const io::FileWriterOptions& opts) { _opts =
opts; }
+
+private:
+ io::FileWriterPtr _writer;
+ io::FileWriterOptions _opts;
+};
+
+class DorisFSDirectory::FSIndexOutputV2 : public
lucene::store::BufferedIndexOutput {
+private:
+ io::FileWriter* _index_v2_file_writer = nullptr;
+
+protected:
+ void flushBuffer(const uint8_t* b, const int32_t size) override;
+
+public:
+ FSIndexOutputV2() = default;
+ void init(io::FileWriter* file_writer);
+ ~FSIndexOutputV2() override;
+ void close() override;
+ int64_t length() const override;
+};
+
/**
* Factory function to create DorisFSDirectory
*/
diff --git a/be/test/olap/rowset/segment_v2/inverted_index_file_writer_test.cpp
b/be/test/olap/rowset/segment_v2/inverted_index_file_writer_test.cpp
index dd3b4195c14..460b99a0ce7 100644
--- a/be/test/olap/rowset/segment_v2/inverted_index_file_writer_test.cpp
+++ b/be/test/olap/rowset/segment_v2/inverted_index_file_writer_test.cpp
@@ -511,5 +511,236 @@ TEST_F(InvertedIndexFileWriterTest,
WriteV2ExceptionHandlingTest) {
ASSERT_EQ(status.code(), ErrorCode::INVERTED_INDEX_CLUCENE_ERROR);
}
+class InvertedIndexFileWriterMockCreateOutputStreamV2 : public
InvertedIndexFileWriter {
+public:
+ InvertedIndexFileWriterMockCreateOutputStreamV2(const io::FileSystemSPtr&
fs,
+ const std::string&
index_path_prefix,
+ const std::string&
rowset_id,
+ int32_t segment_id,
+
InvertedIndexStorageFormatPB storage_format)
+ : InvertedIndexFileWriter(fs, index_path_prefix, rowset_id,
segment_id,
+ storage_format) {}
+
+ MOCK_METHOD((std::pair<lucene::store::Directory*,
std::unique_ptr<lucene::store::IndexOutput>>),
+ create_output_stream_v2, (), (override));
+};
+
+class InvertedIndexFileWriterMockCreateOutputStreamV1 : public
InvertedIndexFileWriter {
+public:
+ InvertedIndexFileWriterMockCreateOutputStreamV1(const io::FileSystemSPtr&
fs,
+ const std::string&
index_path_prefix,
+ const std::string&
rowset_id,
+ int32_t segment_id,
+
InvertedIndexStorageFormatPB storage_format)
+ : InvertedIndexFileWriter(fs, index_path_prefix, rowset_id,
segment_id,
+ storage_format) {}
+
+ MOCK_METHOD((std::pair<lucene::store::Directory*,
std::unique_ptr<lucene::store::IndexOutput>>),
+ create_output_stream_v1, (int64_t index_id, const std::string&
index_suffix),
+ (override));
+};
+
+class MockDorisFSDirectoryOutput : public DorisFSDirectory {
+public:
+ //MOCK_METHOD(lucene::store::IndexOutput*, createOutput, (const char*
name), (override));
+ //MOCK_METHOD(int64_t, fileLength, (const char* name), (const, override));
+ MOCK_METHOD(void, close, (), (override));
+ //MOCK_METHOD(const char*, getObjectName, (), (const, override));
+};
+
+class MockFSIndexOutputV2 : public DorisFSDirectory::FSIndexOutputV2 {
+public:
+ //MOCK_METHOD(void, close, (), (override));
+ MOCK_METHOD(void, flushBuffer, (const uint8_t* b, const int32_t size),
(override));
+};
+
+class MockFSIndexOutputV1 : public DorisFSDirectory::FSIndexOutput {
+public:
+ //MOCK_METHOD(void, close, (), (override));
+ MOCK_METHOD(void, flushBuffer, (const uint8_t* b, const int32_t size),
(override));
+};
+
+TEST_F(InvertedIndexFileWriterTest, WriteV1OutputTest) {
+ int64_t index_id = 1;
+ std::string index_suffix = "suffix1";
+ InvertedIndexFileWriterMockCreateOutputStreamV1 writer_mock(
+ _fs, _index_path_prefix, _rowset_id, _seg_id,
InvertedIndexStorageFormatPB::V1);
+ io::Path
cfs_path(InvertedIndexDescriptor::get_index_file_path_v1(_index_path_prefix,
index_id,
+
index_suffix));
+ auto idx_path = cfs_path.parent_path();
+ std::string idx_name = cfs_path.filename();
+
+ auto* out_dir = DorisFSDirectoryFactory::getDirectory(_fs,
idx_path.c_str());
+ auto* mock_output_v1 = new MockFSIndexOutputV1();
+ EXPECT_CALL(*mock_output_v1, flushBuffer(::testing::_, ::testing::_))
+ .WillOnce(::testing::Throw(CLuceneError(CL_ERR_IO, "Simulated
exception", false)));
+ auto compound_file_output =
std::unique_ptr<DorisFSDirectory::FSIndexOutput>(mock_output_v1);
+ compound_file_output->init(_fs, cfs_path.c_str());
+
+ EXPECT_CALL(writer_mock, create_output_stream_v1(index_id, index_suffix))
+ .WillOnce(::testing::Invoke(
+ [&]() -> std::pair<lucene::store::Directory*,
+
std::unique_ptr<lucene::store::IndexOutput>> {
+ return std::make_pair(out_dir,
std::move(compound_file_output));
+ }));
+
+ auto index_meta = create_mock_tablet_index(index_id, index_suffix);
+ ASSERT_NE(index_meta, nullptr);
+
+ auto open_result = writer_mock.open(index_meta.get());
+ ASSERT_TRUE(open_result.has_value());
+ auto dir = open_result.value();
+
+ auto out_file =
std::unique_ptr<lucene::store::IndexOutput>(dir->createOutput("test_file"));
+ out_file->writeString("test data");
+ out_file->close();
+ dir->close();
+
+ Status status = writer_mock.close();
+ ASSERT_FALSE(status.ok());
+ ASSERT_EQ(status.code(), ErrorCode::INVERTED_INDEX_CLUCENE_ERROR);
+}
+
+TEST_F(InvertedIndexFileWriterTest, WriteV2OutputTest) {
+ io::FileWriterPtr file_writer;
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(_index_path_prefix);
+ io::FileWriterOptions opts;
+ Status st = _fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(st.ok());
+
+ InvertedIndexFileWriterMockCreateOutputStreamV2 writer_mock(
+ _fs, _index_path_prefix, _rowset_id, _seg_id,
InvertedIndexStorageFormatPB::V2);
+ auto* out_dir = DorisFSDirectoryFactory::getDirectory(_fs,
index_path.c_str());
+ auto* mock_output_v2 = new MockFSIndexOutputV2();
+ EXPECT_CALL(*mock_output_v2, flushBuffer(::testing::_, ::testing::_))
+ .WillOnce(::testing::Throw(CLuceneError(CL_ERR_IO, "Simulated
exception", false)));
+ auto compound_file_output =
std::unique_ptr<DorisFSDirectory::FSIndexOutputV2>(mock_output_v2);
+ compound_file_output->init(file_writer.get());
+
+ EXPECT_CALL(writer_mock, create_output_stream_v2())
+ .WillOnce(::testing::Invoke(
+ [&]() -> std::pair<lucene::store::Directory*,
+
std::unique_ptr<lucene::store::IndexOutput>> {
+ return std::make_pair(out_dir,
std::move(compound_file_output));
+ }));
+
+ int64_t index_id = 1;
+ std::string index_suffix = "suffix1";
+ auto index_meta = create_mock_tablet_index(index_id, index_suffix);
+ ASSERT_NE(index_meta, nullptr);
+
+ auto open_result = writer_mock.open(index_meta.get());
+ ASSERT_TRUE(open_result.has_value());
+ auto dir = open_result.value();
+
+ auto out_file =
std::unique_ptr<lucene::store::IndexOutput>(dir->createOutput("test_file"));
+ out_file->writeString("test data");
+ out_file->close();
+ dir->close();
+
+ Status status = writer_mock.close();
+ ASSERT_FALSE(status.ok());
+ ASSERT_EQ(status.code(), ErrorCode::INVERTED_INDEX_CLUCENE_ERROR);
+}
+
+class MockFSIndexOutputCloseV2 : public DorisFSDirectory::FSIndexOutputV2 {
+public:
+ MOCK_METHOD(void, close, (), (override));
+ void base_close() {
DorisFSDirectory::FSIndexOutputV2::BufferedIndexOutput::close(); }
+};
+
+class MockFSIndexOutputCloseV1 : public DorisFSDirectory::FSIndexOutput {
+public:
+ MOCK_METHOD(void, close, (), (override));
+ void base_close() {
DorisFSDirectory::FSIndexOutput::BufferedIndexOutput::close(); }
+};
+
+TEST_F(InvertedIndexFileWriterTest, WriteV2OutputCloseErrorTest) {
+ io::FileWriterPtr file_writer;
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(_index_path_prefix);
+ io::FileWriterOptions opts;
+ Status st = _fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(st.ok());
+
+ InvertedIndexFileWriterMockCreateOutputStreamV2 writer_mock(
+ _fs, _index_path_prefix, _rowset_id, _seg_id,
InvertedIndexStorageFormatPB::V2);
+ auto* out_dir = DorisFSDirectoryFactory::getDirectory(_fs,
index_path.c_str());
+ auto* mock_output_v2 = new MockFSIndexOutputCloseV2();
+ EXPECT_CALL(*mock_output_v2, close()).WillOnce(::testing::Invoke([&]() {
+ mock_output_v2->base_close();
+ throw CLuceneError(CL_ERR_IO, "Simulated exception", false);
+ }));
+ auto compound_file_output =
std::unique_ptr<DorisFSDirectory::FSIndexOutputV2>(mock_output_v2);
+ compound_file_output->init(file_writer.get());
+
+ EXPECT_CALL(writer_mock, create_output_stream_v2())
+ .WillOnce(::testing::Invoke(
+ [&]() -> std::pair<lucene::store::Directory*,
+
std::unique_ptr<lucene::store::IndexOutput>> {
+ return std::make_pair(out_dir,
std::move(compound_file_output));
+ }));
+
+ int64_t index_id = 1;
+ std::string index_suffix = "suffix1";
+ auto index_meta = create_mock_tablet_index(index_id, index_suffix);
+ ASSERT_NE(index_meta, nullptr);
+
+ auto open_result = writer_mock.open(index_meta.get());
+ ASSERT_TRUE(open_result.has_value());
+ auto dir = open_result.value();
+
+ auto out_file =
std::unique_ptr<lucene::store::IndexOutput>(dir->createOutput("test_file"));
+ out_file->writeString("test data");
+ out_file->close();
+ dir->close();
+
+ Status status = writer_mock.close();
+ ASSERT_FALSE(status.ok());
+ ASSERT_EQ(status.code(), ErrorCode::INVERTED_INDEX_CLUCENE_ERROR);
+}
+
+TEST_F(InvertedIndexFileWriterTest, WriteV1OutputCloseErrorTest) {
+ int64_t index_id = 1;
+ std::string index_suffix = "suffix1";
+ InvertedIndexFileWriterMockCreateOutputStreamV1 writer_mock(
+ _fs, _index_path_prefix, _rowset_id, _seg_id,
InvertedIndexStorageFormatPB::V1);
+ io::Path
cfs_path(InvertedIndexDescriptor::get_index_file_path_v1(_index_path_prefix,
index_id,
+
index_suffix));
+ auto idx_path = cfs_path.parent_path();
+ std::string idx_name = cfs_path.filename();
+
+ auto* out_dir = DorisFSDirectoryFactory::getDirectory(_fs,
idx_path.c_str());
+ auto* mock_output_v1 = new MockFSIndexOutputCloseV1();
+ EXPECT_CALL(*mock_output_v1, close()).WillOnce(::testing::Invoke([&]() {
+ mock_output_v1->base_close();
+ throw CLuceneError(CL_ERR_IO, "Simulated exception", false);
+ }));
+ auto compound_file_output =
std::unique_ptr<DorisFSDirectory::FSIndexOutput>(mock_output_v1);
+ compound_file_output->init(_fs, cfs_path.c_str());
+
+ EXPECT_CALL(writer_mock, create_output_stream_v1(index_id, index_suffix))
+ .WillOnce(::testing::Invoke(
+ [&]() -> std::pair<lucene::store::Directory*,
+
std::unique_ptr<lucene::store::IndexOutput>> {
+ return std::make_pair(out_dir,
std::move(compound_file_output));
+ }));
+
+ auto index_meta = create_mock_tablet_index(index_id, index_suffix);
+ ASSERT_NE(index_meta, nullptr);
+
+ auto open_result = writer_mock.open(index_meta.get());
+ ASSERT_TRUE(open_result.has_value());
+ auto dir = open_result.value();
+
+ auto out_file =
std::unique_ptr<lucene::store::IndexOutput>(dir->createOutput("test_file"));
+ out_file->writeString("test data");
+ out_file->close();
+ dir->close();
+
+ Status status = writer_mock.close();
+ ASSERT_FALSE(status.ok());
+ ASSERT_EQ(status.code(), ErrorCode::INVERTED_INDEX_CLUCENE_ERROR);
+}
+
} // namespace segment_v2
-} // namespace doris
+} // namespace doris
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]