Files
clio/tests/unit/data/cassandra/SettingsProviderTests.cpp
2026-03-24 15:25:32 +00:00

167 lines
6.7 KiB
C++

#include "data/cassandra/SettingsProvider.hpp"
#include "data/cassandra/Types.hpp"
#include "util/TmpFile.hpp"
#include "util/config/ConfigDefinition.hpp"
#include "util/config/ConfigFileJson.hpp"
#include "util/config/ConfigValue.hpp"
#include "util/config/ObjectView.hpp"
#include "util/config/Types.hpp"
#include "util/log/Logger.hpp"
#include <boost/json/parse.hpp>
#include <boost/json/value.hpp>
#include <fmt/format.h>
#include <gtest/gtest.h>
#include <chrono>
#include <optional>
#include <thread>
#include <variant>
using namespace util;
using namespace util::config;
using namespace std;
namespace json = boost::json;
using namespace data::cassandra;
inline static ClioConfigDefinition
getParseSettingsConfig(boost::json::value val)
{
ConfigFileJson const jsonVal{val.as_object()};
auto config = ClioConfigDefinition{
{"database.cassandra.threads",
ConfigValue{ConfigType::Integer}.defaultValue(std::thread::hardware_concurrency())},
{"database.cassandra.contact_points",
ConfigValue{ConfigType::String}.defaultValue("127.0.0.1")},
{"database.cassandra.max_write_requests_outstanding",
ConfigValue{ConfigType::Integer}.defaultValue(10000)},
{"database.cassandra.max_read_requests_outstanding",
ConfigValue{ConfigType::Integer}.defaultValue(100000)},
{"database.cassandra.core_connections_per_host",
ConfigValue{ConfigType::Integer}.defaultValue(1)},
{"database.cassandra.certificate", ConfigValue{ConfigType::String}.optional()},
{"database.cassandra.username", ConfigValue{ConfigType::String}.optional()},
{"database.cassandra.password", ConfigValue{ConfigType::String}.optional()},
{"database.cassandra.provider", ConfigValue{ConfigType::String}.defaultValue("cassandra")},
{"database.cassandra.queue_size_io", ConfigValue{ConfigType::Integer}.optional()},
{"database.cassandra.write_batch_size", ConfigValue{ConfigType::Integer}.defaultValue(20)},
{"database.cassandra.connect_timeout", ConfigValue{ConfigType::Integer}.optional()},
{"database.cassandra.certfile", ConfigValue{ConfigType::String}.optional()},
{"database.cassandra.request_timeout", ConfigValue{ConfigType::Integer}.defaultValue(0)},
{"database.cassandra.secure_connect_bundle", ConfigValue{ConfigType::String}.optional()},
{"database.cassandra.username", ConfigValue{ConfigType::String}.optional()},
{"database.cassandra.password", ConfigValue{ConfigType::String}.optional()},
{"database.cassandra.keyspace", ConfigValue{ConfigType::String}.defaultValue("clio")},
{"database.cassandra.port", ConfigValue{ConfigType::Integer}.optional()},
{"database.cassandra.replication_factor", ConfigValue{ConfigType::Integer}.defaultValue(3)},
{"database.cassandra.table_prefix", ConfigValue{ConfigType::String}.optional()},
};
auto const errors = config.parse(jsonVal);
[&]() { ASSERT_FALSE(errors.has_value()); }();
return config;
};
class SettingsProviderTest : virtual public ::testing::Test {};
TEST_F(SettingsProviderTest, Defaults)
{
auto const cfg = getParseSettingsConfig(
json::parse(R"JSON({"database.cassandra.contact_points": "127.0.0.1"})JSON")
);
SettingsProvider const provider{cfg.getObject("database.cassandra")};
auto const settings = provider.getSettings();
EXPECT_EQ(settings.threads, std::thread::hardware_concurrency());
EXPECT_EQ(settings.enableLog, false);
EXPECT_EQ(settings.connectionTimeout, std::chrono::milliseconds{10000});
EXPECT_EQ(settings.requestTimeout, std::chrono::milliseconds{0});
EXPECT_EQ(settings.maxWriteRequestsOutstanding, 10'000);
EXPECT_EQ(settings.maxReadRequestsOutstanding, 100'000);
EXPECT_EQ(settings.coreConnectionsPerHost, 1);
EXPECT_EQ(settings.certificate, std::nullopt);
EXPECT_EQ(settings.username, std::nullopt);
EXPECT_EQ(settings.password, std::nullopt);
EXPECT_EQ(settings.queueSizeIO, std::nullopt);
auto const* cp = std::get_if<Settings::ContactPoints>(&settings.connectionInfo);
ASSERT_TRUE(cp != nullptr);
EXPECT_EQ(cp->contactPoints, "127.0.0.1");
EXPECT_FALSE(cp->port);
EXPECT_EQ(provider.getKeyspace(), "clio");
EXPECT_EQ(provider.getReplicationFactor(), 3);
EXPECT_EQ(provider.getTablePrefix(), std::nullopt);
}
TEST_F(SettingsProviderTest, SimpleConfig)
{
auto const cfg = getParseSettingsConfig(json::parse(R"JSON({
"database.cassandra.contact_points": "123.123.123.123",
"database.cassandra.port": 1234,
"database.cassandra.keyspace": "test",
"database.cassandra.replication_factor": 42,
"database.cassandra.table_prefix": "prefix",
"database.cassandra.threads": 24
})JSON"));
SettingsProvider const provider{cfg.getObject("database.cassandra")};
auto const settings = provider.getSettings();
EXPECT_EQ(settings.threads, 24);
auto const* cp = std::get_if<Settings::ContactPoints>(&settings.connectionInfo);
ASSERT_TRUE(cp != nullptr);
EXPECT_EQ(cp->contactPoints, "123.123.123.123");
EXPECT_EQ(cp->port, 1234);
EXPECT_EQ(provider.getKeyspace(), "test");
EXPECT_EQ(provider.getReplicationFactor(), 42);
EXPECT_EQ(provider.getTablePrefix(), "prefix");
}
TEST_F(SettingsProviderTest, DriverOptionalOptionsSpecified)
{
auto const cfg = getParseSettingsConfig(json::parse(R"JSON({
"database.cassandra.contact_points": "123.123.123.123",
"database.cassandra.queue_size_io": 2
})JSON"));
SettingsProvider const provider{cfg.getObject("database.cassandra")};
auto const settings = provider.getSettings();
EXPECT_EQ(settings.queueSizeIO, 2);
}
TEST_F(SettingsProviderTest, SecureBundleConfig)
{
auto const cfg = getParseSettingsConfig(
json::parse(R"JSON({"database.cassandra.secure_connect_bundle": "bundleData"})JSON")
);
SettingsProvider const provider{cfg.getObject("database.cassandra")};
auto const settings = provider.getSettings();
auto const* sb = std::get_if<Settings::SecureConnectionBundle>(&settings.connectionInfo);
ASSERT_TRUE(sb != nullptr);
EXPECT_EQ(sb->bundle, "bundleData");
}
TEST_F(SettingsProviderTest, CertificateConfig)
{
TmpFile const file{"certificateData"};
auto const cfg = getParseSettingsConfig(
json::parse(
fmt::format(
R"JSON({{
"database.cassandra.contact_points": "127.0.0.1",
"database.cassandra.certfile": "{}"
}})JSON",
file.path
)
)
);
SettingsProvider const provider{cfg.getObject("database.cassandra")};
auto const settings = provider.getSettings();
EXPECT_EQ(settings.certificate, "certificateData");
}