Skip to content

Commit 8185880

Browse files
authored
Merge 7988a93 into 9d6506e
2 parents 9d6506e + 7988a93 commit 8185880

File tree

4 files changed

+130
-4
lines changed

4 files changed

+130
-4
lines changed

ydb/library/yql/tests/postgresql/make-tests.sh

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
../../tools/pg-make-test/pg-make-test \
33
--srcdir=original/cases \
44
--patchdir=patches \
5+
--initscriptscfg=testinits.cfg \
6+
--initscriptsdir=initscripts \
57
--dstdir=cases \
68
--runner=../../tools/pgrun/pgrun \
79
--splitter="../../tools/pgrun/pgrun split-statements" \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
strings: char_tbl varchar_tbl text_tbl
2+
numerology: int2_tbl int4_tbl float8_tbl
3+
horology: time_tbl timetz_tbl timestamp_tbl timestamptz_tbl interval_tbl
4+
expressions: date_tbl
5+
create_misc: hobbies_r.0 equipment_r.0 onek.0 tenk1.0 tenk2.0 person.0 city.0 slow_emp4000.0 fast_emp4000.0 road.0 ihighway.0 shighway.0 a_star.0 b_star.0 c_star.0 d_star.0 e_star.0 f_star.0
6+
select: int8_tbl onek person emp student stud_emp onek2
7+
select_into: int8_tbl onek onek2
8+
select_distinct: tenk1 person emp student stud_emp tmp
9+
select_distinct_on: int4_tbl tmp
10+
subselect: text_tbl int4_tbl int8_tbl onek tenk1 road
11+
union: char_tbl varchar_tbl text_tbl int4_tbl int8_tbl float8_tbl tenk1
12+
join: text_tbl int2_tbl int4_tbl int8_tbl float8_tbl onek tenk1 tenk2
13+
aggregates: varchar_tbl int4_tbl int8_tbl onek tenk1 student aggtest
14+
arrays: int8_tbl tenk1 array_op_test
15+
window: int4_tbl tenk1 tenk2
16+
jsonb: testjsonb
17+
limit: int8_tbl onek tenk1
18+
alter_table: onek tenk1 stud_emp
19+
xml: emp
20+

ydb/library/yql/tools/pg-make-test/__main__.py

+83-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
PROGRAM_NAME = "pg-make-test"
2020
RUNNER = "../pgrun/pgrun"
2121
SPLITTER = "../pgrun/pgrun split-statements"
22+
INIT_SCRIPTS_CFG = "testinits.cfg"
23+
INIT_SCRIPTS_DIR = "initscripts"
2224
REPORT_FILE = "pg_tests.csv"
2325
LOGGER = None
2426

@@ -76,7 +78,9 @@ class TestCaseBuilder:
7678
def __init__(self, config):
7779
self.config = config
7880

79-
def build(self, sqlfile):
81+
def build(self, args):
82+
sqlfile, init_scripts = args
83+
8084
is_split_logging = self.config.logfile is not None and self.config.parallel
8185
if is_split_logging:
8286
logger = get_logger(
@@ -90,6 +94,9 @@ def build(self, sqlfile):
9094
splitted_stmts = list(self.split_sql_file(sqlfile))
9195
stmts_count = len(splitted_stmts)
9296

97+
if init_scripts:
98+
logging.debug("Init scripts: %s", init_scripts)
99+
93100
ressqlfile = self.config.dstdir / sqlfile.name
94101
resoutfile = ressqlfile.with_suffix('.out')
95102
reserrfile_base = resoutfile.with_suffix('.err')
@@ -125,7 +132,19 @@ def build(self, sqlfile):
125132
test_out_name = Path(tempdir) / "test.out"
126133
test_err_name = test_out_name.with_suffix(".err")
127134

128-
logger.debug("Running %s '%s' -> [%s]", self.config.runner, sqlfile, outfile)
135+
if init_scripts:
136+
init_out_name = Path(tempdir) / "init.out"
137+
init_err_name = init_out_name.with_suffix(".err")
138+
139+
for init_script in init_scripts:
140+
logger.debug("Running init script %s '%s'", self.config.runner, init_script)
141+
with open(init_script, 'rb') as f, open(init_out_name, 'wb') as fout, open(init_err_name, 'wb') as ferr:
142+
pi = subprocess.run(self.config.runner + ["--datadir", tempdir], stdin=f, stdout=fout, stderr=ferr)
143+
144+
if pi.returncode != 0:
145+
logger.warning("%s returned error code %d", self.config.runner, pi.returncode)
146+
147+
logger.debug("Running test %s '%s' -> [%s]", self.config.runner, sqlfile, outfile)
129148
with open(sqlfile, 'rb') as f, open(test_out_name, 'wb') as fout, open(test_err_name, 'wb') as ferr:
130149
pi = subprocess.run(self.config.runner + ["--datadir", tempdir], stdin=f, stdout=fout, stderr=ferr)
131150

@@ -323,6 +342,47 @@ def load_patches(patchdir):
323342
if ps is not False:
324343
yield p.stem, ps
325344

345+
reInitScriptsCfgLine = re.compile(r"^([\w.]+):\s*([\w.]+(?:\s+[\w.]+)*)$")
346+
347+
def load_init_scripts(initscriptscfg, initscriptsdir, tests_set):
348+
init_scripts_map = dict()
349+
350+
if not initscriptscfg.is_file():
351+
LOGGER.warning("Init scripts config file is not found: %s", initscriptscfg)
352+
return init_scripts_map
353+
354+
if not initscriptsdir.is_dir():
355+
LOGGER.warning("Init scripts directory is not found: %s", initscriptsdir)
356+
return init_scripts_map
357+
358+
scripts = frozenset(s.stem for s in initscriptsdir.glob("*.sql"))
359+
360+
with open(initscriptscfg, 'r') as cfg:
361+
for lineno, line in enumerate(cfg, 1):
362+
line = line.strip()
363+
364+
if not line:
365+
continue
366+
367+
m = reInitScriptsCfgLine.match(line)
368+
369+
if m is None:
370+
LOGGER.warning("Bad line %d in init scripts config %s", lineno, initscriptscfg)
371+
continue
372+
373+
test_name = m[1]
374+
if test_name not in tests_set:
375+
LOGGER.debug("Skipping init scripts for unknown test case %s", test_name)
376+
continue
377+
378+
deps = [(initscriptsdir / s).with_suffix(".sql") for s in m[2].split() if s in scripts]
379+
if not deps:
380+
LOGGER.debug("No init scripts are listed for test case %s", test_name)
381+
continue
382+
383+
init_scripts_map[test_name] = deps
384+
385+
return init_scripts_map
326386

327387
def patch_cases(cases, patches, patchdir):
328388
for i, sql_full_name in enumerate(cases):
@@ -394,6 +454,22 @@ def patch_cases(cases, patches, patchdir):
394454
multiple=False,
395455
type=click.Path(exists=True, file_okay=False, resolve_path=True, path_type=Path),
396456
)
457+
@click.option(
458+
"--initscriptscfg",
459+
help="Config file for tests' init scripts",
460+
default=INIT_SCRIPTS_CFG,
461+
required=False,
462+
multiple=False,
463+
type=click.Path(exists=True, dir_okay=False, resolve_path=True, path_type=Path)
464+
)
465+
@click.option(
466+
"--initscriptsdir",
467+
help="Directory with tests' init scripts",
468+
default=INIT_SCRIPTS_DIR,
469+
required=False,
470+
multiple=False,
471+
type=click.Path(exists=True, file_okay=False, resolve_path=True, path_type=Path)
472+
)
397473
@click.option("--skip", "-s", help="Comma-separated list of testsuits to skip", multiple=False, type=click.STRING)
398474
@click.option("--runner", help="Test runner", default=RUNNER, required=False, multiple=False, type=click.STRING)
399475
@click.option(
@@ -420,7 +496,7 @@ def patch_cases(cases, patches, patchdir):
420496
)
421497
@click.option("--debug/--no-debug", help="Logs verbosity", default=False, required=False)
422498
@click.version_option(version=svn_version(), prog_name=PROGRAM_NAME)
423-
def cli(cases, srcdir, dstdir, patchdir, skip, runner, splitter, report, parallel, logfile, debug):
499+
def cli(cases, srcdir, dstdir, patchdir, initscriptscfg, initscriptsdir, skip, runner, splitter, report, parallel, logfile, debug):
424500
setup_logging(logfile, debug)
425501

426502
if skip is not None:
@@ -439,6 +515,9 @@ def cli(cases, srcdir, dstdir, patchdir, skip, runner, splitter, report, paralle
439515
else:
440516
cases = [Path(c) if os.path.isabs(c) else config.srcdir / c for c in cases]
441517

518+
init_scripts = load_init_scripts(initscriptscfg, initscriptsdir, frozenset(c.stem for c in cases))
519+
LOGGER.debug("Init scripts: %s", init_scripts)
520+
442521
if config.patchdir is not None:
443522
patches = dict(load_patches(config.patchdir))
444523
LOGGER.info("Patches: %s", ", ".join(p for p in patches))
@@ -453,7 +532,7 @@ def cli(cases, srcdir, dstdir, patchdir, skip, runner, splitter, report, paralle
453532
builder = TestCaseBuilder(config)
454533
if config.parallel:
455534
with Pool() as pool:
456-
results = list(pool.imap_unordered(builder.build, cases))
535+
results = list(pool.imap_unordered(builder.build, [(test_case, init_scripts.get(test_case.stem) or []) for test_case in cases]))
457536
else:
458537
results = [builder.build(c) for c in cases]
459538

ydb/library/yql/tools/pgrun/pgrun.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,28 @@ void ShowFinalAst(TProgramPtr& program, IOutputStream& stream) {
10861086
PrintExprTo(program, stream);
10871087
}
10881088

1089+
void FillTablesMapping(const TFsPath& dataDir, THashMap<TString, TString>& tablesMapping) {
1090+
TVector<TFsPath> children;
1091+
1092+
dataDir.List(children);
1093+
1094+
Cerr << "Registering pre-existing tables\n";
1095+
for (const auto& f: children) {
1096+
if (f.GetExtension() != "attr") {
1097+
continue;
1098+
}
1099+
auto tableName = f.Basename();
1100+
tableName.resize(tableName.length() - 5);
1101+
1102+
if (tableName.EndsWith(".tmp")) {
1103+
continue;
1104+
}
1105+
const auto fullTableName = f.Parent() / tableName;
1106+
Cerr << "\tyt.plato." << tableName << " -> " << fullTableName << '\n';
1107+
tablesMapping[TString("yt.plato.") + tableName] = f.Parent() / tableName;
1108+
}
1109+
}
1110+
10891111
int Main(int argc, char* argv[])
10901112
{
10911113
using namespace NLastGetopt;
@@ -1132,6 +1154,9 @@ int Main(int argc, char* argv[])
11321154

11331155
auto yqlNativeServices = NFile::TYtFileServices::Make(funcRegistry.Get(), {}, fileStorage, tempDir.Path(), keepTempFiles);
11341156
auto ytNativeGateway = CreateYtFileGateway(yqlNativeServices, &emulateOutputForMultirun);
1157+
if (tempDirExists) {
1158+
FillTablesMapping(tempDir.Path(), yqlNativeServices->GetTablesMapping());
1159+
}
11351160

11361161
TVector<TDataProviderInitializer> dataProvidersInit;
11371162
dataProvidersInit.push_back(GetYtNativeDataProviderInitializer(ytNativeGateway));

0 commit comments

Comments
 (0)