Skip to content

Commit a61e142

Browse files
author
shuxu.li
committed
feat: RegisterTable support for InMemoryCatalog
1 parent f39c16d commit a61e142

File tree

2 files changed

+73
-49
lines changed

2 files changed

+73
-49
lines changed

test/in_memory_catalog_test.cc

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "iceberg/catalog/in_memory_catalog.h"
2121

22+
#include <filesystem>
23+
2224
#include <arrow/filesystem/localfs.h>
2325
#include <gmock/gmock.h>
2426
#include <gtest/gtest.h>
@@ -27,17 +29,13 @@
2729
#include "iceberg/table.h"
2830
#include "iceberg/table_metadata.h"
2931
#include "matchers.h"
30-
#include "temp_file_test_base.h"
3132
#include "test_common.h"
3233

3334
namespace iceberg {
3435

3536
class InMemoryCatalogTest : public ::testing::Test {
3637
protected:
3738
void SetUp() override {
38-
// generate a unique temporary file path for the test
39-
temp_filepath_ = GenerateUniqueTempFilePathWithSuffix(".metadata.json");
40-
4139
file_io_ = std::make_shared<iceberg::arrow::ArrowFileSystemFileIO>(
4240
std::make_shared<::arrow::fs::LocalFileSystem>());
4341
std::unordered_map<std::string, std::string> properties = {{"prop1", "val1"}};
@@ -47,14 +45,38 @@ class InMemoryCatalogTest : public ::testing::Test {
4745

4846
void TearDown() override {
4947
// Clean up the temporary files created for the table metadata
48+
for (const auto& path : created_temp_paths_) {
49+
std::error_code ec;
50+
if (std::filesystem::is_directory(path, ec)) {
51+
std::filesystem::remove_all(path, ec);
52+
} else {
53+
std::filesystem::remove(path, ec);
54+
}
55+
}
56+
}
57+
58+
std::string GenerateTestTableLocation(std::string table_name) {
59+
std::filesystem::path temp_dir = std::filesystem::temp_directory_path();
60+
const auto info = ::testing::UnitTest::GetInstance()->current_test_info();
61+
auto table_location = std::format("{}iceberg_test_{}_{}/{}/", temp_dir.string(),
62+
info->test_suite_name(), info->name(), table_name);
63+
// generate a unique directory for the table
5064
std::error_code ec;
51-
std::filesystem::remove_all(temp_filepath_, ec);
65+
std::filesystem::create_directories(table_location, ec);
66+
if (ec) {
67+
throw std::runtime_error(
68+
std::format("Failed to create temporary directory: {}, error message: {}",
69+
table_location, ec.message()));
70+
}
71+
72+
created_temp_paths_.push_back(table_location);
73+
return table_location;
5274
}
5375

54-
// Used to generate a unique temporary metadata path for the test table
55-
std::string temp_filepath_;
5676
std::shared_ptr<FileIO> file_io_;
5777
std::shared_ptr<InMemoryCatalog> catalog_;
78+
// Used to store temporary paths created during the test
79+
std::vector<std::string> created_temp_paths_;
5880
};
5981

6082
TEST_F(InMemoryCatalogTest, CatalogName) {
@@ -82,10 +104,12 @@ TEST_F(InMemoryCatalogTest, RegisterTable) {
82104
std::unique_ptr<TableMetadata> metadata;
83105
ASSERT_NO_FATAL_FAILURE(ReadTableMetadata("TableMetadataV2Valid.json", &metadata));
84106

85-
auto status = TableMetadataUtil::Write(*file_io_, temp_filepath_, *metadata);
107+
auto table_location = GenerateTestTableLocation(tableIdent.name);
108+
auto metadata_location = std::format("{}v1.metadata.json", table_location);
109+
auto status = TableMetadataUtil::Write(*file_io_, metadata_location, *metadata);
86110
EXPECT_THAT(status, IsOk());
87111

88-
auto table = catalog_->RegisterTable(tableIdent, temp_filepath_);
112+
auto table = catalog_->RegisterTable(tableIdent, metadata_location);
89113
EXPECT_THAT(table, IsOk());
90114
ASSERT_EQ(table.value()->name().name, "t1");
91115
ASSERT_EQ(table.value()->location(), "s3://bucket/test/location");

test/temp_file_test_base.h

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -31,46 +31,6 @@
3131

3232
namespace iceberg {
3333

34-
/// \brief Get the test name for inclusion in the filename
35-
inline std::string TestInfo() {
36-
if (const auto info = ::testing::UnitTest::GetInstance()->current_test_info(); info) {
37-
return std::format("{}_{}", info->test_suite_name(), info->name());
38-
}
39-
return "unknown_test";
40-
}
41-
42-
/// \brief Helper to generate a random alphanumeric string for unique filenames
43-
inline std::string GenerateRandomString(size_t length) {
44-
const std::string_view chars =
45-
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
46-
std::random_device rd;
47-
std::mt19937 gen(rd());
48-
std::uniform_int_distribution<> dist(0, static_cast<int>(chars.size() - 1));
49-
50-
std::string result;
51-
result.reserve(length);
52-
for (size_t i = 0; i < length; ++i) {
53-
result += chars[dist(gen)];
54-
}
55-
return result;
56-
}
57-
58-
/// \brief Generates a unique temporary filepath that works across platforms
59-
inline std::string GenerateUniqueTempFilePath() {
60-
std::filesystem::path temp_dir = std::filesystem::temp_directory_path();
61-
std::string file_name =
62-
std::format("iceberg_test_{}_{}.tmp", TestInfo(), GenerateRandomString(8));
63-
return (temp_dir / file_name).string();
64-
}
65-
66-
/// \brief Create a temporary filepath with the specified suffix/extension
67-
inline std::string GenerateUniqueTempFilePathWithSuffix(const std::string& suffix) {
68-
std::filesystem::path temp_dir = std::filesystem::temp_directory_path();
69-
std::string file_name =
70-
std::format("iceberg_test_{}_{}{}", TestInfo(), GenerateRandomString(8), suffix);
71-
return (temp_dir / file_name).string();
72-
}
73-
7434
/// A base class for tests that need to create and manage temporary files.
7535
/// Provides utilities for creating platform-independent temporary files
7636
/// and ensures proper cleanup after tests run.
@@ -123,6 +83,46 @@ class TempFileTestBase : public ::testing::Test {
12383
}
12484
}
12585

86+
/// \brief Generates a unique temporary filepath that works across platforms
87+
std::string GenerateUniqueTempFilePath() const {
88+
std::filesystem::path temp_dir = std::filesystem::temp_directory_path();
89+
std::string file_name =
90+
std::format("iceberg_test_{}_{}.tmp", TestInfo(), GenerateRandomString(8));
91+
return (temp_dir / file_name).string();
92+
}
93+
94+
/// \brief Create a temporary filepath with the specified suffix/extension
95+
std::string GenerateUniqueTempFilePathWithSuffix(const std::string& suffix) {
96+
std::filesystem::path temp_dir = std::filesystem::temp_directory_path();
97+
std::string file_name =
98+
std::format("iceberg_test_{}_{}{}", TestInfo(), GenerateRandomString(8), suffix);
99+
return (temp_dir / file_name).string();
100+
}
101+
102+
/// \brief Helper to generate a random alphanumeric string for unique filenames
103+
std::string GenerateRandomString(size_t length) const {
104+
const std::string_view chars =
105+
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
106+
std::random_device rd;
107+
std::mt19937 gen(rd());
108+
std::uniform_int_distribution<> dist(0, static_cast<int>(chars.size() - 1));
109+
110+
std::string result;
111+
result.reserve(length);
112+
for (size_t i = 0; i < length; ++i) {
113+
result += chars[dist(gen)];
114+
}
115+
return result;
116+
}
117+
118+
/// \brief Get the test name for inclusion in the filename
119+
std::string TestInfo() const {
120+
if (const auto info = ::testing::UnitTest::GetInstance()->current_test_info(); info) {
121+
return std::format("{}_{}", info->test_suite_name(), info->name());
122+
}
123+
return "unknown_test";
124+
}
125+
126126
/// \brief Creates a new temporary filepath and registers it for cleanup
127127
std::string CreateNewTempFilePath() {
128128
std::string filepath = GenerateUniqueTempFilePath();

0 commit comments

Comments
 (0)