Repository: bitcoin/bitcoin
File: src/test/streams_tests.cpp (C++)

Code before:
#endif
        AutoFile xor_file{raw_file(mode), obfuscation};
        xor_file << test1 << test2;
        BOOST_REQUIRE_EQUAL(xor_file.fclose(), 0);
    }
    {
        // Read raw from disk
        AutoFile non_xor_file{raw_file("rb")};
        std::vector<std::byte> raw(7);
        non_xor_file >> std::span{raw};
        BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa");
        // Check that no padding exists
        BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
    }
    {
        AutoFile xor_file{raw_file("rb"), obfuscation};
        std::vector<std::byte> read1, read2;
        xor_file >> read1 >> read2;
        BOOST_CHECK_EQUAL(HexStr(read1), HexStr(test1));
        BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2));
        // Check that eof was reached
        BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"});
    }
    {
        AutoFile xor_file{raw_file("rb"), obfuscation};
        std::vector<std::byte> read2;
        // Check that ignore works
        xor_file.ignore(4);
        xor_file >> read2;
        BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2));
        // Check that ignore and read fail now
        BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
        BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"});
    }
}

BOOST_AUTO_TEST_CASE(streams_vector_writer)
{
    unsigned char a(1);
    unsigned char b(2);
    unsigned char bytes[] = {3, 4, 5, 6};
    std::vector<unsigned char> vch;

    // Each test runs twice. Serializing a second time at the same starting
    // point should yield the same results, even if the first test grew the
    // vector.

    VectorWriter{vch, 0, a, b};
    BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
    VectorWriter{vch, 0, a, b};
    BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));

Review comment (bug):
Why do we get 14?

Tried adding...
```C++
    {
        AutoFile test{raw_file("rb"), obfuscation};
        BOOST_CHECK_EQUAL(test.size(), 14);
    }
```
...just after this block before digging into the data but it fails with `size()` suddenly returning 7 (which would be what we expect: 2 vector compact size bytes + 2+3 bytes of data).

Code after:
BOOST_AUTO_TEST_CASE(xor_file)
{
    fs::path xor_path{m_args.GetDataDirBase() / "test_xor.bin"};
    auto raw_file{[&](const auto& mode) { return fsbridge::fopen(xor_path, mode); }};
    const std::vector<uint8_t> test1{1, 2, 3};
    const std::vector<uint8_t> test2{4, 5};
    const Obfuscation obfuscation{"ff00ff00ff00ff00"_hex};

    {
        // Check errors for missing file
        AutoFile xor_file{raw_file("rb"), obfuscation};
        BOOST_CHECK_EXCEPTION(xor_file << std::byte{}, std::ios_base::failure, HasReason{"AutoFile::write: file handle is nullptr"});
        BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: file handle is nullptr"});
        BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: file handle is nullptr"});
        BOOST_CHECK_EXCEPTION(xor_file.size(), std::ios_base::failure, HasReason{"AutoFile::size: file handle is nullptr"});
    }
    {
#ifdef __MINGW64__
        // Temporary workaround for https://github.com/bitcoin/bitcoin/issues/30210
        const char* mode = "wb";
#else
        const char* mode = "wbx";
#endif
        AutoFile xor_file{raw_file(mode), obfuscation};
        xor_file << test1 << test2;
        BOOST_CHECK_EQUAL(xor_file.size(), 7);
        BOOST_REQUIRE_EQUAL(xor_file.fclose(), 0);
    }
    {
        // Read raw from disk
        AutoFile non_xor_file{raw_file("rb")};
        std::vector<std::byte> raw(7);
        non_xor_file >> std::span{raw};
        BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa");
        // Check that no padding exists
        BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
        BOOST_CHECK_EQUAL(non_xor_file.size(), 7);
    }
    {
        AutoFile xor_file{raw_file("rb"), obfuscation};
        std::vector<std::byte> read1, read2;
        xor_file >> read1 >> read2;
        BOOST_CHECK_EQUAL(HexStr(read1), HexStr(test1));
        BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2));
        // Check that eof was reached
        BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"});
        BOOST_CHECK_EQUAL(xor_file.size(), 7);
    }
    {
        AutoFile xor_file{raw_file("rb"), obfuscation};
        std::vector<std::byte> read2;