src/test/util_tests.cpp
BOOST_FIXTURE_TEST_CASE(util_ArgsMerge, ArgsMergeTestingSetup)
{
    CHash256 out_sha;
    FILE* out_file = nullptr;
    if (const char* out_path = getenv("ARGS_MERGE_TEST_OUT")) {
        out_file = fsbridge::fopen(out_path, "w");
        if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
    }

    ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions, bool soft_set, bool force_set,
                          const std::string& section, const std::string& network, bool net_specific) {
        TestArgsManager parser;
        LOCK(parser.cs_args);

        std::string desc = "net=";
        desc += network;
        parser.m_network = network;

        const std::string& name = net_specific ? "wallet" : "server";
        const std::string key = "-" + name;
        parser.AddArg(key, name, ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
        if (net_specific) parser.SetNetworkOnlyArg(key);

        auto args = GetValues(arg_actions, section, name, "a");
        std::vector<const char*> argv = {"ignored"};
        for (auto& arg : args) {
            arg.insert(0, "-");
            desc += " ";
            desc += arg;
            argv.push_back(arg.c_str());
        }
        std::string error;
        BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
        BOOST_CHECK_EQUAL(error, "");

        std::string conf;
        for (auto& conf_val : GetValues(conf_actions, section, name, "c")) {
            desc += " ";
            desc += conf_val;
            conf += conf_val;
            conf += "\n";
        }
        std::istringstream conf_stream(conf);
        BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
        BOOST_CHECK_EQUAL(error, "");

        if (soft_set) {
            desc += " soft";
            parser.SoftSetArg(key, "soft1");
            parser.SoftSetArg(key, "soft2");
        }

        if (force_set) {
            desc += " force";
            parser.ForceSetArg(key, "force1");
            parser.ForceSetArg(key, "force2");
        }

        desc += " || ";

        if (!parser.IsArgSet(key)) {
            desc += "unset";
            BOOST_CHECK(!parser.IsArgNegated(key));
            BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "default");
            BOOST_CHECK(parser.GetArgs(key).empty());
        } else if (parser.IsArgNegated(key)) {
            desc += "negated";
            BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "0");
            BOOST_CHECK(parser.GetArgs(key).empty());
        } else {
            desc += parser.GetArg(key, "default");
            desc += " |";
            for (const auto& arg : parser.GetArgs(key)) {
                desc += " ";
                desc += arg;
            }
        }

        std::set<std::string> ignored = parser.GetUnsuitableSectionOnlyArgs();
        if (!ignored.empty()) {
            desc += " | ignored";
            for (const auto& arg : ignored) {
                desc += " ";
                desc += arg;
            }
        }

        desc += "\n";

        out_sha.Write((const unsigned char*)desc.data(), desc.size());
        if (out_file) {
            BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
        }
    });

    if (out_file) {
        if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
        out_file = nullptr;
    }

    unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
    out_sha.Finalize(out_sha_bytes);
    std::string out_sha_hex = HexStr(std::begin(out_sha_bytes), std::end(out_sha_bytes));

    // If check below fails, should manually dump the results with:
    //
    //   ARGS_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ArgsMerge
    //
    // And verify diff against previous results to make sure the changes are expected.
    //
    // Results file is formatted like:
    //
    //   <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>
    BOOST_CHECK_EQUAL(out_sha_hex, "8fd4877bb8bf337badca950ede6c917441901962f160e52514e06a60dea46cde");
}
// Regression test covering different ways config settings can be merged. The
// test parses and merges settings, representing the results as strings that get
// compared against an expected hash. To debug, the result strings can be dumped
// to a file (see comments below).
Regression test covering different ways config settings can be merged. The
test parses and merges settings, representing the results as strings that get
compared against an expected hash. To debug, the result strings can be dumped
to a file .
Regression test covering different ways config settings can be merged . The test parses and merges settings representing the results as strings that get compared against an expected hash . To debug the result strings can be dumped to a file .
BOOST_FIXTURE_TEST_CASE(util_ArgsMerge, ArgsMergeTestingSetup)
{
    CHash256 out_sha;
    FILE* out_file = nullptr;
    if (const char* out_path = getenv("ARGS_MERGE_TEST_OUT")) {
        out_file = fsbridge::fopen(out_path, "w");
        if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
    }
    ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions, bool soft_set, bool force_set,
                          const std::string& section, const std::string& network, bool net_specific) {
        TestArgsManager parser;
        LOCK(parser.cs_args);
        std::string desc = "net=";
        desc += network;
        parser.m_network = network;
        const std::string& name = net_specific ? "wallet" : "server";
        const std::string key = "-" + name;
        parser.AddArg(key, name, ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
        if (net_specific) parser.SetNetworkOnlyArg(key);
        auto args = GetValues(arg_actions, section, name, "a");
        std::vector<const char*> argv = {"ignored"};
        for (auto& arg : args) {
            arg.insert(0, "-");
            desc += " ";
            desc += arg;
            argv.push_back(arg.c_str());
        }
        std::string error;
        BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
        BOOST_CHECK_EQUAL(error, "");
        std::string conf;
        for (auto& conf_val : GetValues(conf_actions, section, name, "c")) {
            desc += " ";
            desc += conf_val;
            conf += conf_val;
            conf += "\n";
        }
        std::istringstream conf_stream(conf);
        BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
        BOOST_CHECK_EQUAL(error, "");
        if (soft_set) {
            desc += " soft";
            parser.SoftSetArg(key, "soft1");
            parser.SoftSetArg(key, "soft2");
        }
        if (force_set) {
            desc += " force";
            parser.ForceSetArg(key, "force1");
            parser.ForceSetArg(key, "force2");
        }
        desc += " || ";
        if (!parser.IsArgSet(key)) {
            desc += "unset";
            BOOST_CHECK(!parser.IsArgNegated(key));
            BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "default");
            BOOST_CHECK(parser.GetArgs(key).empty());
        } else if (parser.IsArgNegated(key)) {
            desc += "negated";
            BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "0");
            BOOST_CHECK(parser.GetArgs(key).empty());
        } else {
            desc += parser.GetArg(key, "default");
            desc += " |";
            for (const auto& arg : parser.GetArgs(key)) {
                desc += " ";
                desc += arg;
            }
        }
        std::set<std::string> ignored = parser.GetUnsuitableSectionOnlyArgs();
        if (!ignored.empty()) {
            desc += " | ignored";
            for (const auto& arg : ignored) {
                desc += " ";
                desc += arg;
            }
        }
        desc += "\n";
        out_sha.Write((const unsigned char*)desc.data(), desc.size());
        if (out_file) {
            BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
        }
    });
    if (out_file) {
        if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
        out_file = nullptr;
    }
    unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
    out_sha.Finalize(out_sha_bytes);
    std::string out_sha_hex = HexStr(std::begin(out_sha_bytes), std::end(out_sha_bytes));
       ARGS_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ArgsMerge
     And verify diff against previous results to make sure the changes are expected.
     Results file is formatted like:
       <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>
    BOOST_CHECK_EQUAL(out_sha_hex, "8fd4877bb8bf337badca950ede6c917441901962f160e52514e06a60dea46cde");
}
BOOST_FIXTURE_TEST_CASE ( util_ArgsMerge , ArgsMergeTestingSetup ) { CHash256 out_sha ; FILE * out_file = nullptr ; if ( const char * out_path = getenv ( " " ) ) { out_file = fsbridge :: fopen ( out_path , " " ) ; if ( ! out_file ) throw std :: system_error ( errno , std :: generic_category ( ) , " " ) ; } ForEachMergeSetup ( [ & ] ( const ActionList & arg_actions , const ActionList & conf_actions , bool soft_set , bool force_set , const std :: string & section , const std :: string & network , bool net_specific ) { TestArgsManager parser ; LOCK ( parser . cs_args ) ; std :: string desc = " " ; desc += network ; parser . m_network = network ; const std :: string & name = net_specific ? " " : " " ; const std :: string key = " " + name ; parser . AddArg ( key , name , ArgsManager :: ALLOW_ANY , OptionsCategory :: OPTIONS ) ; if ( net_specific ) parser . SetNetworkOnlyArg ( key ) ; auto args = GetValues ( arg_actions , section , name , " " ) ; std :: vector < const char * > argv = { " " } ; for ( auto & arg : args ) { arg . insert ( 0 , " " ) ; desc += " " ; desc += arg ; argv . push_back ( arg . c_str ( ) ) ; } std :: string error ; BOOST_CHECK ( parser . ParseParameters ( argv . size ( ) , argv . data ( ) , error ) ) ; BOOST_CHECK_EQUAL ( error , " " ) ; std :: string conf ; for ( auto & conf_val : GetValues ( conf_actions , section , name , " " ) ) { desc += " " ; desc += conf_val ; conf += conf_val ; conf += " \n " ; } std :: istringstream conf_stream ( conf ) ; BOOST_CHECK ( parser . ReadConfigStream ( conf_stream , " " , error ) ) ; BOOST_CHECK_EQUAL ( error , " " ) ; if ( soft_set ) { desc += " " ; parser . SoftSetArg ( key , " " ) ; parser . SoftSetArg ( key , " " ) ; } if ( force_set ) { desc += " " ; parser . ForceSetArg ( key , " " ) ; parser . ForceSetArg ( key , " " ) ; } desc += " " ; if ( ! parser . IsArgSet ( key ) ) { desc += " " ; BOOST_CHECK ( ! parser . IsArgNegated ( key ) ) ; BOOST_CHECK_EQUAL ( parser . GetArg ( key , " " ) , " " ) ; BOOST_CHECK ( parser . GetArgs ( key ) . empty ( ) ) ; } else if ( parser . IsArgNegated ( key ) ) { desc += " " ; BOOST_CHECK_EQUAL ( parser . GetArg ( key , " " ) , " " ) ; BOOST_CHECK ( parser . GetArgs ( key ) . empty ( ) ) ; } else { desc += parser . GetArg ( key , " " ) ; desc += " " ; for ( const auto & arg : parser . GetArgs ( key ) ) { desc += " " ; desc += arg ; } } std :: set < std :: string > ignored = parser . GetUnsuitableSectionOnlyArgs ( ) ; if ( ! ignored . empty ( ) ) { desc += " " ; for ( const auto & arg : ignored ) { desc += " " ; desc += arg ; } } desc += " \n " ; out_sha . Write ( ( const unsigned char * ) desc . data ( ) , desc . size ( ) ) ; if ( out_file ) { BOOST_REQUIRE ( fwrite ( desc . data ( ) , 1 , desc . size ( ) , out_file ) == desc . size ( ) ) ; } } ) ; if ( out_file ) { if ( fclose ( out_file ) ) throw std :: system_error ( errno , std :: generic_category ( ) , " " ) ; out_file = nullptr ; } unsigned char out_sha_bytes [ CSHA256 :: OUTPUT_SIZE ] ; out_sha . Finalize ( out_sha_bytes ) ; std :: string out_sha_hex = HexStr ( std :: begin ( out_sha_bytes ) , std :: end ( out_sha_bytes ) ) ; BOOST_CHECK_EQUAL ( out_sha_hex , " " ) ; }
Regression test covering different ways config settings can be merged.
Regression test covering different ways config settings can be merged .
// If check below fails, should manually dump the results with: // //   ARGS_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ArgsMerge // // And verify diff against previous results to make sure the changes are expected. // // Results file is formatted like: // //   <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>