Bitcoin Core 28.99.0
P2P Digital Currency
streams_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2012-2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <streams.h>
6#include <test/util/random.h>
8#include <util/fs.h>
9#include <util/strencodings.h>
10
11#include <boost/test/unit_test.hpp>
12
13using namespace std::string_literals;
14
16
18{
19 fs::path xor_path{m_args.GetDataDirBase() / "test_xor.bin"};
20 auto raw_file{[&](const auto& mode) { return fsbridge::fopen(xor_path, mode); }};
21 const std::vector<uint8_t> test1{1, 2, 3};
22 const std::vector<uint8_t> test2{4, 5};
23 const std::vector<std::byte> xor_pat{std::byte{0xff}, std::byte{0x00}};
24 {
25 // Check errors for missing file
26 AutoFile xor_file{raw_file("rb"), xor_pat};
27 BOOST_CHECK_EXCEPTION(xor_file << std::byte{}, std::ios_base::failure, HasReason{"AutoFile::write: file handle is nullpt"});
28 BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: file handle is nullpt"});
29 BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: file handle is nullpt"});
30 }
31 {
32#ifdef __MINGW64__
33 // Temporary workaround for https://github.com/bitcoin/bitcoin/issues/30210
34 const char* mode = "wb";
35#else
36 const char* mode = "wbx";
37#endif
38 AutoFile xor_file{raw_file(mode), xor_pat};
39 xor_file << test1 << test2;
40 }
41 {
42 // Read raw from disk
43 AutoFile non_xor_file{raw_file("rb")};
44 std::vector<std::byte> raw(7);
45 non_xor_file >> Span{raw};
46 BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa");
47 // Check that no padding exists
48 BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
49 }
50 {
51 AutoFile xor_file{raw_file("rb"), xor_pat};
52 std::vector<std::byte> read1, read2;
53 xor_file >> read1 >> read2;
55 BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2));
56 // Check that eof was reached
57 BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"});
58 }
59 {
60 AutoFile xor_file{raw_file("rb"), xor_pat};
61 std::vector<std::byte> read2;
62 // Check that ignore works
63 xor_file.ignore(4);
64 xor_file >> read2;
65 BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2));
66 // Check that ignore and read fail now
67 BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
68 BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"});
69 }
70}
71
72BOOST_AUTO_TEST_CASE(streams_vector_writer)
73{
74 unsigned char a(1);
75 unsigned char b(2);
76 unsigned char bytes[] = { 3, 4, 5, 6 };
77 std::vector<unsigned char> vch;
78
79 // Each test runs twice. Serializing a second time at the same starting
80 // point should yield the same results, even if the first test grew the
81 // vector.
82
83 VectorWriter{vch, 0, a, b};
84 BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
85 VectorWriter{vch, 0, a, b};
86 BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
87 vch.clear();
88
89 VectorWriter{vch, 2, a, b};
90 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
91 VectorWriter{vch, 2, a, b};
92 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
93 vch.clear();
94
95 vch.resize(5, 0);
96 VectorWriter{vch, 2, a, b};
97 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
98 VectorWriter{vch, 2, a, b};
99 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
100 vch.clear();
101
102 vch.resize(4, 0);
103 VectorWriter{vch, 3, a, b};
104 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
105 VectorWriter{vch, 3, a, b};
106 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
107 vch.clear();
108
109 vch.resize(4, 0);
110 VectorWriter{vch, 4, a, b};
111 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
112 VectorWriter{vch, 4, a, b};
113 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
114 vch.clear();
115
116 VectorWriter{vch, 0, bytes};
117 BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
118 VectorWriter{vch, 0, bytes};
119 BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
120 vch.clear();
121
122 vch.resize(4, 8);
123 VectorWriter{vch, 2, a, bytes, b};
124 BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
125 VectorWriter{vch, 2, a, bytes, b};
126 BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
127 vch.clear();
128}
129
130BOOST_AUTO_TEST_CASE(streams_vector_reader)
131{
132 std::vector<unsigned char> vch = {1, 255, 3, 4, 5, 6};
133
134 SpanReader reader{vch};
135 BOOST_CHECK_EQUAL(reader.size(), 6U);
136 BOOST_CHECK(!reader.empty());
137
138 // Read a single byte as an unsigned char.
139 unsigned char a;
140 reader >> a;
141 BOOST_CHECK_EQUAL(a, 1);
142 BOOST_CHECK_EQUAL(reader.size(), 5U);
143 BOOST_CHECK(!reader.empty());
144
145 // Read a single byte as a int8_t.
146 int8_t b;
147 reader >> b;
148 BOOST_CHECK_EQUAL(b, -1);
149 BOOST_CHECK_EQUAL(reader.size(), 4U);
150 BOOST_CHECK(!reader.empty());
151
152 // Read a 4 bytes as an unsigned int.
153 unsigned int c;
154 reader >> c;
155 BOOST_CHECK_EQUAL(c, 100992003U); // 3,4,5,6 in little-endian base-256
156 BOOST_CHECK_EQUAL(reader.size(), 0U);
157 BOOST_CHECK(reader.empty());
158
159 // Reading after end of byte vector throws an error.
160 signed int d;
161 BOOST_CHECK_THROW(reader >> d, std::ios_base::failure);
162
163 // Read a 4 bytes as a signed int from the beginning of the buffer.
164 SpanReader new_reader{vch};
165 new_reader >> d;
166 BOOST_CHECK_EQUAL(d, 67370753); // 1,255,3,4 in little-endian base-256
167 BOOST_CHECK_EQUAL(new_reader.size(), 2U);
168 BOOST_CHECK(!new_reader.empty());
169
170 // Reading after end of byte vector throws an error even if the reader is
171 // not totally empty.
172 BOOST_CHECK_THROW(new_reader >> d, std::ios_base::failure);
173}
174
175BOOST_AUTO_TEST_CASE(streams_vector_reader_rvalue)
176{
177 std::vector<uint8_t> data{0x82, 0xa7, 0x31};
178 SpanReader reader{data};
179 uint32_t varint = 0;
180 // Deserialize into r-value
181 reader >> VARINT(varint);
182 BOOST_CHECK_EQUAL(varint, 54321U);
183 BOOST_CHECK(reader.empty());
184}
185
186BOOST_AUTO_TEST_CASE(bitstream_reader_writer)
187{
189
190 BitStreamWriter bit_writer{data};
191 bit_writer.Write(0, 1);
192 bit_writer.Write(2, 2);
193 bit_writer.Write(6, 3);
194 bit_writer.Write(11, 4);
195 bit_writer.Write(1, 5);
196 bit_writer.Write(32, 6);
197 bit_writer.Write(7, 7);
198 bit_writer.Write(30497, 16);
199 bit_writer.Flush();
200
201 DataStream data_copy{data};
202 uint32_t serialized_int1;
203 data >> serialized_int1;
204 BOOST_CHECK_EQUAL(serialized_int1, uint32_t{0x7700C35A}); // NOTE: Serialized as LE
205 uint16_t serialized_int2;
206 data >> serialized_int2;
207 BOOST_CHECK_EQUAL(serialized_int2, uint16_t{0x1072}); // NOTE: Serialized as LE
208
209 BitStreamReader bit_reader{data_copy};
210 BOOST_CHECK_EQUAL(bit_reader.Read(1), 0U);
211 BOOST_CHECK_EQUAL(bit_reader.Read(2), 2U);
212 BOOST_CHECK_EQUAL(bit_reader.Read(3), 6U);
213 BOOST_CHECK_EQUAL(bit_reader.Read(4), 11U);
214 BOOST_CHECK_EQUAL(bit_reader.Read(5), 1U);
215 BOOST_CHECK_EQUAL(bit_reader.Read(6), 32U);
216 BOOST_CHECK_EQUAL(bit_reader.Read(7), 7U);
217 BOOST_CHECK_EQUAL(bit_reader.Read(16), 30497U);
218 BOOST_CHECK_THROW(bit_reader.Read(8), std::ios_base::failure);
219}
220
221BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
222{
223 std::vector<std::byte> in;
224
225 // Degenerate case
226 {
227 DataStream ds{in};
228 ds.Xor({0x00, 0x00});
229 BOOST_CHECK_EQUAL(""s, ds.str());
230 }
231
232 in.push_back(std::byte{0x0f});
233 in.push_back(std::byte{0xf0});
234
235 // Single character key
236 {
237 DataStream ds{in};
238 ds.Xor({0xff});
239 BOOST_CHECK_EQUAL("\xf0\x0f"s, ds.str());
240 }
241
242 // Multi character key
243
244 in.clear();
245 in.push_back(std::byte{0xf0});
246 in.push_back(std::byte{0x0f});
247
248 {
249 DataStream ds{in};
250 ds.Xor({0xff, 0x0f});
251 BOOST_CHECK_EQUAL("\x0f\x00"s, ds.str());
252 }
253}
254
255BOOST_AUTO_TEST_CASE(streams_buffered_file)
256{
257 fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
258 AutoFile file{fsbridge::fopen(streams_test_filename, "w+b")};
259
260 // The value at each offset is the offset.
261 for (uint8_t j = 0; j < 40; ++j) {
262 file << j;
263 }
264 file.seek(0, SEEK_SET);
265
266 // The buffer size (second arg) must be greater than the rewind
267 // amount (third arg).
268 try {
269 BufferedFile bfbad{file, 25, 25};
270 BOOST_CHECK(false);
271 } catch (const std::exception& e) {
272 BOOST_CHECK(strstr(e.what(),
273 "Rewind limit must be less than buffer size") != nullptr);
274 }
275
276 // The buffer is 25 bytes, allow rewinding 10 bytes.
277 BufferedFile bf{file, 25, 10};
278 BOOST_CHECK(!bf.eof());
279
280 uint8_t i;
281 bf >> i;
282 BOOST_CHECK_EQUAL(i, 0);
283 bf >> i;
284 BOOST_CHECK_EQUAL(i, 1);
285
286 // After reading bytes 0 and 1, we're positioned at 2.
287 BOOST_CHECK_EQUAL(bf.GetPos(), 2U);
288
289 // Rewind to offset 0, ok (within the 10 byte window).
290 BOOST_CHECK(bf.SetPos(0));
291 bf >> i;
292 BOOST_CHECK_EQUAL(i, 0);
293
294 // We can go forward to where we've been, but beyond may fail.
295 BOOST_CHECK(bf.SetPos(2));
296 bf >> i;
297 BOOST_CHECK_EQUAL(i, 2);
298
299 // If you know the maximum number of bytes that should be
300 // read to deserialize the variable, you can limit the read
301 // extent. The current file offset is 3, so the following
302 // SetLimit() allows zero bytes to be read.
303 BOOST_CHECK(bf.SetLimit(3));
304 try {
305 bf >> i;
306 BOOST_CHECK(false);
307 } catch (const std::exception& e) {
308 BOOST_CHECK(strstr(e.what(),
309 "Attempt to position past buffer limit") != nullptr);
310 }
311 // The default argument removes the limit completely.
312 BOOST_CHECK(bf.SetLimit());
313 // The read position should still be at 3 (no change).
314 BOOST_CHECK_EQUAL(bf.GetPos(), 3U);
315
316 // Read from current offset, 3, forward until position 10.
317 for (uint8_t j = 3; j < 10; ++j) {
318 bf >> i;
319 BOOST_CHECK_EQUAL(i, j);
320 }
321 BOOST_CHECK_EQUAL(bf.GetPos(), 10U);
322
323 // We're guaranteed (just barely) to be able to rewind to zero.
324 BOOST_CHECK(bf.SetPos(0));
325 BOOST_CHECK_EQUAL(bf.GetPos(), 0U);
326 bf >> i;
327 BOOST_CHECK_EQUAL(i, 0);
328
329 // We can set the position forward again up to the farthest
330 // into the stream we've been, but no farther. (Attempting
331 // to go farther may succeed, but it's not guaranteed.)
332 BOOST_CHECK(bf.SetPos(10));
333 bf >> i;
334 BOOST_CHECK_EQUAL(i, 10);
335 BOOST_CHECK_EQUAL(bf.GetPos(), 11U);
336
337 // Now it's only guaranteed that we can rewind to offset 1
338 // (current read position, 11, minus rewind amount, 10).
339 BOOST_CHECK(bf.SetPos(1));
340 BOOST_CHECK_EQUAL(bf.GetPos(), 1U);
341 bf >> i;
342 BOOST_CHECK_EQUAL(i, 1);
343
344 // We can stream into large variables, even larger than
345 // the buffer size.
346 BOOST_CHECK(bf.SetPos(11));
347 {
348 uint8_t a[40 - 11];
349 bf >> a;
350 for (uint8_t j = 0; j < sizeof(a); ++j) {
351 BOOST_CHECK_EQUAL(a[j], 11 + j);
352 }
353 }
354 BOOST_CHECK_EQUAL(bf.GetPos(), 40U);
355
356 // We've read the entire file, the next read should throw.
357 try {
358 bf >> i;
359 BOOST_CHECK(false);
360 } catch (const std::exception& e) {
361 BOOST_CHECK(strstr(e.what(),
362 "BufferedFile::Fill: end of file") != nullptr);
363 }
364 // Attempting to read beyond the end sets the EOF indicator.
365 BOOST_CHECK(bf.eof());
366
367 // Still at offset 40, we can go back 10, to 30.
368 BOOST_CHECK_EQUAL(bf.GetPos(), 40U);
369 BOOST_CHECK(bf.SetPos(30));
370 bf >> i;
371 BOOST_CHECK_EQUAL(i, 30);
372 BOOST_CHECK_EQUAL(bf.GetPos(), 31U);
373
374 // We're too far to rewind to position zero.
375 BOOST_CHECK(!bf.SetPos(0));
376 // But we should now be positioned at least as far back as allowed
377 // by the rewind window (relative to our farthest read position, 40).
378 BOOST_CHECK(bf.GetPos() <= 30U);
379
380 // We can explicitly close the file, or the destructor will do it.
381 file.fclose();
382
383 fs::remove(streams_test_filename);
384}
385
386BOOST_AUTO_TEST_CASE(streams_buffered_file_skip)
387{
388 fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
389 AutoFile file{fsbridge::fopen(streams_test_filename, "w+b")};
390 // The value at each offset is the byte offset (e.g. byte 1 in the file has the value 0x01).
391 for (uint8_t j = 0; j < 40; ++j) {
392 file << j;
393 }
394 file.seek(0, SEEK_SET);
395
396 // The buffer is 25 bytes, allow rewinding 10 bytes.
397 BufferedFile bf{file, 25, 10};
398
399 uint8_t i;
400 // This is like bf >> (7-byte-variable), in that it will cause data
401 // to be read from the file into memory, but it's not copied to us.
402 bf.SkipTo(7);
403 BOOST_CHECK_EQUAL(bf.GetPos(), 7U);
404 bf >> i;
405 BOOST_CHECK_EQUAL(i, 7);
406
407 // The bytes in the buffer up to offset 7 are valid and can be read.
408 BOOST_CHECK(bf.SetPos(0));
409 bf >> i;
410 BOOST_CHECK_EQUAL(i, 0);
411 bf >> i;
412 BOOST_CHECK_EQUAL(i, 1);
413
414 bf.SkipTo(11);
415 bf >> i;
416 BOOST_CHECK_EQUAL(i, 11);
417
418 // SkipTo() honors the transfer limit; we can't position beyond the limit.
419 bf.SetLimit(13);
420 try {
421 bf.SkipTo(14);
422 BOOST_CHECK(false);
423 } catch (const std::exception& e) {
424 BOOST_CHECK(strstr(e.what(), "Attempt to position past buffer limit") != nullptr);
425 }
426
427 // We can position exactly to the transfer limit.
428 bf.SkipTo(13);
429 BOOST_CHECK_EQUAL(bf.GetPos(), 13U);
430
431 file.fclose();
432 fs::remove(streams_test_filename);
433}
434
435BOOST_AUTO_TEST_CASE(streams_buffered_file_rand)
436{
437 // Make this test deterministic.
438 SeedRandomForTest(SeedRand::ZEROS);
439
440 fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
441 for (int rep = 0; rep < 50; ++rep) {
442 AutoFile file{fsbridge::fopen(streams_test_filename, "w+b")};
443 size_t fileSize = m_rng.randrange(256);
444 for (uint8_t i = 0; i < fileSize; ++i) {
445 file << i;
446 }
447 file.seek(0, SEEK_SET);
448
449 size_t bufSize = m_rng.randrange(300) + 1;
450 size_t rewindSize = m_rng.randrange(bufSize);
451 BufferedFile bf{file, bufSize, rewindSize};
452 size_t currentPos = 0;
453 size_t maxPos = 0;
454 for (int step = 0; step < 100; ++step) {
455 if (currentPos >= fileSize)
456 break;
457
458 // We haven't read to the end of the file yet.
459 BOOST_CHECK(!bf.eof());
460 BOOST_CHECK_EQUAL(bf.GetPos(), currentPos);
461
462 // Pretend the file consists of a series of objects of varying
463 // sizes; the boundaries of the objects can interact arbitrarily
464 // with the CBufferFile's internal buffer. These first three
465 // cases simulate objects of various sizes (1, 2, 5 bytes).
466 switch (m_rng.randrange(6)) {
467 case 0: {
468 uint8_t a[1];
469 if (currentPos + 1 > fileSize)
470 continue;
471 bf.SetLimit(currentPos + 1);
472 bf >> a;
473 for (uint8_t i = 0; i < 1; ++i) {
474 BOOST_CHECK_EQUAL(a[i], currentPos);
475 currentPos++;
476 }
477 break;
478 }
479 case 1: {
480 uint8_t a[2];
481 if (currentPos + 2 > fileSize)
482 continue;
483 bf.SetLimit(currentPos + 2);
484 bf >> a;
485 for (uint8_t i = 0; i < 2; ++i) {
486 BOOST_CHECK_EQUAL(a[i], currentPos);
487 currentPos++;
488 }
489 break;
490 }
491 case 2: {
492 uint8_t a[5];
493 if (currentPos + 5 > fileSize)
494 continue;
495 bf.SetLimit(currentPos + 5);
496 bf >> a;
497 for (uint8_t i = 0; i < 5; ++i) {
498 BOOST_CHECK_EQUAL(a[i], currentPos);
499 currentPos++;
500 }
501 break;
502 }
503 case 3: {
504 // SkipTo is similar to the "read" cases above, except
505 // we don't receive the data.
506 size_t skip_length{static_cast<size_t>(m_rng.randrange(5))};
507 if (currentPos + skip_length > fileSize) continue;
508 bf.SetLimit(currentPos + skip_length);
509 bf.SkipTo(currentPos + skip_length);
510 currentPos += skip_length;
511 break;
512 }
513 case 4: {
514 // Find a byte value (that is at or ahead of the current position).
515 size_t find = currentPos + m_rng.randrange(8);
516 if (find >= fileSize)
517 find = fileSize - 1;
518 bf.FindByte(std::byte(find));
519 // The value at each offset is the offset.
520 BOOST_CHECK_EQUAL(bf.GetPos(), find);
521 currentPos = find;
522
523 bf.SetLimit(currentPos + 1);
524 uint8_t i;
525 bf >> i;
526 BOOST_CHECK_EQUAL(i, currentPos);
527 currentPos++;
528 break;
529 }
530 case 5: {
531 size_t requestPos = m_rng.randrange(maxPos + 4);
532 bool okay = bf.SetPos(requestPos);
533 // The new position may differ from the requested position
534 // because we may not be able to rewind beyond the rewind
535 // window, and we may not be able to move forward beyond the
536 // farthest position we've reached so far.
537 currentPos = bf.GetPos();
538 BOOST_CHECK_EQUAL(okay, currentPos == requestPos);
539 // Check that we can position within the rewind window.
540 if (requestPos <= maxPos &&
541 maxPos > rewindSize &&
542 requestPos >= maxPos - rewindSize) {
543 // We requested a position within the rewind window.
544 BOOST_CHECK(okay);
545 }
546 break;
547 }
548 }
549 if (maxPos < currentPos)
550 maxPos = currentPos;
551 }
552 }
553 fs::remove(streams_test_filename);
554}
555
556BOOST_AUTO_TEST_CASE(streams_hashed)
557{
558 DataStream stream{};
559 HashedSourceWriter hash_writer{stream};
560 const std::string data{"bitcoin"};
561 hash_writer << data;
562
563 HashVerifier hash_verifier{stream};
564 std::string result;
565 hash_verifier >> result;
566 BOOST_CHECK_EQUAL(data, result);
567 BOOST_CHECK_EQUAL(hash_writer.GetHash(), hash_verifier.GetHash());
568}
569
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:392
void ignore(size_t nSize)
Definition: streams.cpp:67
Wrapper around an AutoFile& that implements a ring buffer to deserialize from.
Definition: streams.h:477
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
Definition: streams.h:550
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
Definition: streams.h:276
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
Definition: setup_common.h:295
Reads data from an underlying stream, while hashing the read data.
Definition: hash.h:151
Writes data to an underlying source stream, while hashing the written data.
Definition: hash.h:185
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:98
Minimal stream for reading from an existing byte array by Span.
Definition: streams.h:101
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
const std::string test1
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:29
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:26
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:19
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
#define VARINT(obj)
Definition: serialize.h:498
BOOST_AUTO_TEST_CASE(xor_file)
Basic testing setup.
Definition: setup_common.h:63
@ ZEROS
Seed with a compile time constant of zeros.