From 1b6100506f7d1ba89f2a2abe954995dcb8d3746d Mon Sep 17 00:00:00 2001 From: Ying Cai Date: Tue, 6 May 2025 12:05:26 +0800 Subject: [PATCH 1/6] feat: introduce a new config class to manage configurable options following design ideas from Velox. --- src/iceberg/util/config.h | 114 ++++++++++++++++++++++++++++++++++++++ test/CMakeLists.txt | 2 +- test/config_test.cc | 110 ++++++++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 src/iceberg/util/config.h create mode 100644 test/config_test.cc diff --git a/src/iceberg/util/config.h b/src/iceberg/util/config.h new file mode 100644 index 000000000..53d86b380 --- /dev/null +++ b/src/iceberg/util/config.h @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +#pragma once + +#include +#include +#include +#include + +namespace iceberg { + +template +class ConfigBase { + public: + template + class Entry { + Entry( + std::string key, const T& val, + std::function toStr = + [](const T& val) { + if constexpr ((std::is_signed_v && std::is_integral_v) || + std::is_floating_point_v) { + return std::to_string(val); + } else if constexpr (std::is_same_v) { + return val ? "true" : "false"; + } else if constexpr (std::is_same_v || + std::is_same_v) { + return val; + } else { + throw std::runtime_error( + std::format("Explicit toStr() is required for {}", typeid(T).name())); + } + }, + std::function toT = [](const std::string& val) -> T { + if constexpr (std::is_same_v) { + return val; + } else if constexpr (std::is_same_v) { + return val == "true"; + } else if constexpr (std::is_signed_v && std::is_integral_v) { + return static_cast(std::stoll(val)); + } else if constexpr (std::is_floating_point_v) { + return static_cast(std::stod(val)); + } else { + throw std::runtime_error( + std::format("Explicit toT() is required for {}", typeid(T).name())); + } + }) + : key_{std::move(key)}, default_{val}, toStr_{toStr}, toT_{toT} {} + + const std::string key_; + const T default_; + const std::function toStr_; + const std::function toT_; + + friend ConfigBase; + friend ConcreteConfig; + + public: + const std::string& key() const { return key_; } + + T value() const { return default_; } + }; + + template + ConfigBase& set(const Entry& entry, const T& val) { + configs_[entry.key_] = entry.toStr_(val); + return *this; + } + + template + ConfigBase& unset(const Entry& entry) { + configs_.erase(entry.key_); + return *this; + } + + ConfigBase& reset() { + configs_.clear(); + return *this; + } + + template + T get(const Entry& entry) const { + try { + auto iter = configs_.find(entry.key_); + return iter != configs_.cend() ? entry.toT_(iter->second) : entry.default_; + } catch (std::exception& e) { + throw std::runtime_error( + std::format("Failed to get config {} with error: {}", entry.key_, e.what())); + } + } + + std::map const& configs() const { return configs_; } + + protected: + std::map configs_; +}; + +} // namespace iceberg diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bf8caa0b0..3fc3152e6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -57,7 +57,7 @@ target_link_libraries(json_serde_test PRIVATE iceberg_static GTest::gtest_main add_test(NAME json_serde_test COMMAND json_serde_test) add_executable(util_test) -target_sources(util_test PRIVATE expected_test.cc formatter_test.cc) +target_sources(util_test PRIVATE expected_test.cc formatter_test.cc config_test.cc) target_link_libraries(util_test PRIVATE iceberg_static GTest::gtest_main GTest::gmock) add_test(NAME util_test COMMAND util_test) diff --git a/test/config_test.cc b/test/config_test.cc new file mode 100644 index 000000000..1abae89be --- /dev/null +++ b/test/config_test.cc @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#include + +#include +#include + +namespace iceberg { + +enum class TestEnum { VALUE1, VALUE2, VALUE3 }; + +std::string enumToString(const TestEnum& val) { + switch (val) { + case TestEnum::VALUE1: + return "VALUE1"; + case TestEnum::VALUE2: + return "VALUE2"; + case TestEnum::VALUE3: + return "VALUE3"; + default: + throw std::runtime_error("Invalid enum value"); + } +} + +TestEnum stringToEnum(const std::string& val) { + if (val == "VALUE1") { + return TestEnum::VALUE1; + } else if (val == "VALUE2") { + return TestEnum::VALUE2; + } else if (val == "VALUE3") { + return TestEnum::VALUE3; + } else { + throw std::runtime_error("Invalid enum string"); + } +} + +// Define a concrete config class for testing +class TestConfig : public ConfigBase { + public: + template + using Entry = const ConfigBase::Entry; + + inline static const Entry STRING_CONFIG{"string_config", "default_value"}; + inline static const Entry INT_CONFIG{"int_config", 25}; + inline static const Entry BOOL_CONFIG{"bool_config", false}; + inline static const Entry ENUM_CONFIG{"enum_config", TestEnum::VALUE1, + enumToString, stringToEnum}; + inline static const Entry DOUBLE_CONFIG{"double_config", 3.14}; +}; + +TEST(ConfigTest, BasicOperations) { + TestConfig config; + + // Test default values + ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), std::string("default_value")); + ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 25); + ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), false); + ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); + ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 3.14); + + // Test setting values + config.set(TestConfig::STRING_CONFIG, std::string("new_value")); + config.set(TestConfig::INT_CONFIG, 100); + config.set(TestConfig::BOOL_CONFIG, true); + config.set(TestConfig::ENUM_CONFIG, TestEnum::VALUE2); + config.set(TestConfig::DOUBLE_CONFIG, 2.71828); + + ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), "new_value"); + ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 100); + ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), true); + ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE2); + ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 2.71828); + + // Test unsetting a value + config.unset(TestConfig::INT_CONFIG); + config.unset(TestConfig::ENUM_CONFIG); + config.unset(TestConfig::DOUBLE_CONFIG); + ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 25); + ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), "new_value"); + ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), true); + ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); + ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 3.14); + + // Test resetting all values + config.reset(); + ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), "default_value"); + ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 25); + ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), false); + ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); + ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 3.14); +} + +} // namespace iceberg From 0297da8eb760effb688862c136e856cb3ae1d49c Mon Sep 17 00:00:00 2001 From: Ying Cai Date: Tue, 6 May 2025 16:46:16 +0800 Subject: [PATCH 2/6] fix linter issue. --- test/config_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/config_test.cc b/test/config_test.cc index 1abae89be..7267850d5 100644 --- a/test/config_test.cc +++ b/test/config_test.cc @@ -80,13 +80,13 @@ TEST(ConfigTest, BasicOperations) { config.set(TestConfig::INT_CONFIG, 100); config.set(TestConfig::BOOL_CONFIG, true); config.set(TestConfig::ENUM_CONFIG, TestEnum::VALUE2); - config.set(TestConfig::DOUBLE_CONFIG, 2.71828); + config.set(TestConfig::DOUBLE_CONFIG, 2.99); ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), "new_value"); ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 100); ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), true); ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE2); - ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 2.71828); + ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 2.99); // Test unsetting a value config.unset(TestConfig::INT_CONFIG); From 7d5c901d0b4d8e74dac3d95d68bd8c13e2e435bb Mon Sep 17 00:00:00 2001 From: Ying Cai Date: Wed, 7 May 2025 17:42:58 +0800 Subject: [PATCH 3/6] apply review comments. --- src/iceberg/util/config.h | 94 ++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/src/iceberg/util/config.h b/src/iceberg/util/config.h index 53d86b380..3a95b072f 100644 --- a/src/iceberg/util/config.h +++ b/src/iceberg/util/config.h @@ -20,53 +20,60 @@ #include #include -#include #include +#include namespace iceberg { +// Default conversion functions +template +std::string defaultToString(const U& val) { + if constexpr ((std::is_signed_v && std::is_integral_v) || + std::is_floating_point_v) { + return std::to_string(val); + } else if constexpr (std::is_same_v) { + return val ? "true" : "false"; + } else if constexpr (std::is_same_v || + std::is_same_v) { + return val; + } else { + throw std::runtime_error( + std::format("Explicit toStr() is required for {}", typeid(U).name())); + } +} + +template +U defaultFromString(const std::string& val) { + if constexpr (std::is_same_v) { + return val; + } else if constexpr (std::is_same_v) { + return val == "true"; + } else if constexpr (std::is_signed_v && std::is_integral_v) { + return static_cast(std::stoll(val)); + } else if constexpr (std::is_floating_point_v) { + return static_cast(std::stod(val)); + } else { + throw std::runtime_error( + std::format("Explicit toT() is required for {}", typeid(U).name())); + } +} + template class ConfigBase { public: template class Entry { - Entry( - std::string key, const T& val, - std::function toStr = - [](const T& val) { - if constexpr ((std::is_signed_v && std::is_integral_v) || - std::is_floating_point_v) { - return std::to_string(val); - } else if constexpr (std::is_same_v) { - return val ? "true" : "false"; - } else if constexpr (std::is_same_v || - std::is_same_v) { - return val; - } else { - throw std::runtime_error( - std::format("Explicit toStr() is required for {}", typeid(T).name())); - } - }, - std::function toT = [](const std::string& val) -> T { - if constexpr (std::is_same_v) { - return val; - } else if constexpr (std::is_same_v) { - return val == "true"; - } else if constexpr (std::is_signed_v && std::is_integral_v) { - return static_cast(std::stoll(val)); - } else if constexpr (std::is_floating_point_v) { - return static_cast(std::stod(val)); - } else { - throw std::runtime_error( - std::format("Explicit toT() is required for {}", typeid(T).name())); - } - }) - : key_{std::move(key)}, default_{val}, toStr_{toStr}, toT_{toT} {} + public: + Entry(std::string key, const T& val, + std::function to_str = defaultToString, + std::function from_str = defaultFromString) + : key_{std::move(key)}, default_{val}, to_str_{to_str}, from_str_{from_str} {} + private: const std::string key_; const T default_; - const std::function toStr_; - const std::function toT_; + const std::function to_str_; + const std::function from_str_; friend ConfigBase; friend ConcreteConfig; @@ -74,12 +81,12 @@ class ConfigBase { public: const std::string& key() const { return key_; } - T value() const { return default_; } + const T& value() const { return default_; } }; template ConfigBase& set(const Entry& entry, const T& val) { - configs_[entry.key_] = entry.toStr_(val); + configs_[entry.key_] = entry.to_str_(val); return *this; } @@ -96,19 +103,14 @@ class ConfigBase { template T get(const Entry& entry) const { - try { - auto iter = configs_.find(entry.key_); - return iter != configs_.cend() ? entry.toT_(iter->second) : entry.default_; - } catch (std::exception& e) { - throw std::runtime_error( - std::format("Failed to get config {} with error: {}", entry.key_, e.what())); - } + auto iter = configs_.find(entry.key_); + return iter != configs_.cend() ? entry.from_str_(iter->second) : entry.default_; } - std::map const& configs() const { return configs_; } + std::unordered_map const& configs() const { return configs_; } protected: - std::map configs_; + std::unordered_map configs_; }; } // namespace iceberg From 825e48250310131c345ca888fb4dd7284b10bb2a Mon Sep 17 00:00:00 2001 From: Ying Cai Date: Fri, 9 May 2025 16:25:26 +0800 Subject: [PATCH 4/6] fix review issus. --- src/iceberg/util/config.h | 33 ++++++++++++---------- test/config_test.cc | 58 +++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/iceberg/util/config.h b/src/iceberg/util/config.h index 3a95b072f..ff5df3e9b 100644 --- a/src/iceberg/util/config.h +++ b/src/iceberg/util/config.h @@ -23,11 +23,13 @@ #include #include -namespace iceberg { +#include +namespace iceberg { +namespace internal { // Default conversion functions template -std::string defaultToString(const U& val) { +std::string DefaultToString(const U& val) { if constexpr ((std::is_signed_v && std::is_integral_v) || std::is_floating_point_v) { return std::to_string(val); @@ -37,13 +39,13 @@ std::string defaultToString(const U& val) { std::is_same_v) { return val; } else { - throw std::runtime_error( - std::format("Explicit toStr() is required for {}", typeid(U).name())); + throw IcebergError( + std::format("Explicit to_str() is required for {}", typeid(U).name())); } } template -U defaultFromString(const std::string& val) { +U DefaultFromString(const std::string& val) { if constexpr (std::is_same_v) { return val; } else if constexpr (std::is_same_v) { @@ -53,10 +55,11 @@ U defaultFromString(const std::string& val) { } else if constexpr (std::is_floating_point_v) { return static_cast(std::stod(val)); } else { - throw std::runtime_error( - std::format("Explicit toT() is required for {}", typeid(U).name())); + throw IcebergError( + std::format("Explicit from_str() is required for {}", typeid(U).name())); } } +} // namespace internal template class ConfigBase { @@ -65,8 +68,8 @@ class ConfigBase { class Entry { public: Entry(std::string key, const T& val, - std::function to_str = defaultToString, - std::function from_str = defaultFromString) + std::function to_str = internal::DefaultToString, + std::function from_str = internal::DefaultFromString) : key_{std::move(key)}, default_{val}, to_str_{to_str}, from_str_{from_str} {} private: @@ -85,29 +88,29 @@ class ConfigBase { }; template - ConfigBase& set(const Entry& entry, const T& val) { - configs_[entry.key_] = entry.to_str_(val); + ConfigBase& Set(const Entry& entry, const T& val) { + configs_.emplace(entry.key_, entry.to_str_(val)); return *this; } template - ConfigBase& unset(const Entry& entry) { + ConfigBase& Unset(const Entry& entry) { configs_.erase(entry.key_); return *this; } - ConfigBase& reset() { + ConfigBase& Reset() { configs_.clear(); return *this; } template - T get(const Entry& entry) const { + T Get(const Entry& entry) const { auto iter = configs_.find(entry.key_); return iter != configs_.cend() ? entry.from_str_(iter->second) : entry.default_; } - std::unordered_map const& configs() const { return configs_; } + const std::unordered_map& configs() const { return configs_; } protected: std::unordered_map configs_; diff --git a/test/config_test.cc b/test/config_test.cc index 7267850d5..07b223b1b 100644 --- a/test/config_test.cc +++ b/test/config_test.cc @@ -69,42 +69,42 @@ TEST(ConfigTest, BasicOperations) { TestConfig config; // Test default values - ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), std::string("default_value")); - ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 25); - ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), false); - ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); - ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 3.14); + ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), std::string("default_value")); + ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 25); + ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), false); + ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); + ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 3.14); // Test setting values - config.set(TestConfig::STRING_CONFIG, std::string("new_value")); - config.set(TestConfig::INT_CONFIG, 100); - config.set(TestConfig::BOOL_CONFIG, true); - config.set(TestConfig::ENUM_CONFIG, TestEnum::VALUE2); - config.set(TestConfig::DOUBLE_CONFIG, 2.99); + config.Set(TestConfig::STRING_CONFIG, std::string("new_value")); + config.Set(TestConfig::INT_CONFIG, 100); + config.Set(TestConfig::BOOL_CONFIG, true); + config.Set(TestConfig::ENUM_CONFIG, TestEnum::VALUE2); + config.Set(TestConfig::DOUBLE_CONFIG, 2.99); - ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), "new_value"); - ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 100); - ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), true); - ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE2); - ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 2.99); + ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), "new_value"); + ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 100); + ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), true); + ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE2); + ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 2.99); // Test unsetting a value - config.unset(TestConfig::INT_CONFIG); - config.unset(TestConfig::ENUM_CONFIG); - config.unset(TestConfig::DOUBLE_CONFIG); - ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 25); - ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), "new_value"); - ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), true); - ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); - ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 3.14); + config.Unset(TestConfig::INT_CONFIG); + config.Unset(TestConfig::ENUM_CONFIG); + config.Unset(TestConfig::DOUBLE_CONFIG); + ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 25); + ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), "new_value"); + ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), true); + ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); + ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 3.14); // Test resetting all values - config.reset(); - ASSERT_EQ(config.get(TestConfig::STRING_CONFIG), "default_value"); - ASSERT_EQ(config.get(TestConfig::INT_CONFIG), 25); - ASSERT_EQ(config.get(TestConfig::BOOL_CONFIG), false); - ASSERT_EQ(config.get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); - ASSERT_EQ(config.get(TestConfig::DOUBLE_CONFIG), 3.14); + config.Reset(); + ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), "default_value"); + ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 25); + ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), false); + ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); + ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 3.14); } } // namespace iceberg From ae4a549298dbbc6dca43bc30240a8e4f92c6beda Mon Sep 17 00:00:00 2001 From: Ying Cai Date: Sat, 10 May 2025 09:52:53 +0800 Subject: [PATCH 5/6] Apply review comments. --- src/iceberg/util/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iceberg/util/config.h b/src/iceberg/util/config.h index ff5df3e9b..7a3a28b40 100644 --- a/src/iceberg/util/config.h +++ b/src/iceberg/util/config.h @@ -23,7 +23,7 @@ #include #include -#include +#include "iceberg/exception.h" namespace iceberg { namespace internal { From b0984a7ce6f53731e6c3231e5915ed785129a540 Mon Sep 17 00:00:00 2001 From: Ying Cai Date: Mon, 12 May 2025 14:02:10 +0800 Subject: [PATCH 6/6] Apply review comments for tests. --- test/config_test.cc | 72 ++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/test/config_test.cc b/test/config_test.cc index 07b223b1b..1ee04224e 100644 --- a/test/config_test.cc +++ b/test/config_test.cc @@ -26,7 +26,7 @@ namespace iceberg { enum class TestEnum { VALUE1, VALUE2, VALUE3 }; -std::string enumToString(const TestEnum& val) { +std::string EnumToString(const TestEnum& val) { switch (val) { case TestEnum::VALUE1: return "VALUE1"; @@ -39,7 +39,7 @@ std::string enumToString(const TestEnum& val) { } } -TestEnum stringToEnum(const std::string& val) { +TestEnum StringToEnum(const std::string& val) { if (val == "VALUE1") { return TestEnum::VALUE1; } else if (val == "VALUE2") { @@ -57,54 +57,54 @@ class TestConfig : public ConfigBase { template using Entry = const ConfigBase::Entry; - inline static const Entry STRING_CONFIG{"string_config", "default_value"}; - inline static const Entry INT_CONFIG{"int_config", 25}; - inline static const Entry BOOL_CONFIG{"bool_config", false}; - inline static const Entry ENUM_CONFIG{"enum_config", TestEnum::VALUE1, - enumToString, stringToEnum}; - inline static const Entry DOUBLE_CONFIG{"double_config", 3.14}; + inline static const Entry kStringConfig{"string_config", "default_value"}; + inline static const Entry kIntConfig{"int_config", 25}; + inline static const Entry kBoolConfig{"bool_config", false}; + inline static const Entry kEnumConfig{"enum_config", TestEnum::VALUE1, + EnumToString, StringToEnum}; + inline static const Entry kDoubleConfig{"double_config", 3.14}; }; TEST(ConfigTest, BasicOperations) { TestConfig config; // Test default values - ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), std::string("default_value")); - ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 25); - ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), false); - ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); - ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 3.14); + ASSERT_EQ(config.Get(TestConfig::kStringConfig), std::string("default_value")); + ASSERT_EQ(config.Get(TestConfig::kIntConfig), 25); + ASSERT_EQ(config.Get(TestConfig::kBoolConfig), false); + ASSERT_EQ(config.Get(TestConfig::kEnumConfig), TestEnum::VALUE1); + ASSERT_EQ(config.Get(TestConfig::kDoubleConfig), 3.14); // Test setting values - config.Set(TestConfig::STRING_CONFIG, std::string("new_value")); - config.Set(TestConfig::INT_CONFIG, 100); - config.Set(TestConfig::BOOL_CONFIG, true); - config.Set(TestConfig::ENUM_CONFIG, TestEnum::VALUE2); - config.Set(TestConfig::DOUBLE_CONFIG, 2.99); + config.Set(TestConfig::kStringConfig, std::string("new_value")); + config.Set(TestConfig::kIntConfig, 100); + config.Set(TestConfig::kBoolConfig, true); + config.Set(TestConfig::kEnumConfig, TestEnum::VALUE2); + config.Set(TestConfig::kDoubleConfig, 2.99); - ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), "new_value"); - ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 100); - ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), true); - ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE2); - ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 2.99); + ASSERT_EQ(config.Get(TestConfig::kStringConfig), "new_value"); + ASSERT_EQ(config.Get(TestConfig::kIntConfig), 100); + ASSERT_EQ(config.Get(TestConfig::kBoolConfig), true); + ASSERT_EQ(config.Get(TestConfig::kEnumConfig), TestEnum::VALUE2); + ASSERT_EQ(config.Get(TestConfig::kDoubleConfig), 2.99); // Test unsetting a value - config.Unset(TestConfig::INT_CONFIG); - config.Unset(TestConfig::ENUM_CONFIG); - config.Unset(TestConfig::DOUBLE_CONFIG); - ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 25); - ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), "new_value"); - ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), true); - ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); - ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 3.14); + config.Unset(TestConfig::kIntConfig); + config.Unset(TestConfig::kEnumConfig); + config.Unset(TestConfig::kDoubleConfig); + ASSERT_EQ(config.Get(TestConfig::kIntConfig), 25); + ASSERT_EQ(config.Get(TestConfig::kStringConfig), "new_value"); + ASSERT_EQ(config.Get(TestConfig::kBoolConfig), true); + ASSERT_EQ(config.Get(TestConfig::kEnumConfig), TestEnum::VALUE1); + ASSERT_EQ(config.Get(TestConfig::kDoubleConfig), 3.14); // Test resetting all values config.Reset(); - ASSERT_EQ(config.Get(TestConfig::STRING_CONFIG), "default_value"); - ASSERT_EQ(config.Get(TestConfig::INT_CONFIG), 25); - ASSERT_EQ(config.Get(TestConfig::BOOL_CONFIG), false); - ASSERT_EQ(config.Get(TestConfig::ENUM_CONFIG), TestEnum::VALUE1); - ASSERT_EQ(config.Get(TestConfig::DOUBLE_CONFIG), 3.14); + ASSERT_EQ(config.Get(TestConfig::kStringConfig), "default_value"); + ASSERT_EQ(config.Get(TestConfig::kIntConfig), 25); + ASSERT_EQ(config.Get(TestConfig::kBoolConfig), false); + ASSERT_EQ(config.Get(TestConfig::kEnumConfig), TestEnum::VALUE1); + ASSERT_EQ(config.Get(TestConfig::kDoubleConfig), 3.14); } } // namespace iceberg