You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

serialize_tests.cpp 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <boost/test/unit_test.hpp>
  2. #include <string>
  3. #include <vector>
  4. #include "serialize.h"
  5. using namespace std;
  6. BOOST_AUTO_TEST_SUITE(serialize_tests)
  7. BOOST_AUTO_TEST_CASE(varints)
  8. {
  9. // encode
  10. CDataStream ss(SER_DISK, 0);
  11. CDataStream::size_type size = 0;
  12. for (int i = 0; i < 100000; i++) {
  13. ss << VARINT(i);
  14. size += ::GetSerializeSize(VARINT(i), 0, 0);
  15. BOOST_CHECK(size == ss.size());
  16. }
  17. for (uint64 i = 0; i < 100000000000ULL; i += 999999937) {
  18. ss << VARINT(i);
  19. size += ::GetSerializeSize(VARINT(i), 0, 0);
  20. BOOST_CHECK(size == ss.size());
  21. }
  22. // decode
  23. for (int i = 0; i < 100000; i++) {
  24. int j = -1;
  25. ss >> VARINT(j);
  26. BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
  27. }
  28. for (uint64 i = 0; i < 100000000000ULL; i += 999999937) {
  29. uint64 j = -1;
  30. ss >> VARINT(j);
  31. BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
  32. }
  33. }
  34. BOOST_AUTO_TEST_CASE(compactsize)
  35. {
  36. CDataStream ss(SER_DISK, 0);
  37. vector<char>::size_type i, j;
  38. for (i = 1; i <= MAX_SIZE; i *= 2)
  39. {
  40. WriteCompactSize(ss, i-1);
  41. WriteCompactSize(ss, i);
  42. }
  43. for (i = 1; i <= MAX_SIZE; i *= 2)
  44. {
  45. j = ReadCompactSize(ss);
  46. BOOST_CHECK_MESSAGE((i-1) == j, "decoded:" << j << " expected:" << (i-1));
  47. j = ReadCompactSize(ss);
  48. BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
  49. }
  50. }
  51. static bool isCanonicalException(const std::ios_base::failure& ex)
  52. {
  53. return std::string("non-canonical ReadCompactSize()") == ex.what();
  54. }
  55. BOOST_AUTO_TEST_CASE(noncanonical)
  56. {
  57. // Write some non-canonical CompactSize encodings, and
  58. // make sure an exception is thrown when read back.
  59. CDataStream ss(SER_DISK, 0);
  60. vector<char>::size_type n;
  61. // zero encoded with three bytes:
  62. ss.write("\xfd\x00\x00", 3);
  63. BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
  64. // 0xfc encoded with three bytes:
  65. ss.write("\xfd\xfc\x00", 3);
  66. BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
  67. // 0xfd encoded with three bytes is OK:
  68. ss.write("\xfd\xfd\x00", 3);
  69. n = ReadCompactSize(ss);
  70. BOOST_CHECK(n == 0xfd);
  71. // zero encoded with five bytes:
  72. ss.write("\xfe\x00\x00\x00\x00", 5);
  73. BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
  74. // 0xffff encoded with five bytes:
  75. ss.write("\xfe\xff\xff\x00\x00", 5);
  76. BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
  77. // zero encoded with nine bytes:
  78. ss.write("\xff\x00\x00\x00\x00\x00\x00\x00\x00", 9);
  79. BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
  80. // 0x01ffffff encoded with nine bytes:
  81. ss.write("\xff\xff\xff\xff\x01\x00\x00\x00\x00", 9);
  82. BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
  83. }
  84. BOOST_AUTO_TEST_CASE(insert_delete)
  85. {
  86. // Test inserting/deleting bytes.
  87. CDataStream ss(SER_DISK, 0);
  88. BOOST_CHECK_EQUAL(ss.size(), 0);
  89. ss.write("\x00\x01\x02\xff", 4);
  90. BOOST_CHECK_EQUAL(ss.size(), 4);
  91. char c = (char)11;
  92. // Inserting at beginning/end/middle:
  93. ss.insert(ss.begin(), c);
  94. BOOST_CHECK_EQUAL(ss.size(), 5);
  95. BOOST_CHECK_EQUAL(ss[0], c);
  96. BOOST_CHECK_EQUAL(ss[1], 0);
  97. ss.insert(ss.end(), c);
  98. BOOST_CHECK_EQUAL(ss.size(), 6);
  99. BOOST_CHECK_EQUAL(ss[4], (char)0xff);
  100. BOOST_CHECK_EQUAL(ss[5], c);
  101. ss.insert(ss.begin()+2, c);
  102. BOOST_CHECK_EQUAL(ss.size(), 7);
  103. BOOST_CHECK_EQUAL(ss[2], c);
  104. // Delete at beginning/end/middle
  105. ss.erase(ss.begin());
  106. BOOST_CHECK_EQUAL(ss.size(), 6);
  107. BOOST_CHECK_EQUAL(ss[0], 0);
  108. ss.erase(ss.begin()+ss.size()-1);
  109. BOOST_CHECK_EQUAL(ss.size(), 5);
  110. BOOST_CHECK_EQUAL(ss[4], (char)0xff);
  111. ss.erase(ss.begin()+1);
  112. BOOST_CHECK_EQUAL(ss.size(), 4);
  113. BOOST_CHECK_EQUAL(ss[0], 0);
  114. BOOST_CHECK_EQUAL(ss[1], 1);
  115. BOOST_CHECK_EQUAL(ss[2], 2);
  116. BOOST_CHECK_EQUAL(ss[3], (char)0xff);
  117. // Make sure GetAndClear does the right thing:
  118. CSerializeData d;
  119. ss.GetAndClear(d);
  120. BOOST_CHECK_EQUAL(ss.size(), 0);
  121. }
  122. BOOST_AUTO_TEST_SUITE_END()