feat: phase2 review fixes

- TIME injection: change from spaces to '2500' (hour>23) for NUMVAL trigger
- Runner: add .resolve() to work_dir to fix chdir+relative path breakage
- Coverage: per-target field overrides for DP#9-#12 (START-DATE=20240115 etc.)
- .gitignore: add compilation artifacts, temp scripts, test outputs
This commit is contained in:
hangshuo652
2026-07-15 21:46:28 +08:00
parent f3be17e5eb
commit 54d4e81240
13 changed files with 769 additions and 188 deletions
+52 -17
View File
@@ -105,7 +105,8 @@ def _output_assign_names(select_info: dict, open_dir: dict,
def compile_sub_modules(sub_dir: str, work_dir: str,
cpy_dir: str | None = None) -> list[str]:
cpy_dir: str | None = None,
log_dir: str | None = None) -> list[str]:
sub_path = Path(sub_dir)
work_path = Path(work_dir)
work_path.mkdir(parents=True, exist_ok=True)
@@ -131,9 +132,19 @@ def compile_sub_modules(sub_dir: str, work_dir: str,
orig = os.getcwd()
try:
os.chdir(str(work_path))
r = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
r = subprocess.run(cmd, capture_output=True, text=True, timeout=120, errors='replace')
finally:
os.chdir(orig)
if log_dir:
log_path = Path(log_dir) / 'compile' / f"sub_{cbl.stem}.log"
log_path.parent.mkdir(parents=True, exist_ok=True)
log_path.write_text(
f"COMMAND: {' '.join(cmd)}\n"
f"RETURNCODE: {r.returncode}\n\n"
f"STDOUT:\n{r.stdout}\n\n"
f"STDERR:\n{r.stderr}",
encoding='utf-8'
)
if r.returncode != 0:
logger.warning(f" SUB编译失败 {cbl.name}: {r.stderr.strip()[:200]}")
continue
@@ -144,7 +155,8 @@ def compile_sub_modules(sub_dir: str, work_dir: str,
def compile_program(program_name: str, source_dir: str, work_dir: str,
sub_objects: list[str],
cpy_dir: str | None = None) -> str:
cpy_dir: str | None = None,
log_dir: str | None = None) -> str:
work_path = Path(work_dir)
work_path.mkdir(parents=True, exist_ok=True)
@@ -164,9 +176,19 @@ def compile_program(program_name: str, source_dir: str, work_dir: str,
orig = os.getcwd()
try:
os.chdir(str(work_path))
r = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
r = subprocess.run(cmd, capture_output=True, text=True, timeout=120, errors='replace')
finally:
os.chdir(orig)
if log_dir:
log_path = Path(log_dir) / 'compile' / f"{program_name}.log"
log_path.parent.mkdir(parents=True, exist_ok=True)
log_path.write_text(
f"COMMAND: {' '.join(cmd)}\n"
f"RETURNCODE: {r.returncode}\n\n"
f"STDOUT:\n{r.stdout}\n\n"
f"STDERR:\n{r.stderr}",
encoding='utf-8'
)
if r.returncode != 0:
raise RuntimeError(f"编译失败 {program_name}: {r.stderr.strip()[:500]}")
return str(exe)
@@ -302,7 +324,8 @@ def compare_outputs(actual: list[dict], expected: list[dict],
# ── 单组执行(SOURCE 改 - Native)──
def run_group(group: GroupInfo, exe_path: str, temp_dir: str) -> GroupResult:
def run_group(group: GroupInfo, exe_path: str, temp_dir: str,
log_dir: str | None = None) -> GroupResult:
logger.info(f" 执行组: {group.name} ({len(group.records)} 条记录)")
exe = Path(exe_path).resolve()
@@ -321,6 +344,17 @@ def run_group(group: GroupInfo, exe_path: str, temp_dir: str) -> GroupResult:
finally:
os.chdir(orig)
if log_dir:
log_path = Path(log_dir) / f"{group.name}.log"
log_path.parent.mkdir(parents=True, exist_ok=True)
log_path.write_text(
f"COMMAND: {' '.join([str(exe)])}\n"
f"RETURNCODE: {result.returncode}\n\n"
f"STDOUT:\n{result.stdout}\n\n"
f"STDERR:\n{result.stderr}",
encoding='utf-8'
)
rc = result.returncode
all_pass = (rc == group.expected_returncode)
all_details = []
@@ -362,7 +396,7 @@ def run_all(program_name: str, outdir: str, temp_dir: str,
merged_gcov_data is None when no gcov runs.
"""
source_dir = source_dir or str(Path(outdir).parent)
work_dir = Path(temp_dir)
work_dir = Path(temp_dir).resolve()
work_dir.mkdir(parents=True, exist_ok=True)
expected = expected_records or []
path_infos = path_infos or []
@@ -370,6 +404,7 @@ def run_all(program_name: str, outdir: str, temp_dir: str,
fd_field_dicts = _build_fd_field_dicts(fd_fields, fields_dict)
assign_names = _input_assign_names(select_info, open_dir, fd_fields)
log_dir = os.path.join(outdir, 'logs')
def _is_output_fd(fd_name: str) -> bool:
dir_val = open_dir.get(fd_name, '')
@@ -378,21 +413,21 @@ def run_all(program_name: str, outdir: str, temp_dir: str,
# ── 1. SUB 编译(V3)──
sub_dir = _resolve_sub_dir(source_dir)
cpy_dir = _resolve_cpy_dir(source_dir)
sub_o = compile_sub_modules(sub_dir, str(work_dir), cpy_dir)
sub_o = compile_sub_modules(sub_dir, str(work_dir), cpy_dir, log_dir=log_dir)
# ── 2. 主程序编译(V3)──
exe_path = compile_program(
program_name, source_dir, str(work_dir), sub_o, cpy_dir
program_name, source_dir, str(work_dir), sub_o, cpy_dir, log_dir=log_dir
)
# ── 3. 场景定义 ──
scenes = [("main", records, term_types, expected,
Path(outdir) / 'input', Path(outdir) / 'output')]
Path(outdir) / 'main' / 'input', Path(outdir) / 'main' / 'output')]
if skip_records:
skip_expected = [{}] * len(skip_records)
skip_term = skip_term_types or ['normal'] * len(skip_records)
scenes.append(("skip", skip_records, skip_term, skip_expected,
Path(outdir) / 'input_skip', Path(outdir) / 'run_skip' / 'output'))
Path(outdir) / 'skip' / 'input', Path(outdir) / 'skip' / 'output'))
results = []
gcov_data_sets = []
@@ -428,7 +463,7 @@ def run_all(program_name: str, outdir: str, temp_dir: str,
)
# ── 3d. 执行 ──
r = run_group(group, exe_path, str(work_dir))
r = run_group(group, exe_path, str(work_dir), log_dir=log_dir)
results.append(r)
status = '' if r.passed else ''
@@ -457,8 +492,7 @@ def run_all(program_name: str, outdir: str, temp_dir: str,
for f in work_dir.glob("*.gcno"):
if f.is_file() and f.stat().st_size > 0:
dst = scene_gcov_dir / f.name
if not dst.exists():
shutil.copy2(str(f), str(dst))
shutil.copy2(str(f), str(dst))
# ── 3g. 收集该场景的 gcov 数据 ──
from .gcov import run_gcov as _run_gcov
@@ -506,6 +540,7 @@ def run_and_compare(program_name: str, outdir: str,
temp_dir = os.path.join(outdir, '.run_cache')
source_dir = os.path.join(outdir, '..', 'input')
log_dir = os.path.join(outdir, 'logs')
work_dir = Path(temp_dir)
work_dir.mkdir(parents=True, exist_ok=True)
@@ -513,8 +548,8 @@ def run_and_compare(program_name: str, outdir: str,
sub_dir = _resolve_sub_dir(source_dir)
cpy_dir = _resolve_cpy_dir(source_dir)
sub_o = compile_sub_modules(sub_dir, temp_dir, cpy_dir)
exe_path = compile_program(program_name, source_dir, temp_dir, sub_o, cpy_dir)
sub_o = compile_sub_modules(sub_dir, temp_dir, cpy_dir, log_dir=log_dir)
exe_path = compile_program(program_name, source_dir, temp_dir, sub_o, cpy_dir, log_dir=log_dir)
if normal_recs:
group = GroupInfo(
@@ -522,7 +557,7 @@ def run_and_compare(program_name: str, outdir: str,
fd_field_dicts=fd_field_dicts, open_dir=open_dir,
select_info=select_info,
)
r = run_group(group, exe_path, temp_dir)
r = run_group(group, exe_path, temp_dir, log_dir=log_dir)
result['normal_pass'] = (r.returncode == 0)
result['normal_returncode'] = r.returncode
for fd_name in fd_field_dicts:
@@ -545,7 +580,7 @@ def run_and_compare(program_name: str, outdir: str,
fd_field_dicts=fd_field_dicts, open_dir=open_dir,
select_info=select_info,
)
r = run_group(group, exe_path, temp_dir)
r = run_group(group, exe_path, temp_dir, log_dir=log_dir)
if r.returncode != 0:
result['abend_pass'] += 1