feat: SQL between/hostvar-key alignment, class-condition parsing, gcov merge across scenario runs

This commit is contained in:
hangshuo652
2026-08-09 17:43:00 +08:00
parent f331c8fa2a
commit 273a3f8211
31 changed files with 3789 additions and 272 deletions
+36 -7
View File
@@ -31,6 +31,7 @@ class GroupInfo:
select_info: dict = field(default_factory=dict)
overlap_mask: list[bool] = field(default_factory=list)
multi_write_fds: set = field(default_factory=set)
command_args: list = field(default_factory=list)
@dataclass
@@ -335,7 +336,7 @@ def run_group(group: GroupInfo, exe_path: str, temp_dir: str,
try:
os.chdir(str(work_dir))
result = subprocess.run(
[str(exe)], capture_output=True, text=True,
[str(exe)] + list(group.command_args or []), capture_output=True, text=True,
encoding='utf-8', errors='replace', timeout=60,
)
except subprocess.TimeoutExpired:
@@ -434,26 +435,36 @@ def run_all(program_name: str, outdir: str, temp_dir: str,
gcov_root = work_dir / "gcov"
for scene_id, scene_recs, scene_terms, scene_expected, src_in_dir, dst_out_dir in scenes:
# ── 3a. 入力ファイル配置 ──
# ── 3a. 入力ファイル配置(主程序 + 被调子程序的输入文件全部复制)──
# 仅复制 assign_names 会漏掉子程序输入文件(测试驱动调用读文件自程序时
# 会 OPEN 失败 ABEND)。复制目录内全部非 JSON 文件(.json 为 V3 元数据)。
if src_in_dir.is_dir():
for assign in assign_names:
src = src_in_dir / assign
if src.exists():
shutil.copy2(str(src), str(work_dir / assign))
for src in sorted(src_in_dir.iterdir()):
if not src.is_file() or src.suffix.lower() == '.json':
continue
shutil.copy2(str(src), str(work_dir / src.name))
# ── 3b. 清理旧 gcda ──
_clean_gcda(str(work_dir))
# ── 3c. 过滤 non-abend ──
filtered_exp = []
normal_recs = []
abend_pairs = [] # (rec, command_args)
for i, rec in enumerate(scene_expected):
term = scene_terms[i] if i < len(scene_terms) else 'normal'
if term != 'abend':
filtered_exp.append(rec)
for i, rec in enumerate(scene_recs):
term = scene_terms[i] if i < len(scene_terms) else 'normal'
if term == 'abend':
abend_pairs.append((rec, list((rec.get('__CLI_ARGS__') or {}).values())))
else:
normal_recs.append(rec)
group = GroupInfo(
name=f"{program_name}_{scene_id}",
records=scene_recs,
records=normal_recs,
expected_outputs=filtered_exp,
expected_returncode=0,
fd_field_dicts=fd_field_dicts,
@@ -469,6 +480,23 @@ def run_all(program_name: str, outdir: str, temp_dir: str,
status = '' if r.passed else ''
logger.info(f"'{group.name}': returncode={r.returncode}, {status}")
# ── 3d-2. abend 记录单独执行(带命令行参数,触发 ABEND/异常返回)──
for ab_idx, (ab_rec, ab_args) in enumerate(abend_pairs):
ab_group = GroupInfo(
name=f"{program_name}_{scene_id}_abend_{ab_idx + 1}",
records=[ab_rec], expected_outputs=[],
expected_returncode=1,
fd_field_dicts=fd_field_dicts,
open_dir=open_dir,
select_info=select_info,
multi_write_fds=multi_write_fds,
command_args=ab_args,
)
r2 = run_group(ab_group, exe_path, str(work_dir), log_dir=log_dir)
results.append(r2)
status2 = '' if r2.passed else ''
logger.info(f"'{ab_group.name}': returncode={r2.returncode}, {status2}")
# ── 3e. 出力保存 ──
dst_out_dir.mkdir(parents=True, exist_ok=True)
for fd_name in fd_field_dicts:
@@ -579,6 +607,7 @@ def run_and_compare(program_name: str, outdir: str,
expected_returncode=1,
fd_field_dicts=fd_field_dicts, open_dir=open_dir,
select_info=select_info,
command_args=list((rec.get('__CLI_ARGS__') or {}).values()),
)
r = run_group(group, exe_path, temp_dir, log_dir=log_dir)
if r.returncode != 0: