varint_ut.cpp 4.7 KB

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