getarg_tests.cpp
1 // Copyright (c) 2012-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <common/args.h> 6 #include <common/settings.h> 7 #include <logging.h> 8 #include <test/util/common.h> 9 #include <test/util/setup_common.h> 10 #include <univalue.h> 11 #include <util/strencodings.h> 12 13 #include <limits> 14 #include <string> 15 #include <utility> 16 #include <vector> 17 18 #include <boost/test/unit_test.hpp> 19 20 using util::SplitString; 21 22 BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup) 23 24 void ResetArgs(ArgsManager& local_args, const std::string& strArg) 25 { 26 std::vector<std::string> vecArg; 27 if (strArg.size()) { 28 vecArg = SplitString(strArg, ' '); 29 } 30 31 // Insert dummy executable name: 32 vecArg.insert(vecArg.begin(), "testbitcoin"); 33 34 // Convert to char*: 35 std::vector<const char*> vecChar; 36 vecChar.reserve(vecArg.size()); 37 for (const std::string& s : vecArg) 38 vecChar.push_back(s.c_str()); 39 40 std::string error; 41 BOOST_CHECK(local_args.ParseParameters(vecChar.size(), vecChar.data(), error)); 42 } 43 44 void SetupArgs(ArgsManager& local_args, const std::vector<std::pair<std::string, unsigned int>>& args) 45 { 46 for (const auto& arg : args) { 47 local_args.AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS); 48 } 49 } 50 51 // Test behavior of GetArg functions when string, integer, and boolean types 52 // are specified in the settings.json file. GetArg functions are convenience 53 // functions. The GetSetting method can always be used instead of GetArg 54 // methods to retrieve original values, and there's not always an objective 55 // answer to what GetArg behavior is best in every case. This test makes sure 56 // there's test coverage for whatever the current behavior is, so it's not 57 // broken or changed unintentionally. 58 BOOST_AUTO_TEST_CASE(setting_args) 59 { 60 ArgsManager args; 61 SetupArgs(args, {{"-foo", ArgsManager::ALLOW_ANY}}); 62 63 auto set_foo = [&](const common::SettingsValue& value) { 64 args.LockSettings([&](common::Settings& settings) { 65 settings.rw_settings["foo"] = value; 66 }); 67 }; 68 69 set_foo("str"); 70 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "\"str\""); 71 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "str"); 72 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 0); 73 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), false); 74 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), false); 75 76 set_foo("99"); 77 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "\"99\""); 78 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "99"); 79 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 99); 80 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), true); 81 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), true); 82 83 set_foo("3.25"); 84 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "\"3.25\""); 85 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "3.25"); 86 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 3); 87 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), true); 88 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), true); 89 90 set_foo("0"); 91 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "\"0\""); 92 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "0"); 93 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 0); 94 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), false); 95 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), false); 96 97 set_foo(""); 98 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "\"\""); 99 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), ""); 100 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 0); 101 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), true); 102 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), true); 103 104 set_foo(99); 105 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "99"); 106 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "99"); 107 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 99); 108 BOOST_CHECK_THROW(args.GetBoolArg("foo", true), std::runtime_error); 109 BOOST_CHECK_THROW(args.GetBoolArg("foo", false), std::runtime_error); 110 111 set_foo(3.25); 112 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "3.25"); 113 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "3.25"); 114 BOOST_CHECK_THROW(args.GetIntArg("foo", 100), std::runtime_error); 115 BOOST_CHECK_THROW(args.GetBoolArg("foo", true), std::runtime_error); 116 BOOST_CHECK_THROW(args.GetBoolArg("foo", false), std::runtime_error); 117 118 set_foo(0); 119 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "0"); 120 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "0"); 121 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 0); 122 BOOST_CHECK_THROW(args.GetBoolArg("foo", true), std::runtime_error); 123 BOOST_CHECK_THROW(args.GetBoolArg("foo", false), std::runtime_error); 124 125 set_foo(true); 126 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "true"); 127 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "1"); 128 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 1); 129 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), true); 130 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), true); 131 132 set_foo(false); 133 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "false"); 134 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "0"); 135 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 0); 136 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), false); 137 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), false); 138 139 set_foo(UniValue::VOBJ); 140 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "{}"); 141 BOOST_CHECK_THROW(args.GetArg("foo", "default"), std::runtime_error); 142 BOOST_CHECK_THROW(args.GetIntArg("foo", 100), std::runtime_error); 143 BOOST_CHECK_THROW(args.GetBoolArg("foo", true), std::runtime_error); 144 BOOST_CHECK_THROW(args.GetBoolArg("foo", false), std::runtime_error); 145 146 set_foo(UniValue::VARR); 147 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "[]"); 148 BOOST_CHECK_THROW(args.GetArg("foo", "default"), std::runtime_error); 149 BOOST_CHECK_THROW(args.GetIntArg("foo", 100), std::runtime_error); 150 BOOST_CHECK_THROW(args.GetBoolArg("foo", true), std::runtime_error); 151 BOOST_CHECK_THROW(args.GetBoolArg("foo", false), std::runtime_error); 152 153 set_foo(UniValue::VNULL); 154 BOOST_CHECK_EQUAL(args.GetSetting("foo").write(), "null"); 155 BOOST_CHECK_EQUAL(args.GetArg("foo", "default"), "default"); 156 BOOST_CHECK_EQUAL(args.GetIntArg("foo", 100), 100); 157 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", true), true); 158 BOOST_CHECK_EQUAL(args.GetBoolArg("foo", false), false); 159 } 160 161 BOOST_AUTO_TEST_CASE(boolarg) 162 { 163 ArgsManager local_args; 164 165 const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY); 166 SetupArgs(local_args, {foo}); 167 ResetArgs(local_args, "-foo"); 168 BOOST_CHECK(local_args.GetBoolArg("-foo", false)); 169 BOOST_CHECK(local_args.GetBoolArg("-foo", true)); 170 171 BOOST_CHECK(!local_args.GetBoolArg("-fo", false)); 172 BOOST_CHECK(local_args.GetBoolArg("-fo", true)); 173 174 BOOST_CHECK(!local_args.GetBoolArg("-fooo", false)); 175 BOOST_CHECK(local_args.GetBoolArg("-fooo", true)); 176 177 ResetArgs(local_args, "-foo=0"); 178 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 179 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 180 181 ResetArgs(local_args, "-foo=1"); 182 BOOST_CHECK(local_args.GetBoolArg("-foo", false)); 183 BOOST_CHECK(local_args.GetBoolArg("-foo", true)); 184 185 // New 0.6 feature: auto-map -nosomething to !-something: 186 ResetArgs(local_args, "-nofoo"); 187 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 188 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 189 190 ResetArgs(local_args, "-nofoo=1"); 191 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 192 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 193 194 ResetArgs(local_args, "-foo -nofoo"); // -nofoo should win 195 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 196 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 197 198 ResetArgs(local_args, "-foo=1 -nofoo=1"); // -nofoo should win 199 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 200 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 201 202 ResetArgs(local_args, "-foo=0 -nofoo=0"); // -nofoo=0 should win 203 BOOST_CHECK(local_args.GetBoolArg("-foo", false)); 204 BOOST_CHECK(local_args.GetBoolArg("-foo", true)); 205 206 // New 0.6 feature: treat -- same as -: 207 ResetArgs(local_args, "--foo=1"); 208 BOOST_CHECK(local_args.GetBoolArg("-foo", false)); 209 BOOST_CHECK(local_args.GetBoolArg("-foo", true)); 210 211 ResetArgs(local_args, "--nofoo=1"); 212 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 213 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 214 } 215 216 BOOST_AUTO_TEST_CASE(stringarg) 217 { 218 ArgsManager local_args; 219 220 const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY); 221 const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); 222 SetupArgs(local_args, {foo, bar}); 223 ResetArgs(local_args, ""); 224 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", ""), ""); 225 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", "eleven"), "eleven"); 226 227 ResetArgs(local_args, "-foo -bar"); 228 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", ""), ""); 229 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", "eleven"), ""); 230 231 ResetArgs(local_args, "-foo="); 232 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", ""), ""); 233 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", "eleven"), ""); 234 235 ResetArgs(local_args, "-foo=11"); 236 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", ""), "11"); 237 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", "eleven"), "11"); 238 239 ResetArgs(local_args, "-foo=eleven"); 240 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", ""), "eleven"); 241 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", "eleven"), "eleven"); 242 } 243 244 BOOST_AUTO_TEST_CASE(intarg) 245 { 246 ArgsManager local_args; 247 248 const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY); 249 const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); 250 SetupArgs(local_args, {foo, bar}); 251 252 ResetArgs(local_args, ""); 253 BOOST_CHECK(!local_args.GetArg<int64_t>("-foo").has_value()); 254 BOOST_CHECK(!local_args.GetArg<uint8_t>("-bar").has_value()); 255 BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 11), 11); 256 BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 0), 0); 257 BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{222}), 222); 258 BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{0}), 0); 259 260 ResetArgs(local_args, "-foo -bar"); 261 BOOST_CHECK_EQUAL(local_args.GetArg<int64_t>("-foo"), 0); 262 BOOST_CHECK_EQUAL(local_args.GetArg<uint8_t>("-bar"), 0); 263 BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 11), 0); 264 BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{222}), 0); 265 266 // Check under-/overflow behavior. 267 ResetArgs(local_args, "-foo=-9223372036854775809 -bar=9223372036854775808"); 268 BOOST_CHECK_EQUAL(local_args.GetArg<int64_t>("-foo"), std::numeric_limits<int64_t>::min()); 269 BOOST_CHECK_EQUAL(local_args.GetArg<uint8_t>("-bar"), std::numeric_limits<uint8_t>::max()); 270 BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 0), std::numeric_limits<int64_t>::min()); 271 BOOST_CHECK_EQUAL(local_args.GetIntArg("-bar", 0), std::numeric_limits<int64_t>::max()); 272 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", uint8_t{0}), std::numeric_limits<uint8_t>::min()); 273 BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{0}), std::numeric_limits<uint8_t>::max()); 274 275 ResetArgs(local_args, "-foo=11 -bar=12"); 276 BOOST_CHECK_EQUAL(local_args.GetArg<int64_t>("-foo"), 11); 277 BOOST_CHECK_EQUAL(local_args.GetArg<uint8_t>("-bar"), 12); 278 BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 0), 11); 279 BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{11}), 12); 280 281 ResetArgs(local_args, "-foo=NaN -bar=NotANumber"); 282 BOOST_CHECK_EQUAL(local_args.GetArg<int64_t>("-foo"), 0); 283 BOOST_CHECK_EQUAL(local_args.GetArg<uint8_t>("-bar"), 0); 284 BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 1), 0); 285 BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{11}), 0); 286 } 287 288 BOOST_AUTO_TEST_CASE(patharg) 289 { 290 ArgsManager local_args; 291 292 const auto dir = std::make_pair("-dir", ArgsManager::ALLOW_ANY); 293 SetupArgs(local_args, {dir}); 294 ResetArgs(local_args, ""); 295 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), fs::path{}); 296 297 const fs::path root_path{"/"}; 298 ResetArgs(local_args, "-dir=/"); 299 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), root_path); 300 301 ResetArgs(local_args, "-dir=/."); 302 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), root_path); 303 304 ResetArgs(local_args, "-dir=/./"); 305 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), root_path); 306 307 ResetArgs(local_args, "-dir=/.//"); 308 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), root_path); 309 310 #ifdef WIN32 311 const fs::path win_root_path{"C:\\"}; 312 ResetArgs(local_args, "-dir=C:\\"); 313 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), win_root_path); 314 315 ResetArgs(local_args, "-dir=C:/"); 316 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), win_root_path); 317 318 ResetArgs(local_args, "-dir=C:\\\\"); 319 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), win_root_path); 320 321 ResetArgs(local_args, "-dir=C:\\."); 322 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), win_root_path); 323 324 ResetArgs(local_args, "-dir=C:\\.\\"); 325 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), win_root_path); 326 327 ResetArgs(local_args, "-dir=C:\\.\\\\"); 328 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), win_root_path); 329 #endif 330 331 const fs::path absolute_path{"/home/user/.bitcoin"}; 332 ResetArgs(local_args, "-dir=/home/user/.bitcoin"); 333 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 334 335 ResetArgs(local_args, "-dir=/root/../home/user/.bitcoin"); 336 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 337 338 ResetArgs(local_args, "-dir=/home/./user/.bitcoin"); 339 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 340 341 ResetArgs(local_args, "-dir=/home/user/.bitcoin/"); 342 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 343 344 ResetArgs(local_args, "-dir=/home/user/.bitcoin//"); 345 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 346 347 ResetArgs(local_args, "-dir=/home/user/.bitcoin/."); 348 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 349 350 ResetArgs(local_args, "-dir=/home/user/.bitcoin/./"); 351 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 352 353 ResetArgs(local_args, "-dir=/home/user/.bitcoin/.//"); 354 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), absolute_path); 355 356 const fs::path relative_path{"user/.bitcoin"}; 357 ResetArgs(local_args, "-dir=user/.bitcoin"); 358 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 359 360 ResetArgs(local_args, "-dir=somewhere/../user/.bitcoin"); 361 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 362 363 ResetArgs(local_args, "-dir=user/./.bitcoin"); 364 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 365 366 ResetArgs(local_args, "-dir=user/.bitcoin/"); 367 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 368 369 ResetArgs(local_args, "-dir=user/.bitcoin//"); 370 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 371 372 ResetArgs(local_args, "-dir=user/.bitcoin/."); 373 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 374 375 ResetArgs(local_args, "-dir=user/.bitcoin/./"); 376 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 377 378 ResetArgs(local_args, "-dir=user/.bitcoin/.//"); 379 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir"), relative_path); 380 381 // Check negated and default argument handling. Specifying an empty argument 382 // is the same as not specifying the argument. This is convenient for 383 // scripting so later command line arguments can override earlier command 384 // line arguments or bitcoin.conf values. Currently the -dir= case cannot be 385 // distinguished from -dir case with no assignment, but #16545 would add the 386 // ability to distinguish these in the future (and treat the no-assign case 387 // like an imperative command or an error). 388 ResetArgs(local_args, ""); 389 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir", "default"), fs::path{"default"}); 390 ResetArgs(local_args, "-dir=override"); 391 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir", "default"), fs::path{"override"}); 392 ResetArgs(local_args, "-dir="); 393 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir", "default"), fs::path{"default"}); 394 ResetArgs(local_args, "-dir"); 395 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir", "default"), fs::path{"default"}); 396 ResetArgs(local_args, "-nodir"); 397 BOOST_CHECK_EQUAL(local_args.GetPathArg("-dir", "default"), fs::path{""}); 398 } 399 400 BOOST_AUTO_TEST_CASE(doubledash) 401 { 402 ArgsManager local_args; 403 404 const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY); 405 const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); 406 SetupArgs(local_args, {foo, bar}); 407 ResetArgs(local_args, "--foo"); 408 BOOST_CHECK_EQUAL(local_args.GetBoolArg("-foo", false), true); 409 410 ResetArgs(local_args, "--foo=verbose --bar=1"); 411 BOOST_CHECK_EQUAL(local_args.GetArg("-foo", ""), "verbose"); 412 BOOST_CHECK_EQUAL(local_args.GetIntArg("-bar", 0), 1); 413 } 414 415 BOOST_AUTO_TEST_CASE(boolargno) 416 { 417 ArgsManager local_args; 418 419 const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY); 420 const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); 421 SetupArgs(local_args, {foo, bar}); 422 ResetArgs(local_args, "-nofoo"); 423 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 424 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 425 426 ResetArgs(local_args, "-nofoo=1"); 427 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 428 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 429 430 ResetArgs(local_args, "-nofoo=0"); 431 BOOST_CHECK(local_args.GetBoolArg("-foo", true)); 432 BOOST_CHECK(local_args.GetBoolArg("-foo", false)); 433 434 ResetArgs(local_args, "-foo --nofoo"); // --nofoo should win 435 BOOST_CHECK(!local_args.GetBoolArg("-foo", true)); 436 BOOST_CHECK(!local_args.GetBoolArg("-foo", false)); 437 438 ResetArgs(local_args, "-nofoo -foo"); // foo always wins: 439 BOOST_CHECK(local_args.GetBoolArg("-foo", true)); 440 BOOST_CHECK(local_args.GetBoolArg("-foo", false)); 441 } 442 443 BOOST_AUTO_TEST_CASE(logargs) 444 { 445 ArgsManager local_args; 446 447 const auto okaylog_bool = std::make_pair("-okaylog-bool", ArgsManager::ALLOW_ANY); 448 const auto okaylog_negbool = std::make_pair("-okaylog-negbool", ArgsManager::ALLOW_ANY); 449 const auto okaylog = std::make_pair("-okaylog", ArgsManager::ALLOW_ANY); 450 const auto dontlog = std::make_pair("-dontlog", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE); 451 SetupArgs(local_args, {okaylog_bool, okaylog_negbool, okaylog, dontlog}); 452 ResetArgs(local_args, "-okaylog-bool -nookaylog-negbool -okaylog=public -dontlog=private42"); 453 454 // Everything logged to debug.log will also append to str 455 std::string str; 456 auto print_connection = LogInstance().PushBackCallback( 457 [&str](const std::string& s) { 458 str += s; 459 }); 460 461 // Log the arguments 462 local_args.LogArgs(); 463 464 LogInstance().DeleteCallback(print_connection); 465 // Check that what should appear does, and what shouldn't doesn't. 466 BOOST_CHECK(str.find("Command-line arg: okaylog-bool=\"\"") != std::string::npos); 467 BOOST_CHECK(str.find("Command-line arg: okaylog-negbool=false") != std::string::npos); 468 BOOST_CHECK(str.find("Command-line arg: okaylog=\"public\"") != std::string::npos); 469 BOOST_CHECK(str.find("dontlog=****") != std::string::npos); 470 BOOST_CHECK(str.find("private42") == std::string::npos); 471 } 472 473 BOOST_AUTO_TEST_SUITE_END()