19
19
PROGRAM_NAME = "pg-make-test"
20
20
RUNNER = "../pgrun/pgrun"
21
21
SPLITTER = "../pgrun/pgrun split-statements"
22
+ INIT_SCRIPTS_CFG = "testinits.cfg"
23
+ INIT_SCRIPTS_DIR = "initscripts"
22
24
REPORT_FILE = "pg_tests.csv"
23
25
LOGGER = None
24
26
@@ -76,7 +78,9 @@ class TestCaseBuilder:
76
78
def __init__ (self , config ):
77
79
self .config = config
78
80
79
- def build (self , sqlfile ):
81
+ def build (self , args ):
82
+ sqlfile , init_scripts = args
83
+
80
84
is_split_logging = self .config .logfile is not None and self .config .parallel
81
85
if is_split_logging :
82
86
logger = get_logger (
@@ -90,6 +94,9 @@ def build(self, sqlfile):
90
94
splitted_stmts = list (self .split_sql_file (sqlfile ))
91
95
stmts_count = len (splitted_stmts )
92
96
97
+ if init_scripts :
98
+ logging .debug ("Init scripts: %s" , init_scripts )
99
+
93
100
ressqlfile = self .config .dstdir / sqlfile .name
94
101
resoutfile = ressqlfile .with_suffix ('.out' )
95
102
reserrfile_base = resoutfile .with_suffix ('.err' )
@@ -125,7 +132,19 @@ def build(self, sqlfile):
125
132
test_out_name = Path (tempdir ) / "test.out"
126
133
test_err_name = test_out_name .with_suffix (".err" )
127
134
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 )
129
148
with open (sqlfile , 'rb' ) as f , open (test_out_name , 'wb' ) as fout , open (test_err_name , 'wb' ) as ferr :
130
149
pi = subprocess .run (self .config .runner + ["--datadir" , tempdir ], stdin = f , stdout = fout , stderr = ferr )
131
150
@@ -323,6 +342,47 @@ def load_patches(patchdir):
323
342
if ps is not False :
324
343
yield p .stem , ps
325
344
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
326
386
327
387
def patch_cases (cases , patches , patchdir ):
328
388
for i , sql_full_name in enumerate (cases ):
@@ -394,6 +454,22 @@ def patch_cases(cases, patches, patchdir):
394
454
multiple = False ,
395
455
type = click .Path (exists = True , file_okay = False , resolve_path = True , path_type = Path ),
396
456
)
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
+ )
397
473
@click .option ("--skip" , "-s" , help = "Comma-separated list of testsuits to skip" , multiple = False , type = click .STRING )
398
474
@click .option ("--runner" , help = "Test runner" , default = RUNNER , required = False , multiple = False , type = click .STRING )
399
475
@click .option (
@@ -420,7 +496,7 @@ def patch_cases(cases, patches, patchdir):
420
496
)
421
497
@click .option ("--debug/--no-debug" , help = "Logs verbosity" , default = False , required = False )
422
498
@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 ):
424
500
setup_logging (logfile , debug )
425
501
426
502
if skip is not None :
@@ -439,6 +515,9 @@ def cli(cases, srcdir, dstdir, patchdir, skip, runner, splitter, report, paralle
439
515
else :
440
516
cases = [Path (c ) if os .path .isabs (c ) else config .srcdir / c for c in cases ]
441
517
518
+ init_scripts = load_init_scripts (initscriptscfg , initscriptsdir , frozenset (c .stem for c in cases ))
519
+ LOGGER .debug ("Init scripts: %s" , init_scripts )
520
+
442
521
if config .patchdir is not None :
443
522
patches = dict (load_patches (config .patchdir ))
444
523
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
453
532
builder = TestCaseBuilder (config )
454
533
if config .parallel :
455
534
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 ] ))
457
536
else :
458
537
results = [builder .build (c ) for c in cases ]
459
538
0 commit comments