aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/tests/common/udf_test/test.py
blob: 218b05b4bde35b1a32a6b759242051a7acc7ebbb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os
import os.path
import glob
import codecs
import shutil

import pytest

import yql_utils
from yqlrun import YQLRun

import yatest.common

project_path = yatest.common.context.project_path
SOURCE_PATH = yql_utils.yql_source_path((project_path + '/cases').replace('\\', '/'))
DATA_PATH = yatest.common.output_path('cases')
ASTDIFF_PATH = yql_utils.yql_binary_path(os.getenv('YQL_ASTDIFF_PATH') or 'yql/essentials/tools/astdiff/astdiff')


def pytest_generate_tests(metafunc):
    if os.path.exists(SOURCE_PATH):
        shutil.copytree(SOURCE_PATH, DATA_PATH)
        cases = sorted([os.path.basename(sql_query)[:-4] for sql_query in glob.glob(DATA_PATH + '/*.sql')])

    else:
        cases = []
    metafunc.parametrize(['case'], [(case, ) for case in cases])


def test(case):
    program_file = os.path.join(DATA_PATH, case + '.sql')

    with codecs.open(program_file, encoding='utf-8') as f:
        program = f.readlines()

    header = program[0]
    canonize_ast = False

    if header.startswith('--ignore'):
        pytest.skip(header)
    elif header.startswith('--sanitizer ignore') and yatest.common.context.sanitize is not None:
        pytest.skip(header)
    elif header.startswith('--sanitizer ignore address') and yatest.common.context.sanitize == 'address':
        pytest.skip(header)
    elif header.startswith('--sanitizer ignore memory') and yatest.common.context.sanitize == 'memory':
        pytest.skip(header)
    elif header.startswith('--sanitizer ignore thread') and yatest.common.context.sanitize == 'thread':
        pytest.skip(header)
    elif header.startswith('--sanitizer ignore undefined') and yatest.common.context.sanitize == 'undefined':
        pytest.skip(header)
    elif header.startswith('--canonize ast'):
        canonize_ast = True

    program = '\n'.join(['use plato;'] + program)

    cfg = yql_utils.get_program_cfg(None, case, DATA_PATH)
    files = {}
    diff_tool = None
    scan_udfs = False
    for item in cfg:
        if item[0] == 'file':
            files[item[1]] = item[2]
        if item[0] == 'diff_tool':
            diff_tool = item[1:]
        if item[0] == 'scan_udfs':
            scan_udfs = True

    in_tables = yql_utils.get_input_tables(None, cfg, DATA_PATH, def_attr=yql_utils.KSV_ATTR)

    udfs_dir = yql_utils.get_udfs_path([
        yatest.common.build_path(os.path.join(yatest.common.context.project_path, ".."))
    ])

    xfail = yql_utils.is_xfail(cfg)
    if yql_utils.get_param('TARGET_PLATFORM') and xfail:
        pytest.skip('xfail is not supported on non-default target platform')

    extra_env = dict(os.environ)
    extra_env["YQL_UDF_RESOLVER"] = "1"
    extra_env["YQL_ARCADIA_BINARY_PATH"] = os.path.expandvars(yatest.common.build_path('.'))
    extra_env["YQL_ARCADIA_SOURCE_PATH"] = os.path.expandvars(yatest.common.source_path('.'))
    extra_env["Y_NO_AVX_IN_DOT_PRODUCT"] = "1"

    # this breaks tests using V0 syntax
    if "YA_TEST_RUNNER" in extra_env:
        del extra_env["YA_TEST_RUNNER"]

    yqlrun_res = YQLRun(udfs_dir=udfs_dir, prov='yt', use_sql2yql=False, cfg_dir=os.getenv('YQL_CONFIG_DIR') or 'yql/essentials/cfg/udf_test').yql_exec(
        program=program,
        run_sql=True,
        tables=in_tables,
        files=files,
        check_error=not xfail,
        extra_env=extra_env,
        require_udf_resolver=True,
        scan_udfs=scan_udfs
    )

    if xfail:
        assert yqlrun_res.execution_result.exit_code != 0

    results_path = os.path.join(yql_utils.yql_output_path(), case + '.results.txt')
    with open(results_path, 'w') as f:
        f.write(yqlrun_res.results)

    to_canonize = [yqlrun_res.std_err] if xfail else [yatest.common.canonical_file(yqlrun_res.results_file, local=True, diff_tool=diff_tool)]

    if canonize_ast:
        to_canonize += [yatest.common.canonical_file(yqlrun_res.opt_file, local=True, diff_tool=ASTDIFF_PATH)]

    return to_canonize