protobuf_file_options_ut.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #include "common_ut.h"
  2. #include <yt/cpp/mapreduce/interface/errors.h>
  3. #include <yt/cpp/mapreduce/interface/format.h>
  4. #include <yt/cpp/mapreduce/interface/ut/protobuf_file_options_ut.pb.h>
  5. #include <yt/cpp/mapreduce/tests/yt_unittest_lib/yt_unittest_lib.h>
  6. #include <library/cpp/testing/gtest/gtest.h>
  7. using namespace NYT;
  8. namespace {
  9. NTi::TTypePtr GetUrlRowType(bool required)
  10. {
  11. static const NTi::TTypePtr structType = NTi::Struct({
  12. {"Host", ToTypeV3(EValueType::VT_STRING, false)},
  13. {"Path", ToTypeV3(EValueType::VT_STRING, false)},
  14. {"HttpCode", ToTypeV3(EValueType::VT_INT32, false)}});
  15. return required ? structType : NTi::TTypePtr(NTi::Optional(structType));
  16. }
  17. } // namespace
  18. TEST(TProtobufFileOptionsTest, TRowFieldSerializationOption)
  19. {
  20. const auto schema = CreateTableSchema<NTestingFileOptions::TRowFieldSerializationOption>();
  21. ASSERT_SERIALIZABLES_EQ(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. TEST(TProtobufFileOptionsTest, TRowMixedSerializationOptions)
  26. {
  27. const auto schema = CreateTableSchema<NTestingFileOptions::TRowMixedSerializationOptions>();
  28. ASSERT_SERIALIZABLES_EQ(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. TEST(TProtobufFileOptionsTest, 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_EQ(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. TEST(TProtobufFileOptionsTest, 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_EQ(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. TEST(TProtobufFileOptionsTest, 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_EQ(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. static TNode GetColumns(const TFormat& format, int tableIndex = 0)
  122. {
  123. return format.Config.GetAttributes()["tables"][tableIndex]["columns"];
  124. }
  125. TEST(TProtobufFormatFileOptionsTest, TRowFieldSerializationOption)
  126. {
  127. const auto format = TFormat::Protobuf<NTestingFileOptions::TRowFieldSerializationOption>();
  128. auto columns = GetColumns(format);
  129. EXPECT_EQ(columns[0]["name"], "UrlRow_1");
  130. EXPECT_EQ(columns[0]["proto_type"], "message");
  131. EXPECT_EQ(columns[0]["field_number"], 1);
  132. EXPECT_EQ(columns[1]["name"], "UrlRow_2");
  133. EXPECT_EQ(columns[1]["proto_type"], "structured_message");
  134. EXPECT_EQ(columns[1]["field_number"], 2);
  135. const auto& fields = columns[1]["fields"];
  136. EXPECT_EQ(fields[0]["name"], "Host");
  137. EXPECT_EQ(fields[0]["proto_type"], "string");
  138. EXPECT_EQ(fields[0]["field_number"], 1);
  139. EXPECT_EQ(fields[1]["name"], "Path");
  140. EXPECT_EQ(fields[1]["proto_type"], "string");
  141. EXPECT_EQ(fields[1]["field_number"], 2);
  142. EXPECT_EQ(fields[2]["name"], "HttpCode");
  143. EXPECT_EQ(fields[2]["proto_type"], "sint32");
  144. EXPECT_EQ(fields[2]["field_number"], 3);
  145. }
  146. TEST(TProtobufFormatFileOptionsTest, Map)
  147. {
  148. const auto format = TFormat::Protobuf<NTestingFileOptions::TWithMap>();
  149. auto columns = GetColumns(format);
  150. EXPECT_EQ(columns.Size(), 2u);
  151. {
  152. const auto& column = columns[0];
  153. EXPECT_EQ(column["name"], "MapDefault");
  154. EXPECT_EQ(column["proto_type"], "structured_message");
  155. EXPECT_EQ(column["fields"].Size(), 2u);
  156. EXPECT_EQ(column["fields"][0]["proto_type"], "int64");
  157. EXPECT_EQ(column["fields"][1]["proto_type"], "structured_message");
  158. }
  159. {
  160. const auto& column = columns[1];
  161. EXPECT_EQ(column["name"], "MapDict");
  162. EXPECT_EQ(column["proto_type"], "structured_message");
  163. EXPECT_EQ(column["fields"].Size(), 2u);
  164. EXPECT_EQ(column["fields"][0]["proto_type"], "int64");
  165. EXPECT_EQ(column["fields"][1]["proto_type"], "structured_message");
  166. }
  167. }
  168. TEST(TProtobufFormatFileOptionsTest, Oneof)
  169. {
  170. const auto format = TFormat::Protobuf<NTestingFileOptions::TWithOneof>();
  171. auto columns = GetColumns(format);
  172. EXPECT_EQ(columns.Size(), 4u);
  173. {
  174. const auto& column = columns[0];
  175. EXPECT_EQ(column["name"], "DefaultVariant");
  176. EXPECT_EQ(column["proto_type"], "structured_message");
  177. EXPECT_EQ(column["fields"].Size(), 5u);
  178. EXPECT_EQ(column["fields"][0]["name"], "field");
  179. const auto& oneof2 = column["fields"][1];
  180. EXPECT_EQ(oneof2["name"], "Oneof2");
  181. EXPECT_EQ(oneof2["proto_type"], "oneof");
  182. EXPECT_EQ(oneof2["fields"][0]["name"], "y2");
  183. EXPECT_EQ(oneof2["fields"][1]["name"], "z2");
  184. EXPECT_EQ(oneof2["fields"][1]["proto_type"], "structured_message");
  185. const auto& embeddedFields = oneof2["fields"][1]["fields"];
  186. EXPECT_EQ(embeddedFields[0]["name"], "x");
  187. EXPECT_EQ(embeddedFields[1]["name"], "y");
  188. EXPECT_EQ(oneof2["fields"][2]["name"], "x2");
  189. EXPECT_EQ(column["fields"][2]["name"], "x1");
  190. EXPECT_EQ(column["fields"][3]["name"], "y1");
  191. EXPECT_EQ(column["fields"][4]["name"], "z1");
  192. };
  193. {
  194. const auto& column = columns[1];
  195. EXPECT_EQ(column["name"], "NoDefault");
  196. EXPECT_EQ(column["proto_type"], "structured_message");
  197. const auto& fields = column["fields"];
  198. EXPECT_EQ(fields.Size(), 7u);
  199. EXPECT_EQ(fields[0]["name"], "field");
  200. EXPECT_EQ(fields[1]["name"], "y2");
  201. EXPECT_EQ(fields[2]["name"], "z2");
  202. EXPECT_EQ(fields[2]["proto_type"], "structured_message");
  203. const auto& embeddedFields = fields[2]["fields"];
  204. EXPECT_EQ(embeddedFields[0]["name"], "x");
  205. EXPECT_EQ(embeddedFields[1]["name"], "y");
  206. EXPECT_EQ(fields[3]["name"], "x2");
  207. EXPECT_EQ(fields[4]["name"], "x1");
  208. EXPECT_EQ(fields[5]["name"], "y1");
  209. EXPECT_EQ(fields[6]["name"], "z1");
  210. };
  211. {
  212. const auto& column = columns[2];
  213. EXPECT_EQ(column["name"], "SerializationProtobuf");
  214. EXPECT_EQ(column["proto_type"], "structured_message");
  215. EXPECT_EQ(column["fields"].Size(), 3u);
  216. EXPECT_EQ(column["fields"][0]["name"], "x1");
  217. EXPECT_EQ(column["fields"][1]["name"], "y1");
  218. EXPECT_EQ(column["fields"][2]["name"], "z1");
  219. }
  220. {
  221. const auto& column = columns[3];
  222. EXPECT_EQ(column["name"], "MemberOfTopLevelOneof");
  223. EXPECT_EQ(column["proto_type"], "int64");
  224. }
  225. }