format_ut.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #include "common.h"
  2. #include "errors.h"
  3. #include "format.h"
  4. #include "common_ut.h"
  5. #include <yt/cpp/mapreduce/interface/proto3_ut.pb.h>
  6. #include <yt/cpp/mapreduce/interface/protobuf_table_schema_ut.pb.h>
  7. #include <library/cpp/testing/unittest/registar.h>
  8. using namespace NYT;
  9. static TNode GetColumns(const TFormat& format, int tableIndex = 0)
  10. {
  11. return format.Config.GetAttributes()["tables"][tableIndex]["columns"];
  12. }
  13. Y_UNIT_TEST_SUITE(ProtobufFormat)
  14. {
  15. Y_UNIT_TEST(TIntegral)
  16. {
  17. const auto format = TFormat::Protobuf<NUnitTesting::TIntegral>();
  18. auto columns = GetColumns(format);
  19. struct TColumn
  20. {
  21. TString Name;
  22. TString ProtoType;
  23. int FieldNumber;
  24. };
  25. auto expected = TVector<TColumn>{
  26. {"DoubleField", "double", 1},
  27. {"FloatField", "float", 2},
  28. {"Int32Field", "int32", 3},
  29. {"Int64Field", "int64", 4},
  30. {"Uint32Field", "uint32", 5},
  31. {"Uint64Field", "uint64", 6},
  32. {"Sint32Field", "sint32", 7},
  33. {"Sint64Field", "sint64", 8},
  34. {"Fixed32Field", "fixed32", 9},
  35. {"Fixed64Field", "fixed64", 10},
  36. {"Sfixed32Field", "sfixed32", 11},
  37. {"Sfixed64Field", "sfixed64", 12},
  38. {"BoolField", "bool", 13},
  39. {"EnumField", "enum_string", 14},
  40. };
  41. UNIT_ASSERT_VALUES_EQUAL(columns.Size(), expected.size());
  42. for (int i = 0; i < static_cast<int>(columns.Size()); ++i) {
  43. UNIT_ASSERT_VALUES_EQUAL(columns[i]["name"], expected[i].Name);
  44. UNIT_ASSERT_VALUES_EQUAL(columns[i]["proto_type"], expected[i].ProtoType);
  45. UNIT_ASSERT_VALUES_EQUAL(columns[i]["field_number"], expected[i].FieldNumber);
  46. }
  47. }
  48. Y_UNIT_TEST(TRowFieldSerializationOption)
  49. {
  50. const auto format = TFormat::Protobuf<NUnitTesting::TRowFieldSerializationOption>();
  51. auto columns = GetColumns(format);
  52. UNIT_ASSERT_VALUES_EQUAL(columns[0]["name"], "UrlRow_1");
  53. UNIT_ASSERT_VALUES_EQUAL(columns[0]["proto_type"], "structured_message");
  54. UNIT_ASSERT_VALUES_EQUAL(columns[0]["field_number"], 1);
  55. const auto& fields = columns[0]["fields"];
  56. UNIT_ASSERT_VALUES_EQUAL(fields[0]["name"], "Host");
  57. UNIT_ASSERT_VALUES_EQUAL(fields[0]["proto_type"], "string");
  58. UNIT_ASSERT_VALUES_EQUAL(fields[0]["field_number"], 1);
  59. UNIT_ASSERT_VALUES_EQUAL(fields[1]["name"], "Path");
  60. UNIT_ASSERT_VALUES_EQUAL(fields[1]["proto_type"], "string");
  61. UNIT_ASSERT_VALUES_EQUAL(fields[1]["field_number"], 2);
  62. UNIT_ASSERT_VALUES_EQUAL(fields[2]["name"], "HttpCode");
  63. UNIT_ASSERT_VALUES_EQUAL(fields[2]["proto_type"], "sint32");
  64. UNIT_ASSERT_VALUES_EQUAL(fields[2]["field_number"], 3);
  65. UNIT_ASSERT_VALUES_EQUAL(columns[1]["name"], "UrlRow_2");
  66. UNIT_ASSERT_VALUES_EQUAL(columns[1]["proto_type"], "message");
  67. UNIT_ASSERT_VALUES_EQUAL(columns[1]["field_number"], 2);
  68. }
  69. Y_UNIT_TEST(Packed)
  70. {
  71. const auto format = TFormat::Protobuf<NUnitTesting::TPacked>();
  72. auto column = GetColumns(format)[0];
  73. UNIT_ASSERT_VALUES_EQUAL(column["name"], "PackedListInt64");
  74. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "int64");
  75. UNIT_ASSERT_VALUES_EQUAL(column["field_number"], 1);
  76. UNIT_ASSERT_VALUES_EQUAL(column["packed"], true);
  77. UNIT_ASSERT_VALUES_EQUAL(column["repeated"], true);
  78. }
  79. Y_UNIT_TEST(Cyclic)
  80. {
  81. UNIT_ASSERT_EXCEPTION(TFormat::Protobuf<NUnitTesting::TCyclic>(), TApiUsageError);
  82. UNIT_ASSERT_EXCEPTION(TFormat::Protobuf<NUnitTesting::TCyclic::TA>(), TApiUsageError);
  83. UNIT_ASSERT_EXCEPTION(TFormat::Protobuf<NUnitTesting::TCyclic::TB>(), TApiUsageError);
  84. UNIT_ASSERT_EXCEPTION(TFormat::Protobuf<NUnitTesting::TCyclic::TC>(), TApiUsageError);
  85. UNIT_ASSERT_EXCEPTION(TFormat::Protobuf<NUnitTesting::TCyclic::TD>(), TApiUsageError);
  86. const auto format = TFormat::Protobuf<NUnitTesting::TCyclic::TE>();
  87. auto column = GetColumns(format)[0];
  88. UNIT_ASSERT_VALUES_EQUAL(column["name"], "d");
  89. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "message");
  90. UNIT_ASSERT_VALUES_EQUAL(column["field_number"], 1);
  91. }
  92. Y_UNIT_TEST(Map)
  93. {
  94. const auto format = TFormat::Protobuf<NUnitTesting::TWithMap>();
  95. auto columns = GetColumns(format);
  96. UNIT_ASSERT_VALUES_EQUAL(columns.Size(), 5);
  97. {
  98. const auto& column = columns[0];
  99. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MapDefault");
  100. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  101. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 2);
  102. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["proto_type"], "int64");
  103. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["proto_type"], "message");
  104. }
  105. {
  106. const auto& column = columns[1];
  107. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MapListOfStructsLegacy");
  108. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  109. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 2);
  110. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["proto_type"], "int64");
  111. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["proto_type"], "message");
  112. }
  113. {
  114. const auto& column = columns[2];
  115. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MapListOfStructs");
  116. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  117. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 2);
  118. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["proto_type"], "int64");
  119. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["proto_type"], "structured_message");
  120. }
  121. {
  122. const auto& column = columns[3];
  123. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MapOptionalDict");
  124. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  125. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 2);
  126. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["proto_type"], "int64");
  127. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["proto_type"], "structured_message");
  128. }
  129. {
  130. const auto& column = columns[4];
  131. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MapDict");
  132. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  133. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 2);
  134. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["proto_type"], "int64");
  135. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["proto_type"], "structured_message");
  136. }
  137. }
  138. Y_UNIT_TEST(Oneof)
  139. {
  140. const auto format = TFormat::Protobuf<NUnitTesting::TWithOneof>();
  141. auto columns = GetColumns(format);
  142. UNIT_ASSERT_VALUES_EQUAL(columns.Size(), 4);
  143. auto check = [] (const TNode& column, TStringBuf name, TStringBuf oneof2Name) {
  144. UNIT_ASSERT_VALUES_EQUAL(column["name"], name);
  145. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  146. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 5);
  147. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["name"], "field");
  148. const auto& oneof2 = column["fields"][1];
  149. UNIT_ASSERT_VALUES_EQUAL(oneof2["name"], oneof2Name);
  150. UNIT_ASSERT_VALUES_EQUAL(oneof2["proto_type"], "oneof");
  151. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][0]["name"], "y2");
  152. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][1]["name"], "z2");
  153. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][1]["proto_type"], "structured_message");
  154. const auto& embeddedOneof = oneof2["fields"][1]["fields"][0];
  155. UNIT_ASSERT_VALUES_EQUAL(embeddedOneof["name"], "Oneof");
  156. UNIT_ASSERT_VALUES_EQUAL(embeddedOneof["fields"][0]["name"], "x");
  157. UNIT_ASSERT_VALUES_EQUAL(embeddedOneof["fields"][1]["name"], "y");
  158. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][2]["name"], "x2");
  159. UNIT_ASSERT_VALUES_EQUAL(column["fields"][2]["name"], "x1");
  160. UNIT_ASSERT_VALUES_EQUAL(column["fields"][3]["name"], "y1");
  161. UNIT_ASSERT_VALUES_EQUAL(column["fields"][4]["name"], "z1");
  162. };
  163. check(columns[0], "DefaultSeparateFields", "variant_field_name");
  164. check(columns[1], "NoDefault", "Oneof2");
  165. {
  166. const auto& column = columns[2];
  167. UNIT_ASSERT_VALUES_EQUAL(column["name"], "SerializationProtobuf");
  168. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  169. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 3);
  170. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["name"], "x1");
  171. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["name"], "y1");
  172. UNIT_ASSERT_VALUES_EQUAL(column["fields"][2]["name"], "z1");
  173. }
  174. {
  175. const auto& column = columns[3];
  176. UNIT_ASSERT_VALUES_EQUAL(column["name"], "TopLevelOneof");
  177. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "oneof");
  178. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 1);
  179. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["name"], "MemberOfTopLevelOneof");
  180. }
  181. }
  182. }
  183. Y_UNIT_TEST_SUITE(Proto3)
  184. {
  185. Y_UNIT_TEST(TWithOptional)
  186. {
  187. const auto format = TFormat::Protobuf<NTestingProto3::TWithOptional>();
  188. auto columns = GetColumns(format);
  189. UNIT_ASSERT_VALUES_EQUAL(columns[0]["name"], "x");
  190. UNIT_ASSERT_VALUES_EQUAL(columns[0]["proto_type"], "int64");
  191. UNIT_ASSERT_VALUES_EQUAL(columns[0]["field_number"], 1);
  192. }
  193. Y_UNIT_TEST(TWithOptionalMessage)
  194. {
  195. const auto format = TFormat::Protobuf<NTestingProto3::TWithOptionalMessage>();
  196. auto columns = GetColumns(format);
  197. UNIT_ASSERT_VALUES_EQUAL(columns[0]["name"], "x");
  198. UNIT_ASSERT_VALUES_EQUAL(columns[0]["proto_type"], "structured_message");
  199. UNIT_ASSERT_VALUES_EQUAL(columns[0]["field_number"], 1);
  200. UNIT_ASSERT_VALUES_EQUAL(columns[0]["fields"].Size(), 1);
  201. UNIT_ASSERT_VALUES_EQUAL(columns[0]["fields"][0]["name"], "x");
  202. UNIT_ASSERT_VALUES_EQUAL(columns[0]["fields"][0]["proto_type"], "int64");
  203. UNIT_ASSERT_VALUES_EQUAL(columns[0]["fields"][0]["field_number"], 1);
  204. }
  205. }