diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 30a44870f..61a9504da 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -1,218 +1,221 @@ // Copyright (c) 2012-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include -#include // for 'operator+=()' #include -using namespace boost::assign; // bring 'operator+=()' into scope - BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(streams_vector_writer) { uint8_t a(1); uint8_t b(2); uint8_t bytes[] = {3, 4, 5, 6}; std::vector 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. CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b); BOOST_CHECK((vch == std::vector{{1, 2}})); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b); BOOST_CHECK((vch == std::vector{{1, 2}})); vch.clear(); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 1, 2}})); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 1, 2}})); vch.clear(); vch.resize(5, 0); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 1, 2, 0}})); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 1, 2, 0}})); vch.clear(); vch.resize(4, 0); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 0, 1, 2}})); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 0, 1, 2}})); vch.clear(); vch.resize(4, 0); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 0, 0, 1, 2}})); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b); BOOST_CHECK((vch == std::vector{{0, 0, 0, 0, 1, 2}})); vch.clear(); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes); BOOST_CHECK((vch == std::vector{{3, 4, 5, 6}})); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes); BOOST_CHECK((vch == std::vector{{3, 4, 5, 6}})); vch.clear(); vch.resize(4, 8); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b); BOOST_CHECK((vch == std::vector{{8, 8, 1, 3, 4, 5, 6, 2}})); CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b); BOOST_CHECK((vch == std::vector{{8, 8, 1, 3, 4, 5, 6, 2}})); vch.clear(); } BOOST_AUTO_TEST_CASE(streams_vector_reader) { std::vector vch = {1, 255, 3, 4, 5, 6}; VectorReader reader(SER_NETWORK, INIT_PROTO_VERSION, vch, 0); BOOST_CHECK_EQUAL(reader.size(), 6); BOOST_CHECK(!reader.empty()); // Read a single byte as an uint8_t. uint8_t a; reader >> a; BOOST_CHECK_EQUAL(a, 1); BOOST_CHECK_EQUAL(reader.size(), 5); BOOST_CHECK(!reader.empty()); // Read a single byte as a (signed) int8_t. int8_t b; reader >> b; BOOST_CHECK_EQUAL(b, -1); BOOST_CHECK_EQUAL(reader.size(), 4); BOOST_CHECK(!reader.empty()); // Read a 4 bytes as an unsigned uint32_t. uint32_t c; reader >> c; // 100992003 = 3,4,5,6 in little-endian base-256 BOOST_CHECK_EQUAL(c, 100992003); BOOST_CHECK_EQUAL(reader.size(), 0); BOOST_CHECK(reader.empty()); // Reading after end of byte vector throws an error. int32_t d; BOOST_CHECK_THROW(reader >> d, std::ios_base::failure); // Read a 4 bytes as a (signed) int32_t from the beginning of the buffer. VectorReader new_reader(SER_NETWORK, INIT_PROTO_VERSION, vch, 0); new_reader >> d; // 67370753 = 1,255,3,4 in little-endian base-256 BOOST_CHECK_EQUAL(d, 67370753); BOOST_CHECK_EQUAL(new_reader.size(), 2); BOOST_CHECK(!new_reader.empty()); // Reading after end of byte vector throws an error even if the reader is // not totally empty. BOOST_CHECK_THROW(new_reader >> d, std::ios_base::failure); } BOOST_AUTO_TEST_CASE(bitstream_reader_writer) { CDataStream data(SER_NETWORK, INIT_PROTO_VERSION); BitStreamWriter bit_writer(data); bit_writer.Write(0, 1); bit_writer.Write(2, 2); bit_writer.Write(6, 3); bit_writer.Write(11, 4); bit_writer.Write(1, 5); bit_writer.Write(32, 6); bit_writer.Write(7, 7); bit_writer.Write(30497, 16); bit_writer.Flush(); CDataStream data_copy(data); uint32_t serialized_int1; data >> serialized_int1; // NOTE: Serialized as LE BOOST_CHECK_EQUAL(serialized_int1, (uint32_t)0x7700C35A); uint16_t serialized_int2; data >> serialized_int2; // NOTE: Serialized as LE BOOST_CHECK_EQUAL(serialized_int2, (uint16_t)0x1072); BitStreamReader bit_reader(data_copy); BOOST_CHECK_EQUAL(bit_reader.Read(1), 0); BOOST_CHECK_EQUAL(bit_reader.Read(2), 2); BOOST_CHECK_EQUAL(bit_reader.Read(3), 6); BOOST_CHECK_EQUAL(bit_reader.Read(4), 11); BOOST_CHECK_EQUAL(bit_reader.Read(5), 1); BOOST_CHECK_EQUAL(bit_reader.Read(6), 32); BOOST_CHECK_EQUAL(bit_reader.Read(7), 7); BOOST_CHECK_EQUAL(bit_reader.Read(16), 30497); BOOST_CHECK_THROW(bit_reader.Read(8), std::ios_base::failure); } BOOST_AUTO_TEST_CASE(streams_serializedata_xor) { std::vector in; std::vector expected_xor; std::vector key; CDataStream ds(in, 0, 0); // Degenerate case - key += '\x00', '\x00'; + key.push_back('\x00'); + key.push_back('\x00'); ds.Xor(key); BOOST_CHECK_EQUAL(std::string(expected_xor.begin(), expected_xor.end()), std::string(ds.begin(), ds.end())); - in += '\x0f', '\xf0'; - expected_xor += '\xf0', '\x0f'; + in.push_back('\x0f'); + in.push_back('\xf0'); + expected_xor.push_back('\xf0'); + expected_xor.push_back('\x0f'); // Single character key ds.clear(); ds.insert(ds.begin(), in.begin(), in.end()); key.clear(); - key += '\xff'; + key.push_back('\xff'); ds.Xor(key); BOOST_CHECK_EQUAL(std::string(expected_xor.begin(), expected_xor.end()), std::string(ds.begin(), ds.end())); // Multi character key in.clear(); expected_xor.clear(); - in += '\xf0', '\x0f'; - expected_xor += '\x0f', '\x00'; + in.push_back('\xf0'); + in.push_back('\x0f'); + expected_xor.push_back('\x0f'); + expected_xor.push_back('\x00'); ds.clear(); ds.insert(ds.begin(), in.begin(), in.end()); key.clear(); - key += '\xff', '\x0f'; + key.push_back('\xff'); + key.push_back('\x0f'); ds.Xor(key); BOOST_CHECK_EQUAL(std::string(expected_xor.begin(), expected_xor.end()), std::string(ds.begin(), ds.end())); } BOOST_AUTO_TEST_CASE(streams_empty_vector) { std::vector in; CDataStream ds(in, 0, 0); // read 0 bytes used to cause a segfault on some older systems. BOOST_CHECK_NO_THROW(ds.read(nullptr, 0)); // Same goes for writing 0 bytes from a vector ... const std::vector vdata{'f', 'o', 'o', 'b', 'a', 'r'}; BOOST_CHECK_NO_THROW(ds.insert(ds.begin(), vdata.begin(), vdata.begin())); BOOST_CHECK_NO_THROW(ds.insert(ds.begin(), vdata.begin(), vdata.end())); // ... or an array. const char adata[6] = {'f', 'o', 'o', 'b', 'a', 'r'}; BOOST_CHECK_NO_THROW(ds.insert(ds.begin(), &adata[0], &adata[0])); BOOST_CHECK_NO_THROW(ds.insert(ds.begin(), &adata[0], &adata[6])); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/lint/lint-boost-dependencies.sh b/test/lint/lint-boost-dependencies.sh index 0c034b547..6e3e1fd5d 100755 --- a/test/lint/lint-boost-dependencies.sh +++ b/test/lint/lint-boost-dependencies.sh @@ -1,70 +1,69 @@ #!/usr/bin/env bash # # Copyright (c) 2018 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # # Guard against accidental introduction of new Boost dependencies. export LC_ALL=C EXPECTED_BOOST_INCLUDES=( boost/algorithm/string.hpp boost/algorithm/string/classification.hpp boost/algorithm/string/replace.hpp boost/algorithm/string/split.hpp - boost/assign/std/vector.hpp boost/chrono/chrono.hpp boost/date_time/posix_time/posix_time.hpp boost/filesystem.hpp boost/filesystem/fstream.hpp boost/multi_index/composite_key.hpp boost/multi_index/hashed_index.hpp boost/multi_index/member.hpp boost/multi_index/ordered_index.hpp boost/multi_index/sequenced_index.hpp boost/multi_index_container.hpp boost/noncopyable.hpp boost/optional.hpp boost/preprocessor/cat.hpp boost/preprocessor/stringize.hpp boost/range/iterator.hpp boost/range/adaptor/sliced.hpp boost/signals2/connection.hpp boost/signals2/last_value.hpp boost/signals2/signal.hpp boost/test/unit_test.hpp boost/thread.hpp boost/thread/condition_variable.hpp boost/thread/locks.hpp boost/thread/mutex.hpp boost/thread/shared_mutex.hpp boost/thread/thread.hpp boost/variant.hpp boost/variant/apply_visitor.hpp boost/variant/static_visitor.hpp ) for BOOST_INCLUDE in $(git grep '^#include ' | sort -u); do IS_EXPECTED_INCLUDE=0 for EXPECTED_BOOST_INCLUDE in "${EXPECTED_BOOST_INCLUDES[@]}"; do if [[ "${BOOST_INCLUDE}" == "${EXPECTED_BOOST_INCLUDE}" ]]; then IS_EXPECTED_INCLUDE=1 break fi done if [[ ${IS_EXPECTED_INCLUDE} == 0 ]]; then echo "A new Boost dependency in the form of \"${BOOST_INCLUDE}\" appears to have been introduced:" git grep "${BOOST_INCLUDE}" -- "*.cpp" "*.h" echo fi done for EXPECTED_BOOST_INCLUDE in "${EXPECTED_BOOST_INCLUDES[@]}"; do if ! git grep -q "^#include <${EXPECTED_BOOST_INCLUDE}>" -- "*.cpp" "*.h"; then echo "Good job! The Boost dependency \"${EXPECTED_BOOST_INCLUDE}\" is no longer used." echo "Please remove it from EXPECTED_BOOST_INCLUDES in $0" echo "to make sure this dependency is not accidentally reintroduced." echo fi done