varint_ut.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include <library/cpp/testing/gtest/gtest.h>
  2. #include <library/cpp/yt/coding/varint.h>
  3. #include <util/random/random.h>
  4. #include <util/string/escape.h>
  5. #include <tuple>
  6. namespace NYT {
  7. namespace {
  8. using ::testing::Values;
  9. ////////////////////////////////////////////////////////////////////////////////
  10. class TWriteVarIntTest
  11. : public ::testing::TestWithParam<std::tuple<ui64, std::string>>
  12. { };
  13. TEST_P(TWriteVarIntTest, Serialization)
  14. {
  15. ui64 value = std::get<0>(GetParam());
  16. std::string rightAnswer = std::get<1>(GetParam());
  17. TStringStream outputStream;
  18. WriteVarUint64(&outputStream, value);
  19. EXPECT_EQ(rightAnswer, outputStream.Str());
  20. }
  21. ////////////////////////////////////////////////////////////////////////////////
  22. class TReadVarIntTest: public ::testing::TestWithParam<std::tuple<ui64, std::string> >
  23. { };
  24. TEST_P(TReadVarIntTest, Serialization)
  25. {
  26. ui64 rightAnswer = std::get<0>(GetParam());
  27. auto input = TString(std::get<1>(GetParam()));
  28. TStringInput inputStream(input);
  29. ui64 value;
  30. ReadVarUint64(&inputStream, &value);
  31. EXPECT_EQ(rightAnswer, value);
  32. }
  33. TEST(TReadVarIntTest, Overflow)
  34. {
  35. TString input("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 11);
  36. TStringInput inputStream(input);
  37. ui64 value;
  38. EXPECT_ANY_THROW(ReadVarUint64(&inputStream, &value));
  39. }
  40. ////////////////////////////////////////////////////////////////////////////////
  41. auto ValuesForVarIntTests = Values(
  42. // Simple cases.
  43. std::make_tuple(0x0ull, std::string("\x00", 1)),
  44. std::make_tuple(0x1ull, std::string("\x01", 1)),
  45. std::make_tuple(0x2ull, std::string("\x02", 1)),
  46. std::make_tuple(0x3ull, std::string("\x03", 1)),
  47. std::make_tuple(0x4ull, std::string("\x04", 1)),
  48. // The following "magic numbers" are critical points for varint encoding.
  49. std::make_tuple((1ull << 7) - 1, std::string("\x7f", 1)),
  50. std::make_tuple((1ull << 7), std::string("\x80\x01", 2)),
  51. std::make_tuple((1ull << 14) - 1, std::string("\xff\x7f", 2)),
  52. std::make_tuple((1ull << 14), std::string("\x80\x80\x01", 3)),
  53. std::make_tuple((1ull << 21) - 1, std::string("\xff\xff\x7f", 3)),
  54. std::make_tuple((1ull << 21), std::string("\x80\x80\x80\x01", 4)),
  55. std::make_tuple((1ull << 28) - 1, std::string("\xff\xff\xff\x7f", 4)),
  56. std::make_tuple((1ull << 28), std::string("\x80\x80\x80\x80\x01", 5)),
  57. std::make_tuple((1ull << 35) - 1, std::string("\xff\xff\xff\xff\x7f", 5)),
  58. std::make_tuple((1ull << 35), std::string("\x80\x80\x80\x80\x80\x01", 6)),
  59. std::make_tuple((1ull << 42) - 1, std::string("\xff\xff\xff\xff\xff\x7f", 6)),
  60. std::make_tuple((1ull << 42), std::string("\x80\x80\x80\x80\x80\x80\x01", 7)),
  61. std::make_tuple((1ull << 49) - 1, std::string("\xff\xff\xff\xff\xff\xff\x7f", 7)),
  62. std::make_tuple((1ull << 49), std::string("\x80\x80\x80\x80\x80\x80\x80\x01", 8)),
  63. std::make_tuple((1ull << 56) - 1, std::string("\xff\xff\xff\xff\xff\xff\xff\x7f", 8)),
  64. std::make_tuple((1ull << 56), std::string("\x80\x80\x80\x80\x80\x80\x80\x80\x01", 9)),
  65. std::make_tuple((1ull << 63) - 1, std::string("\xff\xff\xff\xff\xff\xff\xff\xff\x7f", 9)),
  66. std::make_tuple((1ull << 63), std::string("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 10)),
  67. // Boundary case.
  68. std::make_tuple(static_cast<ui64>(-1), std::string("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01", 10))
  69. );
  70. INSTANTIATE_TEST_SUITE_P(ValueParametrized, TWriteVarIntTest,
  71. ValuesForVarIntTests);
  72. INSTANTIATE_TEST_SUITE_P(ValueParametrized, TReadVarIntTest,
  73. ValuesForVarIntTests);
  74. ////////////////////////////////////////////////////////////////////////////////
  75. TEST(TVarInt32Test, RandomValues)
  76. {
  77. srand(100500); // Set seed
  78. const int numberOfValues = 10000;
  79. TStringStream stream;
  80. for (int i = 0; i < numberOfValues; ++i) {
  81. i32 expected = static_cast<i32>(RandomNumber<ui32>());
  82. WriteVarInt32(&stream, expected);
  83. i32 actual;
  84. ReadVarInt32(&stream, &actual);
  85. EXPECT_EQ(expected, actual)
  86. << "Encoded Variant: " << EscapeC(stream.Str());
  87. }
  88. }
  89. ////////////////////////////////////////////////////////////////////////////////
  90. TEST(TVarInt64Test, RandomValues)
  91. {
  92. srand(100500); // Set seed
  93. const int numberOfValues = 10000;
  94. TStringStream stream;
  95. for (int i = 0; i < numberOfValues; ++i) {
  96. i64 expected = static_cast<i64>(RandomNumber<ui64>());
  97. WriteVarInt64(&stream, expected);
  98. i64 actual;
  99. ReadVarInt64(&stream, &actual);
  100. EXPECT_EQ(expected, actual)
  101. << "Encoded Variant: " << EscapeC(stream.Str());
  102. }
  103. }
  104. ////////////////////////////////////////////////////////////////////////////////
  105. } // namespace
  106. } // namespace NYT