10 #include <boost/test/unit_test.hpp>
21 #include <system_error>
35 inline std::ostream&
operator<<(std::ostream& os,
const std::pair<std::string, common::SettingsValue>& kv)
38 out.pushKVEnd(kv.first, kv.second);
54 fs::path path = m_args.GetDataDirBase() /
"settings.json";
63 std::map<std::string, common::SettingsValue> expected{
71 std::map<std::string, common::SettingsValue>
values;
72 std::vector<std::string> errors;
74 BOOST_CHECK_EQUAL_COLLECTIONS(
values.begin(),
values.end(), expected.begin(), expected.end());
90 BOOST_CHECK_EQUAL_COLLECTIONS(errors.begin(), errors.end(), dup_keys.begin(), dup_keys.end());
96 std::vector<std::string> non_kv = {strprintf("Found non-object value \"non-kv\" in settings file %s",
fs::PathToString(path))};
97 BOOST_CHECK_EQUAL_COLLECTIONS(errors.begin(), errors.end(), non_kv.begin(), non_kv.end());
103 BOOST_CHECK_EQUAL_COLLECTIONS(errors.begin(), errors.end(), fail_parse.begin(), fail_parse.end());
111 for (
const auto& item :
GetSettingsList(settings,
"section",
"name",
false)) {
124 settings.
ro_config[
"section"][
"name"].push_back(2);
127 CheckValues(settings, R
"("val2")", R"(["val1","val2",2])");
130 settings2.ro_config["section"][
"name"].push_back(
"val2");
131 settings2.
ro_config[
"section"][
"name"].push_back(
"val3");
134 CheckValues(settings2, R
"("val2")", R"(["val2","val3"])");
162 template <
typename Fn>
170 for (
bool force_set : {
false,
true}) {
171 for (
bool ignore_default_section_config : {
false,
true}) {
172 fn(arg_actions, conf_actions, force_set, ignore_default_section_config);
187 FILE* out_file =
nullptr;
188 if (
const char* out_path = getenv(
"SETTINGS_MERGE_TEST_OUT")) {
190 if (!out_file)
throw std::system_error(errno, std::generic_category(),
"fopen failed");
194 ForEachMergeSetup([&](
const ActionList& arg_actions,
const ActionList& conf_actions,
bool force_set,
195 bool ignore_default_section_config) {
197 int value_suffix = 0;
200 const std::string&
name = ignore_default_section_config ?
"wallet" :
"server";
201 auto push_values = [&](Action action,
const char* value_prefix,
const std::string& name_prefix,
202 std::vector<common::SettingsValue>& dest) {
203 if (action == SET || action == SECTION_SET) {
204 for (
int i = 0; i < 2; ++i) {
205 dest.push_back(value_prefix +
ToString(++value_suffix));
206 desc +=
" " + name_prefix +
name +
"=" + dest.back().get_str();
208 }
else if (action == NEGATE || action == SECTION_NEGATE) {
209 dest.push_back(
false);
210 desc +=
" " + name_prefix +
"no" +
name;
216 desc +=
" " +
name +
"=forced";
218 for (Action arg_action : arg_actions) {
221 for (Action conf_action : conf_actions) {
222 bool use_section = conf_action == SECTION_SET || conf_action == SECTION_NEGATE;
223 push_values(conf_action,
"c", use_section ? network +
"." :
"",
228 desc +=
GetSetting(settings, network,
name, ignore_default_section_config,
false,
false).
write();
230 for (
const auto& s :
GetSettingsList(settings, network,
name, ignore_default_section_config)) {
240 BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
245 if (fclose(out_file))
throw std::system_error(errno, std::generic_category(),
"fclose failed");
251 std::string out_sha_hex =
HexStr(out_sha_bytes);
262 BOOST_CHECK_EQUAL(out_sha_hex,
"79db02d74e3e193196541b67c068b40ebd0c124a24b3ecbe9cbf7e85b1c4ba7a");
std::string ChainTypeToString(ChainType chain)
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
CHash256 & Write(Span< const unsigned char > input)
void Finalize(Span< unsigned char > output)
static const size_t OUTPUT_SIZE
void push_back(UniValue val)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
BOOST_AUTO_TEST_SUITE_END()
bool ReadSettings(const fs::path &path, std::map< std::string, SettingsValue > &values, std::vector< std::string > &errors)
Read settings file.
SettingsValue GetSetting(const Settings &settings, const std::string §ion, const std::string &name, bool ignore_default_section_config, bool ignore_nonpersistent, bool get_chain_type)
Get settings value from combined sources: forced settings, command line arguments,...
std::vector< SettingsValue > GetSettingsList(const Settings &settings, const std::string §ion, const std::string &name, bool ignore_default_section_config)
Get combined setting value similar to GetSetting(), except if setting was specified multiple times,...
bool OnlyHasDefaultSectionSetting(const Settings &settings, const std::string §ion, const std::string &name)
Return true if a setting is set in the default config file section, and not overridden by a higher pr...
static std::string PathToString(const path &path)
Convert path object to a byte string.
FILE * fopen(const fs::path &p, const char *mode)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
BOOST_AUTO_TEST_CASE(ReadWrite)
static void CheckValues(const common::Settings &settings, const std::string &single_val, const std::string &list_val)
Check settings struct contents against expected json strings.
void WriteText(const fs::path &path, const std::string &text)
BOOST_FIXTURE_TEST_CASE(Merge, MergeTestingSetup)
std::ostream & operator<<(std::ostream &os, const common::SettingsValue &value)
bool operator==(const common::SettingsValue &a, const common::SettingsValue &b)
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(Span{std::forward< V >(v)}))
Like the Span constructor, but for (const) unsigned char member types only.
void ForEachNoDup(CharType(&string)[StringLength], CharType min_char, CharType max_char, Fn &&fn)
Iterate over string values and call function for each string without successive duplicate characters.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
void ForEachMergeSetup(Fn &&fn)
Enumerate all possible test configurations.
Action[MAX_ACTIONS] ActionList
static constexpr int MAX_ACTIONS
Max number of actions to sequence together.
std::map< std::string, std::map< std::string, std::vector< SettingsValue > > > ro_config
Map of config section name and setting name to list of config file values.
std::map< std::string, SettingsValue > forced_settings
Map of setting name to forced setting value.
std::map< std::string, std::vector< SettingsValue > > command_line_options
Map of setting name to list of command line values.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.