#include "pb_io.h" #include "is_equal.h" #include #include #include #include #include #include static NProtobufUtilUt::TTextTest GetCorrectMessage() { NProtobufUtilUt::TTextTest m; m.SetFoo(42); return m; } static NProtobufUtilUt::TTextEnumTest GetCorrectEnumMessage() { NProtobufUtilUt::TTextEnumTest m; m.SetSlot(NProtobufUtilUt::TTextEnumTest::EET_SLOT_1); return m; } static const TString CORRECT_MESSAGE = R"(Foo: 42 )"; static const TString CORRECT_ENUM_NAME_MESSAGE = R"(Slot: EET_SLOT_1 )"; static const TString CORRECT_ENUM_ID_MESSAGE = R"(Slot: 1 )"; static const TString INCORRECT_MESSAGE = R"(Bar: 1 )"; static const TString INCORRECT_ENUM_NAME_MESSAGE = R"(Slot: EET_SLOT_3 )"; static const TString INCORRECT_ENUM_ID_MESSAGE = R"(Slot: 3 )"; static const TString CORRECT_BASE64_MESSAGE = "CCo,"; static const TString CORRECT_UNEVEN_BASE64_MESSAGE = "CCo"; static const TString INCORRECT_BASE64_MESSAGE = "CC"; Y_UNIT_TEST_SUITE(TTestProtoBufIO) { Y_UNIT_TEST(TestBase64) { { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(NProtoBuf::TryParseFromBase64String(CORRECT_BASE64_MESSAGE, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(!NProtoBuf::TryParseFromBase64String(INCORRECT_BASE64_MESSAGE, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(NProtoBuf::TryParseFromBase64String(CORRECT_UNEVEN_BASE64_MESSAGE , message, true)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(!NProtoBuf::TryParseFromBase64String(CORRECT_UNEVEN_BASE64_MESSAGE , message, false)); } { UNIT_ASSERT_VALUES_EQUAL(CORRECT_BASE64_MESSAGE, NProtoBuf::SerializeToBase64String(GetCorrectMessage())); } { const auto m = NProtoBuf::ParseFromBase64String(CORRECT_BASE64_MESSAGE); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); } } Y_UNIT_TEST(TestParseFromTextFormat) { TTempDir tempDir; const TFsPath correctFileName = TFsPath{tempDir()} / "correct.pb.txt"; const TFsPath incorrectFileName = TFsPath{tempDir()} / "incorrect.pb.txt"; TFileOutput{correctFileName}.Write(CORRECT_MESSAGE); TFileOutput{incorrectFileName}.Write(INCORRECT_MESSAGE); { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(TryParseFromTextFormat(correctFileName, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(!TryParseFromTextFormat(incorrectFileName, message)); } { NProtobufUtilUt::TTextTest message; TStringInput in{CORRECT_MESSAGE}; UNIT_ASSERT(TryParseFromTextFormat(in, message)); } { NProtobufUtilUt::TTextTest message; TStringInput in{INCORRECT_MESSAGE}; UNIT_ASSERT(!TryParseFromTextFormat(in, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_NO_EXCEPTION(TryParseFromTextFormat(incorrectFileName, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(!TryParseFromTextFormat("this_file_doesnt_exists", message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_NO_EXCEPTION(TryParseFromTextFormat("this_file_doesnt_exists", message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_EXCEPTION(ParseFromTextFormat("this_file_doesnt_exists", message), TFileError); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_NO_EXCEPTION(ParseFromTextFormat(correctFileName, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_EXCEPTION(ParseFromTextFormat(incorrectFileName, message), yexception); } { NProtobufUtilUt::TTextTest message; TStringInput in{CORRECT_MESSAGE}; UNIT_ASSERT_NO_EXCEPTION(ParseFromTextFormat(in, message)); } { NProtobufUtilUt::TTextTest message; TStringInput in{INCORRECT_MESSAGE}; UNIT_ASSERT_EXCEPTION(ParseFromTextFormat(in, message), yexception); } { NProtobufUtilUt::TTextTest m; const auto f = [&correctFileName](NProtobufUtilUt::TTextTest& mm) { mm = ParseFromTextFormat(correctFileName); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); } { UNIT_ASSERT_EXCEPTION(ParseFromTextFormat(incorrectFileName), yexception); } { NProtobufUtilUt::TTextTest m; TStringInput in{CORRECT_MESSAGE}; const auto f = [&in](NProtobufUtilUt::TTextTest& mm) { mm = ParseFromTextFormat(in); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); } { TStringInput in{INCORRECT_MESSAGE}; UNIT_ASSERT_EXCEPTION(ParseFromTextFormat(in), yexception); } { const TFsPath correctFileName2 = TFsPath{tempDir()} / "serialized.pb.txt"; const auto original = GetCorrectMessage(); UNIT_ASSERT_NO_EXCEPTION(SerializeToTextFormat(original, correctFileName2)); const auto serializedStr = TUnbufferedFileInput{correctFileName2}.ReadAll(); UNIT_ASSERT_VALUES_EQUAL(serializedStr, CORRECT_MESSAGE); } { const auto original = GetCorrectMessage(); TStringStream out; UNIT_ASSERT_NO_EXCEPTION(SerializeToTextFormat(original, out)); UNIT_ASSERT_VALUES_EQUAL(out.Str(), CORRECT_MESSAGE); } { NProtobufUtilUt::TTextTest m; const auto f = [&correctFileName](NProtobufUtilUt::TTextTest& mm) { mm = ParseFromTextFormat( correctFileName, EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); } { const NProtobufUtilUt::TTextTest empty; NProtobufUtilUt::TTextTest m; const auto f = [&incorrectFileName](NProtobufUtilUt::TTextTest& mm) { mm = ParseFromTextFormat( incorrectFileName, EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(empty, m)); } } Y_UNIT_TEST(TestSerializeToTextFormatWithEnumId) { TTempDir tempDir; const TFsPath correctNameFileName = TFsPath{tempDir()} / "correct_name.pb.txt"; const TFsPath incorrectNameFileName = TFsPath{tempDir()} / "incorrect_name.pb.txt"; const TFsPath correctIdFileName = TFsPath{tempDir()} / "correct_id.pb.txt"; const TFsPath incorrectIdFileName = TFsPath{tempDir()} / "incorrect_id.pb.txt"; TFileOutput{correctNameFileName}.Write(CORRECT_ENUM_NAME_MESSAGE); TFileOutput{incorrectNameFileName}.Write(INCORRECT_ENUM_NAME_MESSAGE); TFileOutput{correctIdFileName}.Write(CORRECT_ENUM_ID_MESSAGE); TFileOutput{incorrectIdFileName}.Write(INCORRECT_ENUM_ID_MESSAGE); { NProtobufUtilUt::TTextEnumTest message; for (auto correct_message: {CORRECT_ENUM_ID_MESSAGE, CORRECT_ENUM_NAME_MESSAGE}) { TStringInput in{correct_message}; UNIT_ASSERT_NO_EXCEPTION(ParseFromTextFormat(in, message)); } } { NProtobufUtilUt::TTextEnumTest message; for (auto incorrect_message: {INCORRECT_ENUM_ID_MESSAGE, INCORRECT_ENUM_NAME_MESSAGE}) { TStringInput in{incorrect_message}; UNIT_ASSERT_EXCEPTION(ParseFromTextFormat(in, message), yexception); } } { const auto f = [](NProtobufUtilUt::TTextEnumTest& mm, const TString fileName) { mm = ParseFromTextFormat(fileName); }; for (auto fileName: {correctIdFileName, correctNameFileName}) { NProtobufUtilUt::TTextEnumTest m; UNIT_ASSERT_NO_EXCEPTION(f(m, fileName)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectEnumMessage(), m)); } } { UNIT_ASSERT_EXCEPTION(ParseFromTextFormat(incorrectIdFileName), yexception); UNIT_ASSERT_EXCEPTION(ParseFromTextFormat(incorrectNameFileName), yexception); } { const auto original = GetCorrectEnumMessage(); TStringStream out; UNIT_ASSERT_NO_EXCEPTION(SerializeToTextFormat(original, out)); UNIT_ASSERT_VALUES_EQUAL(out.Str(), CORRECT_ENUM_NAME_MESSAGE); } { const auto original = GetCorrectEnumMessage(); TStringStream out; UNIT_ASSERT_NO_EXCEPTION(SerializeToTextFormatWithEnumId(original, out)); UNIT_ASSERT_VALUES_EQUAL(out.Str(), CORRECT_ENUM_ID_MESSAGE); } } Y_UNIT_TEST(TestMergeFromTextFormat) { // // Tests cases below are identical to `Parse` tests // TTempDir tempDir; const TFsPath correctFileName = TFsPath{tempDir()} / "correct.pb.txt"; const TFsPath incorrectFileName = TFsPath{tempDir()} / "incorrect.pb.txt"; TFileOutput{correctFileName}.Write(CORRECT_MESSAGE); TFileOutput{incorrectFileName}.Write(INCORRECT_MESSAGE); { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(TryMergeFromTextFormat(correctFileName, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(!TryMergeFromTextFormat(incorrectFileName, message)); } { NProtobufUtilUt::TTextTest message; TStringInput in{CORRECT_MESSAGE}; UNIT_ASSERT(TryMergeFromTextFormat(in, message)); } { NProtobufUtilUt::TTextTest message; TStringInput in{INCORRECT_MESSAGE}; UNIT_ASSERT(!TryMergeFromTextFormat(in, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_NO_EXCEPTION(TryMergeFromTextFormat(incorrectFileName, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT(!TryMergeFromTextFormat("this_file_doesnt_exists", message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_NO_EXCEPTION(TryMergeFromTextFormat("this_file_doesnt_exists", message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_EXCEPTION(MergeFromTextFormat("this_file_doesnt_exists", message), TFileError); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_NO_EXCEPTION(MergeFromTextFormat(correctFileName, message)); } { NProtobufUtilUt::TTextTest message; UNIT_ASSERT_EXCEPTION(MergeFromTextFormat(incorrectFileName, message), yexception); } { NProtobufUtilUt::TTextTest message; TStringInput in{CORRECT_MESSAGE}; UNIT_ASSERT_NO_EXCEPTION(MergeFromTextFormat(in, message)); } { NProtobufUtilUt::TTextTest message; TStringInput in{INCORRECT_MESSAGE}; UNIT_ASSERT_EXCEPTION(MergeFromTextFormat(in, message), yexception); } { NProtobufUtilUt::TTextTest m; const auto f = [&correctFileName](NProtobufUtilUt::TTextTest& mm) { mm = MergeFromTextFormat(correctFileName); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); } { UNIT_ASSERT_EXCEPTION(MergeFromTextFormat(incorrectFileName), yexception); } { NProtobufUtilUt::TTextTest m; TStringInput in{CORRECT_MESSAGE}; const auto f = [&in](NProtobufUtilUt::TTextTest& mm) { mm = MergeFromTextFormat(in); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); } { TStringInput in{INCORRECT_MESSAGE}; UNIT_ASSERT_EXCEPTION(MergeFromTextFormat(in), yexception); } { const TFsPath correctFileName2 = TFsPath{tempDir()} / "serialized.pb.txt"; const auto original = GetCorrectMessage(); UNIT_ASSERT_NO_EXCEPTION(SerializeToTextFormat(original, correctFileName2)); const auto serializedStr = TUnbufferedFileInput{correctFileName2}.ReadAll(); UNIT_ASSERT_VALUES_EQUAL(serializedStr, CORRECT_MESSAGE); } { const auto original = GetCorrectMessage(); TStringStream out; UNIT_ASSERT_NO_EXCEPTION(SerializeToTextFormat(original, out)); UNIT_ASSERT_VALUES_EQUAL(out.Str(), CORRECT_MESSAGE); } { NProtobufUtilUt::TTextTest m; const auto f = [&correctFileName](NProtobufUtilUt::TTextTest& mm) { mm = MergeFromTextFormat( correctFileName, EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); } { const NProtobufUtilUt::TTextTest empty; NProtobufUtilUt::TTextTest m; const auto f = [&incorrectFileName](NProtobufUtilUt::TTextTest& mm) { mm = MergeFromTextFormat( incorrectFileName, EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(empty, m)); } // // Test cases for `Merge` // { NProtobufUtilUt::TTextTest message; message.SetFoo(100500); TStringInput in{CORRECT_MESSAGE}; UNIT_ASSERT(TryMergeFromTextFormat(in, message)); UNIT_ASSERT(NProtoBuf::IsEqual(message, GetCorrectMessage())); } } Y_UNIT_TEST(TestMergeFromString) { NProtobufUtilUt::TMergeTest message; NProtobufUtilUt::TMergeTest messageFirstHalf; NProtobufUtilUt::TMergeTest messageSecondHalf; for (ui32 v = ~0; v != 0; v >>= 1) { message.AddMergeInt(v); (v > 0xffff ? messageFirstHalf : messageSecondHalf).AddMergeInt(v); } const TString full = message.SerializeAsString(); { NProtobufUtilUt::TMergeTest m1; UNIT_ASSERT(NProtoBuf::MergeFromString(m1, full)); UNIT_ASSERT(NProtoBuf::IsEqual(message, m1)); } { NProtobufUtilUt::TMergeTest m2; TStringBuf s0 = TStringBuf(full).SubStr(0, 3); TStringBuf s1 = TStringBuf(full).SubStr(3); // объединение результатов двух MergePartialFromString не эквивалентно вызову MergePartialFromString от объединения строк UNIT_ASSERT(!(NProtoBuf::MergePartialFromString(m2, s0) && NProtoBuf::MergePartialFromString(m2, s1))); } { NProtobufUtilUt::TMergeTest m3; UNIT_ASSERT(NProtoBuf::MergePartialFromString(m3, messageFirstHalf.SerializeAsString())); UNIT_ASSERT(NProtoBuf::MergeFromString(m3, messageSecondHalf.SerializeAsString())); UNIT_ASSERT(NProtoBuf::IsEqual(message, m3)); } } }