Branch data Line data Source code
1 : : // Copyright (c) 2011-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 <clientversion.h>
6 : : #include <common/signmessage.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC
7 : : #include <hash.h> // For Hash()
8 : : #include <key.h> // For CKey
9 : : #include <script/parsing.h>
10 : : #include <sync.h>
11 : : #include <test/util/random.h>
12 : : #include <test/util/setup_common.h>
13 : : #include <uint256.h>
14 : : #include <util/bitdeque.h>
15 : : #include <util/fs.h>
16 : : #include <util/fs_helpers.h>
17 : : #include <util/moneystr.h>
18 : : #include <util/overflow.h>
19 : : #include <util/readwritefile.h>
20 : : #include <util/strencodings.h>
21 : : #include <util/string.h>
22 : : #include <util/time.h>
23 : : #include <util/vector.h>
24 : :
25 : : #include <array>
26 : : #include <cmath>
27 : : #include <fstream>
28 : : #include <limits>
29 : : #include <map>
30 : : #include <optional>
31 : : #include <stdint.h>
32 : : #include <string.h>
33 : : #include <thread>
34 : : #include <univalue.h>
35 : : #include <utility>
36 : : #include <vector>
37 : :
38 : : #include <sys/types.h>
39 : :
40 : : #ifndef WIN32
41 : : #include <signal.h>
42 : : #include <sys/wait.h>
43 : : #endif
44 : :
45 : : #include <boost/test/unit_test.hpp>
46 : :
47 : : using namespace std::literals;
48 : : using util::Join;
49 : : using util::RemovePrefix;
50 : : using util::RemovePrefixView;
51 : : using util::ReplaceAll;
52 : : using util::Split;
53 : : using util::SplitString;
54 : : using util::TrimString;
55 : : using util::TrimStringView;
56 : :
57 : : static const std::string STRING_WITH_EMBEDDED_NULL_CHAR{"1"s "\0" "1"s};
58 : :
59 : : /* defined in logging.cpp */
60 : : namespace BCLog {
61 : : std::string LogEscapeMessage(std::string_view str);
62 : : }
63 : :
64 : : BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
65 : :
66 : : namespace {
67 : : class NoCopyOrMove
68 : : {
69 : : public:
70 : : int i;
71 : 2 : explicit NoCopyOrMove(int i) : i{i} { }
72 : :
73 : : NoCopyOrMove() = delete;
74 : : NoCopyOrMove(const NoCopyOrMove&) = delete;
75 : : NoCopyOrMove(NoCopyOrMove&&) = delete;
76 : : NoCopyOrMove& operator=(const NoCopyOrMove&) = delete;
77 : : NoCopyOrMove& operator=(NoCopyOrMove&&) = delete;
78 : :
79 [ - + ]: 6 : operator bool() const { return i != 0; }
80 : :
81 : 2 : int get_ip1() { return i + 1; }
82 : 2 : bool test()
83 : : {
84 : : // Check that Assume can be used within a lambda and still call methods
85 : 2 : [&]() { Assume(get_ip1()); }();
86 : 2 : return Assume(get_ip1() != 5);
87 : : }
88 : : };
89 : : } // namespace
90 : :
91 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_check)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
92 : : {
93 : : // Check that Assert can forward
94 [ + - ]: 2 : const std::unique_ptr<int> p_two = Assert(std::make_unique<int>(2));
95 : : // Check that Assert works on lvalues and rvalues
96 [ + - + - ]: 2 : const int two = *Assert(p_two);
97 [ + - ]: 2 : Assert(two == 2);
98 [ + - ]: 2 : Assert(true);
99 : : // Check that Assume can be used as unary expression
100 : 2 : const bool result{Assume(two == 2)};
101 [ + - ]: 2 : Assert(result);
102 : :
103 : : // Check that Assert doesn't require copy/move
104 : 2 : NoCopyOrMove x{9};
105 [ + - ]: 2 : Assert(x).i += 3;
106 [ + - ]: 2 : Assert(x).test();
107 : :
108 : : // Check nested Asserts
109 [ + - + - : 2 : BOOST_CHECK_EQUAL(Assert((Assert(x).test() ? 3 : 0)), 3);
- + + - +
- ]
110 : :
111 : : // Check -Wdangling-gsl does not trigger when copying the int. (It would
112 : : // trigger on "const int&")
113 [ + - + - ]: 2 : const int nine{*Assert(std::optional<int>{9})};
114 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(9, nine);
115 : 2 : }
116 : :
117 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_criticalsection)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
118 : : {
119 : 2 : RecursiveMutex cs;
120 : :
121 : 4 : do {
122 : 2 : LOCK(cs);
123 [ + - ]: 2 : break;
124 : :
125 : : BOOST_ERROR("break was swallowed!");
126 : 2 : } while(0);
127 : :
128 : 2 : do {
129 : 2 : TRY_LOCK(cs, lockTest);
130 [ + - ]: 2 : if (lockTest) {
131 [ + - + - : 4 : BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
+ - ]
132 [ + - ]: 2 : break;
133 : : }
134 : :
135 [ # # # # : 0 : BOOST_ERROR("break was swallowed!");
# # ]
136 : 2 : } while(0);
137 : 2 : }
138 : :
139 : : static const unsigned char ParseHex_expected[65] = {
140 : : 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
141 : : 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
142 : : 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
143 : : 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
144 : : 0x5f
145 : : };
146 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(parse_hex)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
147 : : {
148 : 2 : std::vector<unsigned char> result;
149 [ + - ]: 2 : std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
150 : : // Basic test vector
151 [ + - ]: 4 : result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
152 [ + - + - : 4 : BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
+ - + - ]
153 [ + - ]: 4 : result = TryParseHex<uint8_t>("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f").value();
154 [ + - + - : 4 : BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
+ - + - ]
155 : :
156 : : // Spaces between bytes must be supported
157 [ + - ]: 4 : result = ParseHex("12 34 56 78");
158 [ + - + - : 4 : BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
+ - + - +
- - + + -
+ - ]
159 [ + - ]: 4 : result = TryParseHex<uint8_t>("12 34 56 78").value();
160 [ + - + - : 4 : BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
+ - + - +
- - + + -
+ - ]
161 : :
162 : : // Leading space must be supported (used in BerkeleyEnvironment::Salvage)
163 [ + - ]: 4 : result = ParseHex(" 89 34 56 78");
164 [ + - + - : 4 : BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
+ - + - +
- - + + -
+ - ]
165 [ + - ]: 4 : result = TryParseHex<uint8_t>(" 89 34 56 78").value();
166 [ + - + - : 4 : BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
+ - + - +
- - + + -
+ - ]
167 : :
168 : : // Mixed case and spaces are supported
169 [ + - ]: 4 : result = ParseHex(" Ff aA ");
170 [ + - + - : 4 : BOOST_CHECK(result.size() == 2 && result[0] == 0xff && result[1] == 0xaa);
+ - - + +
- + - ]
171 [ + - ]: 4 : result = TryParseHex<uint8_t>(" Ff aA ").value();
172 [ + - + - : 4 : BOOST_CHECK(result.size() == 2 && result[0] == 0xff && result[1] == 0xaa);
+ - - + +
- + - ]
173 : :
174 : : // Empty string is supported
175 [ + - ]: 4 : result = ParseHex("");
176 [ + - + - : 4 : BOOST_CHECK(result.size() == 0);
+ - ]
177 [ + - ]: 4 : result = TryParseHex<uint8_t>("").value();
178 [ + - + - : 4 : BOOST_CHECK(result.size() == 0);
+ - ]
179 : :
180 : : // Spaces between nibbles is treated as invalid
181 [ + - + - : 2 : BOOST_CHECK_EQUAL(ParseHex("AAF F").size(), 0);
+ - ]
182 [ + - + - : 4 : BOOST_CHECK(!TryParseHex("AAF F").has_value());
+ - + - ]
183 : :
184 : : // Embedded null is treated as invalid
185 [ + - ]: 2 : const std::string with_embedded_null{" 11 "s
186 : : " \0 "
187 : 2 : " 22 "s};
188 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(with_embedded_null.size(), 11);
189 [ + - + - : 2 : BOOST_CHECK_EQUAL(ParseHex(with_embedded_null).size(), 0);
+ - ]
190 [ + - + - : 4 : BOOST_CHECK(!TryParseHex(with_embedded_null).has_value());
+ - + - ]
191 : :
192 : : // Non-hex is treated as invalid
193 [ + - + - : 2 : BOOST_CHECK_EQUAL(ParseHex("1234 invalid 1234").size(), 0);
+ - ]
194 [ + - + - : 4 : BOOST_CHECK(!TryParseHex("1234 invalid 1234").has_value());
+ - + - ]
195 : :
196 : : // Truncated input is treated as invalid
197 [ + - + - : 2 : BOOST_CHECK_EQUAL(ParseHex("12 3").size(), 0);
+ - ]
198 [ + - + - : 4 : BOOST_CHECK(!TryParseHex("12 3").has_value());
+ - ]
199 : 2 : }
200 : :
201 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_HexStr)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
202 : : {
203 [ + - ]: 2 : BOOST_CHECK_EQUAL(
204 : : HexStr(ParseHex_expected),
205 : : "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
206 : :
207 [ + - ]: 2 : BOOST_CHECK_EQUAL(
208 : : HexStr(Span{ParseHex_expected}.last(0)),
209 : : "");
210 : :
211 [ + - ]: 2 : BOOST_CHECK_EQUAL(
212 : : HexStr(Span{ParseHex_expected}.first(0)),
213 : : "");
214 : :
215 : 2 : {
216 : 2 : const std::vector<char> in_s{ParseHex_expected, ParseHex_expected + 5};
217 : 2 : const Span<const uint8_t> in_u{MakeUCharSpan(in_s)};
218 : 2 : const Span<const std::byte> in_b{MakeByteSpan(in_s)};
219 [ + - ]: 2 : const std::string out_exp{"04678afdb0"};
220 : :
221 [ + - + - : 2 : BOOST_CHECK_EQUAL(HexStr(in_u), out_exp);
+ - ]
222 [ + - + - : 2 : BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
+ - ]
223 [ + - + - : 2 : BOOST_CHECK_EQUAL(HexStr(in_b), out_exp);
+ - ]
224 : 2 : }
225 : :
226 : 2 : {
227 : 2 : auto input = std::string();
228 [ + + ]: 514 : for (size_t i=0; i<256; ++i) {
229 [ + - ]: 512 : input.push_back(static_cast<char>(i));
230 : : }
231 : :
232 [ + - ]: 2 : auto hex = HexStr(input);
233 [ + - + - : 4 : BOOST_TEST_REQUIRE(hex.size() == 512);
+ - ]
234 : 2 : static constexpr auto hexmap = std::string_view("0123456789abcdef");
235 [ + + ]: 514 : for (size_t i = 0; i < 256; ++i) {
236 [ + - ]: 512 : auto upper = hexmap.find(hex[i * 2]);
237 [ + - ]: 512 : auto lower = hexmap.find(hex[i * 2 + 1]);
238 [ + - + - : 1024 : BOOST_TEST_REQUIRE(upper != std::string_view::npos);
+ - + - ]
239 [ + - + - : 1024 : BOOST_TEST_REQUIRE(lower != std::string_view::npos);
+ - + - ]
240 [ + - + - : 1024 : BOOST_TEST_REQUIRE(i == upper*16 + lower);
+ - ]
241 : : }
242 : 2 : }
243 : 2 : }
244 : :
245 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(span_write_bytes)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
246 : : {
247 : 2 : std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}};
248 : 2 : const auto mut_bytes{MakeWritableByteSpan(mut_arr)};
249 : 2 : mut_bytes[1] = std::byte{0x11};
250 [ + - ]: 2 : BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa);
251 [ + - ]: 2 : BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11);
252 : 2 : }
253 : :
254 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_Join)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
255 : : {
256 : : // Normal version
257 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(Join(std::vector<std::string>{}, ", "), "");
258 [ + - + + : 6 : BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo"}, ", "), "foo");
+ - + - +
- + + - -
- - ]
259 [ + - + + : 10 : BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo", "bar"}, ", "), "foo, bar");
+ - + - +
- + + - -
- - ]
260 : :
261 : : // Version with unary operator
262 : 8 : const auto op_upper = [](const std::string& s) { return ToUpper(s); };
263 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(Join(std::list<std::string>{}, ", ", op_upper), "");
264 [ + - + + : 6 : BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo"}, ", ", op_upper), "FOO");
+ - + - +
- + + - -
- - ]
265 [ + - + + : 10 : BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo", "bar"}, ", ", op_upper), "FOO, BAR");
+ - + - +
- + + - -
- - ]
266 : 2 : }
267 : :
268 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_ReplaceAll)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
269 : : {
270 : 2 : const std::string original("A test \"%s\" string '%s'.");
271 : 12 : auto test_replaceall = [&original](const std::string& search, const std::string& substitute, const std::string& expected) {
272 : 10 : auto test = original;
273 [ + - ]: 10 : ReplaceAll(test, search, substitute);
274 [ + - + - ]: 10 : BOOST_CHECK_EQUAL(test, expected);
275 : 12 : };
276 : :
277 [ + - + - : 4 : test_replaceall("", "foo", original);
+ - ]
278 [ + - + - : 4 : test_replaceall(original, "foo", "foo");
+ - ]
279 [ + - + - : 4 : test_replaceall("%s", "foo", "A test \"foo\" string 'foo'.");
+ - + - ]
280 [ + - + - : 4 : test_replaceall("\"", "foo", "A test foo%sfoo string '%s'.");
+ - + - ]
281 [ + - + - : 4 : test_replaceall("'", "foo", "A test \"%s\" string foo%sfoo.");
+ - + - ]
282 : 2 : }
283 : :
284 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_TrimString)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
285 : : {
286 [ + - ]: 2 : BOOST_CHECK_EQUAL(TrimString(" foo bar "), "foo bar");
287 [ + - ]: 2 : BOOST_CHECK_EQUAL(TrimStringView("\t \n \n \f\n\r\t\v\tfoo \n \f\n\r\t\v\tbar\t \n \f\n\r\t\v\t\n "), "foo \n \f\n\r\t\v\tbar");
288 [ + - ]: 2 : BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar");
289 [ + - ]: 2 : BOOST_CHECK_EQUAL(TrimStringView("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n ");
290 [ + - ]: 2 : BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar");
291 [ + - ]: 2 : BOOST_CHECK_EQUAL(TrimStringView("foo bar", "fobar"), " ");
292 [ + - + - : 2 : BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7));
+ - ]
293 [ + - + - : 2 : BOOST_CHECK_EQUAL(TrimStringView(std::string(" foo ", 5)), std::string("foo", 3));
+ - ]
294 [ + - + - : 2 : BOOST_CHECK_EQUAL(TrimString(std::string("\t\t\0\0\n\n", 6)), std::string("\0\0", 2));
+ - ]
295 [ + - + - : 2 : BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6)), std::string("\x05\x04\x03\x02\x01\x00", 6));
+ - ]
296 [ + - + - : 2 : BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01", 5)), std::string("\0", 1));
+ - + - ]
297 [ + - + - : 2 : BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), "");
+ - ]
298 : 2 : }
299 : :
300 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
301 : : {
302 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890963199), "32767-12-31T23:59:59Z");
303 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890876800), "32767-12-31T00:00:00Z");
304 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
305 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z");
306 : 2 : }
307 : :
308 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_FormatISO8601Date)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
309 : : {
310 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601Date(971890963199), "32767-12-31");
311 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601Date(971890876800), "32767-12-31");
312 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30");
313 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatISO8601Date(0), "1970-01-01");
314 : 2 : }
315 : :
316 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_FormatMoney)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
317 : : {
318 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
319 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
320 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00");
321 : :
322 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
323 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
324 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
325 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
326 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
327 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
328 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
329 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
330 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00");
331 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10");
332 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
333 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
334 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
335 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
336 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
337 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
338 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
339 : :
340 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max()), "92233720368.54775807");
341 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 1), "92233720368.54775806");
342 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 2), "92233720368.54775805");
343 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 3), "92233720368.54775804");
344 : : // ...
345 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 3), "-92233720368.54775805");
346 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 2), "-92233720368.54775806");
347 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 1), "-92233720368.54775807");
348 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min()), "-92233720368.54775808");
349 : 2 : }
350 : :
351 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_ParseMoney)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
352 : : {
353 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0);
354 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney(".").value(), 0);
355 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.").value(), 0);
356 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney(".0").value(), 0);
357 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney(".6789").value(), 6789'0000);
358 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("12345.").value(), COIN * 12345);
359 : :
360 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789);
361 : :
362 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000);
363 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000);
364 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000);
365 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000);
366 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000);
367 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100);
368 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10);
369 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("1.00").value(), COIN);
370 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("1").value(), COIN);
371 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney(" 1").value(), COIN);
372 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("1 ").value(), COIN);
373 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney(" 1 ").value(), COIN);
374 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10);
375 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100);
376 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000);
377 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000);
378 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000);
379 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000);
380 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000);
381 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.00000001").value(), COIN/100000000);
382 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001 ").value(), COIN/100000000);
383 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000);
384 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000);
385 : :
386 : : // Parsing amount that cannot be represented should fail
387 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("100000000.00"));
+ - ]
388 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("0.000000001"));
+ - ]
389 : :
390 : : // Parsing empty string should fail
391 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(""));
+ - ]
392 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" "));
+ - ]
393 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" "));
+ - ]
394 : :
395 : : // Parsing two numbers should fail
396 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(".."));
+ - ]
397 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("0..0"));
+ - ]
398 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("1 2"));
+ - ]
399 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" 1 2 "));
+ - ]
400 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" 1.2 3 "));
+ - ]
401 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" 1 2.3 "));
+ - ]
402 : :
403 : : // Embedded whitespace should fail
404 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" -1 .2 "));
+ - ]
405 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" 1 .2 "));
+ - ]
406 [ + - + - : 4 : BOOST_CHECK(!ParseMoney(" +1 .2 "));
+ - ]
407 : :
408 : : // Attempted 63 bit overflow should fail
409 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("92233720368.54775808"));
+ - ]
410 : :
411 : : // Parsing negative amounts must fail
412 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("-1"));
+ - ]
413 : :
414 : : // Parsing strings with embedded NUL characters should fail
415 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("\0-1"s));
+ - ]
416 [ + - + - ]: 4 : BOOST_CHECK(!ParseMoney(STRING_WITH_EMBEDDED_NULL_CHAR));
417 [ + - + - : 4 : BOOST_CHECK(!ParseMoney("1\0"s));
+ - ]
418 : 2 : }
419 : :
420 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_IsHex)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
421 : : {
422 [ + - + - ]: 4 : BOOST_CHECK(IsHex("00"));
423 [ + - + - ]: 4 : BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
424 [ + - + - ]: 4 : BOOST_CHECK(IsHex("ff"));
425 [ + - + - ]: 4 : BOOST_CHECK(IsHex("FF"));
426 : :
427 [ + - + - ]: 4 : BOOST_CHECK(!IsHex(""));
428 [ + - + - ]: 4 : BOOST_CHECK(!IsHex("0"));
429 [ + - + - ]: 4 : BOOST_CHECK(!IsHex("a"));
430 [ + - + - ]: 4 : BOOST_CHECK(!IsHex("eleven"));
431 [ + - + - ]: 4 : BOOST_CHECK(!IsHex("00xx00"));
432 [ + - + - ]: 4 : BOOST_CHECK(!IsHex("0x0000"));
433 : 2 : }
434 : :
435 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
436 : : {
437 : 2 : SeedRandomForTest(SeedRand::ZEROS);
438 [ + + ]: 20 : for (int mod=2;mod<11;mod++)
439 : : {
440 : 18 : int mask = 1;
441 : : // Really rough binomial confidence approximation.
442 : 18 : int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.);
443 : : //mask is 2^ceil(log2(mod))-1
444 [ + + ]: 50 : while(mask<mod-1)mask=(mask<<1)+1;
445 : :
446 : : int count = 0;
447 : : //How often does it get a zero from the uniform range [0,mod)?
448 [ + + ]: 180018 : for (int i = 0; i < 10000; i++) {
449 : 235594 : uint32_t rval;
450 : 235594 : do{
451 : 235594 : rval=InsecureRand32()&mask;
452 [ + + ]: 235594 : }while(rval>=(uint32_t)mod);
453 : 180000 : count += rval==0;
454 : : }
455 [ + - ]: 36 : BOOST_CHECK(count<=10000/mod+err);
456 [ + - ]: 36 : BOOST_CHECK(count>=10000/mod-err);
457 : : }
458 : 2 : }
459 : :
460 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
461 : : {
462 [ + - + - : 4 : BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
+ - ]
463 [ + - + - : 4 : BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
+ - ]
464 [ + - + - : 4 : BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
+ - ]
465 [ + - + - : 4 : BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
+ - ]
466 [ + - + - : 4 : BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
+ - ]
467 [ + - + - : 4 : BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
+ - ]
468 [ + - + - : 4 : BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
+ - ]
469 : 2 : }
470 : :
471 : : /* Test strprintf formatting directives.
472 : : * Put a string before and after to ensure sanity of element sizes on stack. */
473 : : #define B "check_prefix"
474 : : #define E "check_postfix"
475 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(strprintf_numbers)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
476 : : {
477 : 2 : int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
478 : 2 : uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
479 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
480 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
481 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
482 : :
483 : 2 : size_t st = 12345678; /* unsigned size_t test value */
484 : 2 : ssize_t sst = -12345678; /* signed size_t test value */
485 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
486 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
487 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
488 : :
489 : 2 : ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
490 : 2 : ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
491 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
492 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
493 [ + - + - ]: 4 : BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
494 : 2 : }
495 : : #undef B
496 : : #undef E
497 : :
498 : : /* Check for mingw/wine issue #3494
499 : : * Remove this test before time.ctime(0xffffffff) == 'Sun Feb 7 07:28:15 2106'
500 : : */
501 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(gettime)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
502 : : {
503 [ + - + - ]: 4 : BOOST_CHECK((GetTime() & ~0xFFFFFFFFLL) == 0);
504 : 2 : }
505 : :
506 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_time_GetTime)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
507 : : {
508 : 2 : SetMockTime(111);
509 : : // Check that mock time does not change after a sleep
510 [ + + ]: 6 : for (const auto& num_sleep : {0ms, 1ms}) {
511 : 4 : UninterruptibleSleep(num_sleep);
512 [ + - ]: 4 : BOOST_CHECK_EQUAL(111, GetTime()); // Deprecated time getter
513 [ + - ]: 4 : BOOST_CHECK_EQUAL(111, Now<NodeSeconds>().time_since_epoch().count());
514 [ + - ]: 4 : BOOST_CHECK_EQUAL(111, TicksSinceEpoch<std::chrono::seconds>(NodeClock::now()));
515 [ + - ]: 4 : BOOST_CHECK_EQUAL(111, TicksSinceEpoch<SecondsDouble>(Now<NodeSeconds>()));
516 [ + - ]: 4 : BOOST_CHECK_EQUAL(111, GetTime<std::chrono::seconds>().count());
517 [ + - ]: 4 : BOOST_CHECK_EQUAL(111000, GetTime<std::chrono::milliseconds>().count());
518 [ + - ]: 4 : BOOST_CHECK_EQUAL(111000, TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()));
519 [ + - ]: 4 : BOOST_CHECK_EQUAL(111000000, GetTime<std::chrono::microseconds>().count());
520 : : }
521 : :
522 : 2 : SetMockTime(0);
523 : : // Check that steady time and system time changes after a sleep
524 : 2 : const auto steady_ms_0 = Now<SteadyMilliseconds>();
525 : 2 : const auto steady_0 = std::chrono::steady_clock::now();
526 : 2 : const auto ms_0 = GetTime<std::chrono::milliseconds>();
527 : 2 : const auto us_0 = GetTime<std::chrono::microseconds>();
528 : 2 : UninterruptibleSleep(1ms);
529 [ + - ]: 4 : BOOST_CHECK(steady_ms_0 < Now<SteadyMilliseconds>());
530 [ + - ]: 4 : BOOST_CHECK(steady_0 + 1ms <= std::chrono::steady_clock::now());
531 [ + - ]: 4 : BOOST_CHECK(ms_0 < GetTime<std::chrono::milliseconds>());
532 [ + - ]: 4 : BOOST_CHECK(us_0 < GetTime<std::chrono::microseconds>());
533 : 2 : }
534 : :
535 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_IsDigit)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
536 : : {
537 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit('0'), true);
538 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit('1'), true);
539 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit('8'), true);
540 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit('9'), true);
541 : :
542 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit('0' - 1), false);
543 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit('9' + 1), false);
544 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit(0), false);
545 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit(1), false);
546 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit(8), false);
547 [ + - ]: 2 : BOOST_CHECK_EQUAL(IsDigit(9), false);
548 : 2 : }
549 : :
550 : : /* Check for overflow */
551 : : template <typename T>
552 : 4 : static void TestAddMatrixOverflow()
553 : : {
554 : 4 : constexpr T MAXI{std::numeric_limits<T>::max()};
555 [ + - ]: 8 : BOOST_CHECK(!CheckedAdd(T{1}, MAXI));
556 [ + - ]: 8 : BOOST_CHECK(!CheckedAdd(MAXI, MAXI));
557 [ + - ]: 4 : BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI));
558 [ + - ]: 4 : BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(MAXI, MAXI));
559 : :
560 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(0, CheckedAdd(T{0}, T{0}).value());
561 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{0}, MAXI).value());
562 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{1}, MAXI - 1).value());
563 [ + - + - ]: 4 : BOOST_CHECK_EQUAL(MAXI - 1, CheckedAdd(T{1}, MAXI - 2).value());
564 [ + - ]: 4 : BOOST_CHECK_EQUAL(0, SaturatingAdd(T{0}, T{0}));
565 [ + - ]: 4 : BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{0}, MAXI));
566 [ + - ]: 4 : BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI - 1));
567 [ + - ]: 4 : BOOST_CHECK_EQUAL(MAXI - 1, SaturatingAdd(T{1}, MAXI - 2));
568 : 4 : }
569 : :
570 : : /* Check for overflow or underflow */
571 : : template <typename T>
572 : 2 : static void TestAddMatrix()
573 : : {
574 : 2 : TestAddMatrixOverflow<T>();
575 : 2 : constexpr T MINI{std::numeric_limits<T>::min()};
576 : 2 : constexpr T MAXI{std::numeric_limits<T>::max()};
577 [ + - ]: 4 : BOOST_CHECK(!CheckedAdd(T{-1}, MINI));
578 [ + - ]: 4 : BOOST_CHECK(!CheckedAdd(MINI, MINI));
579 [ + - ]: 2 : BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI));
580 [ + - ]: 2 : BOOST_CHECK_EQUAL(MINI, SaturatingAdd(MINI, MINI));
581 : :
582 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{0}, MINI).value());
583 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{-1}, MINI + 1).value());
584 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(-1, CheckedAdd(MINI, MAXI).value());
585 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(MINI + 1, CheckedAdd(T{-1}, MINI + 2).value());
586 [ + - ]: 2 : BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{0}, MINI));
587 [ + - ]: 2 : BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI + 1));
588 [ + - ]: 2 : BOOST_CHECK_EQUAL(MINI + 1, SaturatingAdd(T{-1}, MINI + 2));
589 [ + - ]: 2 : BOOST_CHECK_EQUAL(-1, SaturatingAdd(MINI, MAXI));
590 : 2 : }
591 : :
592 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(util_overflow)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
593 : : {
594 : 2 : TestAddMatrixOverflow<unsigned>();
595 : 2 : TestAddMatrix<signed>();
596 : 2 : }
597 : :
598 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ParseInt32)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
599 : : {
600 : 2 : int32_t n;
601 : : // Valid values
602 [ + - + - ]: 4 : BOOST_CHECK(ParseInt32("1234", nullptr));
603 [ + - + - : 4 : BOOST_CHECK(ParseInt32("0", &n) && n == 0);
- + + - ]
604 [ + - + - : 4 : BOOST_CHECK(ParseInt32("1234", &n) && n == 1234);
- + + - ]
605 [ + - + - : 4 : BOOST_CHECK(ParseInt32("01234", &n) && n == 1234); // no octal
- + + - ]
606 [ + - + - : 4 : BOOST_CHECK(ParseInt32("2147483647", &n) && n == 2147483647);
- + + - ]
607 [ + - + - : 4 : BOOST_CHECK(ParseInt32("-2147483648", &n) && n == (-2147483647 - 1)); // (-2147483647 - 1) equals INT_MIN
- + + - ]
608 [ + - + - : 4 : BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234);
- + + - ]
609 [ + - + - : 4 : BOOST_CHECK(ParseInt32("00000000000000001234", &n) && n == 1234);
- + + - ]
610 [ + - + - : 4 : BOOST_CHECK(ParseInt32("-00000000000000001234", &n) && n == -1234);
- + + - ]
611 [ + - + - : 4 : BOOST_CHECK(ParseInt32("00000000000000000000", &n) && n == 0);
- + + - ]
612 [ + - + - : 4 : BOOST_CHECK(ParseInt32("-00000000000000000000", &n) && n == 0);
- + + - ]
613 : : // Invalid values
614 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("", &n));
615 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside
616 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("1 ", &n));
617 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("++1", &n));
618 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("+-1", &n));
619 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("-+1", &n));
620 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("--1", &n));
621 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("1a", &n));
622 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("aap", &n));
623 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
624 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
625 : : // Overflow and underflow
626 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("-2147483649", nullptr));
627 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("2147483648", nullptr));
628 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("-32482348723847471234", nullptr));
629 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt32("32482348723847471234", nullptr));
630 : 2 : }
631 : :
632 : : template <typename T>
633 : 16 : static void RunToIntegralTests()
634 : : {
635 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>(STRING_WITH_EMBEDDED_NULL_CHAR));
636 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>(" 1"));
637 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("1 "));
638 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("1a"));
639 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("1.1"));
640 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("1.9"));
641 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("+01.9"));
642 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("-"));
643 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("+"));
644 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>(" -1"));
645 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("-1 "));
646 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>(" -1 "));
647 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("+1"));
648 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>(" +1"));
649 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>(" +1 "));
650 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("+-1"));
651 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("-+1"));
652 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("++1"));
653 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("--1"));
654 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>(""));
655 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("aap"));
656 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("0x1"));
657 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("-32482348723847471234"));
658 [ + - ]: 32 : BOOST_CHECK(!ToIntegral<T>("32482348723847471234"));
659 : 16 : }
660 : :
661 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ToIntegral)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
662 : : {
663 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("1234").value(), 1'234);
664 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("0").value(), 0);
665 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("01234").value(), 1'234);
666 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000001234").value(), 1'234);
667 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000001234").value(), -1'234);
668 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000000000").value(), 0);
669 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000000000").value(), 0);
670 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1234").value(), -1'234);
671 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1").value(), -1);
672 : :
673 : 2 : RunToIntegralTests<uint64_t>();
674 : 2 : RunToIntegralTests<int64_t>();
675 : 2 : RunToIntegralTests<uint32_t>();
676 : 2 : RunToIntegralTests<int32_t>();
677 : 2 : RunToIntegralTests<uint16_t>();
678 : 2 : RunToIntegralTests<int16_t>();
679 : 2 : RunToIntegralTests<uint8_t>();
680 : 2 : RunToIntegralTests<int8_t>();
681 : :
682 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int64_t>("-9223372036854775809"));
683 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int64_t>("-9223372036854775808").value(), -9'223'372'036'854'775'807LL - 1LL);
684 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int64_t>("9223372036854775807").value(), 9'223'372'036'854'775'807);
685 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int64_t>("9223372036854775808"));
686 : :
687 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint64_t>("-1"));
688 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("0").value(), 0U);
689 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("18446744073709551615").value(), 18'446'744'073'709'551'615ULL);
690 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint64_t>("18446744073709551616"));
691 : :
692 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int32_t>("-2147483649"));
693 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-2147483648").value(), -2'147'483'648LL);
694 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int32_t>("2147483647").value(), 2'147'483'647);
695 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int32_t>("2147483648"));
696 : :
697 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint32_t>("-1"));
698 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("0").value(), 0U);
699 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("4294967295").value(), 4'294'967'295U);
700 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint32_t>("4294967296"));
701 : :
702 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int16_t>("-32769"));
703 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int16_t>("-32768").value(), -32'768);
704 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int16_t>("32767").value(), 32'767);
705 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int16_t>("32768"));
706 : :
707 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint16_t>("-1"));
708 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("0").value(), 0U);
709 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("65535").value(), 65'535U);
710 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint16_t>("65536"));
711 : :
712 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int8_t>("-129"));
713 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int8_t>("-128").value(), -128);
714 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<int8_t>("127").value(), 127);
715 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<int8_t>("128"));
716 : :
717 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint8_t>("-1"));
718 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("0").value(), 0U);
719 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("255").value(), 255U);
720 [ + - ]: 4 : BOOST_CHECK(!ToIntegral<uint8_t>("256"));
721 : 2 : }
722 : :
723 : 16 : int64_t atoi64_legacy(const std::string& str)
724 : : {
725 : 16 : return strtoll(str.c_str(), nullptr, 10);
726 : : }
727 : :
728 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_LocaleIndependentAtoi)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
729 : : {
730 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1234"), 1'234);
731 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0"), 0);
732 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("01234"), 1'234);
733 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1234"), -1'234);
734 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" 1"), 1);
735 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1 "), 1);
736 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1a"), 1);
737 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.1"), 1);
738 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.9"), 1);
739 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+01.9"), 1);
740 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1"), -1);
741 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1"), -1);
742 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1 "), -1);
743 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1 "), -1);
744 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+1"), 1);
745 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1"), 1);
746 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1 "), 1);
747 : :
748 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+-1"), 0);
749 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-+1"), 0);
750 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("++1"), 0);
751 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("--1"), 0);
752 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(""), 0);
753 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("aap"), 0);
754 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0x1"), 0);
755 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-32482348723847471234"), -2'147'483'647 - 1);
756 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("32482348723847471234"), 2'147'483'647);
757 : :
758 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775809"), -9'223'372'036'854'775'807LL - 1LL);
759 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775808"), -9'223'372'036'854'775'807LL - 1LL);
760 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775807"), 9'223'372'036'854'775'807);
761 [ + - ]: 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775808"), 9'223'372'036'854'775'807);
762 : :
763 : 2 : std::map<std::string, int64_t> atoi64_test_pairs = {
764 [ + - ]: 2 : {"-9223372036854775809", std::numeric_limits<int64_t>::min()},
765 : 2 : {"-9223372036854775808", -9'223'372'036'854'775'807LL - 1LL},
766 : 2 : {"9223372036854775807", 9'223'372'036'854'775'807},
767 : 2 : {"9223372036854775808", std::numeric_limits<int64_t>::max()},
768 : 2 : {"+-", 0},
769 : 2 : {"0x1", 0},
770 : 2 : {"ox1", 0},
771 : 2 : {"", 0},
772 [ + + - - ]: 18 : };
773 : :
774 [ + + ]: 18 : for (const auto& pair : atoi64_test_pairs) {
775 [ + - + - : 16 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), pair.second);
+ - ]
776 : : }
777 : :
778 : : // Ensure legacy compatibility with previous versions of Bitcoin Core's atoi64
779 [ + + ]: 18 : for (const auto& pair : atoi64_test_pairs) {
780 [ + - + - : 16 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), atoi64_legacy(pair.first));
+ - ]
781 : : }
782 : :
783 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("-1"), 0U);
+ - ]
784 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("0"), 0U);
+ - ]
785 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551615"), 18'446'744'073'709'551'615ULL);
+ - ]
786 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551616"), 18'446'744'073'709'551'615ULL);
+ - ]
787 : :
788 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483649"), -2'147'483'648LL);
+ - ]
789 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483648"), -2'147'483'648LL);
+ - ]
790 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483647"), 2'147'483'647);
+ - ]
791 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483648"), 2'147'483'647);
+ - ]
792 : :
793 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("-1"), 0U);
+ - ]
794 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("0"), 0U);
+ - ]
795 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967295"), 4'294'967'295U);
+ - ]
796 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967296"), 4'294'967'295U);
+ - ]
797 : :
798 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32769"), -32'768);
+ - ]
799 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32768"), -32'768);
+ - ]
800 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32767"), 32'767);
+ - ]
801 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32768"), 32'767);
+ - ]
802 : :
803 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("-1"), 0U);
+ - ]
804 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("0"), 0U);
+ - ]
805 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65535"), 65'535U);
+ - ]
806 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65536"), 65'535U);
+ - ]
807 : :
808 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-129"), -128);
+ - ]
809 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-128"), -128);
+ - ]
810 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("127"), 127);
+ - ]
811 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("128"), 127);
+ - ]
812 : :
813 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("-1"), 0U);
+ - ]
814 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("0"), 0U);
+ - ]
815 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("255"), 255U);
+ - ]
816 [ + - + - : 2 : BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("256"), 255U);
+ - ]
817 [ + - + - : 4 : }
+ - + - +
- + - + -
- + - - ]
818 : :
819 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ParseInt64)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
820 : : {
821 : 2 : int64_t n;
822 : : // Valid values
823 [ + - + - ]: 4 : BOOST_CHECK(ParseInt64("1234", nullptr));
824 [ + - + - : 4 : BOOST_CHECK(ParseInt64("0", &n) && n == 0LL);
- + + - ]
825 [ + - + - : 4 : BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL);
- + + - ]
826 [ + - + - : 4 : BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal
- + + - ]
827 [ + - + - : 4 : BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL);
- + + - ]
828 [ + - + - : 4 : BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL);
- + + - ]
829 [ + - + - : 4 : BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == int64_t{9223372036854775807});
- + + - ]
830 [ + - + - : 4 : BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == int64_t{-9223372036854775807-1});
- + + - ]
831 [ + - + - : 4 : BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL);
- + + - ]
832 : : // Invalid values
833 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("", &n));
834 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside
835 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("1 ", &n));
836 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("1a", &n));
837 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("aap", &n));
838 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex
839 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
840 : : // Overflow and underflow
841 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("-9223372036854775809", nullptr));
842 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("9223372036854775808", nullptr));
843 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("-32482348723847471234", nullptr));
844 [ + - + - ]: 4 : BOOST_CHECK(!ParseInt64("32482348723847471234", nullptr));
845 : 2 : }
846 : :
847 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ParseUInt8)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
848 : : {
849 : 2 : uint8_t n;
850 : : // Valid values
851 [ + - + - ]: 4 : BOOST_CHECK(ParseUInt8("255", nullptr));
852 [ + - + - : 4 : BOOST_CHECK(ParseUInt8("0", &n) && n == 0);
- + + - ]
853 [ + - + - : 4 : BOOST_CHECK(ParseUInt8("255", &n) && n == 255);
- + + - ]
854 [ + - + - : 4 : BOOST_CHECK(ParseUInt8("0255", &n) && n == 255); // no octal
- + + - ]
855 [ + - + - : 4 : BOOST_CHECK(ParseUInt8("255", &n) && n == static_cast<uint8_t>(255));
- + + - ]
856 [ + - + - : 4 : BOOST_CHECK(ParseUInt8("+255", &n) && n == 255);
- + + - ]
857 [ + - + - : 4 : BOOST_CHECK(ParseUInt8("00000000000000000012", &n) && n == 12);
- + + - ]
858 [ + - + - : 4 : BOOST_CHECK(ParseUInt8("00000000000000000000", &n) && n == 0);
- + + - ]
859 : : // Invalid values
860 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("-00000000000000000000", &n));
861 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("", &n));
862 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8(" 1", &n)); // no padding inside
863 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8(" -1", &n));
864 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("++1", &n));
865 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("+-1", &n));
866 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("-+1", &n));
867 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("--1", &n));
868 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("-1", &n));
869 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("1 ", &n));
870 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("1a", &n));
871 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("aap", &n));
872 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("0x1", &n)); // no hex
873 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
874 : : // Overflow and underflow
875 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("-255", &n));
876 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("256", &n));
877 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("-123", &n));
878 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("-123", nullptr));
879 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt8("256", nullptr));
880 : 2 : }
881 : :
882 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ParseUInt16)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
883 : : {
884 : 2 : uint16_t n;
885 : : // Valid values
886 [ + - + - ]: 4 : BOOST_CHECK(ParseUInt16("1234", nullptr));
887 [ + - + - : 4 : BOOST_CHECK(ParseUInt16("0", &n) && n == 0);
- + + - ]
888 [ + - + - : 4 : BOOST_CHECK(ParseUInt16("1234", &n) && n == 1234);
- + + - ]
889 [ + - + - : 4 : BOOST_CHECK(ParseUInt16("01234", &n) && n == 1234); // no octal
- + + - ]
890 [ + - + - : 4 : BOOST_CHECK(ParseUInt16("65535", &n) && n == static_cast<uint16_t>(65535));
- + + - ]
891 [ + - + - : 4 : BOOST_CHECK(ParseUInt16("+65535", &n) && n == 65535);
- + + - ]
892 [ + - + - : 4 : BOOST_CHECK(ParseUInt16("00000000000000000012", &n) && n == 12);
- + + - ]
893 [ + - + - : 4 : BOOST_CHECK(ParseUInt16("00000000000000000000", &n) && n == 0);
- + + - ]
894 : : // Invalid values
895 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("-00000000000000000000", &n));
896 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("", &n));
897 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16(" 1", &n)); // no padding inside
898 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16(" -1", &n));
899 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("++1", &n));
900 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("+-1", &n));
901 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("-+1", &n));
902 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("--1", &n));
903 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("-1", &n));
904 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("1 ", &n));
905 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("1a", &n));
906 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("aap", &n));
907 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("0x1", &n)); // no hex
908 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
909 : : // Overflow and underflow
910 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("-65535", &n));
911 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("65536", &n));
912 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("-123", &n));
913 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("-123", nullptr));
914 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt16("65536", nullptr));
915 : 2 : }
916 : :
917 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ParseUInt32)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
918 : : {
919 : 2 : uint32_t n;
920 : : // Valid values
921 [ + - + - ]: 4 : BOOST_CHECK(ParseUInt32("1234", nullptr));
922 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("0", &n) && n == 0);
- + + - ]
923 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234);
- + + - ]
924 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal
- + + - ]
925 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647);
- + + - ]
926 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("2147483648", &n) && n == uint32_t{2147483648});
- + + - ]
927 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("4294967295", &n) && n == uint32_t{4294967295});
- + + - ]
928 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("+1234", &n) && n == 1234);
- + + - ]
929 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("00000000000000001234", &n) && n == 1234);
- + + - ]
930 [ + - + - : 4 : BOOST_CHECK(ParseUInt32("00000000000000000000", &n) && n == 0);
- + + - ]
931 : : // Invalid values
932 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("-00000000000000000000", &n));
933 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("", &n));
934 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside
935 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32(" -1", &n));
936 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("++1", &n));
937 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("+-1", &n));
938 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("-+1", &n));
939 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("--1", &n));
940 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("-1", &n));
941 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("1 ", &n));
942 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("1a", &n));
943 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("aap", &n));
944 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
945 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
946 : : // Overflow and underflow
947 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("-2147483648", &n));
948 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("4294967296", &n));
949 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("-1234", &n));
950 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("-32482348723847471234", nullptr));
951 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt32("32482348723847471234", nullptr));
952 : 2 : }
953 : :
954 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ParseUInt64)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
955 : : {
956 : 2 : uint64_t n;
957 : : // Valid values
958 [ + - + - ]: 4 : BOOST_CHECK(ParseUInt64("1234", nullptr));
959 [ + - + - : 4 : BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL);
- + + - ]
960 [ + - + - : 4 : BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL);
- + + - ]
961 [ + - + - : 4 : BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal
- + + - ]
962 [ + - + - : 4 : BOOST_CHECK(ParseUInt64("2147483647", &n) && n == 2147483647LL);
- + + - ]
963 [ + - + - : 4 : BOOST_CHECK(ParseUInt64("9223372036854775807", &n) && n == 9223372036854775807ULL);
- + + - ]
964 [ + - + - : 4 : BOOST_CHECK(ParseUInt64("9223372036854775808", &n) && n == 9223372036854775808ULL);
- + + - ]
965 [ + - + - : 4 : BOOST_CHECK(ParseUInt64("18446744073709551615", &n) && n == 18446744073709551615ULL);
- + + - ]
966 : : // Invalid values
967 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("", &n));
968 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64(" 1", &n)); // no padding inside
969 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64(" -1", &n));
970 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("1 ", &n));
971 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("1a", &n));
972 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("aap", &n));
973 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("0x1", &n)); // no hex
974 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
975 : : // Overflow and underflow
976 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("-9223372036854775809", nullptr));
977 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("18446744073709551616", nullptr));
978 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("-32482348723847471234", nullptr));
979 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("-2147483648", &n));
980 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n));
981 [ + - + - ]: 4 : BOOST_CHECK(!ParseUInt64("-1234", &n));
982 : 2 : }
983 : :
984 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_FormatParagraph)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
985 : : {
986 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
987 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
988 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test");
989 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
990 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
991 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest");
992 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test");
993 : :
994 : : // Make sure we don't indent a fully-new line following a too-long line ending
995 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4), "test\n test\nabc");
996 : :
997 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length until it gets here", 79), "This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length\nuntil it gets here");
998 : :
999 : : // Test wrap length is exact
1000 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p");
1001 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p");
1002 : : // Indent should be included in length of lines
1003 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg h i j k", 79, 4), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\n f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg\n h i j k");
1004 : :
1005 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string.", 79), "This is a very long test string. This is a second sentence in the very long\ntest string.");
1006 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string.");
1007 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string.");
1008 [ + - ]: 2 : BOOST_CHECK_EQUAL(FormatParagraph("Testing that normal newlines do not get indented.\nLike here.", 79), "Testing that normal newlines do not get indented.\nLike here.");
1009 : 2 : }
1010 : :
1011 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1012 : : {
1013 : 2 : std::vector<std::string> comments;
1014 [ + - ]: 2 : comments.emplace_back("comment1");
1015 : 2 : std::vector<std::string> comments2;
1016 [ + - ]: 2 : comments2.emplace_back("comment1");
1017 [ + - + - ]: 4 : comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014
1018 [ + - + - : 2 : BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:9.99.0/"));
+ - + - +
- ]
1019 [ + - + - : 2 : BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:9.99.0(comment1)/"));
+ - + - +
- ]
1020 [ + - + - : 2 : BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:9.99.0(comment1; Comment2; .,_?@-; )/"));
+ - + - +
- ]
1021 : 2 : }
1022 : :
1023 [ + - + - : 14 : BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1024 : : {
1025 : 2 : int64_t amount = 0;
1026 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("0", 8, &amount));
1027 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 0LL);
1028 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("1", 8, &amount));
1029 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 100000000LL);
1030 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount));
1031 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 0LL);
1032 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount));
1033 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, -10000000LL);
1034 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount));
1035 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 110000000LL);
1036 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount));
1037 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 110000000LL);
1038 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount));
1039 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 1100000000LL);
1040 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount));
1041 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 11000000LL);
1042 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("1000", 8, &amount));
1043 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 100000000000LL);
1044 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount));
1045 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, -100000000000LL);
1046 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount));
1047 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 1LL);
1048 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount));
1049 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 1LL);
1050 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount));
1051 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, -1LL);
1052 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount));
1053 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 100000000000000001LL);
1054 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount));
1055 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, 999999999999999999LL);
1056 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount));
1057 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, -999999999999999999LL);
1058 : :
1059 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("", 8, &amount));
1060 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-", 8, &amount));
1061 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount));
1062 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount));
1063 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount));
1064 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount));
1065 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount));
1066 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount));
1067 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount));
1068 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount));
1069 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount));
1070 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount));
1071 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount));
1072 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount));
1073 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount));
1074 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount));
1075 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount));
1076 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount));
1077 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount));
1078 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount));
1079 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount));
1080 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount));
1081 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount));
1082 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount));
1083 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount));
1084 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount));
1085 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount));
1086 : :
1087 : : // Test with 3 decimal places for fee rates in sat/vB.
1088 [ + - + - ]: 4 : BOOST_CHECK(ParseFixedPoint("0.001", 3, &amount));
1089 [ + - ]: 2 : BOOST_CHECK_EQUAL(amount, CAmount{1});
1090 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("0.0009", 3, &amount));
1091 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("31.00100001", 3, &amount));
1092 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("31.0011", 3, &amount));
1093 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("31.99999999", 3, &amount));
1094 [ + - + - ]: 4 : BOOST_CHECK(!ParseFixedPoint("31.999999999999999999999", 3, &amount));
1095 : 2 : }
1096 : :
1097 : : #ifndef WIN32 // Cannot do this test on WIN32 due to lack of fork()
1098 : : static constexpr char LockCommand = 'L';
1099 : : static constexpr char UnlockCommand = 'U';
1100 : : static constexpr char ExitCommand = 'X';
1101 : : enum : char {
1102 : : ResSuccess = 2, // Start with 2 to avoid accidental collision with common values 0 and 1
1103 : : ResErrorWrite,
1104 : : ResErrorLock,
1105 : : ResUnlockSuccess,
1106 : : };
1107 : :
1108 : 1 : [[noreturn]] static void TestOtherProcess(fs::path dirname, fs::path lockname, int fd)
1109 : : {
1110 : 6 : char ch;
1111 : 6 : while (true) {
1112 : 6 : int rv = read(fd, &ch, 1); // Wait for command
1113 [ - + ]: 6 : assert(rv == 1);
1114 [ + + + - ]: 6 : switch (ch) {
1115 : 4 : case LockCommand:
1116 : 12 : ch = [&] {
1117 [ + + - + ]: 4 : switch (util::LockDirectory(dirname, lockname)) {
1118 : : case util::LockResult::Success: return ResSuccess;
1119 : 1 : case util::LockResult::ErrorWrite: return ResErrorWrite;
1120 : 1 : case util::LockResult::ErrorLock: return ResErrorLock;
1121 : : } // no default case, so the compiler can warn about missing cases
1122 : 0 : assert(false);
1123 : 4 : }();
1124 : 4 : rv = write(fd, &ch, 1);
1125 [ + - ]: 4 : assert(rv == 1);
1126 : : break;
1127 : 1 : case UnlockCommand:
1128 : 1 : ReleaseDirectoryLocks();
1129 : 1 : ch = ResUnlockSuccess; // Always succeeds
1130 : 1 : rv = write(fd, &ch, 1);
1131 [ + - ]: 1 : assert(rv == 1);
1132 : : break;
1133 : 1 : case ExitCommand:
1134 : 1 : close(fd);
1135 : 1 : exit(0);
1136 : 0 : default:
1137 : 0 : assert(0);
1138 : : }
1139 : : }
1140 : : }
1141 : : #endif
1142 : :
1143 [ + - + - : 12 : BOOST_AUTO_TEST_CASE(test_LockDirectory)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1144 : : {
1145 [ + - ]: 4 : fs::path dirname = m_args.GetDataDirBase() / "lock_dir";
1146 [ + - ]: 2 : const fs::path lockname = ".lock";
1147 : : #ifndef WIN32
1148 : : // Revert SIGCHLD to default, otherwise boost.test will catch and fail on
1149 : : // it: there is BOOST_TEST_IGNORE_SIGCHLD but that only works when defined
1150 : : // at build-time of the boost library
1151 : 2 : void (*old_handler)(int) = signal(SIGCHLD, SIG_DFL);
1152 : :
1153 : : // Fork another process for testing before creating the lock, so that we
1154 : : // won't fork while holding the lock (which might be undefined, and is not
1155 : : // relevant as test case as that is avoided with -daemonize).
1156 : 2 : int fd[2];
1157 [ + - + - ]: 2 : BOOST_CHECK_EQUAL(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0);
1158 : 2 : pid_t pid = fork();
1159 [ + + ]: 2 : if (!pid) {
1160 [ + - + - : 1 : BOOST_CHECK_EQUAL(close(fd[1]), 0); // Child: close parent end
+ - ]
1161 [ + - + - ]: 1 : TestOtherProcess(dirname, lockname, fd[0]);
1162 : : }
1163 [ + - + - : 1 : BOOST_CHECK_EQUAL(close(fd[0]), 0); // Parent: close child end
+ - ]
1164 : :
1165 : 1 : char ch;
1166 : : // Lock on non-existent directory should fail
1167 [ + - + - : 1 : BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
+ - ]
1168 [ + - + - : 1 : BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
+ - ]
1169 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ch, ResErrorWrite);
1170 : : #endif
1171 : : // Lock on non-existent directory should fail
1172 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname), util::LockResult::ErrorWrite);
+ - ]
1173 : :
1174 [ + - ]: 1 : fs::create_directories(dirname);
1175 : :
1176 : : // Probing lock on new directory should succeed
1177 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success);
+ - ]
1178 : :
1179 : : // Persistent lock on new directory should succeed
1180 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname), util::LockResult::Success);
+ - ]
1181 : :
1182 : : // Another lock on the directory from the same thread should succeed
1183 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname), util::LockResult::Success);
+ - ]
1184 : :
1185 : : // Another lock on the directory from a different thread within the same process should succeed
1186 : 1 : util::LockResult threadresult;
1187 [ + - ]: 2 : std::thread thr([&] { threadresult = util::LockDirectory(dirname, lockname); });
1188 [ + - ]: 1 : thr.join();
1189 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(threadresult, util::LockResult::Success);
1190 : : #ifndef WIN32
1191 : : // Try to acquire lock in child process while we're holding it, this should fail.
1192 [ + - + - : 1 : BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
+ - ]
1193 [ + - + - : 1 : BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
+ - ]
1194 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ch, ResErrorLock);
1195 : :
1196 : : // Give up our lock
1197 [ + - ]: 1 : ReleaseDirectoryLocks();
1198 : : // Probing lock from our side now should succeed, but not hold on to the lock.
1199 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success);
+ - ]
1200 : :
1201 : : // Try to acquire the lock in the child process, this should be successful.
1202 [ + - + - : 1 : BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
+ - ]
1203 [ + - + - : 1 : BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
+ - ]
1204 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ch, ResSuccess);
1205 : :
1206 : : // When we try to probe the lock now, it should fail.
1207 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::ErrorLock);
+ - ]
1208 : :
1209 : : // Unlock the lock in the child process
1210 [ + - + - : 1 : BOOST_CHECK_EQUAL(write(fd[1], &UnlockCommand, 1), 1);
+ - ]
1211 [ + - + - : 1 : BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
+ - ]
1212 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ch, ResUnlockSuccess);
1213 : :
1214 : : // When we try to probe the lock now, it should succeed.
1215 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success);
+ - ]
1216 : :
1217 : : // Re-lock the lock in the child process, then wait for it to exit, check
1218 : : // successful return. After that, we check that exiting the process
1219 : : // has released the lock as we would expect by probing it.
1220 : 1 : int processstatus;
1221 [ + - + - : 1 : BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
+ - ]
1222 : : // The following line invokes the ~CNetCleanup dtor without
1223 : : // a paired SetupNetworking call. This is acceptable as long as
1224 : : // ~CNetCleanup is a no-op for non-Windows platforms.
1225 [ + - + - : 1 : BOOST_CHECK_EQUAL(write(fd[1], &ExitCommand, 1), 1);
+ - ]
1226 [ + - + - : 1 : BOOST_CHECK_EQUAL(waitpid(pid, &processstatus, 0), pid);
+ - ]
1227 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(processstatus, 0);
1228 [ + - + - : 1 : BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success);
+ - ]
1229 : :
1230 : : // Restore SIGCHLD
1231 : 1 : signal(SIGCHLD, old_handler);
1232 [ + - + - : 1 : BOOST_CHECK_EQUAL(close(fd[1]), 0); // Close our side of the socketpair
+ - ]
1233 : : #endif
1234 : : // Clean up
1235 [ + - ]: 1 : ReleaseDirectoryLocks();
1236 [ + - ]: 1 : fs::remove_all(dirname);
1237 : 3 : }
1238 : :
1239 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(test_ToLower)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1240 : : {
1241 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower('@'), '@');
1242 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower('A'), 'a');
1243 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower('Z'), 'z');
1244 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower('['), '[');
1245 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower(0), 0);
1246 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff');
1247 : :
1248 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower(""), "");
1249 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl");
1250 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff");
1251 : 1 : }
1252 : :
1253 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(test_ToUpper)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1254 : : {
1255 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper('`'), '`');
1256 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper('a'), 'A');
1257 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper('z'), 'Z');
1258 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper('{'), '{');
1259 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper(0), 0);
1260 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff');
1261 : :
1262 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper(""), "");
1263 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL");
1264 [ + - ]: 1 : BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff");
1265 : 1 : }
1266 : :
1267 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(test_Capitalize)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1268 : : {
1269 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(Capitalize(""), "");
1270 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(Capitalize("bitcoin"), "Bitcoin");
1271 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff");
1272 : 1 : }
1273 : :
1274 : 28 : static std::string SpanToStr(const Span<const char>& span)
1275 : : {
1276 : 28 : return std::string(span.begin(), span.end());
1277 : : }
1278 : :
1279 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(test_script_parsing)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1280 : : {
1281 : 1 : using namespace script;
1282 [ + - ]: 1 : std::string input;
1283 : 1 : Span<const char> sp;
1284 : 1 : bool success;
1285 : :
1286 : : // Const(...): parse a constant, update span to skip it if successful
1287 [ + - ]: 1 : input = "MilkToastHoney";
1288 [ + - ]: 1 : sp = input;
1289 [ + - + - ]: 1 : success = Const("", sp); // empty
1290 [ + - + - : 2 : BOOST_CHECK(success);
+ - ]
1291 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
+ - ]
1292 : :
1293 [ + - + - ]: 1 : success = Const("Milk", sp);
1294 [ + - + - : 2 : BOOST_CHECK(success);
+ - ]
1295 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney");
+ - ]
1296 : :
1297 [ + - + - ]: 1 : success = Const("Bread", sp);
1298 [ + - + - : 2 : BOOST_CHECK(!success);
+ - ]
1299 : :
1300 [ + - + - ]: 1 : success = Const("Toast", sp);
1301 [ + - + - : 2 : BOOST_CHECK(success);
+ - ]
1302 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey");
+ - ]
1303 : :
1304 [ + - + - ]: 1 : success = Const("Honeybadger", sp);
1305 [ + - + - : 2 : BOOST_CHECK(!success);
+ - ]
1306 : :
1307 [ + - + - ]: 1 : success = Const("Honey", sp);
1308 [ + - + - : 2 : BOOST_CHECK(success);
+ - ]
1309 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), "");
+ - ]
1310 : :
1311 : : // Func(...): parse a function call, update span to argument if successful
1312 [ + - ]: 1 : input = "Foo(Bar(xy,z()))";
1313 [ + - ]: 1 : sp = input;
1314 : :
1315 [ + - + - ]: 1 : success = Func("FooBar", sp);
1316 [ + - + - : 2 : BOOST_CHECK(!success);
+ - ]
1317 : :
1318 [ + - + - ]: 1 : success = Func("Foo(", sp);
1319 [ + - + - : 2 : BOOST_CHECK(!success);
+ - ]
1320 : :
1321 [ + - + - ]: 1 : success = Func("Foo", sp);
1322 [ + - + - : 2 : BOOST_CHECK(success);
+ - ]
1323 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), "Bar(xy,z())");
+ - ]
1324 : :
1325 [ + - + - ]: 1 : success = Func("Bar", sp);
1326 [ + - + - : 2 : BOOST_CHECK(success);
+ - ]
1327 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), "xy,z()");
+ - ]
1328 : :
1329 [ + - + - ]: 1 : success = Func("xy", sp);
1330 [ + - + - : 2 : BOOST_CHECK(!success);
+ - ]
1331 : :
1332 : : // Expr(...): return expression that span begins with, update span to skip it
1333 : 1 : Span<const char> result;
1334 : :
1335 [ + - ]: 1 : input = "(n*(n-1))/2";
1336 [ + - ]: 1 : sp = input;
1337 [ + - ]: 1 : result = Expr(sp);
1338 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(result), "(n*(n-1))/2");
+ - ]
1339 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), "");
+ - ]
1340 : :
1341 [ + - ]: 1 : input = "foo,bar";
1342 [ + - ]: 1 : sp = input;
1343 [ + - ]: 1 : result = Expr(sp);
1344 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(result), "foo");
+ - ]
1345 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), ",bar");
+ - ]
1346 : :
1347 [ + - ]: 1 : input = "(aaaaa,bbbbb()),c";
1348 [ + - ]: 1 : sp = input;
1349 [ + - ]: 1 : result = Expr(sp);
1350 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(result), "(aaaaa,bbbbb())");
+ - ]
1351 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), ",c");
+ - ]
1352 : :
1353 [ + - ]: 1 : input = "xyz)foo";
1354 [ + - ]: 1 : sp = input;
1355 [ + - ]: 1 : result = Expr(sp);
1356 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(result), "xyz");
+ - ]
1357 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), ")foo");
+ - ]
1358 : :
1359 [ + - ]: 1 : input = "((a),(b),(c)),xxx";
1360 [ + - ]: 1 : sp = input;
1361 [ + - ]: 1 : result = Expr(sp);
1362 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(result), "((a),(b),(c))");
+ - ]
1363 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx");
+ - ]
1364 : :
1365 : : // Split(...): split a string on every instance of sep, return vector
1366 : 1 : std::vector<Span<const char>> results;
1367 : :
1368 [ + - ]: 1 : input = "xxx";
1369 [ + - ]: 2 : results = Split(input, 'x');
1370 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(results.size(), 4U);
1371 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
+ - ]
1372 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[1]), "");
+ - ]
1373 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[2]), "");
+ - ]
1374 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
+ - ]
1375 : :
1376 [ + - ]: 1 : input = "one#two#three";
1377 [ + - ]: 2 : results = Split(input, '-');
1378 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(results.size(), 1U);
1379 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#two#three");
+ - ]
1380 : :
1381 [ + - ]: 1 : input = "one#two#three";
1382 [ + - ]: 2 : results = Split(input, '#');
1383 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(results.size(), 3U);
1384 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one");
+ - ]
1385 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two");
+ - ]
1386 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
+ - ]
1387 : :
1388 [ + - ]: 1 : input = "*foo*bar*";
1389 [ + - ]: 2 : results = Split(input, '*');
1390 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(results.size(), 4U);
1391 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
+ - ]
1392 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo");
+ - ]
1393 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar");
+ - ]
1394 [ + - + - : 1 : BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
+ - ]
1395 : 1 : }
1396 : :
1397 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(test_SplitString)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1398 : : {
1399 : : // Empty string.
1400 : 1 : {
1401 : 1 : std::vector<std::string> result = SplitString("", '-');
1402 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result.size(), 1);
1403 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[0], "");
1404 : 1 : }
1405 : :
1406 : : // Empty items.
1407 : 1 : {
1408 : 1 : std::vector<std::string> result = SplitString("-", '-');
1409 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result.size(), 2);
1410 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[0], "");
1411 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[1], "");
1412 : 1 : }
1413 : :
1414 : : // More empty items.
1415 : 1 : {
1416 : 1 : std::vector<std::string> result = SplitString("--", '-');
1417 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result.size(), 3);
1418 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[0], "");
1419 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[1], "");
1420 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[2], "");
1421 : 1 : }
1422 : :
1423 : : // Separator is not present.
1424 : 1 : {
1425 : 1 : std::vector<std::string> result = SplitString("abc", '-');
1426 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result.size(), 1);
1427 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[0], "abc");
1428 : 1 : }
1429 : :
1430 : : // Basic behavior.
1431 : 1 : {
1432 : 1 : std::vector<std::string> result = SplitString("a-b", '-');
1433 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result.size(), 2);
1434 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[0], "a");
1435 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[1], "b");
1436 : 1 : }
1437 : :
1438 : : // Case-sensitivity of the separator.
1439 : 1 : {
1440 : 1 : std::vector<std::string> result = SplitString("AAA", 'a');
1441 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result.size(), 1);
1442 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(result[0], "AAA");
1443 : 1 : }
1444 : :
1445 : : // multiple split characters
1446 : 1 : {
1447 : 1 : using V = std::vector<std::string>;
1448 [ + - + + : 9 : BOOST_TEST(SplitString("a,b.c:d;e", ",;") == V({"a", "b.c:d", "e"}));
+ - + - +
- + - + +
- - - - ]
1449 [ + - + + : 13 : BOOST_TEST(SplitString("a,b.c:d;e", ",;:.") == V({"a", "b", "c", "d", "e"}));
+ - + - +
- + - + +
- - - - ]
1450 [ + - + + : 5 : BOOST_TEST(SplitString("a,b.c:d;e", "") == V({"a,b.c:d;e"}));
+ - + - +
- + - + +
- - - - ]
1451 [ + - + + : 5 : BOOST_TEST(SplitString("aaa", "bcdefg") == V({"aaa"}));
+ - + - +
- + - + +
- - - - ]
1452 [ + - + + : 8 : BOOST_TEST(SplitString("x\0a,b"s, "\0"s) == V({"x", "a,b"}));
+ - + - +
- + - + -
+ + - - -
- ]
1453 [ + - + + : 8 : BOOST_TEST(SplitString("x\0a,b"s, '\0') == V({"x", "a,b"}));
+ - + - +
- + - + +
- - - - ]
1454 [ + - + + : 10 : BOOST_TEST(SplitString("x\0a,b"s, "\0,"s) == V({"x", "a", "b"}));
+ - + - +
- + - + -
+ + - - -
- ]
1455 [ + - + + : 11 : BOOST_TEST(SplitString("abcdefg", "bcd") == V({"a", "", "", "efg"}));
+ - + - +
- + - + +
- - - - ]
1456 : : }
1457 : 1 : }
1458 : :
1459 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1460 : : {
1461 : : // ASCII and UTF-8 must pass through unaltered.
1462 [ + - ]: 1 : BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓");
1463 : : // Newlines must pass through unaltered.
1464 [ + - ]: 1 : BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n");
1465 : : // Other control characters are escaped in C syntax.
1466 [ + - ]: 1 : BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)");
1467 : : // Embedded NULL characters are escaped too.
1468 : 1 : const std::string NUL("O\x00O", 3);
1469 [ + - + - : 1 : BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
+ - ]
1470 : 1 : }
1471 : :
1472 : : namespace {
1473 : :
1474 : : struct Tracker
1475 : : {
1476 : : //! Points to the original object (possibly itself) we moved/copied from
1477 : : const Tracker* origin;
1478 : : //! How many copies where involved between the original object and this one (moves are not counted)
1479 : : int copies{0};
1480 : :
1481 : 1 : Tracker() noexcept : origin(this) {}
1482 : 10 : Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
1483 : 13 : Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
1484 : : Tracker& operator=(const Tracker& t) noexcept
1485 : : {
1486 : : if (this != &t) {
1487 : : origin = t.origin;
1488 : : copies = t.copies + 1;
1489 : : }
1490 : : return *this;
1491 : : }
1492 : : };
1493 : :
1494 : : }
1495 : :
1496 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(test_tracked_vector)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1497 : : {
1498 : 1 : Tracker t1;
1499 : 1 : Tracker t2;
1500 : 1 : Tracker t3;
1501 : :
1502 [ + - ]: 2 : BOOST_CHECK(t1.origin == &t1);
1503 [ + - ]: 2 : BOOST_CHECK(t2.origin == &t2);
1504 [ + - ]: 2 : BOOST_CHECK(t3.origin == &t3);
1505 : :
1506 : 1 : auto v1 = Vector(t1);
1507 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v1.size(), 1U);
1508 [ + - + - : 2 : BOOST_CHECK(v1[0].origin == &t1);
+ - ]
1509 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v1[0].copies, 1);
1510 : :
1511 [ + - ]: 1 : auto v2 = Vector(std::move(t2));
1512 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v2.size(), 1U);
1513 [ + - + - : 2 : BOOST_CHECK(v2[0].origin == &t2); // NOLINT(*-use-after-move)
+ - ]
1514 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v2[0].copies, 0);
1515 : :
1516 [ + - ]: 1 : auto v3 = Vector(t1, std::move(t2));
1517 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v3.size(), 2U);
1518 [ + - + - : 2 : BOOST_CHECK(v3[0].origin == &t1);
+ - ]
1519 [ + - + - : 2 : BOOST_CHECK(v3[1].origin == &t2); // NOLINT(*-use-after-move)
+ - ]
1520 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v3[0].copies, 1);
1521 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v3[1].copies, 0);
1522 : :
1523 [ + - ]: 1 : auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3));
1524 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v4.size(), 3U);
1525 [ + - + - : 2 : BOOST_CHECK(v4[0].origin == &t1);
+ - ]
1526 [ + - + - : 2 : BOOST_CHECK(v4[1].origin == &t2);
+ - ]
1527 [ + - + - : 2 : BOOST_CHECK(v4[2].origin == &t3); // NOLINT(*-use-after-move)
+ - ]
1528 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v4[0].copies, 1);
1529 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v4[1].copies, 1);
1530 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v4[2].copies, 0);
1531 : :
1532 [ + - + - ]: 1 : auto v5 = Cat(v1, v4);
1533 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v5.size(), 4U);
1534 [ + - + - : 2 : BOOST_CHECK(v5[0].origin == &t1);
+ - ]
1535 [ + - + - : 2 : BOOST_CHECK(v5[1].origin == &t1);
+ - ]
1536 [ + - + - : 2 : BOOST_CHECK(v5[2].origin == &t2);
+ - ]
1537 [ + - + - : 2 : BOOST_CHECK(v5[3].origin == &t3);
+ - ]
1538 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v5[0].copies, 2);
1539 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v5[1].copies, 2);
1540 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v5[2].copies, 2);
1541 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v5[3].copies, 1);
1542 : :
1543 [ + - ]: 1 : auto v6 = Cat(std::move(v1), v3);
1544 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v6.size(), 3U);
1545 [ + - + - : 2 : BOOST_CHECK(v6[0].origin == &t1);
+ - ]
1546 [ + - + - : 2 : BOOST_CHECK(v6[1].origin == &t1);
+ - ]
1547 [ + - + - : 2 : BOOST_CHECK(v6[2].origin == &t2);
+ - ]
1548 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v6[0].copies, 1);
1549 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v6[1].copies, 2);
1550 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v6[2].copies, 1);
1551 : :
1552 [ + - + - ]: 1 : auto v7 = Cat(v2, std::move(v4));
1553 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v7.size(), 4U);
1554 [ + - + - : 2 : BOOST_CHECK(v7[0].origin == &t2);
+ - ]
1555 [ + - + - : 2 : BOOST_CHECK(v7[1].origin == &t1);
+ - ]
1556 [ + - + - : 2 : BOOST_CHECK(v7[2].origin == &t2);
+ - ]
1557 [ + - + - : 2 : BOOST_CHECK(v7[3].origin == &t3);
+ - ]
1558 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v7[0].copies, 1);
1559 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v7[1].copies, 1);
1560 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v7[2].copies, 1);
1561 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v7[3].copies, 0);
1562 : :
1563 [ + - ]: 1 : auto v8 = Cat(std::move(v2), std::move(v3));
1564 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v8.size(), 3U);
1565 [ + - + - : 2 : BOOST_CHECK(v8[0].origin == &t2);
+ - ]
1566 [ + - + - : 2 : BOOST_CHECK(v8[1].origin == &t1);
+ - ]
1567 [ + - + - : 2 : BOOST_CHECK(v8[2].origin == &t2);
+ - ]
1568 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v8[0].copies, 0);
1569 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v8[1].copies, 1);
1570 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v8[2].copies, 0);
1571 : 1 : }
1572 : :
1573 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(message_sign)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1574 : : {
1575 : 1 : const std::array<unsigned char, 32> privkey_bytes = {
1576 : : // just some random data
1577 : : // derived address from this private key: 15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs
1578 : : 0xD9, 0x7F, 0x51, 0x08, 0xF1, 0x1C, 0xDA, 0x6E,
1579 : : 0xEE, 0xBA, 0xAA, 0x42, 0x0F, 0xEF, 0x07, 0x26,
1580 : : 0xB1, 0xF8, 0x98, 0x06, 0x0B, 0x98, 0x48, 0x9F,
1581 : : 0xA3, 0x09, 0x84, 0x63, 0xC0, 0x03, 0x28, 0x66
1582 : : };
1583 : :
1584 : 1 : const std::string message = "Trust no one";
1585 : :
1586 [ + - ]: 1 : const std::string expected_signature =
1587 [ + - ]: 1 : "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=";
1588 : :
1589 : 1 : CKey privkey;
1590 [ + - ]: 1 : std::string generated_signature;
1591 : :
1592 [ + - + - : 2 : BOOST_REQUIRE_MESSAGE(!privkey.IsValid(),
+ - ]
1593 : : "Confirm the private key is invalid");
1594 : :
1595 [ + - + - : 2 : BOOST_CHECK_MESSAGE(!MessageSign(privkey, message, generated_signature),
+ - + - ]
1596 : : "Sign with an invalid private key");
1597 : :
1598 [ + - ]: 1 : privkey.Set(privkey_bytes.begin(), privkey_bytes.end(), true);
1599 : :
1600 [ + - + - : 2 : BOOST_REQUIRE_MESSAGE(privkey.IsValid(),
+ - ]
1601 : : "Confirm the private key is valid");
1602 : :
1603 [ + - + - : 2 : BOOST_CHECK_MESSAGE(MessageSign(privkey, message, generated_signature),
+ - + - ]
1604 : : "Sign with a valid private key");
1605 : :
1606 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(expected_signature, generated_signature);
1607 : 1 : }
1608 : :
1609 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(message_verify)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1610 : : {
1611 [ + - + - : 1 : BOOST_CHECK_EQUAL(
+ - + - ]
1612 : : MessageVerify(
1613 : : "invalid address",
1614 : : "signature should be irrelevant",
1615 : : "message too"),
1616 : : MessageVerificationResult::ERR_INVALID_ADDRESS);
1617 : :
1618 [ + - + - : 1 : BOOST_CHECK_EQUAL(
+ - + - ]
1619 : : MessageVerify(
1620 : : "3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV",
1621 : : "signature should be irrelevant",
1622 : : "message too"),
1623 : : MessageVerificationResult::ERR_ADDRESS_NO_KEY);
1624 : :
1625 [ + - + - : 1 : BOOST_CHECK_EQUAL(
+ - + - ]
1626 : : MessageVerify(
1627 : : "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
1628 : : "invalid signature, not in base64 encoding",
1629 : : "message should be irrelevant"),
1630 : : MessageVerificationResult::ERR_MALFORMED_SIGNATURE);
1631 : :
1632 [ + - + - : 1 : BOOST_CHECK_EQUAL(
+ - + - ]
1633 : : MessageVerify(
1634 : : "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
1635 : : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1636 : : "message should be irrelevant"),
1637 : : MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED);
1638 : :
1639 [ + - + - : 1 : BOOST_CHECK_EQUAL(
+ - + - ]
1640 : : MessageVerify(
1641 : : "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
1642 : : "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
1643 : : "I never signed this"),
1644 : : MessageVerificationResult::ERR_NOT_SIGNED);
1645 : :
1646 [ + - + - : 1 : BOOST_CHECK_EQUAL(
+ - + - ]
1647 : : MessageVerify(
1648 : : "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
1649 : : "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
1650 : : "Trust no one"),
1651 : : MessageVerificationResult::OK);
1652 : :
1653 [ + - + - : 1 : BOOST_CHECK_EQUAL(
+ - + - ]
1654 : : MessageVerify(
1655 : : "11canuhp9X2NocwCq7xNrQYTmUgZAnLK3",
1656 : : "IIcaIENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzIAaHRtbCeDZINyavx14=",
1657 : : "Trust me"),
1658 : : MessageVerificationResult::OK);
1659 : 1 : }
1660 : :
1661 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(message_hash)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1662 : : {
1663 : 1 : const std::string unsigned_tx = "...";
1664 [ + - ]: 1 : const std::string prefixed_message =
1665 [ + - ]: 2 : std::string(1, (char)MESSAGE_MAGIC.length()) +
1666 [ + - ]: 2 : MESSAGE_MAGIC +
1667 [ + - + - : 2 : std::string(1, (char)unsigned_tx.length()) +
+ - ]
1668 [ + - ]: 1 : unsigned_tx;
1669 : :
1670 [ + - ]: 1 : const uint256 signature_hash = Hash(unsigned_tx);
1671 [ + - ]: 1 : const uint256 message_hash1 = Hash(prefixed_message);
1672 [ + - ]: 1 : const uint256 message_hash2 = MessageHash(unsigned_tx);
1673 : :
1674 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(message_hash1, message_hash2);
1675 [ + - + - ]: 1 : BOOST_CHECK_NE(message_hash1, signature_hash);
1676 : 1 : }
1677 : :
1678 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(remove_prefix)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1679 : : {
1680 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefix("./common/system.h", "./"), "common/system.h");
1681 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefixView("foo", "foo"), "");
1682 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o");
1683 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefixView("foo", "f"), "oo");
1684 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefix("foo", ""), "foo");
1685 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefixView("fo", "foo"), "fo");
1686 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefix("f", "foo"), "f");
1687 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefixView("", "foo"), "");
1688 [ + - ]: 1 : BOOST_CHECK_EQUAL(RemovePrefix("", ""), "");
1689 : 1 : }
1690 : :
1691 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_ParseByteUnits)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1692 : : {
1693 : 1 : auto noop = ByteUnit::NOOP;
1694 : :
1695 : : // no multiplier
1696 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("1", noop).value(), 1);
1697 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("0", noop).value(), 0);
1698 : :
1699 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("1k", noop).value(), 1000ULL);
1700 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("1K", noop).value(), 1ULL << 10);
1701 : :
1702 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("2m", noop).value(), 2'000'000ULL);
1703 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("2M", noop).value(), 2ULL << 20);
1704 : :
1705 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("3g", noop).value(), 3'000'000'000ULL);
1706 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("3G", noop).value(), 3ULL << 30);
1707 : :
1708 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("4t", noop).value(), 4'000'000'000'000ULL);
1709 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("4T", noop).value(), 4ULL << 40);
1710 : :
1711 : : // check default multiplier
1712 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("5", ByteUnit::K).value(), 5ULL << 10);
1713 : :
1714 : : // NaN
1715 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("", noop));
1716 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("foo", noop));
1717 : :
1718 : : // whitespace
1719 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("123m ", noop));
1720 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits(" 123m", noop));
1721 : :
1722 : : // no +-
1723 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("-123m", noop));
1724 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("+123m", noop));
1725 : :
1726 : : // zero padding
1727 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(ParseByteUnits("020M", noop).value(), 20ULL << 20);
1728 : :
1729 : : // fractions not allowed
1730 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("0.5T", noop));
1731 : :
1732 : : // overflow
1733 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("18446744073709551615g", noop));
1734 : :
1735 : : // invalid unit
1736 [ + - + - ]: 2 : BOOST_CHECK(!ParseByteUnits("1x", noop));
1737 : 1 : }
1738 : :
1739 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_ReadBinaryFile)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1740 : : {
1741 : 1 : fs::path tmpfolder = m_args.GetDataDirBase();
1742 [ + - + - ]: 2 : fs::path tmpfile = tmpfolder / "read_binary.dat";
1743 : 1 : std::string expected_text;
1744 [ + + ]: 31 : for (int i = 0; i < 30; i++) {
1745 [ + - ]: 30 : expected_text += "0123456789";
1746 : : }
1747 : 1 : {
1748 [ + - ]: 1 : std::ofstream file{tmpfile};
1749 [ + - ]: 1 : file << expected_text;
1750 : 1 : }
1751 : 1 : {
1752 : : // read all contents in file
1753 [ + - + - ]: 1 : auto [valid, text] = ReadBinaryFile(tmpfile);
1754 [ + - + - : 2 : BOOST_CHECK(valid);
+ - ]
1755 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(text, expected_text);
1756 : 0 : }
1757 : 1 : {
1758 : : // read half contents in file
1759 [ + - + - ]: 1 : auto [valid, text] = ReadBinaryFile(tmpfile, expected_text.size() / 2);
1760 [ + - + - : 2 : BOOST_CHECK(valid);
+ - ]
1761 [ + - + - : 1 : BOOST_CHECK_EQUAL(text, expected_text.substr(0, expected_text.size() / 2));
+ - ]
1762 : 0 : }
1763 : 1 : {
1764 : : // read from non-existent file
1765 [ + - + - ]: 2 : fs::path invalid_file = tmpfolder / "invalid_binary.dat";
1766 [ + - ]: 1 : auto [valid, text] = ReadBinaryFile(invalid_file);
1767 [ + - + - : 2 : BOOST_CHECK(!valid);
+ - ]
1768 [ + - + - ]: 2 : BOOST_CHECK(text.empty());
1769 : 2 : }
1770 : 3 : }
1771 : :
1772 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_WriteBinaryFile)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1773 : : {
1774 : 1 : fs::path tmpfolder = m_args.GetDataDirBase();
1775 [ + - + - ]: 2 : fs::path tmpfile = tmpfolder / "write_binary.dat";
1776 [ + - ]: 1 : std::string expected_text = "bitcoin";
1777 [ + - ]: 1 : auto valid = WriteBinaryFile(tmpfile, expected_text);
1778 [ + - ]: 1 : std::string actual_text;
1779 [ + - ]: 1 : std::ifstream file{tmpfile};
1780 [ + - ]: 1 : file >> actual_text;
1781 [ + - + - : 2 : BOOST_CHECK(valid);
+ - ]
1782 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(actual_text, expected_text);
1783 : 3 : }
1784 : :
1785 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(clearshrink_test)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1786 : : {
1787 : 1 : {
1788 : 1 : std::vector<uint8_t> v = {1, 2, 3};
1789 : 1 : ClearShrink(v);
1790 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v.size(), 0);
1791 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v.capacity(), 0);
1792 : 0 : }
1793 : :
1794 : 1 : {
1795 : 1 : std::vector<bool> v = {false, true, false, false, true, true};
1796 : 1 : ClearShrink(v);
1797 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v.size(), 0);
1798 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v.capacity(), 0);
1799 : 0 : }
1800 : :
1801 : 1 : {
1802 : 1 : std::deque<int> v = {1, 3, 3, 7};
1803 : 1 : ClearShrink(v);
1804 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(v.size(), 0);
1805 : : // std::deque has no capacity() we can observe.
1806 : 1 : }
1807 : 1 : }
1808 : :
1809 : : BOOST_AUTO_TEST_SUITE_END()
|