protobuf_file_options_ut.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include "errors.h"
  2. #include "format.h"
  3. #include "common_ut.h"
  4. #include <yt/cpp/mapreduce/interface/protobuf_file_options_ut.pb.h>
  5. #include <yt/cpp/mapreduce/tests/yt_unittest_lib/yt_unittest_lib.h>
  6. #include <library/cpp/testing/unittest/registar.h>
  7. using namespace NYT;
  8. Y_UNIT_TEST_SUITE(ProtobufFileOptions)
  9. {
  10. NTi::TTypePtr GetUrlRowType(bool required)
  11. {
  12. static const NTi::TTypePtr structType = NTi::Struct({
  13. {"Host", ToTypeV3(EValueType::VT_STRING, false)},
  14. {"Path", ToTypeV3(EValueType::VT_STRING, false)},
  15. {"HttpCode", ToTypeV3(EValueType::VT_INT32, false)}});
  16. return required ? structType : NTi::TTypePtr(NTi::Optional(structType));
  17. }
  18. Y_UNIT_TEST(TRowFieldSerializationOption)
  19. {
  20. const auto schema = CreateTableSchema<NTestingFileOptions::TRowFieldSerializationOption>();
  21. ASSERT_SERIALIZABLES_EQUAL(schema, TTableSchema()
  22. .AddColumn(TColumnSchema().Name("UrlRow_1").Type(ToTypeV3(EValueType::VT_STRING, false)))
  23. .AddColumn(TColumnSchema().Name("UrlRow_2").Type(GetUrlRowType(false))));
  24. }
  25. Y_UNIT_TEST(TRowMixedSerializationOptions)
  26. {
  27. const auto schema = CreateTableSchema<NTestingFileOptions::TRowMixedSerializationOptions>();
  28. ASSERT_SERIALIZABLES_EQUAL(schema, TTableSchema()
  29. .AddColumn(TColumnSchema().Name("UrlRow_1").Type(ToTypeV3(EValueType::VT_STRING, false)))
  30. .AddColumn(TColumnSchema().Name("UrlRow_2").Type(GetUrlRowType(false))));
  31. }
  32. Y_UNIT_TEST(FieldSortOrder)
  33. {
  34. const auto schema = CreateTableSchema<NTestingFileOptions::TFieldSortOrder>();
  35. auto asInProtoFile = NTi::Optional(NTi::Struct({
  36. {"x", NTi::Optional(NTi::Int64())},
  37. {"y", NTi::Optional(NTi::String())},
  38. {"z", NTi::Optional(NTi::Bool())},
  39. }));
  40. auto byFieldNumber = NTi::Optional(NTi::Struct({
  41. {"z", NTi::Optional(NTi::Bool())},
  42. {"x", NTi::Optional(NTi::Int64())},
  43. {"y", NTi::Optional(NTi::String())},
  44. }));
  45. ASSERT_SERIALIZABLES_EQUAL(schema, TTableSchema()
  46. .AddColumn(TColumnSchema().Name("EmbeddedDefault").Type(asInProtoFile))
  47. .AddColumn(TColumnSchema().Name("EmbeddedAsInProtoFile").Type(asInProtoFile))
  48. .AddColumn(TColumnSchema().Name("EmbeddedByFieldNumber").Type(byFieldNumber)));
  49. }
  50. Y_UNIT_TEST(Map)
  51. {
  52. const auto schema = CreateTableSchema<NTestingFileOptions::TWithMap>();
  53. auto createKeyValueStruct = [] (NTi::TTypePtr key, NTi::TTypePtr value) {
  54. return NTi::List(NTi::Struct({
  55. {"key", NTi::Optional(key)},
  56. {"value", NTi::Optional(value)},
  57. }));
  58. };
  59. auto embedded = NTi::Struct({
  60. {"x", NTi::Optional(NTi::Int64())},
  61. {"y", NTi::Optional(NTi::String())},
  62. });
  63. ASSERT_SERIALIZABLES_EQUAL(schema, TTableSchema()
  64. .AddColumn(TColumnSchema()
  65. .Name("MapDefault")
  66. .Type(createKeyValueStruct(NTi::Int64(), embedded)))
  67. .AddColumn(TColumnSchema()
  68. .Name("MapDict")
  69. .Type(NTi::Dict(NTi::Int64(), embedded))));
  70. }
  71. Y_UNIT_TEST(Oneof)
  72. {
  73. const auto schema = CreateTableSchema<NTestingFileOptions::TWithOneof>();
  74. auto embedded = NTi::Struct({
  75. {"x", NTi::Optional(NTi::Int64())},
  76. {"y", NTi::Optional(NTi::String())},
  77. });
  78. auto defaultVariantType = NTi::Optional(NTi::Struct({
  79. {"field", NTi::Optional(NTi::String())},
  80. {"Oneof2", NTi::Optional(NTi::Variant(NTi::Struct({
  81. {"y2", NTi::String()},
  82. {"z2", embedded},
  83. {"x2", NTi::Int64()},
  84. })))},
  85. {"x1", NTi::Optional(NTi::Int64())},
  86. {"y1", NTi::Optional(NTi::String())},
  87. {"z1", NTi::Optional(embedded)},
  88. }));
  89. auto noDefaultType = NTi::Optional(NTi::Struct({
  90. {"field", NTi::Optional(NTi::String())},
  91. {"y2", NTi::Optional(NTi::String())},
  92. {"z2", NTi::Optional(embedded)},
  93. {"x2", NTi::Optional(NTi::Int64())},
  94. {"x1", NTi::Optional(NTi::Int64())},
  95. {"y1", NTi::Optional(NTi::String())},
  96. {"z1", NTi::Optional(embedded)},
  97. }));
  98. ASSERT_SERIALIZABLES_EQUAL(schema, TTableSchema()
  99. .AddColumn(TColumnSchema()
  100. .Name("DefaultVariant")
  101. .Type(defaultVariantType)
  102. )
  103. .AddColumn(TColumnSchema()
  104. .Name("NoDefault")
  105. .Type(noDefaultType)
  106. )
  107. .AddColumn(TColumnSchema()
  108. .Name("SerializationProtobuf")
  109. .Type(NTi::Optional(NTi::Struct({
  110. {"x1", NTi::Optional(NTi::Int64())},
  111. {"y1", NTi::Optional(NTi::String())},
  112. {"z1", NTi::Optional(NTi::String())},
  113. })))
  114. )
  115. .AddColumn(TColumnSchema()
  116. .Name("MemberOfTopLevelOneof")
  117. .Type(NTi::Optional(NTi::Int64()))
  118. )
  119. );
  120. }
  121. }
  122. static TNode GetColumns(const TFormat& format, int tableIndex = 0)
  123. {
  124. return format.Config.GetAttributes()["tables"][tableIndex]["columns"];
  125. }
  126. Y_UNIT_TEST_SUITE(ProtobufFormatFileOptions)
  127. {
  128. Y_UNIT_TEST(TRowFieldSerializationOption)
  129. {
  130. const auto format = TFormat::Protobuf<NTestingFileOptions::TRowFieldSerializationOption>();
  131. auto columns = GetColumns(format);
  132. UNIT_ASSERT_VALUES_EQUAL(columns[0]["name"], "UrlRow_1");
  133. UNIT_ASSERT_VALUES_EQUAL(columns[0]["proto_type"], "message");
  134. UNIT_ASSERT_VALUES_EQUAL(columns[0]["field_number"], 1);
  135. UNIT_ASSERT_VALUES_EQUAL(columns[1]["name"], "UrlRow_2");
  136. UNIT_ASSERT_VALUES_EQUAL(columns[1]["proto_type"], "structured_message");
  137. UNIT_ASSERT_VALUES_EQUAL(columns[1]["field_number"], 2);
  138. const auto& fields = columns[1]["fields"];
  139. UNIT_ASSERT_VALUES_EQUAL(fields[0]["name"], "Host");
  140. UNIT_ASSERT_VALUES_EQUAL(fields[0]["proto_type"], "string");
  141. UNIT_ASSERT_VALUES_EQUAL(fields[0]["field_number"], 1);
  142. UNIT_ASSERT_VALUES_EQUAL(fields[1]["name"], "Path");
  143. UNIT_ASSERT_VALUES_EQUAL(fields[1]["proto_type"], "string");
  144. UNIT_ASSERT_VALUES_EQUAL(fields[1]["field_number"], 2);
  145. UNIT_ASSERT_VALUES_EQUAL(fields[2]["name"], "HttpCode");
  146. UNIT_ASSERT_VALUES_EQUAL(fields[2]["proto_type"], "sint32");
  147. UNIT_ASSERT_VALUES_EQUAL(fields[2]["field_number"], 3);
  148. }
  149. Y_UNIT_TEST(Map)
  150. {
  151. const auto format = TFormat::Protobuf<NTestingFileOptions::TWithMap>();
  152. auto columns = GetColumns(format);
  153. UNIT_ASSERT_VALUES_EQUAL(columns.Size(), 2);
  154. {
  155. const auto& column = columns[0];
  156. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MapDefault");
  157. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  158. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 2);
  159. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["proto_type"], "int64");
  160. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["proto_type"], "structured_message");
  161. }
  162. {
  163. const auto& column = columns[1];
  164. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MapDict");
  165. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  166. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 2);
  167. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["proto_type"], "int64");
  168. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["proto_type"], "structured_message");
  169. }
  170. }
  171. Y_UNIT_TEST(Oneof)
  172. {
  173. const auto format = TFormat::Protobuf<NTestingFileOptions::TWithOneof>();
  174. auto columns = GetColumns(format);
  175. UNIT_ASSERT_VALUES_EQUAL(columns.Size(), 4);
  176. {
  177. const auto& column = columns[0];
  178. UNIT_ASSERT_VALUES_EQUAL(column["name"], "DefaultVariant");
  179. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  180. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 5);
  181. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["name"], "field");
  182. const auto& oneof2 = column["fields"][1];
  183. UNIT_ASSERT_VALUES_EQUAL(oneof2["name"], "Oneof2");
  184. UNIT_ASSERT_VALUES_EQUAL(oneof2["proto_type"], "oneof");
  185. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][0]["name"], "y2");
  186. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][1]["name"], "z2");
  187. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][1]["proto_type"], "structured_message");
  188. const auto& embeddedFields = oneof2["fields"][1]["fields"];
  189. UNIT_ASSERT_VALUES_EQUAL(embeddedFields[0]["name"], "x");
  190. UNIT_ASSERT_VALUES_EQUAL(embeddedFields[1]["name"], "y");
  191. UNIT_ASSERT_VALUES_EQUAL(oneof2["fields"][2]["name"], "x2");
  192. UNIT_ASSERT_VALUES_EQUAL(column["fields"][2]["name"], "x1");
  193. UNIT_ASSERT_VALUES_EQUAL(column["fields"][3]["name"], "y1");
  194. UNIT_ASSERT_VALUES_EQUAL(column["fields"][4]["name"], "z1");
  195. };
  196. {
  197. const auto& column = columns[1];
  198. UNIT_ASSERT_VALUES_EQUAL(column["name"], "NoDefault");
  199. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  200. const auto& fields = column["fields"];
  201. UNIT_ASSERT_VALUES_EQUAL(fields.Size(), 7);
  202. UNIT_ASSERT_VALUES_EQUAL(fields[0]["name"], "field");
  203. UNIT_ASSERT_VALUES_EQUAL(fields[1]["name"], "y2");
  204. UNIT_ASSERT_VALUES_EQUAL(fields[2]["name"], "z2");
  205. UNIT_ASSERT_VALUES_EQUAL(fields[2]["proto_type"], "structured_message");
  206. const auto& embeddedFields = fields[2]["fields"];
  207. UNIT_ASSERT_VALUES_EQUAL(embeddedFields[0]["name"], "x");
  208. UNIT_ASSERT_VALUES_EQUAL(embeddedFields[1]["name"], "y");
  209. UNIT_ASSERT_VALUES_EQUAL(fields[3]["name"], "x2");
  210. UNIT_ASSERT_VALUES_EQUAL(fields[4]["name"], "x1");
  211. UNIT_ASSERT_VALUES_EQUAL(fields[5]["name"], "y1");
  212. UNIT_ASSERT_VALUES_EQUAL(fields[6]["name"], "z1");
  213. };
  214. {
  215. const auto& column = columns[2];
  216. UNIT_ASSERT_VALUES_EQUAL(column["name"], "SerializationProtobuf");
  217. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "structured_message");
  218. UNIT_ASSERT_VALUES_EQUAL(column["fields"].Size(), 3);
  219. UNIT_ASSERT_VALUES_EQUAL(column["fields"][0]["name"], "x1");
  220. UNIT_ASSERT_VALUES_EQUAL(column["fields"][1]["name"], "y1");
  221. UNIT_ASSERT_VALUES_EQUAL(column["fields"][2]["name"], "z1");
  222. }
  223. {
  224. const auto& column = columns[3];
  225. UNIT_ASSERT_VALUES_EQUAL(column["name"], "MemberOfTopLevelOneof");
  226. UNIT_ASSERT_VALUES_EQUAL(column["proto_type"], "int64");
  227. }
  228. }
  229. }