[dvsim] Exit with error on test failures

- This PR fixes #1692 - it return with 1 if test errors were
encountered.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/util/dvsim.py b/util/dvsim.py
index 40c89be..e39aa4a 100755
--- a/util/dvsim.py
+++ b/util/dvsim.py
@@ -470,6 +470,11 @@
     else:
         log.info("No items specified to be run.")
 
+    # Exit with non-zero status if there were errors or failures.
+    if cfg.has_errors():
+        log.error("Errors were encountered in this run.")
+        sys.exit(1)
+
 
 if __name__ == '__main__':
     main()
diff --git a/util/dvsim/FlowCfg.py b/util/dvsim/FlowCfg.py
index eea6ca2..a001f7b 100644
--- a/util/dvsim/FlowCfg.py
+++ b/util/dvsim/FlowCfg.py
@@ -67,6 +67,7 @@
         self.timestamp = args.timestamp
 
         # Results
+        self.errors_seen = False
         self.rel_path = ""
         self.results_title = ""
         self.results_server_prefix = ""
@@ -431,6 +432,7 @@
             result = item._gen_results()
             print(result)
             results.append(result)
+            self.errors_seen |= item.errors_seen
 
         if self.is_master_cfg: self.gen_results_summary()
 
@@ -440,6 +442,7 @@
         return
 
     def _get_results_page_link(self, link_text):
+        if not self.args.publish: return link_text
         results_page_url = self.results_server_page.replace(
             self.results_server_prefix, self.results_server_url_prefix)
         return "[%s](%s)" % (link_text, results_page_url)
@@ -620,3 +623,6 @@
             log.log(VERBOSE, cmd_output.stdout.decode("utf-8"))
         except Exception as e:
             log.error("%s: Failed to publish results:\n\"%s\"", e, str(cmd))
+
+    def has_errors(self):
+        return self.errors_seen
diff --git a/util/dvsim/SimCfg.py b/util/dvsim/SimCfg.py
index 7186724..62cd278 100644
--- a/util/dvsim/SimCfg.py
+++ b/util/dvsim/SimCfg.py
@@ -472,6 +472,7 @@
         # Add title if there are indeed failures
         if fail_msgs != "":
             fail_msgs = "\n## List of Failures\n" + fail_msgs
+            self.errors_seen = True
 
         # Generate results table for runs.
         results_str = "## " + self.results_title + "\n"
@@ -501,8 +502,6 @@
             results_str += "\n### [Coverage Dashboard](cov_report/dashboard.html)\n\n"
             results_str += self.cov_report_deploy.cov_results
             self.results_summary["Coverage"] = self.cov_report_deploy.cov_total
-        else:
-            self.results_summary["Coverage"] = "-- %"
 
         # append link of detail result to block name
         self.results_summary["Name"] = self._get_results_page_link(
@@ -510,6 +509,7 @@
 
         # Append failures for triage
         self.results_md = results_str + fail_msgs
+        results_str += fail_msgs
 
         # Write results to the scratch area
         results_file = self.scratch_path + "/results_" + self.timestamp + ".md"
@@ -524,7 +524,8 @@
     def gen_results_summary(self):
 
         # sim summary result has 5 columns from each SimCfg.results_summary
-        header = ["Name", "Passing", "Total", "Pass Rate", "Coverage"]
+        header = ["Name", "Passing", "Total", "Pass Rate"]
+        if self.cov: header.append('Coverage')
         table = [header]
         colalign = ("center", ) * len(header)
         for item in self.cfgs: