Tidy up merge_cov.py to use metadata / pathlib

This commit is contained in:
Harry Callahan 2022-10-21 12:49:58 +01:00
parent dfcf8d00d0
commit 04f5ff61c7
2 changed files with 66 additions and 50 deletions

View file

@ -14,27 +14,23 @@ import sys
import pathlib3x as pathlib
from typing import Set
from metadata import RegressionMetadata
from metadata import RegressionMetadata, LockedMetadata
from setup_imports import _OT_LOWRISC_IP
from scripts_lib import run_one
def find_cov_dirs(start_dir: str, simulator: str) -> Set[str]:
assert simulator in ['xlm', 'vcs']
# For VCS, all generated coverage databases will be named "test.vdb"
vdb_dir_name = "test.vdb"
def find_cov_dirs(start_dir: pathlib.Path, simulator: str) -> Set[pathlib.Path]:
"""Gather a set of the coverage databases/directories."""
cov_dirs = set()
for path, dirs, files in os.walk(start_dir):
for file in files:
if file.endswith(".ucd") and simulator == 'xlm':
logging.info("Found coverage database (ucd) at %s" % path)
cov_dirs.add(path)
if vdb_dir_name in dirs and simulator == 'vcs':
vdb_path = os.path.join(path, vdb_dir_name)
logging.info("Found coverage database (vdb) at %s" % vdb_path)
cov_dirs.add(vdb_path)
if simulator == 'xlm':
for p in start_dir.glob('**/*.ucd'):
logging.info(f"Found coverage database (ucd) at {p}")
cov_dirs.add(p.parent)
if simulator == 'vcs':
for p in start_dir.glob('**/test.vdb'):
logging.info(f"Found coverage database (vdb) at {p}")
cov_dirs.add(p.parent)
if not cov_dirs:
logging.info(f"No coverage found for {simulator}")
@ -43,67 +39,81 @@ def find_cov_dirs(start_dir: str, simulator: str) -> Set[str]:
return cov_dirs
def merge_cov_vcs(cov_dir: str, verbose: bool, cov_dirs: Set[str]) -> int:
def merge_cov_vcs(md: RegressionMetadata, cov_dirs: Set[pathlib.Path]) -> int:
logging.info("Generating merged coverage directory")
cmd = (['urg', '-full64',
'-format', 'both',
'-dbname', os.path.join(cov_dir, 'merged.vdb'),
'-report', os.path.join(cov_dir, 'report'),
'-log', os.path.join(cov_dir, 'merge.log'),
'-dbname', str(md.cov_dir/'merged.vdb'),
'-report', str(md.cov_dir/'report'),
'-log', str(md.cov_dir/'merge.log'),
'-dir'] +
list(cov_dirs))
return run_one(verbose, cmd, redirect_stdstreams='/dev/null')
return run_one(md.verbose, cmd, redirect_stdstreams='/dev/null')
def merge_cov_xlm(cov_dir: str, verbose: bool, cov_dirs: Set[str]) -> int:
def merge_cov_xlm(md: RegressionMetadata, cov_dirs: Set[pathlib.Path]) -> int:
"""Merge xcelium-generated coverage using the OT scripts.
The vendored-in OpenTitan IP contains .tcl scripts that can merge xcelium
coverage using the Cadnece 'imc' Integrated-Metrics-Centre tool.
"""
xcelium_scripts = _OT_LOWRISC_IP/'dv/tools/xcelium'
# The merge TCL code uses a glob to find all available scopes and previous
# runs. In order to actually get the databases we need to go up once so
# that the "*" finds the directory we've seen.
cov_dir_parents = {os.path.normpath(os.path.join(d, '..'))
for d in cov_dirs}
merge_dir = os.path.join(cov_dir, 'merged')
report_dir = os.path.join(cov_dir, 'report')
cov_dir_parents = ' '.join(str(d.parent) for d in cov_dirs)
# Get all needed directories for merge and report stages.
xlm_cov_dirs = {
'cov_merge_db_dir': merge_dir,
'cov_report_dir': report_dir
'cov_merge_db_dir': str(md.dir_cov_merged),
'cov_report_dir': str(md.dir_cov_report),
'cov_db_dirs': cov_dir_parents
}
logging.info(f"xlm_cov_dirs : {xlm_cov_dirs}")
# Finally, set an environment variable containing all the directories that
# should be merged (this is how the list gets passed down to the TCL script
# that handles them)
xlm_cov_dirs['cov_db_dirs'] = ' '.join(cov_dir_parents)
xlm_env = os.environ.copy()
xlm_env.update(xlm_cov_dirs)
# First do the merge
imc_cmd = ["imc", "-64bit", "-licqueue"]
os.makedirs(merge_dir, exist_ok=True)
cov_merge_tcl = os.path.join(xcelium_scripts, "cov_merge.tcl")
merge_ret = run_one(verbose,
imc_cmd + ["-exec", cov_merge_tcl,
"-logfile", os.path.join(cov_dir,
'merge.log'),
"-nostdout"],
env=xlm_env)
# Update the metdadata file with the commands we're about to run
with LockedMetadata(md.dir_metadata, __file__) as md:
md.cov_merge_log = md.dir_cov / 'merge.log'
md.cov_merge_stdout = md.dir_cov / 'merge.log.stdout'
md.cov_merge_cmds = [(imc_cmd + ["-exec", str(xcelium_scripts/"cov_merge.tcl"),
"-logfile", str(md.dir_cov/'merge.log')])]
md.cov_report_log = md.dir_cov / 'report.log'
md.cov_report_stdout = md.dir_cov / 'report.log.stdout'
md.cov_report_cmds = [(imc_cmd + ["-load", str(md.dir_cov_merged),
"-exec", str(xcelium_scripts/"cov_report.tcl"),
"-logfile", str(md.dir_cov/'report.log')])]
# First do the merge
md.dir_cov_merged.mkdir(exist_ok=True, parents=True)
with open(md.cov_merge_stdout, 'wb') as fd:
merge_ret = run_one(verbose=md.verbose,
cmd=md.cov_merge_cmds[0],
redirect_stdstreams=fd,
env=xlm_env)
if merge_ret:
return merge_ret
# Then do the reporting
cov_report_tcl = os.path.join(xcelium_scripts, "cov_report.tcl")
os.makedirs(report_dir, exist_ok=True)
report_ret = run_one(verbose,
imc_cmd + ["-load", merge_dir,
"-exec", cov_report_tcl,
"-logfile", os.path.join(cov_dir,
'report.log'),
"-nostdout"],
env=xlm_env)
os.makedirs(md.dir_cov_report, exist_ok=True)
with open(md.cov_report_stdout, 'wb') as fd:
report_ret = run_one(verbose=md.verbose,
cmd=md.cov_report_cmds[0],
redirect_stdstreams=fd,
env=xlm_env)
return report_ret
@ -120,13 +130,13 @@ def main():
md.dir_cov.mkdir(exist_ok=True, parents=True)
# Compile a list of all directories that contain coverage databases
cov_dirs = find_cov_dirs(str(md.dir_run), md.simulator)
cov_dirs = find_cov_dirs(md.dir_run, md.simulator)
merge_funs = {
'vcs': merge_cov_vcs,
'xlm': merge_cov_xlm
}
return merge_funs[md.simulator](str(md.dir_cov), md.verbose, cov_dirs)
return merge_funs[md.simulator](md, cov_dirs)
if __name__ == '__main__':

View file

@ -81,6 +81,12 @@ class RegressionMetadata(scripts_lib.testdata_cls):
riscvdv_fcov_log : Optional[pathlib.Path] = None
riscvdv_fcov_stdout : Optional[pathlib.Path] = None
riscvdv_fcov_cmds : Optional[List[List[str]]] = None
cov_merge_log : Optional[pathlib.Path] = None
cov_merge_stdout : Optional[pathlib.Path] = None
cov_merge_cmds : Optional[List[List[str]]] = None
cov_report_log : Optional[pathlib.Path] = None
cov_report_stdout : Optional[pathlib.Path] = None
cov_report_cmds : Optional[List[List[str]]] = None
regr_log : Optional[pathlib.Path] = None
regr_log_junit : Optional[pathlib.Path] = None
regr_log_junit_merged : Optional[pathlib.Path] = None