13#include <boost/test/unit_test.hpp>
15using namespace std::string_literals;
21 fs::path xor_path{m_args.GetDataDirBase() /
"test_xor.bin"};
22 auto raw_file{[&](
const auto& mode) {
return fsbridge::fopen(xor_path, mode); }};
23 const std::vector<uint8_t>
test1{1, 2, 3};
24 const std::vector<uint8_t> test2{4, 5};
25 const std::vector<std::byte> xor_pat{std::byte{0xff}, std::byte{0x00}};
28 AutoFile xor_file{raw_file(
"rb"), xor_pat};
29 BOOST_CHECK_EXCEPTION(xor_file << std::byte{}, std::ios_base::failure,
HasReason{
"AutoFile::write: file handle is nullpt"});
30 BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure,
HasReason{
"AutoFile::read: file handle is nullpt"});
31 BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure,
HasReason{
"AutoFile::ignore: file handle is nullpt"});
36 const char* mode =
"wb";
38 const char* mode =
"wbx";
40 AutoFile xor_file{raw_file(mode), xor_pat};
41 xor_file <<
test1 << test2;
45 AutoFile non_xor_file{raw_file(
"rb")};
46 std::vector<std::byte> raw(7);
47 non_xor_file >> std::span{raw};
50 BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure,
HasReason{
"AutoFile::ignore: end of file"});
53 AutoFile xor_file{raw_file(
"rb"), xor_pat};
54 std::vector<std::byte> read1, read2;
55 xor_file >> read1 >> read2;
59 BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure,
HasReason{
"AutoFile::read: end of file"});
62 AutoFile xor_file{raw_file(
"rb"), xor_pat};
63 std::vector<std::byte> read2;
69 BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure,
HasReason{
"AutoFile::ignore: end of file"});
70 BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure,
HasReason{
"AutoFile::read: end of file"});
78 unsigned char bytes[] = { 3, 4, 5, 6 };
79 std::vector<unsigned char> vch;
86 BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
88 BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
92 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
94 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
99 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
101 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
106 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
108 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
113 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
115 BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
119 BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
121 BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
126 BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
128 BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
134 std::vector<unsigned char> vch = {1, 255, 3, 4, 5, 6};
179 std::vector<uint8_t>
data{0x82, 0xa7, 0x31};
193 bit_writer.Write(0, 1);
194 bit_writer.Write(2, 2);
195 bit_writer.Write(6, 3);
196 bit_writer.Write(11, 4);
197 bit_writer.Write(1, 5);
198 bit_writer.Write(32, 6);
199 bit_writer.Write(7, 7);
200 bit_writer.Write(30497, 16);
204 uint32_t serialized_int1;
205 data >> serialized_int1;
207 uint16_t serialized_int2;
208 data >> serialized_int2;
225 std::vector<std::byte> in;
230 ds.
Xor({0x00, 0x00});
234 in.push_back(std::byte{0x0f});
235 in.push_back(std::byte{0xf0});
247 in.push_back(std::byte{0xf0});
248 in.push_back(std::byte{0x0f});
252 ds.
Xor({0xff, 0x0f});
259 fs::path streams_test_filename = m_args.GetDataDirBase() /
"streams_test_tmp";
263 for (uint8_t j = 0; j < 40; ++j) {
266 file.seek(0, SEEK_SET);
273 }
catch (
const std::exception& e) {
275 "Rewind limit must be less than buffer size") !=
nullptr);
309 }
catch (
const std::exception& e) {
311 "Attempt to position past buffer limit") !=
nullptr);
319 for (uint8_t j = 3; j < 10; ++j) {
352 for (uint8_t j = 0; j <
sizeof(a); ++j) {
362 }
catch (
const std::exception& e) {
364 "BufferedFile::Fill: end of file") !=
nullptr);
385 fs::remove(streams_test_filename);
390 fs::path streams_test_filename = m_args.GetDataDirBase() /
"streams_test_tmp";
393 for (uint8_t j = 0; j < 40; ++j) {
396 file.seek(0, SEEK_SET);
425 }
catch (
const std::exception& e) {
426 BOOST_CHECK(strstr(e.what(),
"Attempt to position past buffer limit") !=
nullptr);
434 fs::remove(streams_test_filename);
442 fs::path streams_test_filename = m_args.GetDataDirBase() /
"streams_test_tmp";
443 for (
int rep = 0; rep < 50; ++rep) {
445 size_t fileSize = m_rng.randrange(256);
446 for (uint8_t i = 0; i < fileSize; ++i) {
449 file.seek(0, SEEK_SET);
451 size_t bufSize = m_rng.randrange(300) + 1;
452 size_t rewindSize = m_rng.randrange(bufSize);
454 size_t currentPos = 0;
456 for (
int step = 0; step < 100; ++step) {
457 if (currentPos >= fileSize)
468 switch (m_rng.randrange(6)) {
471 if (currentPos + 1 > fileSize)
473 bf.SetLimit(currentPos + 1);
475 for (uint8_t i = 0; i < 1; ++i) {
483 if (currentPos + 2 > fileSize)
485 bf.SetLimit(currentPos + 2);
487 for (uint8_t i = 0; i < 2; ++i) {
495 if (currentPos + 5 > fileSize)
497 bf.SetLimit(currentPos + 5);
499 for (uint8_t i = 0; i < 5; ++i) {
508 size_t skip_length{
static_cast<size_t>(m_rng.randrange(5))};
509 if (currentPos + skip_length > fileSize)
continue;
510 bf.SetLimit(currentPos + skip_length);
511 bf.SkipTo(currentPos + skip_length);
512 currentPos += skip_length;
517 size_t find = currentPos + m_rng.randrange(8);
518 if (find >= fileSize)
520 bf.FindByte(std::byte(find));
525 bf.SetLimit(currentPos + 1);
533 size_t requestPos = m_rng.randrange(maxPos + 4);
534 bool okay = bf.SetPos(requestPos);
539 currentPos = bf.GetPos();
542 if (requestPos <= maxPos &&
543 maxPos > rewindSize &&
544 requestPos >= maxPos - rewindSize) {
551 if (maxPos < currentPos)
555 fs::remove(streams_test_filename);
560 const size_t file_size{1 + m_rng.randrange<
size_t>(1 << 17)};
561 const size_t buf_size{1 + m_rng.randrange(file_size)};
565 const std::vector obfuscation{m_rng.randbytes<std::byte>(8)};
569 AutoFile{test_file.Open(pos,
false), obfuscation}.
write(m_rng.randbytes<std::byte>(file_size));
574 AutoFile direct_file{test_file.Open(pos,
true), obfuscation};
576 AutoFile buffered_file{test_file.Open(pos,
true), obfuscation};
577 BufferedReader buffered_reader{std::move(buffered_file), buf_size};
579 for (
size_t total_read{0}; total_read < file_size;) {
580 const size_t read{
Assert(std::min(1 + m_rng.randrange(m_rng.randbool() ? buf_size : 2 * buf_size), file_size - total_read))};
583 direct_file.read(direct_file_buffer);
586 buffered_reader.read(buffered_buffer);
588 BOOST_CHECK_EQUAL_COLLECTIONS(
589 direct_file_buffer.begin(), direct_file_buffer.end(),
590 buffered_buffer.begin(), buffered_buffer.end()
598 BOOST_CHECK_EXCEPTION(direct_file.read(excess_byte), std::ios_base::failure,
HasReason{
"end of file"});
603 BOOST_CHECK_EXCEPTION(buffered_reader.read(excess_byte), std::ios_base::failure,
HasReason{
"end of file"});
607 fs::remove(test_file.FileName(pos));
612 const size_t file_size{1 + m_rng.randrange<
size_t>(1 << 17)};
613 const size_t buf_size{1 + m_rng.randrange(file_size)};
618 const std::vector obfuscation{m_rng.randbytes<std::byte>(8)};
621 DataBuffer test_data{m_rng.randbytes<std::byte>(file_size)};
623 AutoFile direct_file{test_direct.Open(pos,
false), obfuscation};
625 AutoFile buffered_file{test_buffered.Open(pos,
false), obfuscation};
628 for (
size_t total_written{0}; total_written < file_size;) {
629 const size_t write_size{
Assert(std::min(1 + m_rng.randrange(m_rng.randbool() ? buf_size : 2 * buf_size), file_size - total_written))};
631 auto current_span = std::span{test_data}.subspan(total_written, write_size);
632 direct_file.write(current_span);
633 buffered.write(current_span);
635 total_written += write_size;
643 AutoFile verify_direct{test_direct.Open(pos,
true), obfuscation};
644 verify_direct.
read(direct_result);
647 BOOST_CHECK_EXCEPTION(verify_direct.read(excess_byte), std::ios_base::failure,
HasReason{
"end of file"});
652 AutoFile verify_buffered{test_buffered.Open(pos,
true), obfuscation};
653 verify_buffered.
read(buffered_result);
656 BOOST_CHECK_EXCEPTION(verify_buffered.read(excess_byte), std::ios_base::failure,
HasReason{
"end of file"});
659 BOOST_CHECK_EQUAL_COLLECTIONS(
660 direct_result.begin(), direct_result.end(),
661 buffered_result.begin(), buffered_result.end()
664 fs::remove(test_direct.FileName(pos));
665 fs::remove(test_buffered.FileName(pos));
670 const uint32_t v1{m_rng.rand32()}, v2{m_rng.rand32()}, v3{m_rng.rand32()};
671 const fs::path test_file{m_args.GetDataDirBase() /
"test_buffered_write_read.bin"};
678 f.
write(std::as_bytes(std::span{&v3, 1}));
682 uint32_t _v1{0}, _v2{0}, _v3{0};
684 BufferedReader f(std::move(file),
sizeof(v1) +
sizeof(v2) +
sizeof(v3));
686 f.
read(std::as_writable_bytes(std::span{&_v3, 1}));
692 BOOST_CHECK_EXCEPTION(f.
read(excess_byte), std::ios_base::failure,
HasReason{
"end of file"});
695 fs::remove(test_file);
702 const std::string
data{
"bitcoin"};
707 hash_verifier >> result;
#define Assert(val)
Identity function.
Non-refcounted RAII wrapper for FILE*.
void ignore(size_t nSize)
void write(std::span< const std::byte > src)
void read(std::span< std::byte > dst)
Wrapper around an AutoFile& that implements a ring buffer to deserialize from.
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
Wrapper that buffers reads from an underlying stream.
void read(std::span< std::byte > dst)
Wrapper that buffers writes to an underlying stream.
void write(std::span< const std::byte > src)
Double ended buffer combining vector and stream-like interfaces.
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
FlatFileSeq represents a sequence of numbered files storing raw data.
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
Reads data from an underlying stream, while hashing the read data.
Writes data to an underlying source stream, while hashing the written data.
Minimal stream for reading from an existing byte array by std::span.
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
FILE * fopen(const fs::path &p, const char *mode)
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
#define BOOST_CHECK_THROW(stmt, excMatch)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
std::vector< std::byte > DataBuffer
BOOST_AUTO_TEST_CASE(xor_file)
@ ZEROS
Seed with a compile time constant of zeros.