#include #include #include #include #include namespace NYT { namespace { using ::testing::Values; //////////////////////////////////////////////////////////////////////////////// class TWriteVarIntTest: public ::testing::TestWithParam > { }; TEST_P(TWriteVarIntTest, Serialization) { ui64 value = std::get<0>(GetParam()); TString rightAnswer = std::get<1>(GetParam()); TStringStream outputStream; WriteVarUint64(&outputStream, value); EXPECT_EQ(rightAnswer, outputStream.Str()); } //////////////////////////////////////////////////////////////////////////////// class TReadVarIntTest: public ::testing::TestWithParam > { }; TEST_P(TReadVarIntTest, Serialization) { ui64 rightAnswer = std::get<0>(GetParam()); TString input = std::get<1>(GetParam()); TStringInput inputStream(input); ui64 value; ReadVarUint64(&inputStream, &value); EXPECT_EQ(rightAnswer, value); } TEST(TReadVarIntTest, Overflow) { TString input("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 11); TStringInput inputStream(input); ui64 value; EXPECT_ANY_THROW(ReadVarUint64(&inputStream, &value)); } //////////////////////////////////////////////////////////////////////////////// auto ValuesForVarIntTests = Values( // Simple cases. std::make_tuple(0x0ull, TString("\x00", 1)), std::make_tuple(0x1ull, TString("\x01", 1)), std::make_tuple(0x2ull, TString("\x02", 1)), std::make_tuple(0x3ull, TString("\x03", 1)), std::make_tuple(0x4ull, TString("\x04", 1)), // The following "magic numbers" are critical points for varint encoding. std::make_tuple((1ull << 7) - 1, TString("\x7f", 1)), std::make_tuple((1ull << 7), TString("\x80\x01", 2)), std::make_tuple((1ull << 14) - 1, TString("\xff\x7f", 2)), std::make_tuple((1ull << 14), TString("\x80\x80\x01", 3)), std::make_tuple((1ull << 21) - 1, TString("\xff\xff\x7f", 3)), std::make_tuple((1ull << 21), TString("\x80\x80\x80\x01", 4)), std::make_tuple((1ull << 28) - 1, TString("\xff\xff\xff\x7f", 4)), std::make_tuple((1ull << 28), TString("\x80\x80\x80\x80\x01", 5)), std::make_tuple((1ull << 35) - 1, TString("\xff\xff\xff\xff\x7f", 5)), std::make_tuple((1ull << 35), TString("\x80\x80\x80\x80\x80\x01", 6)), std::make_tuple((1ull << 42) - 1, TString("\xff\xff\xff\xff\xff\x7f", 6)), std::make_tuple((1ull << 42), TString("\x80\x80\x80\x80\x80\x80\x01", 7)), std::make_tuple((1ull << 49) - 1, TString("\xff\xff\xff\xff\xff\xff\x7f", 7)), std::make_tuple((1ull << 49), TString("\x80\x80\x80\x80\x80\x80\x80\x01", 8)), std::make_tuple((1ull << 56) - 1, TString("\xff\xff\xff\xff\xff\xff\xff\x7f", 8)), std::make_tuple((1ull << 56), TString("\x80\x80\x80\x80\x80\x80\x80\x80\x01", 9)), std::make_tuple((1ull << 63) - 1, TString("\xff\xff\xff\xff\xff\xff\xff\xff\x7f", 9)), std::make_tuple((1ull << 63), TString("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 10)), // Boundary case. std::make_tuple(static_cast(-1), TString("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01", 10)) ); INSTANTIATE_TEST_SUITE_P(ValueParametrized, TWriteVarIntTest, ValuesForVarIntTests); INSTANTIATE_TEST_SUITE_P(ValueParametrized, TReadVarIntTest, ValuesForVarIntTests); //////////////////////////////////////////////////////////////////////////////// TEST(TVarInt32Test, RandomValues) { srand(100500); // Set seed const int numberOfValues = 10000; TStringStream stream; for (int i = 0; i < numberOfValues; ++i) { i32 expected = static_cast(RandomNumber()); WriteVarInt32(&stream, expected); i32 actual; ReadVarInt32(&stream, &actual); EXPECT_EQ(expected, actual) << "Encoded Variant: " << EscapeC(stream.Str()); } } //////////////////////////////////////////////////////////////////////////////// TEST(TVarInt64Test, RandomValues) { srand(100500); // Set seed const int numberOfValues = 10000; TStringStream stream; for (int i = 0; i < numberOfValues; ++i) { i64 expected = static_cast(RandomNumber()); WriteVarInt64(&stream, expected); i64 actual; ReadVarInt64(&stream, &actual); EXPECT_EQ(expected, actual) << "Encoded Variant: " << EscapeC(stream.Str()); } } //////////////////////////////////////////////////////////////////////////////// } // namespace } // namespace NYT