refactor: Clio Config (#1593)

Add constraint + parse json into Config
Second part of refactoring Clio Config; First PR found
[here](https://github.com/XRPLF/clio/pull/1544)

Steps that are left to implement:
- Replacing all the places where we fetch config values (by using
config.valueOr/MaybeValue) to instead get it from Config Definition
- Generate markdown file using Clio Config Description
This commit is contained in:
Peter Chen
2024-09-19 10:10:04 -04:00
committed by GitHub
parent 0282504f18
commit af4fde9a3a
26 changed files with 2075 additions and 352 deletions

View File

@@ -19,11 +19,13 @@
#include "util/newconfig/ArrayView.hpp"
#include "util/newconfig/ConfigDefinition.hpp"
#include "util/newconfig/ConfigValue.hpp"
#include "util/newconfig/ConfigFileJson.hpp"
#include "util/newconfig/FakeConfigData.hpp"
#include "util/newconfig/ObjectView.hpp"
#include "util/newconfig/Types.hpp"
#include "util/newconfig/ValueView.hpp"
#include <boost/json/parse.hpp>
#include <gtest/gtest.h>
#include <cstddef>
@@ -31,33 +33,65 @@
using namespace util::config;
struct ArrayViewTest : testing::Test {
ClioConfigDefinition const configData = generateConfig();
ArrayViewTest()
{
ConfigFileJson const jsonFileObj{boost::json::parse(JSONData).as_object()};
auto const errors = configData.parse(jsonFileObj);
EXPECT_TRUE(!errors.has_value());
}
ClioConfigDefinition configData = generateConfig();
};
TEST_F(ArrayViewTest, ArrayValueTest)
// Array View tests can only be tested after the values are populated from user Config
// into ConfigClioDefinition
TEST_F(ArrayViewTest, ArrayGetValueDouble)
{
ArrayView const arrVals = configData.getArray("array.[].sub");
auto valIt = arrVals.begin<ValueView>();
auto const precision = 1e-9;
EXPECT_NEAR((*valIt++).asDouble(), 111.11, precision);
EXPECT_NEAR((*valIt++).asDouble(), 4321.55, precision);
EXPECT_EQ(valIt, arrVals.end<ValueView>());
ArrayView const arrVals = configData.getArray("array.[].sub");
EXPECT_NEAR(111.11, arrVals.valueAt(0).asDouble(), precision);
auto const firstVal = arrVals.valueAt(0);
EXPECT_EQ(firstVal.type(), ConfigType::Double);
EXPECT_TRUE(firstVal.hasValue());
EXPECT_FALSE(firstVal.isOptional());
EXPECT_NEAR(111.11, firstVal.asDouble(), precision);
EXPECT_NEAR(4321.55, arrVals.valueAt(1).asDouble(), precision);
ArrayView const arrVals2 = configData.getArray("array.[].sub2");
auto val2It = arrVals2.begin<ValueView>();
EXPECT_EQ((*val2It++).asString(), "subCategory");
EXPECT_EQ((*val2It++).asString(), "temporary");
EXPECT_EQ(val2It, arrVals2.end<ValueView>());
ValueView const tempVal = arrVals2.valueAt(0);
EXPECT_EQ(tempVal.type(), ConfigType::String);
EXPECT_EQ("subCategory", tempVal.asString());
}
TEST_F(ArrayViewTest, ArrayWithObjTest)
TEST_F(ArrayViewTest, ArrayGetValueString)
{
ArrayView const arrVals = configData.getArray("array.[].sub2");
ValueView const firstVal = arrVals.valueAt(0);
EXPECT_EQ(firstVal.type(), ConfigType::String);
EXPECT_EQ("subCategory", firstVal.asString());
EXPECT_EQ("london", arrVals.valueAt(2).asString());
}
TEST_F(ArrayViewTest, IterateValuesDouble)
{
auto const precision = 1e-9;
ArrayView const arrVals = configData.getArray("array.[].sub");
auto valIt = arrVals.begin<ValueView>();
EXPECT_NEAR((*valIt++).asDouble(), 111.11, precision);
EXPECT_NEAR((*valIt++).asDouble(), 4321.55, precision);
EXPECT_NEAR((*valIt++).asDouble(), 5555.44, precision);
EXPECT_EQ(valIt, arrVals.end<ValueView>());
}
TEST_F(ArrayViewTest, IterateValuesString)
{
ArrayView const arrVals = configData.getArray("array.[].sub2");
auto val2It = arrVals.begin<ValueView>();
EXPECT_EQ((*val2It++).asString(), "subCategory");
EXPECT_EQ((*val2It++).asString(), "temporary");
EXPECT_EQ((*val2It++).asString(), "london");
EXPECT_EQ(val2It, arrVals.end<ValueView>());
}
TEST_F(ArrayViewTest, ArrayWithObj)
{
ArrayView const arrVals = configData.getArray("array.[]");
ArrayView const arrValAlt = configData.getArray("array");
@@ -73,20 +107,19 @@ TEST_F(ArrayViewTest, IterateArray)
{
auto arr = configData.getArray("dosguard.whitelist");
EXPECT_EQ(2, arr.size());
EXPECT_EQ(arr.valueAt(0).asString(), "125.5.5.2");
EXPECT_EQ(arr.valueAt(1).asString(), "204.2.2.2");
EXPECT_EQ(arr.valueAt(0).asString(), "125.5.5.1");
EXPECT_EQ(arr.valueAt(1).asString(), "204.2.2.1");
auto it = arr.begin<ValueView>();
EXPECT_EQ((*it++).asString(), "125.5.5.2");
EXPECT_EQ((*it++).asString(), "204.2.2.2");
EXPECT_EQ((*it++).asString(), "125.5.5.1");
EXPECT_EQ((*it++).asString(), "204.2.2.1");
EXPECT_EQ((it), arr.end<ValueView>());
}
TEST_F(ArrayViewTest, DifferentArrayIterators)
TEST_F(ArrayViewTest, CompareDifferentArrayIterators)
{
auto const subArray = configData.getArray("array.[].sub");
auto const dosguardArray = configData.getArray("dosguard.whitelist.[]");
ASSERT_EQ(subArray.size(), dosguardArray.size());
auto itArray = subArray.begin<ValueView>();
auto itDosguard = dosguardArray.begin<ValueView>();
@@ -98,7 +131,7 @@ TEST_F(ArrayViewTest, DifferentArrayIterators)
TEST_F(ArrayViewTest, IterateObject)
{
auto arr = configData.getArray("array");
EXPECT_EQ(2, arr.size());
EXPECT_EQ(3, arr.size());
auto it = arr.begin<ObjectView>();
EXPECT_EQ(111.11, (*it).getValue("sub").asDouble());
@@ -107,33 +140,37 @@ TEST_F(ArrayViewTest, IterateObject)
EXPECT_EQ(4321.55, (*it).getValue("sub").asDouble());
EXPECT_EQ("temporary", (*it++).getValue("sub2").asString());
EXPECT_EQ(5555.44, (*it).getValue("sub").asDouble());
EXPECT_EQ("london", (*it++).getValue("sub2").asString());
EXPECT_EQ(it, arr.end<ObjectView>());
}
struct ArrayViewDeathTest : ArrayViewTest {};
TEST_F(ArrayViewDeathTest, IncorrectAccess)
TEST_F(ArrayViewDeathTest, AccessArrayOutOfBounce)
{
ArrayView const arr = configData.getArray("higher");
// dies because higher only has 1 object (trying to access 2nd element)
EXPECT_DEATH({ [[maybe_unused]] auto _ = configData.getArray("higher").objectAt(1); }, ".*");
}
// dies because higher only has 1 object
EXPECT_DEATH({ [[maybe_unused]] auto _ = arr.objectAt(1); }, ".*");
ArrayView const arrVals2 = configData.getArray("array.[].sub2");
ValueView const tempVal = arrVals2.valueAt(0);
// dies because array.[].sub2 only has 2 config values
EXPECT_DEATH([[maybe_unused]] auto _ = arrVals2.valueAt(2), ".*");
TEST_F(ArrayViewDeathTest, AccessIndexOfWrongType)
{
auto const& arrVals2 = configData.getArray("array.[].sub2");
auto const& tempVal = arrVals2.valueAt(0);
// dies as value is not of type int
EXPECT_DEATH({ [[maybe_unused]] auto _ = tempVal.asIntType<int>(); }, ".*");
}
TEST_F(ArrayViewDeathTest, IncorrectIterateAccess)
TEST_F(ArrayViewDeathTest, GetValueWhenItIsObject)
{
ArrayView const arr = configData.getArray("higher");
EXPECT_DEATH({ [[maybe_unused]] auto _ = arr.begin<ValueView>(); }, ".*");
}
TEST_F(ArrayViewDeathTest, GetObjectWhenItIsValue)
{
ArrayView const dosguardWhitelist = configData.getArray("dosguard.whitelist");
EXPECT_DEATH({ [[maybe_unused]] auto _ = dosguardWhitelist.begin<ObjectView>(); }, ".*");
}