[dv regr tool] Publish results to OT web server
- Added --publish switch to upload regression results to
reports.opentitan.org
- Maintains the same hierarchy as src tree
- Latest one always goes to reports.opentitan.org/hw/ip/uart/dv/latest/results.md
- Maintains a history of 7 results
- History can be looked up at reports.opentitan.org/hw/ip/uart/dv/history.md
- report directories older than 7 most recent are deleted
- if 'latest' directory exists, then it is renamed to its timestamp
- All results are in MD format - #1411 tracks their inline conversion to
html
Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/util/dvsim/Deploy.py b/util/dvsim/Deploy.py
index cd9f0cf..37b3775 100644
--- a/util/dvsim/Deploy.py
+++ b/util/dvsim/Deploy.py
@@ -54,6 +54,7 @@
self.cmd = ""
self.odir = ""
self.log = ""
+ self.fail_msg = ""
# Flag to indicate whether to 'overwrite' if odir already exists,
# or to backup the existing one and create a new one.
@@ -210,19 +211,31 @@
def set_status(self):
self.status = 'P'
if self.dry_run is False:
+ for fail_pattern in self.fail_patterns:
+ grep_cmd = "grep -m 1 -E \'" + fail_pattern + "\' " + self.log
+ (status, rslt) = subprocess.getstatusoutput(grep_cmd + " -c")
+ if rslt != "0":
+ (status, rslt) = subprocess.getstatusoutput(grep_cmd)
+ msg = "```\n{}\n```\n".format(rslt)
+ self.fail_msg += msg
+ log.log(VERBOSE, msg)
+ self.status = 'F'
+ break
+
+ # Return if status is fail - no need to look for pass patterns.
+ if self.status == 'F': return
+
+ # If fail patterns were not found, ensure pass patterns indeed were.
for pass_pattern in self.pass_patterns:
grep_cmd = "grep -c -m 1 -E \'" + pass_pattern + "\' " + self.log
(status, rslt) = subprocess.getstatusoutput(grep_cmd)
if rslt == "0":
- log.log(VERBOSE, "No pass patterns found: %s", self.name)
+ msg = "Pass pattern \"{}\" not found.<br>\n".format(
+ pass_pattern)
+ self.fail_msg += msg
+ log.log(VERBOSE, msg)
self.status = 'F'
-
- for fail_pattern in self.fail_patterns:
- grep_cmd = "grep -c -m 1 -E \'" + fail_pattern + "\' " + self.log
- (status, rslt) = subprocess.getstatusoutput(grep_cmd)
- if rslt != "0":
- log.log(VERBOSE, "Fail patterns found: %s", self.name)
- self.status = 'F'
+ break
# Recursively set sub-item's status if parent item fails
def set_sub_status(self, status):
@@ -249,7 +262,14 @@
if self.process.poll() is not None:
self.log_fd.close()
if self.process.returncode != 0:
- # TODO: read the log to diagnose the failure
+ msg = "Last 2 lines of the log:<br>\n"
+ self.fail_msg += msg
+ log.log(VERBOSE, msg)
+ get_fail_msg_cmd = "tail -n 2 " + self.log
+ msg = run_cmd(get_fail_msg_cmd)
+ msg = "```\n{}\n```\n".format(msg)
+ self.fail_msg += msg
+ log.log(VERBOSE, msg)
self.status = "F"
else:
self.set_status()
@@ -263,6 +283,7 @@
@staticmethod
def deploy(items):
dispatched_items = []
+
def dispatch_items(items):
item_names = {}
for item in items:
@@ -393,6 +414,12 @@
super().parse_dict(sim_cfg.__dict__)
self.build_mode = self.name
self.__post_init__()
+
+ # Start fail message construction
+ self.fail_msg = "\n**BUILD:** {}<br>\n".format(self.name)
+ log_sub_path = self.log.replace(self.sim_cfg.scratch_root + '/', '')
+ self.fail_msg += "**LOG: {}<br>\n".format(log_sub_path)
+
CompileSim.items.append(self)
@@ -442,9 +469,15 @@
self.renew_odir = True
self.build_mode = test.build_mode.name
self.__post_init__()
- # Construct custom odir link name for RunTest items by combining name
- # and index
+ # For output dir link, use run_dir_name instead.
self.odir_ln = self.run_dir_name
+
+ # Start fail message construction
+ self.fail_msg = "\n**TEST:** {}, ".format(self.name)
+ self.fail_msg += "**SEED:** {}<br>\n".format(self.seed)
+ log_sub_path = self.log.replace(self.sim_cfg.scratch_root + '/', '')
+ self.fail_msg += "**LOG:** {}<br>\n".format(log_sub_path)
+
RunTest.items.append(self)
@staticmethod