common_file.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import codecs
  2. import cyson
  3. import os
  4. import re
  5. import pytest
  6. import yatest.common
  7. import ydb.library.yql.providers.common.proto.gateways_config_pb2 as gateways_config_pb2
  8. from common_test_tools import ASTDIFF_PATH, DATA_PATH, get_program_cfg, get_supported_providers, cut_unstable, get_program
  9. from yql_utils import is_xfail, is_skip_forceblocks, get_param, get_tables, get_files, KSV_ATTR, execute, yql_binary_path, \
  10. normalize_source_code_path, get_gateway_cfg_suffix
  11. from yqlrun import YQLRun
  12. from google.protobuf import text_format
  13. def get_block_gateways_config():
  14. config_message = gateways_config_pb2.TGatewaysConfig()
  15. config_message.SqlCore.TranslationFlags.extend(['EmitAggApply'])
  16. flags = config_message.YqlCore.Flags.add()
  17. flags.Name = 'UseBlocks'
  18. config = text_format.MessageToString(config_message)
  19. return config
  20. def yqlrun_yt_results(provider, prepare, suite, case, config):
  21. if (suite, case) not in yqlrun_yt_results.cache:
  22. if provider not in get_supported_providers(config):
  23. pytest.skip('%s provider is not supported here' % provider)
  24. prepare = prepare or (lambda s: s)
  25. program = prepare(get_program(suite, case))
  26. if 'ScriptUdf' in program:
  27. pytest.skip('ScriptUdf')
  28. xfail = is_xfail(config)
  29. in_tables, out_tables = get_tables(suite, config, DATA_PATH, def_attr=KSV_ATTR)
  30. files = get_files(suite, config, DATA_PATH)
  31. for table in in_tables:
  32. if cyson.loads(table.attr).get("type") == "document":
  33. content = table.content
  34. else:
  35. content = table.attr
  36. if 'Python' in content or 'Javascript' in content:
  37. pytest.skip('ScriptUdf')
  38. yqlrun = YQLRun(prov=provider, keep_temp=True, udfs_dir=yql_binary_path('ydb/library/yql/tests/common/test_framework/udfs_deps'))
  39. res, tables_res = execute(
  40. yqlrun,
  41. program=program,
  42. input_tables=in_tables,
  43. output_tables=out_tables,
  44. files=files,
  45. check_error=not xfail,
  46. verbose=True)
  47. tmp_tables = [os.path.join(yqlrun.res_dir, f) for f in sorted(filter(lambda f: f.endswith(".tmp") or f.endswith(".attr"), os.listdir(yqlrun.res_dir)))]
  48. if xfail:
  49. assert res.execution_result.exit_code != 0
  50. yqlrun_yt_results.cache[(suite, case)] = res, tables_res, tmp_tables
  51. return yqlrun_yt_results.cache[(suite, case)]
  52. yqlrun_yt_results.cache = {}
  53. def run_test(provider, prepare, suite, case, tmpdir, what):
  54. if get_param('TARGET_PLATFORM'):
  55. if "ArcPython" in case:
  56. pytest.skip('ArcPython is not supported on non-default target platform')
  57. config = get_program_cfg(suite, case)
  58. (res, tables_res, tmp_tables) = yqlrun_yt_results(provider, prepare, suite, case, config)
  59. xfail = is_xfail(config)
  60. to_canonize = []
  61. if get_gateway_cfg_suffix() != '' and what != 'Results':
  62. pytest.skip('non-default gateways.conf')
  63. if what == 'Plan' and not xfail:
  64. to_canonize = [yatest.common.canonical_file(res.plan_file)]
  65. if what == 'Results':
  66. if not xfail:
  67. if os.path.exists(res.results_file):
  68. stable_res = cut_unstable(res.results)
  69. if stable_res != res.results:
  70. with open(res.results_file, 'w') as f:
  71. f.write(stable_res)
  72. to_canonize.append(yatest.common.canonical_file(res.results_file))
  73. for table in tables_res:
  74. if os.path.exists(tables_res[table].file):
  75. to_canonize.append(yatest.common.canonical_file(tables_res[table].file))
  76. if res.std_err:
  77. to_canonize.append(normalize_source_code_path(res.std_err))
  78. if what == 'Debug' and not xfail:
  79. to_canonize = [yatest.common.canonical_file(res.opt_file, diff_tool=ASTDIFF_PATH)]
  80. for file in tmp_tables:
  81. to_canonize.append(yatest.common.canonical_file(file))
  82. if what == 'RunOnOpt':
  83. if xfail:
  84. pytest.skip('xfail is not supported in this mode')
  85. in_tables, out_tables = get_tables(suite, config, DATA_PATH, def_attr=KSV_ATTR)
  86. files = get_files(suite, config, DATA_PATH)
  87. opt_res, opt_tables_res = execute(
  88. YQLRun(prov=provider, keep_temp=False, udfs_dir=yql_binary_path('ydb/library/yql/tests/common/test_framework/udfs_deps')),
  89. program=res.opt,
  90. input_tables=in_tables,
  91. output_tables=out_tables,
  92. files=files,
  93. check_error=True,
  94. verbose=True)
  95. check_result = True
  96. check_plan = True
  97. check_ast = False # Temporary disable
  98. with open(os.path.join(DATA_PATH, suite, case + '.yql')) as prog:
  99. program_content = prog.read()
  100. if "# canonize yson here" in program_content:
  101. check_result = False
  102. if "# ignore runonopt ast diff" in program_content:
  103. check_ast = False
  104. if "# ignore runonopt plan diff" in program_content:
  105. check_plan = False
  106. if check_result:
  107. if os.path.exists(res.results_file):
  108. assert res.results == opt_res.results
  109. for table in tables_res:
  110. if os.path.exists(tables_res[table].file):
  111. assert tables_res[table].content == opt_tables_res[table].content
  112. if check_plan:
  113. assert res.plan == opt_res.plan
  114. if check_ast:
  115. yatest.common.process.execute([ASTDIFF_PATH, res.opt_file, opt_res.opt_file], check_exit_code=True)
  116. return None
  117. if what == 'ForceBlocks':
  118. if xfail:
  119. pytest.skip('xfail is not supported in this mode')
  120. if is_skip_forceblocks(config):
  121. pytest.skip('no force_blocks test requested')
  122. prepare = prepare or (lambda s: s)
  123. program = prepare(get_program(suite, case))
  124. if re.search(r"skip force_blocks", program):
  125. pytest.skip('no force_blocks test requested')
  126. in_tables, out_tables = get_tables(suite, config, DATA_PATH, def_attr=KSV_ATTR)
  127. files = get_files(suite, config, DATA_PATH)
  128. gateway_config = get_block_gateways_config()
  129. blocks_res, blocks_tables_res = execute(
  130. YQLRun(prov=provider, keep_temp=False, udfs_dir=yql_binary_path('ydb/library/yql/tests/common/test_framework/udfs_deps'), gateway_config=gateway_config),
  131. program=program,
  132. input_tables=in_tables,
  133. output_tables=out_tables,
  134. files=files,
  135. check_error=True,
  136. verbose=True)
  137. if os.path.exists(res.results_file):
  138. assert res.results == blocks_res.results, 'RESULTS_DIFFER\nBlocks result:\n %s\n\nScalar result:\n %s\n' % (blocks_res.results, res.results)
  139. for table in tables_res:
  140. if os.path.exists(tables_res[table].file):
  141. assert tables_res[table].content == blocks_tables_res[table].content, \
  142. 'RESULTS_DIFFER FOR TABLE %s\nBlocks result:\n %s\n\nScalar result:\n %s\n' % \
  143. (table, blocks_tables_res[table].content, tables_res[table].content)
  144. return None
  145. return to_canonize