Move internal code-coverage tool to use qa-tools public repo

- CI scripts to use qa-tools repository rather
than test-definitions.
- Consolidate functions to access qa-tools in a
file (qa-code-coverage.sh).
- Refactoring in merge reports script.

Signed-off-by: Saul Romero <saul.romero@arm.com>
Change-Id: I1b447273b216d739bcfcfeddf469a8f4f1c2b16b
diff --git a/script/qa-code-coverage.sh b/script/qa-code-coverage.sh
new file mode 100644
index 0000000..4fc0d9a
--- /dev/null
+++ b/script/qa-code-coverage.sh
@@ -0,0 +1,264 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Include variables and functions to be used by these scripts
+source "$CI_ROOT/utils.sh"
+################################################################################
+# CI VARIABLES:
+# workspace, warehouse, artefacts
+# GLOBAL VARIABLES:
+# OUTDIR, PROJECT, FALLBACK_PLUGIN_URL, FALLBACK_FILES, PLUGIN_BINARY
+################################################################################
+# Defining constants
+GERRIT_URL=${GERRIT_URL:-https://gerrit.oss.arm.com}
+QA_REPO_USER=jenkins_auto
+QA_REPO_INTERNAL=${QA_REPO_INTERNAL:-https://${QA_REPO_USER}:${QA_REPO_TOKEN}@git.gitlab.arm.com/tooling/qa-tools-internal.git}
+QA_REPO_PUBLIC=${QA_REPO_PUBLIC:-https://git.gitlab.arm.com/tooling/qa-tools.git}
+QA_REPO_NAME=qa-tools
+# Internal globals
+CODE_COVERAGE_FOLDER="${OUTDIR:-$workspace}/qa-code-coverage"
+DEBUG_FOLDER=${artefacts}/debug
+RELEASE_FOLDER=${artefacts}/release
+TRACE_FILE_PREFIX=covtrace
+CONFIG_JSON=${CODE_COVERAGE_FOLDER}/configuration_file.json
+INTERMEDIATE_LAYER_FILE=${CODE_COVERAGE_FOLDER}/intermediate_layer.json
+INFO_FILE=${CODE_COVERAGE_FOLDER}/coverage.info
+REPORT_FOLDER=${CODE_COVERAGE_FOLDER}/lcov
+
+if echo "$JENKINS_URL" | grep -q "oss.arm.com"; then
+  QA_REPO=${QA_REPO_PUBLIC}
+  QA_REFSPEC=${QA_REFSPEC:-master}
+else
+  QA_REPO="https://review.trustedfirmware.org/ci/qa-tools"
+  QA_REFSPEC="openci"
+fi
+
+
+################################################################################
+# Deploy qa-tools into the current directory
+# GLOBALS:
+#   QA_REPO, QA_REPO_NAME, QA_REFSPEC
+# ARGUMENTS:
+#   None
+# OUTPUTS:
+#   Clones the qa-tools repo from the global variables with the given
+#   commit hash.
+# RETURN:
+#   0 if succeeds, non-zero on error.
+################################################################################
+deploy_qa_tools() {
+  git clone "${QA_REPO}" ${QA_REPO_NAME}
+  cd ${QA_REPO_NAME} && git checkout "${QA_REFSPEC}" && cd ..
+}
+
+
+################################################################################
+# Builds or downloads the QA Code Coverage Tool
+# GLOBALS:
+#   CODE_COVERAGE_FOLDER, QA_REPO, QA_REPO_NAME, QA_REFSPEC, FALLBACK_PLUGIN_URL
+# ARGUMENTS:
+#   None
+# OUTPUTS:
+#   Creates coverage folder and builds/downloads there the plugin binaries.
+#   It exports the binary plugin location to coverage_trace_plugin.
+# RETURN:
+#   0 if succeeds, non-zero on error.
+################################################################################
+build_tool() {
+  echo "Building QA Code coverage tool..."
+  PLUGIN_BINARY="${FALLBACK_FILES%%,*}" # The first in the list of the binary files
+  local PVLIB_HOME="warehouse/SysGen/PVModelLib/$model_version/$model_build/external"
+  local LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CODE_COVERAGE_FOLDER
+  mkdir -p ${CODE_COVERAGE_FOLDER}
+  pushd "${CODE_COVERAGE_FOLDER}"
+  deploy_qa_tools
+  local cc_source=$(find . -type f -name 'coverage_trace.cc')
+  local fallback="wget -q ${FALLBACK_PLUGIN_URL}/{$FALLBACK_FILES}"
+  echo "Warehouse=${warehouse}"
+  eval "$fallback"
+  ls -al
+  export coverage_trace_plugin="${CODE_COVERAGE_FOLDER}/${PLUGIN_BINARY}"
+  popd
+}
+
+  ################################################################################
+  # Creates configuration file for intermediate layer generation
+  # GLOBALS:
+  #   PROJECT, CONFIG_JSON, INTERMEDIATE_LAYER_FILE, CODE_COVERAGE_FOLDER
+  # ARGUMENTS:
+  #   $1 Folder where are the elf/axf files.
+  #   $2 List of elf/axf file names.
+  #   $3 Path for trace files.
+  #   $4 Root folder name where all the repos are cloned.
+  # OUTPUTS:
+  #   Creates coverage folder and builds/downloads there the plugin binaries.
+  # RETURN:
+  #   0 if succeeds, non-zero on error.
+  ################################################################################
+create_config_json() {
+  set +e
+  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
+  then
+    cat << END
+Missing argument at '${FUNCNAME[0]}'.
+USAGE:
+  create_config_json ' Glob binaries' 'Glob trace files' 'Repos root folder name'
+  Example:
+    create_config_json 'bl1.elf bl2.elf' 'tf'
+END
+    exit 1
+  fi
+  local ELF_FOLDER=$1
+  local dwarf_array=($2)
+  local TRACE_FOLDER=$3
+  local root_repos_foolder="${4:-$workspace}"
+  local scm_sources=""
+
+  # Obtaining binaries from array
+  bin_section=""
+  for index in "${!dwarf_array[@]}"
+  do
+      local elf_file="${ELF_FOLDER}/${dwarf_array[$index]}"
+      cp "$elf_file" ${CODE_COVERAGE_FOLDER}/.
+      read -r -d '' bin_section << EOM
+${bin_section}
+              {
+                  "name": "$elf_file",
+                  "traces": [
+                              "${TRACE_FOLDER}/${TRACE_FILE_PREFIX:-covtrace}-*.log"
+                            ]
+              }
+EOM
+  if [ $index -lt $((${#dwarf_array[@]} - 1)) ];then
+      bin_section="${bin_section},"
+  fi
+  done
+
+  if [ "$PROJECT" = "SCP" ]; then
+      read -r -d '' scm_sources << EOM
+              [
+                  {
+                  "type": "git",
+                  "URL":  "$CC_SCP_URL",
+                  "COMMIT": "$CC_SCP_COMMIT",
+                  "REFSPEC": "$CC_SCP_REFSPEC",
+                  "LOCATION": "scp"
+                  },
+                  {
+                  "type": "git",
+                  "URL":  "$CC_CMSIS_URL",
+                  "COMMIT": "$CC_CMSIS_COMMIT",
+                  "REFSPEC": "$CC_CMSIS_REFSPEC",
+                  "LOCATION": "scp/contrib/cmsis/git"
+                  }
+              ]
+EOM
+elif [ "$PROJECT" = "TF-A" ]; then
+      read -r -d '' scm_sources << EOM
+              [
+                  {
+                  "type": "git",
+                  "URL":  "$CC_TRUSTED_FIRMWARE_URL",
+                  "COMMIT": "$CC_TRUSTED_FIRMWARE_COMMIT",
+                  "REFSPEC": "$CC_TRUSTED_FIRMWARE_REFSPEC",
+                  "LOCATION": "trusted_firmware"
+                  },
+                  {
+                  "type": "http",
+                  "URL":  "$mbedtls_archive",
+                  "COMPRESSION": "xz",
+                  "EXTRA_PARAMS": "--strip-components=1",
+                  "LOCATION": "mbedtls"
+                  }
+              ]
+EOM
+  else
+      echo "SCM sources not provided for project '${PROJECT}'"
+      exit 1
+  fi
+local metadata="\"BUILD_CONFIG\": \"${BUILD_CONFIG}\", \"RUN_CONFIG\": \"${RUN_CONFIG}\""
+cat <<EOF > "${CONFIG_JSON}"
+{
+  "configuration":
+      {
+      "remove_workspace": true,
+      "include_assembly": true
+      },
+  "parameters":
+      {
+      "objdump": "${OBJDUMP}",
+      "readelf": "${READELF}",
+      "sources": $scm_sources,
+      "workspace": "${root_repos_foolder}",
+      "output_file": "${INTERMEDIATE_LAYER_FILE}",
+      "metadata": {$metadata}
+      },
+  "elfs": [
+          ${bin_section}
+      ]
+}
+EOF
+
+}
+
+################################################################################
+# Creates intermediate layer json file with trace coverage data.
+#
+# Creates a configuration JSON file to be the input for the intermediate
+# layer file creation.
+# GLOBALS:
+#   TRACE_FILE_PREFIX, CODE_COVERAGE_FOLDER
+# ARGUMENTS:
+#   $1 Location of trace files.
+#   $2 Location of elf/axf files.
+#   $3 List of binaries to be checked the traces.
+#   $4 Root folder name where all the repos are cloned.
+# OUTPUTS:
+#   A configuration JSON file.
+#   An intermediate layer JSON  file.
+# RETURN:
+#   0 if succeeds, non-zero on error.
+################################################################################
+create_intermediate_layer() {
+  local TRACE_FOLDER="$1"
+  local ELF_FOLDER="$2"
+  local LIST_OF_BINARIES="$3"
+  local root_repos_foolder="$4"
+
+  # Copying trace files into the qa-tools executables folder
+  if [ $(ls -1 ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* 2>/dev/null | wc -l) != 0 ]; then
+    cp ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* ${CODE_COVERAGE_FOLDER}/.
+  else
+    echo "Trace files not present, aborting reports..."
+    ls -al ${TRACE_FOLDER}
+    exit -1
+  fi
+  create_config_json "${ELF_FOLDER}" "${LIST_OF_BINARIES}" "${TRACE_FOLDER}" "$root_repos_foolder"
+  python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/intermediate_layer.py \
+    --config-json ${CONFIG_JSON}
+
+}
+
+
+################################################################################
+# Creates LCOV coverage report.
+# GLOBALS:
+#   CODE_COVERAGE_FOLDER, workspace, INTERMEDIATE_LAYER_FILE, INFO_FILE,
+#   REPORT_FOLDER
+# ARGUMENTS:
+#   None
+# OUTPUTS:
+#   A coverage info file.
+#   LCOV HTML coverage report.
+# RETURN:
+#   0 if succeeds, non-zero on error.
+################################################################################
+create_coverage_report() {
+	python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/generate_info_file.py \
+	--workspace ${workspace} --json ${INTERMEDIATE_LAYER_FILE} --info ${INFO_FILE}
+	genhtml --branch-coverage ${INFO_FILE} --output-directory ${REPORT_FOLDER}
+}