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