lava_wait_jobs.py: Produce coverage report

If coverage option is enabled:

1. Download ELF artifacts from tf-m-build-config subjob.
2. Run report preparation tools from qa-tools project:
intermediate_layer.py, generate_info_file.py, and then
lcov's genhtml.

Besides the produced report, the ELF files and qa-tools'
config/intermediate files are also included in build
artifacts, to allow reproducing and debugging results.

Implementation-wise, code coverage report related code is added to
module "codecov_helper", to separate it from the LAVA code
per se.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
Change-Id: I9152674fe715e1d8b488f74cd2da2cb745010c1f
diff --git a/lava_helper/codecov_helper.py b/lava_helper/codecov_helper.py
new file mode 100644
index 0000000..ad4ad55
--- /dev/null
+++ b/lava_helper/codecov_helper.py
@@ -0,0 +1,44 @@
+__copyright__ = """
+/*
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+ """
+
+"""
+Module with helper functions for code coverage reports.
+"""
+
+import os
+import subprocess
+
+from lava_helper import test_lava_dispatch_credentials
+
+
+def run(cmd, cwd=None):
+    print("+ %s" % cmd, flush=True)
+    subprocess.check_call(cmd, shell=True, cwd=cwd)
+
+
+def coverage_reports(jobs, user_args):
+    lava = test_lava_dispatch_credentials(user_args)
+    for job_id, info in jobs.items():
+        job_dir = info["job_dir"]
+        metadata = info["metadata"]
+
+        if os.getenv("CODE_COVERAGE_EN") == "TRUE" and info["device_type"] == "fvp":
+
+            def dl_artifact(fname):
+                lava.fetch_file(
+                    metadata["build_job_url"] + "artifact/trusted-firmware-m/build/bin/" + fname,
+                    os.path.join(job_dir, fname)
+                )
+
+            dl_artifact("bl2.axf")
+            dl_artifact("tfm_s.axf")
+            dl_artifact("tfm_ns.axf")
+            run("python3 $SHARE_FOLDER/qa-tools/coverage-tool/coverage-reporting/intermediate_layer.py --config-json $SHARE_FOLDER/tf-m-ci-scripts/lava_helper/trace2covjson.json --local-workspace $SHARE_FOLDER", cwd=job_dir)
+            run("python3 $SHARE_FOLDER/qa-tools/coverage-tool/coverage-reporting/generate_info_file.py --workspace $SHARE_FOLDER --json covjson.json", cwd=job_dir)
+            run("genhtml --branch-coverage coverage.info --output-directory trace_report", cwd=job_dir)
diff --git a/lava_helper/lava_wait_jobs.py b/lava_helper/lava_wait_jobs.py
index 262eec2..9e1532b 100755
--- a/lava_helper/lava_wait_jobs.py
+++ b/lava_helper/lava_wait_jobs.py
@@ -26,6 +26,8 @@
 from lava_helper_configs import *
 from lava_helper import test_lava_dispatch_credentials
 from lava_submit_jobs import *
+import codecov_helper
+
 
 try:
     from tfm_ci_pylib.utils import save_json, load_json, sort_dict,\
@@ -83,6 +85,7 @@
     test_report(finished_jobs, user_args)
     failure_report(finished_jobs, user_args)
     csv_report(finished_jobs)
+    codecov_helper.coverage_reports(finished_jobs, user_args)
 
 
 def get_finished_jobs(job_list, user_args, lava):
diff --git a/lava_helper/trace2covjson.json b/lava_helper/trace2covjson.json
new file mode 100644
index 0000000..d32a4bb
--- /dev/null
+++ b/lava_helper/trace2covjson.json
@@ -0,0 +1,57 @@
+{
+    "configuration":
+        {
+        "remove_workspace": true,
+        "include_assembly": true
+        },
+    "parameters":
+        {
+        "objdump": "/home/buildslave/compiler/gcc-7-3-1/bin/arm-none-eabi-objdump",
+        "readelf": "/home/buildslave/compiler/gcc-7-3-1/bin/arm-none-eabi-readelf",
+        "sources": [
+                    {
+                    "type": "git",
+                    "URL":  "https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/",
+                    "COMMIT": "",
+                    "REFSPEC": "",
+                    "LOCATION": "trusted-firmware-m"
+                    },
+                    {
+                    "type": "git",
+                    "URL":  "https://mucboot.com/mcuboot.git",
+                    "COMMIT": "",
+                    "REFSPEC": "",
+                    "LOCATION": "mcuboot"
+                    },
+                    {
+                    "type": "git",
+                    "URL":  "https://tf.org/mbed/mbed-crypto.git",
+                    "COMMIT": "",
+                    "REFSPEC": "",
+                    "LOCATION": "mbed-crypto"
+                    }
+                ],
+        "workspace": "/home/buildslave/workspace/tf-m-build-config",
+        "output_file": "covjson.json"
+        },
+    "elfs": [
+            {
+                    "name": "bl2.axf",
+                    "traces": [
+                                "covtrace-FVP_MPS2_AEMv8M.cpu0.log"
+                              ]
+                },
+            {
+                    "name": "tfm_s.axf",
+                    "traces": [
+                                "covtrace-FVP_MPS2_AEMv8M.cpu0.log"
+                              ]
+                },
+            {
+                    "name": "tfm_ns.axf",
+                    "traces": [
+                                "covtrace-FVP_MPS2_AEMv8M.cpu0.log"
+                              ]
+                }
+        ]
+}