| Saul Romero | cacda17 | 2023-03-10 14:23:41 +0000 | [diff] [blame] | 1 | #!/usr/bin/env bash | 
|  | 2 | # | 
|  | 3 | # Copyright (c) 2023, Arm Limited. All rights reserved. | 
|  | 4 | # | 
|  | 5 | # SPDX-License-Identifier: BSD-3-Clause | 
|  | 6 | # | 
|  | 7 |  | 
|  | 8 | # Include variables and functions to be used by these scripts | 
|  | 9 | source "$CI_ROOT/utils.sh" | 
|  | 10 | ################################################################################ | 
|  | 11 | # CI VARIABLES: | 
|  | 12 | # workspace, warehouse, artefacts | 
|  | 13 | # GLOBAL VARIABLES: | 
|  | 14 | # OUTDIR, PROJECT, FALLBACK_PLUGIN_URL, FALLBACK_FILES, PLUGIN_BINARY | 
|  | 15 | ################################################################################ | 
|  | 16 | # Defining constants | 
|  | 17 | GERRIT_URL=${GERRIT_URL:-https://gerrit.oss.arm.com} | 
|  | 18 | QA_REPO_USER=jenkins_auto | 
|  | 19 | QA_REPO_INTERNAL=${QA_REPO_INTERNAL:-https://${QA_REPO_USER}:${QA_REPO_TOKEN}@git.gitlab.arm.com/tooling/qa-tools-internal.git} | 
|  | 20 | QA_REPO_PUBLIC=${QA_REPO_PUBLIC:-https://git.gitlab.arm.com/tooling/qa-tools.git} | 
|  | 21 | QA_REPO_NAME=qa-tools | 
|  | 22 | # Internal globals | 
|  | 23 | CODE_COVERAGE_FOLDER="${OUTDIR:-$workspace}/qa-code-coverage" | 
|  | 24 | DEBUG_FOLDER=${artefacts}/debug | 
|  | 25 | RELEASE_FOLDER=${artefacts}/release | 
|  | 26 | TRACE_FILE_PREFIX=covtrace | 
|  | 27 | CONFIG_JSON=${CODE_COVERAGE_FOLDER}/configuration_file.json | 
|  | 28 | INTERMEDIATE_LAYER_FILE=${CODE_COVERAGE_FOLDER}/intermediate_layer.json | 
|  | 29 | INFO_FILE=${CODE_COVERAGE_FOLDER}/coverage.info | 
|  | 30 | REPORT_FOLDER=${CODE_COVERAGE_FOLDER}/lcov | 
|  | 31 |  | 
| Paul Sokolovsky | d008f5d | 2023-03-24 16:10:47 +0700 | [diff] [blame] | 32 | QA_REPO=${QA_TOOLS_REPO:-$QA_REPO_PUBLIC} | 
| Saul Romero | 95e8d4e | 2023-12-11 10:03:55 +0000 | [diff] [blame] | 33 | QA_REFSPEC=${QA_TOOLS_BRANCH:-$TEST_DEFINITIONS_TAG} | 
|  | 34 | QA_REFSPEC=${QA_REFSPEC:-stable} | 
| Saul Romero | cacda17 | 2023-03-10 14:23:41 +0000 | [diff] [blame] | 35 |  | 
|  | 36 |  | 
|  | 37 | ################################################################################ | 
|  | 38 | # Deploy qa-tools into the current directory | 
|  | 39 | # GLOBALS: | 
|  | 40 | #   QA_REPO, QA_REPO_NAME, QA_REFSPEC | 
|  | 41 | # ARGUMENTS: | 
|  | 42 | #   None | 
|  | 43 | # OUTPUTS: | 
|  | 44 | #   Clones the qa-tools repo from the global variables with the given | 
|  | 45 | #   commit hash. | 
|  | 46 | # RETURN: | 
|  | 47 | #   0 if succeeds, non-zero on error. | 
|  | 48 | ################################################################################ | 
|  | 49 | deploy_qa_tools() { | 
|  | 50 | git clone "${QA_REPO}" ${QA_REPO_NAME} | 
|  | 51 | cd ${QA_REPO_NAME} && git checkout "${QA_REFSPEC}" && cd .. | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 |  | 
|  | 55 | ################################################################################ | 
|  | 56 | # Builds or downloads the QA Code Coverage Tool | 
|  | 57 | # GLOBALS: | 
|  | 58 | #   CODE_COVERAGE_FOLDER, QA_REPO, QA_REPO_NAME, QA_REFSPEC, FALLBACK_PLUGIN_URL | 
|  | 59 | # ARGUMENTS: | 
|  | 60 | #   None | 
|  | 61 | # OUTPUTS: | 
|  | 62 | #   Creates coverage folder and builds/downloads there the plugin binaries. | 
|  | 63 | #   It exports the binary plugin location to coverage_trace_plugin. | 
|  | 64 | # RETURN: | 
|  | 65 | #   0 if succeeds, non-zero on error. | 
|  | 66 | ################################################################################ | 
|  | 67 | build_tool() { | 
|  | 68 | echo "Building QA Code coverage tool..." | 
|  | 69 | PLUGIN_BINARY="${FALLBACK_FILES%%,*}" # The first in the list of the binary files | 
|  | 70 | local PVLIB_HOME="warehouse/SysGen/PVModelLib/$model_version/$model_build/external" | 
|  | 71 | local LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CODE_COVERAGE_FOLDER | 
|  | 72 | mkdir -p ${CODE_COVERAGE_FOLDER} | 
|  | 73 | pushd "${CODE_COVERAGE_FOLDER}" | 
|  | 74 | deploy_qa_tools | 
|  | 75 | local cc_source=$(find . -type f -name 'coverage_trace.cc') | 
| Saul Romero | cacda17 | 2023-03-10 14:23:41 +0000 | [diff] [blame] | 76 | echo "Warehouse=${warehouse}" | 
| Leandro Belli | 9ed0762 | 2024-07-18 13:58:17 +0100 | [diff] [blame] | 77 |  | 
|  | 78 | IFS=',' read -r -a files <<< "$FALLBACK_FILES" | 
|  | 79 | for file in "${files[@]}"; do | 
|  | 80 | url="${FALLBACK_PLUGIN_URL}/${file}" \ | 
|  | 81 | saveas="${CODE_COVERAGE_FOLDER}/${file}" \ | 
|  | 82 | fetch_file | 
|  | 83 | done | 
|  | 84 |  | 
| Saul Romero | cacda17 | 2023-03-10 14:23:41 +0000 | [diff] [blame] | 85 | ls -al | 
|  | 86 | export coverage_trace_plugin="${CODE_COVERAGE_FOLDER}/${PLUGIN_BINARY}" | 
|  | 87 | popd | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | ################################################################################ | 
|  | 91 | # Creates configuration file for intermediate layer generation | 
|  | 92 | # GLOBALS: | 
|  | 93 | #   PROJECT, CONFIG_JSON, INTERMEDIATE_LAYER_FILE, CODE_COVERAGE_FOLDER | 
|  | 94 | # ARGUMENTS: | 
|  | 95 | #   $1 Folder where are the elf/axf files. | 
|  | 96 | #   $2 List of elf/axf file names. | 
|  | 97 | #   $3 Path for trace files. | 
|  | 98 | #   $4 Root folder name where all the repos are cloned. | 
|  | 99 | # OUTPUTS: | 
|  | 100 | #   Creates coverage folder and builds/downloads there the plugin binaries. | 
|  | 101 | # RETURN: | 
|  | 102 | #   0 if succeeds, non-zero on error. | 
|  | 103 | ################################################################################ | 
|  | 104 | create_config_json() { | 
|  | 105 | set +e | 
|  | 106 | if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] | 
|  | 107 | then | 
|  | 108 | cat << END | 
|  | 109 | Missing argument at '${FUNCNAME[0]}'. | 
|  | 110 | USAGE: | 
|  | 111 | create_config_json ' Glob binaries' 'Glob trace files' 'Repos root folder name' | 
|  | 112 | Example: | 
|  | 113 | create_config_json 'bl1.elf bl2.elf' 'tf' | 
|  | 114 | END | 
|  | 115 | exit 1 | 
|  | 116 | fi | 
|  | 117 | local ELF_FOLDER=$1 | 
|  | 118 | local dwarf_array=($2) | 
|  | 119 | local TRACE_FOLDER=$3 | 
|  | 120 | local root_repos_foolder="${4:-$workspace}" | 
|  | 121 | local scm_sources="" | 
|  | 122 |  | 
|  | 123 | # Obtaining binaries from array | 
|  | 124 | bin_section="" | 
|  | 125 | for index in "${!dwarf_array[@]}" | 
|  | 126 | do | 
|  | 127 | local elf_file="${ELF_FOLDER}/${dwarf_array[$index]}" | 
|  | 128 | cp "$elf_file" ${CODE_COVERAGE_FOLDER}/. | 
|  | 129 | read -r -d '' bin_section << EOM | 
|  | 130 | ${bin_section} | 
|  | 131 | { | 
|  | 132 | "name": "$elf_file", | 
|  | 133 | "traces": [ | 
|  | 134 | "${TRACE_FOLDER}/${TRACE_FILE_PREFIX:-covtrace}-*.log" | 
|  | 135 | ] | 
|  | 136 | } | 
|  | 137 | EOM | 
|  | 138 | if [ $index -lt $((${#dwarf_array[@]} - 1)) ];then | 
|  | 139 | bin_section="${bin_section}," | 
|  | 140 | fi | 
|  | 141 | done | 
|  | 142 |  | 
|  | 143 | if [ "$PROJECT" = "SCP" ]; then | 
|  | 144 | read -r -d '' scm_sources << EOM | 
|  | 145 | [ | 
|  | 146 | { | 
|  | 147 | "type": "git", | 
|  | 148 | "URL":  "$CC_SCP_URL", | 
|  | 149 | "COMMIT": "$CC_SCP_COMMIT", | 
|  | 150 | "REFSPEC": "$CC_SCP_REFSPEC", | 
|  | 151 | "LOCATION": "scp" | 
|  | 152 | }, | 
|  | 153 | { | 
|  | 154 | "type": "git", | 
|  | 155 | "URL":  "$CC_CMSIS_URL", | 
|  | 156 | "COMMIT": "$CC_CMSIS_COMMIT", | 
|  | 157 | "REFSPEC": "$CC_CMSIS_REFSPEC", | 
|  | 158 | "LOCATION": "scp/contrib/cmsis/git" | 
|  | 159 | } | 
|  | 160 | ] | 
|  | 161 | EOM | 
|  | 162 | elif [ "$PROJECT" = "TF-A" ]; then | 
|  | 163 | read -r -d '' scm_sources << EOM | 
|  | 164 | [ | 
|  | 165 | { | 
|  | 166 | "type": "git", | 
|  | 167 | "URL":  "$CC_TRUSTED_FIRMWARE_URL", | 
|  | 168 | "COMMIT": "$CC_TRUSTED_FIRMWARE_COMMIT", | 
|  | 169 | "REFSPEC": "$CC_TRUSTED_FIRMWARE_REFSPEC", | 
|  | 170 | "LOCATION": "trusted_firmware" | 
|  | 171 | }, | 
|  | 172 | { | 
|  | 173 | "type": "http", | 
|  | 174 | "URL":  "$mbedtls_archive", | 
|  | 175 | "COMPRESSION": "xz", | 
|  | 176 | "EXTRA_PARAMS": "--strip-components=1", | 
|  | 177 | "LOCATION": "mbedtls" | 
|  | 178 | } | 
|  | 179 | ] | 
|  | 180 | EOM | 
| Saul Romero | 82bcfb0 | 2023-06-27 16:24:13 +0100 | [diff] [blame] | 181 | elif [ "$PROJECT" = "HAFNIUM" ]; then | 
|  | 182 | read -r -d '' scm_sources << EOM | 
|  | 183 | [ | 
|  | 184 | { | 
|  | 185 | "type": "git", | 
|  | 186 | "URL":  "$CC_TRUSTED_FIRMWARE_URL", | 
|  | 187 | "COMMIT": "$CC_TRUSTED_FIRMWARE_COMMIT", | 
|  | 188 | "REFSPEC": "$CC_TRUSTED_FIRMWARE_REFSPEC", | 
|  | 189 | "LOCATION": "trusted_firmware" | 
|  | 190 | }, | 
|  | 191 | { | 
|  | 192 | "type": "git", | 
|  | 193 | "URL":  "$CC_SPM_URL", | 
|  | 194 | "COMMIT": "$CC_SPM_COMMIT", | 
|  | 195 | "REFSPEC": "$CC_SPM_REFSPEC", | 
|  | 196 | "LOCATION": "spm" | 
|  | 197 | } | 
|  | 198 | ] | 
|  | 199 | EOM | 
| Saul Romero | cacda17 | 2023-03-10 14:23:41 +0000 | [diff] [blame] | 200 | else | 
|  | 201 | echo "SCM sources not provided for project '${PROJECT}'" | 
|  | 202 | exit 1 | 
|  | 203 | fi | 
|  | 204 | local metadata="\"BUILD_CONFIG\": \"${BUILD_CONFIG}\", \"RUN_CONFIG\": \"${RUN_CONFIG}\"" | 
|  | 205 | cat <<EOF > "${CONFIG_JSON}" | 
|  | 206 | { | 
|  | 207 | "configuration": | 
|  | 208 | { | 
|  | 209 | "remove_workspace": true, | 
|  | 210 | "include_assembly": true | 
|  | 211 | }, | 
|  | 212 | "parameters": | 
|  | 213 | { | 
|  | 214 | "objdump": "${OBJDUMP}", | 
|  | 215 | "readelf": "${READELF}", | 
|  | 216 | "sources": $scm_sources, | 
|  | 217 | "workspace": "${root_repos_foolder}", | 
|  | 218 | "output_file": "${INTERMEDIATE_LAYER_FILE}", | 
|  | 219 | "metadata": {$metadata} | 
|  | 220 | }, | 
|  | 221 | "elfs": [ | 
|  | 222 | ${bin_section} | 
|  | 223 | ] | 
|  | 224 | } | 
|  | 225 | EOF | 
|  | 226 |  | 
|  | 227 | } | 
|  | 228 |  | 
|  | 229 | ################################################################################ | 
|  | 230 | # Creates intermediate layer json file with trace coverage data. | 
|  | 231 | # | 
|  | 232 | # Creates a configuration JSON file to be the input for the intermediate | 
|  | 233 | # layer file creation. | 
|  | 234 | # GLOBALS: | 
|  | 235 | #   TRACE_FILE_PREFIX, CODE_COVERAGE_FOLDER | 
|  | 236 | # ARGUMENTS: | 
|  | 237 | #   $1 Location of trace files. | 
|  | 238 | #   $2 Location of elf/axf files. | 
|  | 239 | #   $3 List of binaries to be checked the traces. | 
|  | 240 | #   $4 Root folder name where all the repos are cloned. | 
|  | 241 | # OUTPUTS: | 
|  | 242 | #   A configuration JSON file. | 
|  | 243 | #   An intermediate layer JSON  file. | 
|  | 244 | # RETURN: | 
|  | 245 | #   0 if succeeds, non-zero on error. | 
|  | 246 | ################################################################################ | 
|  | 247 | create_intermediate_layer() { | 
|  | 248 | local TRACE_FOLDER="$1" | 
|  | 249 | local ELF_FOLDER="$2" | 
|  | 250 | local LIST_OF_BINARIES="$3" | 
|  | 251 | local root_repos_foolder="$4" | 
|  | 252 |  | 
|  | 253 | # Copying trace files into the qa-tools executables folder | 
|  | 254 | if [ $(ls -1 ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* 2>/dev/null | wc -l) != 0 ]; then | 
|  | 255 | cp ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* ${CODE_COVERAGE_FOLDER}/. | 
|  | 256 | else | 
|  | 257 | echo "Trace files not present, aborting reports..." | 
|  | 258 | ls -al ${TRACE_FOLDER} | 
|  | 259 | exit -1 | 
|  | 260 | fi | 
|  | 261 | create_config_json "${ELF_FOLDER}" "${LIST_OF_BINARIES}" "${TRACE_FOLDER}" "$root_repos_foolder" | 
|  | 262 | python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/intermediate_layer.py \ | 
|  | 263 | --config-json ${CONFIG_JSON} | 
|  | 264 |  | 
|  | 265 | } | 
|  | 266 |  | 
|  | 267 |  | 
|  | 268 | ################################################################################ | 
|  | 269 | # Creates LCOV coverage report. | 
|  | 270 | # GLOBALS: | 
|  | 271 | #   CODE_COVERAGE_FOLDER, workspace, INTERMEDIATE_LAYER_FILE, INFO_FILE, | 
|  | 272 | #   REPORT_FOLDER | 
|  | 273 | # ARGUMENTS: | 
|  | 274 | #   None | 
|  | 275 | # OUTPUTS: | 
|  | 276 | #   A coverage info file. | 
|  | 277 | #   LCOV HTML coverage report. | 
|  | 278 | # RETURN: | 
|  | 279 | #   0 if succeeds, non-zero on error. | 
|  | 280 | ################################################################################ | 
|  | 281 | create_coverage_report() { | 
|  | 282 | python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/generate_info_file.py \ | 
|  | 283 | --workspace ${workspace} --json ${INTERMEDIATE_LAYER_FILE} --info ${INFO_FILE} | 
|  | 284 | genhtml --branch-coverage ${INFO_FILE} --output-directory ${REPORT_FOLDER} | 
|  | 285 | } |