7
7
#include < clientversion.h>
8
8
#include < primitives/transaction.h>
9
9
#include < sync.h>
10
+ #include < test/util.h>
10
11
#include < util/strencodings.h>
11
12
#include < util/moneystr.h>
12
13
#include < test/setup_common.h>
@@ -580,7 +581,7 @@ BOOST_AUTO_TEST_CASE(util_GetChainName)
580
581
581
582
// Test different ways settings can be merged, and verify results. This test can
582
583
// be used to confirm that updates to settings code don't change behavior
583
- // unintentially .
584
+ // unintentionally .
584
585
//
585
586
// The test covers:
586
587
//
@@ -600,20 +601,22 @@ BOOST_AUTO_TEST_CASE(util_GetChainName)
600
601
// outside a network section, and non-network specific settings like "-server"
601
602
// that aren't sensitive to the network.
602
603
//
603
- struct SettingsMergeTestingSetup : public BasicTestingSetup {
604
+ struct ArgsMergeTestingSetup : public BasicTestingSetup {
604
605
// ! Max number of actions to sequence together. Can decrease this when
605
606
// ! debugging to make test results easier to understand.
606
607
static constexpr int MAX_ACTIONS = 3 ;
607
608
608
- enum Action { SET = 0 , NEGATE, SECTION_SET, SECTION_NEGATE, END };
609
+ enum Action { NONE, SET , NEGATE, SECTION_SET, SECTION_NEGATE };
609
610
using ActionList = Action[MAX_ACTIONS];
610
611
611
612
// ! Enumerate all possible test configurations.
612
613
template <typename Fn>
613
614
void ForEachMergeSetup (Fn&& fn)
614
615
{
615
- ForEachActionList ([&](const ActionList& arg_actions) {
616
- ForEachActionList ([&](const ActionList& conf_actions) {
616
+ ActionList arg_actions = {};
617
+ ForEachNoDup (arg_actions, SET, SECTION_NEGATE, [&] {
618
+ ActionList conf_actions = {};
619
+ ForEachNoDup (conf_actions, SET, SECTION_NEGATE, [&] {
617
620
for (bool soft_set : {false , true }) {
618
621
for (bool force_set : {false , true }) {
619
622
for (const std::string& section : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET}) {
@@ -629,36 +632,6 @@ struct SettingsMergeTestingSetup : public BasicTestingSetup {
629
632
});
630
633
}
631
634
632
- // ! Enumerate interesting combinations of actions.
633
- template <typename Fn>
634
- void ForEachActionList (Fn&& fn)
635
- {
636
- ActionList actions = {SET};
637
- for (bool done = false ; !done;) {
638
- int prev_action = -1 ;
639
- bool skip_actions = false ;
640
- for (Action action : actions) {
641
- if ((prev_action == END && action != END) || (prev_action != END && action == prev_action)) {
642
- // To cut down list of enumerated settings, skip enumerating
643
- // settings with ignored actions after an END, and settings that
644
- // repeat the same action twice in a row.
645
- skip_actions = true ;
646
- break ;
647
- }
648
- prev_action = action;
649
- }
650
- if (!skip_actions) fn (actions);
651
- done = true ;
652
- for (Action& action : actions) {
653
- action = Action (action < END ? action + 1 : 0 );
654
- if (action) {
655
- done = false ;
656
- break ;
657
- }
658
- }
659
- }
660
- }
661
-
662
635
// ! Translate actions into a list of <key>=<value> setting strings.
663
636
std::vector<std::string> GetValues (const ActionList& actions,
664
637
const std::string& section,
@@ -668,7 +641,7 @@ struct SettingsMergeTestingSetup : public BasicTestingSetup {
668
641
std::vector<std::string> values;
669
642
int suffix = 0 ;
670
643
for (Action action : actions) {
671
- if (action == END ) break ;
644
+ if (action == NONE ) break ;
672
645
std::string prefix;
673
646
if (action == SECTION_SET || action == SECTION_NEGATE) prefix = section + " ." ;
674
647
if (action == SET || action == SECTION_SET) {
@@ -687,12 +660,12 @@ struct SettingsMergeTestingSetup : public BasicTestingSetup {
687
660
// Regression test covering different ways config settings can be merged. The
688
661
// test parses and merges settings, representing the results as strings that get
689
662
// compared against an expected hash. To debug, the result strings can be dumped
690
- // to a file (see below).
691
- BOOST_FIXTURE_TEST_CASE (util_SettingsMerge, SettingsMergeTestingSetup )
663
+ // to a file (see comments below).
664
+ BOOST_FIXTURE_TEST_CASE (util_ArgsMerge, ArgsMergeTestingSetup )
692
665
{
693
666
CHash256 out_sha;
694
667
FILE* out_file = nullptr ;
695
- if (const char * out_path = getenv (" SETTINGS_MERGE_TEST_OUT " )) {
668
+ if (const char * out_path = getenv (" ARGS_MERGE_TEST_OUT " )) {
696
669
out_file = fsbridge::fopen (out_path, " w" );
697
670
if (!out_file) throw std::system_error (errno, std::generic_category (), " fopen failed" );
698
671
}
@@ -706,7 +679,7 @@ BOOST_FIXTURE_TEST_CASE(util_SettingsMerge, SettingsMergeTestingSetup)
706
679
desc += network;
707
680
parser.m_network = network;
708
681
709
- const std::string& name = net_specific ? " server " : " wallet " ;
682
+ const std::string& name = net_specific ? " wallet " : " server " ;
710
683
const std::string key = " -" + name;
711
684
parser.AddArg (key, name, false , OptionsCategory::OPTIONS);
712
685
if (net_specific) parser.SetNetworkOnlyArg (key);
@@ -794,14 +767,116 @@ BOOST_FIXTURE_TEST_CASE(util_SettingsMerge, SettingsMergeTestingSetup)
794
767
795
768
// If check below fails, should manually dump the results with:
796
769
//
797
- // SETTINGS_MERGE_TEST_OUT =results.txt ./test_bitcoin --run_test=util_tests/util_SettingsMerge
770
+ // ARGS_MERGE_TEST_OUT =results.txt ./test_bitcoin --run_test=util_tests/util_ArgsMerge
798
771
//
799
772
// And verify diff against previous results to make sure the changes are expected.
800
773
//
801
774
// Results file is formatted like:
802
775
//
803
776
// <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>
804
- BOOST_CHECK_EQUAL (out_sha_hex, " 80964e17fbd3c5569d3c824d032e28e2d319ef57494735b0e76eb7aad9957f2c" );
777
+ BOOST_CHECK_EQUAL (out_sha_hex, " b835eef5977d69114eb039a976201f8c7121f34fe2b7ea2b73cafb516e5c9dc8" );
778
+ }
779
+
780
+ // Similar test as above, but for ArgsManager::GetChainName function.
781
+ struct ChainMergeTestingSetup : public BasicTestingSetup {
782
+ static constexpr int MAX_ACTIONS = 2 ;
783
+
784
+ enum Action { NONE, ENABLE_TEST, DISABLE_TEST, NEGATE_TEST, ENABLE_REG, DISABLE_REG, NEGATE_REG };
785
+ using ActionList = Action[MAX_ACTIONS];
786
+
787
+ // ! Enumerate all possible test configurations.
788
+ template <typename Fn>
789
+ void ForEachMergeSetup (Fn&& fn)
790
+ {
791
+ ActionList arg_actions = {};
792
+ ForEachNoDup (arg_actions, ENABLE_TEST, NEGATE_REG, [&] {
793
+ ActionList conf_actions = {};
794
+ ForEachNoDup (conf_actions, ENABLE_TEST, NEGATE_REG, [&] { fn (arg_actions, conf_actions); });
795
+ });
796
+ }
797
+ };
798
+
799
+ BOOST_FIXTURE_TEST_CASE (util_ChainMerge, ChainMergeTestingSetup)
800
+ {
801
+ CHash256 out_sha;
802
+ FILE* out_file = nullptr ;
803
+ if (const char * out_path = getenv (" CHAIN_MERGE_TEST_OUT" )) {
804
+ out_file = fsbridge::fopen (out_path, " w" );
805
+ if (!out_file) throw std::system_error (errno, std::generic_category (), " fopen failed" );
806
+ }
807
+
808
+ ForEachMergeSetup ([&](const ActionList& arg_actions, const ActionList& conf_actions) {
809
+ TestArgsManager parser;
810
+ LOCK (parser.cs_args );
811
+ parser.AddArg (" -regtest" , " regtest" , false , OptionsCategory::OPTIONS);
812
+ parser.AddArg (" -testnet" , " testnet" , false , OptionsCategory::OPTIONS);
813
+
814
+ auto arg = [](Action action) { return action == ENABLE_TEST ? " -testnet=1" :
815
+ action == DISABLE_TEST ? " -testnet=0" :
816
+ action == NEGATE_TEST ? " -notestnet=1" :
817
+ action == ENABLE_REG ? " -regtest=1" :
818
+ action == DISABLE_REG ? " -regtest=0" :
819
+ action == NEGATE_REG ? " -noregtest=1" : nullptr ; };
820
+
821
+ std::string desc;
822
+ std::vector<const char *> argv = {" ignored" };
823
+ for (Action action : arg_actions) {
824
+ const char * argstr = arg (action);
825
+ if (!argstr) break ;
826
+ argv.push_back (argstr);
827
+ desc += " " ;
828
+ desc += argv.back ();
829
+ }
830
+ std::string error;
831
+ BOOST_CHECK (parser.ParseParameters (argv.size (), argv.data (), error));
832
+ BOOST_CHECK_EQUAL (error, " " );
833
+
834
+ std::string conf;
835
+ for (Action action : conf_actions) {
836
+ const char * argstr = arg (action);
837
+ if (!argstr) break ;
838
+ desc += " " ;
839
+ desc += argstr + 1 ;
840
+ conf += argstr + 1 ;
841
+ }
842
+ std::istringstream conf_stream (conf);
843
+ BOOST_CHECK (parser.ReadConfigStream (conf_stream, " filepath" , error));
844
+ BOOST_CHECK_EQUAL (error, " " );
845
+
846
+ desc += " || " ;
847
+ try {
848
+ desc += parser.GetChainName ();
849
+ } catch (const std::runtime_error& e) {
850
+ desc += " error: " ;
851
+ desc += e.what ();
852
+ }
853
+ desc += " \n " ;
854
+
855
+ out_sha.Write ((const unsigned char *)desc.data (), desc.size ());
856
+ if (out_file) {
857
+ BOOST_REQUIRE (fwrite (desc.data (), 1 , desc.size (), out_file) == desc.size ());
858
+ }
859
+ });
860
+
861
+ if (out_file) {
862
+ if (fclose (out_file)) throw std::system_error (errno, std::generic_category (), " fclose failed" );
863
+ out_file = nullptr ;
864
+ }
865
+
866
+ unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
867
+ out_sha.Finalize (out_sha_bytes);
868
+ std::string out_sha_hex = HexStr (std::begin (out_sha_bytes), std::end (out_sha_bytes));
869
+
870
+ // If check below fails, should manually dump the results with:
871
+ //
872
+ // CHAIN_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ChainMerge
873
+ //
874
+ // And verify diff against previous results to make sure the changes are expected.
875
+ //
876
+ // Results file is formatted like:
877
+ //
878
+ // <input> || <output>
879
+ BOOST_CHECK_EQUAL (out_sha_hex, " b284f4b4a15dd6bf8c06213a69a004b1960388e1d9917173927db52ac220927f" );
805
880
}
806
881
807
882
BOOST_AUTO_TEST_CASE (util_FormatMoney)
0 commit comments