common_ut.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include "common_ut.h"
  2. #include "fluent.h"
  3. #include <yt/cpp/mapreduce/interface/common.h>
  4. #include <yt/cpp/mapreduce/tests/yt_unittest_lib/yt_unittest_lib.h>
  5. #include <library/cpp/testing/unittest/registar.h>
  6. #include <library/cpp/yson/node/node_io.h>
  7. #include <library/cpp/yson/node/node_builder.h>
  8. #include <util/generic/xrange.h>
  9. using namespace NYT;
  10. template <class T>
  11. TString SaveToString(const T& obj)
  12. {
  13. TString s;
  14. TStringOutput out(s);
  15. ::Save(&out, obj);
  16. return s;
  17. }
  18. template <class T>
  19. T LoadFromString(TStringBuf s)
  20. {
  21. TMemoryInput in(s);
  22. T obj;
  23. ::Load(&in, obj);
  24. return obj;
  25. }
  26. template <class T>
  27. T SaveLoad(const T& obj)
  28. {
  29. return LoadFromString<T>(SaveToString(obj));
  30. }
  31. Y_UNIT_TEST_SUITE(Common)
  32. {
  33. Y_UNIT_TEST(SortColumnsLegacy)
  34. {
  35. TSortColumns keys1("a", "b");
  36. UNIT_ASSERT((keys1.Parts_ == TSortColumns{"a", "b"}));
  37. keys1.Add("c", "d");
  38. UNIT_ASSERT((keys1.Parts_ == TSortColumns{"a", "b", "c", "d"}));
  39. auto keys2 = TSortColumns(keys1).Add("e", "f");
  40. UNIT_ASSERT((keys1.Parts_ == TSortColumns{"a", "b", "c", "d"}));
  41. UNIT_ASSERT((keys2.Parts_ == TSortColumns{"a", "b", "c", "d", "e", "f"}));
  42. auto keys3 = TSortColumns(keys1).Add("e").Add("f").Add("g");
  43. UNIT_ASSERT((keys1.Parts_ == TSortColumns{"a", "b", "c", "d"}));
  44. UNIT_ASSERT((keys3.Parts_ == TSortColumns{"a", "b", "c", "d", "e", "f", "g"}));
  45. }
  46. Y_UNIT_TEST(SortColumn)
  47. {
  48. auto ascending = TSortColumn("a");
  49. UNIT_ASSERT_VALUES_EQUAL(ascending.Name(), "a");
  50. UNIT_ASSERT_VALUES_EQUAL(ascending.SortOrder(), ESortOrder::SO_ASCENDING);
  51. UNIT_ASSERT_VALUES_EQUAL(ascending, TSortColumn("a", ESortOrder::SO_ASCENDING));
  52. UNIT_ASSERT_VALUES_UNEQUAL(ascending, TSortColumn("a", ESortOrder::SO_DESCENDING));
  53. UNIT_ASSERT_NO_EXCEPTION(ascending.EnsureAscending());
  54. UNIT_ASSERT_VALUES_EQUAL(static_cast<TString>(ascending), "a");
  55. UNIT_ASSERT_VALUES_EQUAL(ascending, "a");
  56. auto another = ascending;
  57. UNIT_ASSERT_NO_EXCEPTION(another = "another");
  58. UNIT_ASSERT_VALUES_EQUAL(another.Name(), "another");
  59. UNIT_ASSERT_VALUES_EQUAL(another.SortOrder(), ESortOrder::SO_ASCENDING);
  60. UNIT_ASSERT_VALUES_EQUAL(another, TSortColumn("another", ESortOrder::SO_ASCENDING));
  61. UNIT_ASSERT_VALUES_UNEQUAL(another, TSortColumn("another", ESortOrder::SO_DESCENDING));
  62. auto ascendingNode = BuildYsonNodeFluently().Value(ascending);
  63. UNIT_ASSERT_VALUES_EQUAL(ascendingNode, TNode("a"));
  64. UNIT_ASSERT_VALUES_EQUAL(SaveLoad(ascending), ascending);
  65. UNIT_ASSERT_VALUES_UNEQUAL(SaveToString(ascending), SaveToString(TString("a")));
  66. auto descending = TSortColumn("a", ESortOrder::SO_DESCENDING);
  67. UNIT_ASSERT_VALUES_EQUAL(descending.Name(), "a");
  68. UNIT_ASSERT_VALUES_EQUAL(descending.SortOrder(), ESortOrder::SO_DESCENDING);
  69. UNIT_ASSERT_VALUES_EQUAL(descending, TSortColumn("a", ESortOrder::SO_DESCENDING));
  70. UNIT_ASSERT_VALUES_UNEQUAL(descending, TSortColumn("a", ESortOrder::SO_ASCENDING));
  71. UNIT_ASSERT_EXCEPTION(descending.EnsureAscending(), yexception);
  72. UNIT_ASSERT_EXCEPTION(static_cast<TString>(descending), yexception);
  73. UNIT_ASSERT_EXCEPTION(descending == "a", yexception);
  74. UNIT_ASSERT_EXCEPTION(descending = "a", yexception);
  75. auto descendingNode = BuildYsonNodeFluently().Value(descending);
  76. UNIT_ASSERT_VALUES_EQUAL(descendingNode, TNode()("name", "a")("sort_order", "descending"));
  77. UNIT_ASSERT_VALUES_EQUAL(SaveLoad(descending), descending);
  78. UNIT_ASSERT_VALUES_UNEQUAL(SaveToString(descending), SaveToString("a"));
  79. UNIT_ASSERT_VALUES_EQUAL(ToString(TSortColumn("blah")), "blah");
  80. UNIT_ASSERT_VALUES_EQUAL(ToString(TSortColumn("blah", ESortOrder::SO_DESCENDING)), "{\"name\"=\"blah\";\"sort_order\"=\"descending\"}");
  81. }
  82. Y_UNIT_TEST(SortColumns)
  83. {
  84. TSortColumns ascending("a", "b");
  85. UNIT_ASSERT(ascending.Parts_ == (TSortColumns{"a", "b"}));
  86. UNIT_ASSERT_NO_EXCEPTION(ascending.EnsureAscending());
  87. UNIT_ASSERT_VALUES_EQUAL(static_cast<TColumnNames>(ascending).Parts_, (TVector<TString>{"a", "b"}));
  88. UNIT_ASSERT_VALUES_EQUAL(ascending.GetNames(), (TVector<TString>{"a", "b"}));
  89. auto mixed = ascending;
  90. mixed.Add(TSortColumn("c", ESortOrder::SO_DESCENDING), "d");
  91. UNIT_ASSERT((mixed.Parts_ != TVector<TSortColumn>{"a", "b", "c", "d"}));
  92. UNIT_ASSERT((mixed.Parts_ == TVector<TSortColumn>{"a", "b", TSortColumn("c", ESortOrder::SO_DESCENDING), "d"}));
  93. UNIT_ASSERT_VALUES_EQUAL(mixed.GetNames(), (TVector<TString>{"a", "b", "c", "d"}));
  94. UNIT_ASSERT_EXCEPTION(mixed.EnsureAscending(), yexception);
  95. UNIT_ASSERT_EXCEPTION(static_cast<TColumnNames>(mixed), yexception);
  96. }
  97. Y_UNIT_TEST(KeyBound)
  98. {
  99. auto keyBound = TKeyBound(ERelation::Greater, TKey(7, "a", TNode()("x", "y")));
  100. UNIT_ASSERT_VALUES_EQUAL(keyBound.Relation(), ERelation::Greater);
  101. UNIT_ASSERT_EQUAL(keyBound.Key(), TKey(7, "a", TNode()("x", "y")));
  102. auto keyBound1 = TKeyBound().Relation(ERelation::Greater).Key(TKey(7, "a", TNode()("x", "y")));
  103. auto expectedNode = TNode()
  104. .Add(">")
  105. .Add(TNode().Add(7).Add("a").Add(TNode()("x", "y")));
  106. UNIT_ASSERT_VALUES_EQUAL(expectedNode, BuildYsonNodeFluently().Value(keyBound));
  107. UNIT_ASSERT_VALUES_EQUAL(expectedNode, BuildYsonNodeFluently().Value(keyBound1));
  108. keyBound.Relation(ERelation::LessOrEqual);
  109. keyBound.Key(TKey("A", 7));
  110. UNIT_ASSERT_VALUES_EQUAL(keyBound.Relation(), ERelation::LessOrEqual);
  111. UNIT_ASSERT_EQUAL(keyBound.Key(), TKey("A", 7));
  112. UNIT_ASSERT_VALUES_EQUAL(
  113. BuildYsonNodeFluently().Value(keyBound),
  114. TNode()
  115. .Add("<=")
  116. .Add(TNode().Add("A").Add(7)));
  117. }
  118. Y_UNIT_TEST(TTableSchema)
  119. {
  120. TTableSchema schema;
  121. schema
  122. .AddColumn(TColumnSchema().Name("a").Type(EValueType::VT_STRING).SortOrder(SO_ASCENDING))
  123. .AddColumn(TColumnSchema().Name("b").Type(EValueType::VT_UINT64))
  124. .AddColumn(TColumnSchema().Name("c").Type(EValueType::VT_INT64));
  125. auto checkSortBy = [](TTableSchema schema, const TVector<TString>& columns) {
  126. auto initialSchema = schema;
  127. schema.SortBy(columns);
  128. for (auto i: xrange(columns.size())) {
  129. UNIT_ASSERT_VALUES_EQUAL(schema.Columns()[i].Name(), columns[i]);
  130. UNIT_ASSERT_VALUES_EQUAL(schema.Columns()[i].SortOrder(), ESortOrder::SO_ASCENDING);
  131. }
  132. for (auto i: xrange(columns.size(), (size_t)initialSchema.Columns().size())) {
  133. UNIT_ASSERT_VALUES_EQUAL(schema.Columns()[i].SortOrder(), Nothing());
  134. }
  135. UNIT_ASSERT_VALUES_EQUAL(initialSchema.Columns().size(), schema.Columns().size());
  136. return schema;
  137. };
  138. auto newSchema = checkSortBy(schema, {"b"});
  139. UNIT_ASSERT_VALUES_EQUAL(newSchema.Columns()[1].Name(), TString("a"));
  140. UNIT_ASSERT_VALUES_EQUAL(newSchema.Columns()[2].Name(), TString("c"));
  141. checkSortBy(schema, {"b", "c"});
  142. checkSortBy(schema, {"c", "a"});
  143. UNIT_ASSERT_EXCEPTION(checkSortBy(schema, {"b", "b"}), yexception);
  144. UNIT_ASSERT_EXCEPTION(checkSortBy(schema, {"a", "junk"}), yexception);
  145. }
  146. Y_UNIT_TEST(TColumnSchema_TypeV3)
  147. {
  148. {
  149. auto column = TColumnSchema().Type(NTi::Interval());
  150. UNIT_ASSERT_VALUES_EQUAL(column.Required(), true);
  151. UNIT_ASSERT_VALUES_EQUAL(column.Type(), VT_INTERVAL);
  152. }
  153. {
  154. auto column = TColumnSchema().Type(NTi::Optional(NTi::Date()));
  155. UNIT_ASSERT_VALUES_EQUAL(column.Required(), false);
  156. UNIT_ASSERT_VALUES_EQUAL(column.Type(), VT_DATE);
  157. }
  158. {
  159. auto column = TColumnSchema().Type(NTi::Null());
  160. UNIT_ASSERT_VALUES_EQUAL(column.Required(), false);
  161. UNIT_ASSERT_VALUES_EQUAL(column.Type(), VT_NULL);
  162. }
  163. {
  164. auto column = TColumnSchema().Type(NTi::Optional(NTi::Null()));
  165. UNIT_ASSERT_VALUES_EQUAL(column.Required(), false);
  166. UNIT_ASSERT_VALUES_EQUAL(column.Type(), VT_ANY);
  167. }
  168. }
  169. Y_UNIT_TEST(ToTypeV3)
  170. {
  171. UNIT_ASSERT_VALUES_EQUAL(*ToTypeV3(VT_INT32, true), *NTi::Int32());
  172. UNIT_ASSERT_VALUES_EQUAL(*ToTypeV3(VT_UTF8, false), *NTi::Optional(NTi::Utf8()));
  173. }
  174. Y_UNIT_TEST(DeserializeColumn)
  175. {
  176. auto deserialize = [] (TStringBuf yson) {
  177. auto node = NodeFromYsonString(yson);
  178. TColumnSchema column;
  179. Deserialize(column, node);
  180. return column;
  181. };
  182. auto column = deserialize("{name=foo; type=int64; required=%false}");
  183. UNIT_ASSERT_VALUES_EQUAL(column.Name(), "foo");
  184. UNIT_ASSERT_VALUES_EQUAL(*column.TypeV3(), *NTi::Optional(NTi::Int64()));
  185. column = deserialize("{name=bar; type=utf8; required=%true; type_v3=utf8}");
  186. UNIT_ASSERT_VALUES_EQUAL(column.Name(), "bar");
  187. UNIT_ASSERT_VALUES_EQUAL(*column.TypeV3(), *NTi::Utf8());
  188. }
  189. Y_UNIT_TEST(ColumnSchemaEquality)
  190. {
  191. auto base = TColumnSchema()
  192. .Name("col")
  193. .TypeV3(NTi::Optional(NTi::List(NTi::String())))
  194. .SortOrder(ESortOrder::SO_ASCENDING)
  195. .Lock("lock")
  196. .Expression("x + 12")
  197. .Aggregate("sum")
  198. .Group("group");
  199. auto other = base;
  200. ASSERT_SERIALIZABLES_EQUAL(other, base);
  201. other.Name("other");
  202. ASSERT_SERIALIZABLES_UNEQUAL(other, base);
  203. other = base;
  204. other.TypeV3(NTi::List(NTi::String()));
  205. ASSERT_SERIALIZABLES_UNEQUAL(other, base);
  206. other = base;
  207. other.ResetSortOrder();
  208. ASSERT_SERIALIZABLES_UNEQUAL(other, base);
  209. other = base;
  210. other.Lock("lock1");
  211. ASSERT_SERIALIZABLES_UNEQUAL(other, base);
  212. other = base;
  213. other.Expression("x + 13");
  214. ASSERT_SERIALIZABLES_UNEQUAL(other, base);
  215. other = base;
  216. other.ResetAggregate();
  217. ASSERT_SERIALIZABLES_UNEQUAL(other, base);
  218. other = base;
  219. other.Group("group1");
  220. ASSERT_SERIALIZABLES_UNEQUAL(other, base);
  221. }
  222. Y_UNIT_TEST(TableSchemaEquality)
  223. {
  224. auto col1 = TColumnSchema()
  225. .Name("col1")
  226. .TypeV3(NTi::Optional(NTi::List(NTi::String())))
  227. .SortOrder(ESortOrder::SO_ASCENDING);
  228. auto col2 = TColumnSchema()
  229. .Name("col2")
  230. .TypeV3(NTi::Uint32());
  231. auto schema = TTableSchema()
  232. .AddColumn(col1)
  233. .AddColumn(col2)
  234. .Strict(true)
  235. .UniqueKeys(true);
  236. auto other = schema;
  237. ASSERT_SERIALIZABLES_EQUAL(other, schema);
  238. other.Strict(false);
  239. ASSERT_SERIALIZABLES_UNEQUAL(other, schema);
  240. other = schema;
  241. other.MutableColumns()[0].TypeV3(NTi::List(NTi::String()));
  242. ASSERT_SERIALIZABLES_UNEQUAL(other, schema);
  243. other = schema;
  244. other.MutableColumns().push_back(col1);
  245. ASSERT_SERIALIZABLES_UNEQUAL(other, schema);
  246. other = schema;
  247. other.UniqueKeys(false);
  248. ASSERT_SERIALIZABLES_UNEQUAL(other, schema);
  249. }
  250. }