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 |
Saul Romero | 135468b | 2023-11-28 13:55:43 +0000 | [diff] [blame] | 9 | set -x |
Saul Romero | cacda17 | 2023-03-10 14:23:41 +0000 | [diff] [blame] | 10 | source "$CI_ROOT/utils.sh" |
| 11 | ################################################################################ |
| 12 | # CI VARIABLES: |
| 13 | # workspace, warehouse, artefacts |
| 14 | # GLOBAL VARIABLES: |
| 15 | # OUTDIR, PROJECT, FALLBACK_PLUGIN_URL, FALLBACK_FILES, PLUGIN_BINARY |
| 16 | ################################################################################ |
| 17 | # Defining constants |
| 18 | GERRIT_URL=${GERRIT_URL:-https://gerrit.oss.arm.com} |
| 19 | QA_REPO_USER=jenkins_auto |
| 20 | QA_REPO_INTERNAL=${QA_REPO_INTERNAL:-https://${QA_REPO_USER}:${QA_REPO_TOKEN}@git.gitlab.arm.com/tooling/qa-tools-internal.git} |
| 21 | QA_REPO_PUBLIC=${QA_REPO_PUBLIC:-https://git.gitlab.arm.com/tooling/qa-tools.git} |
| 22 | QA_REPO_NAME=qa-tools |
| 23 | # Internal globals |
| 24 | CODE_COVERAGE_FOLDER="${OUTDIR:-$workspace}/qa-code-coverage" |
| 25 | DEBUG_FOLDER=${artefacts}/debug |
| 26 | RELEASE_FOLDER=${artefacts}/release |
| 27 | TRACE_FILE_PREFIX=covtrace |
| 28 | CONFIG_JSON=${CODE_COVERAGE_FOLDER}/configuration_file.json |
| 29 | INTERMEDIATE_LAYER_FILE=${CODE_COVERAGE_FOLDER}/intermediate_layer.json |
| 30 | INFO_FILE=${CODE_COVERAGE_FOLDER}/coverage.info |
| 31 | REPORT_FOLDER=${CODE_COVERAGE_FOLDER}/lcov |
| 32 | |
Paul Sokolovsky | d008f5d | 2023-03-24 16:10:47 +0700 | [diff] [blame] | 33 | QA_REPO=${QA_TOOLS_REPO:-$QA_REPO_PUBLIC} |
| 34 | QA_REFSPEC=${QA_TOOLS_BRANCH:-master} |
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') |
| 76 | local fallback="wget -q ${FALLBACK_PLUGIN_URL}/{$FALLBACK_FILES}" |
| 77 | echo "Warehouse=${warehouse}" |
| 78 | eval "$fallback" |
| 79 | ls -al |
| 80 | export coverage_trace_plugin="${CODE_COVERAGE_FOLDER}/${PLUGIN_BINARY}" |
| 81 | popd |
| 82 | } |
| 83 | |
| 84 | ################################################################################ |
| 85 | # Creates configuration file for intermediate layer generation |
| 86 | # GLOBALS: |
| 87 | # PROJECT, CONFIG_JSON, INTERMEDIATE_LAYER_FILE, CODE_COVERAGE_FOLDER |
| 88 | # ARGUMENTS: |
| 89 | # $1 Folder where are the elf/axf files. |
| 90 | # $2 List of elf/axf file names. |
| 91 | # $3 Path for trace files. |
| 92 | # $4 Root folder name where all the repos are cloned. |
| 93 | # OUTPUTS: |
| 94 | # Creates coverage folder and builds/downloads there the plugin binaries. |
| 95 | # RETURN: |
| 96 | # 0 if succeeds, non-zero on error. |
| 97 | ################################################################################ |
| 98 | create_config_json() { |
| 99 | set +e |
| 100 | if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] |
| 101 | then |
| 102 | cat << END |
| 103 | Missing argument at '${FUNCNAME[0]}'. |
| 104 | USAGE: |
| 105 | create_config_json ' Glob binaries' 'Glob trace files' 'Repos root folder name' |
| 106 | Example: |
| 107 | create_config_json 'bl1.elf bl2.elf' 'tf' |
| 108 | END |
| 109 | exit 1 |
| 110 | fi |
| 111 | local ELF_FOLDER=$1 |
| 112 | local dwarf_array=($2) |
| 113 | local TRACE_FOLDER=$3 |
| 114 | local root_repos_foolder="${4:-$workspace}" |
| 115 | local scm_sources="" |
| 116 | |
| 117 | # Obtaining binaries from array |
| 118 | bin_section="" |
| 119 | for index in "${!dwarf_array[@]}" |
| 120 | do |
| 121 | local elf_file="${ELF_FOLDER}/${dwarf_array[$index]}" |
| 122 | cp "$elf_file" ${CODE_COVERAGE_FOLDER}/. |
| 123 | read -r -d '' bin_section << EOM |
| 124 | ${bin_section} |
| 125 | { |
| 126 | "name": "$elf_file", |
| 127 | "traces": [ |
| 128 | "${TRACE_FOLDER}/${TRACE_FILE_PREFIX:-covtrace}-*.log" |
| 129 | ] |
| 130 | } |
| 131 | EOM |
| 132 | if [ $index -lt $((${#dwarf_array[@]} - 1)) ];then |
| 133 | bin_section="${bin_section}," |
| 134 | fi |
| 135 | done |
| 136 | |
| 137 | if [ "$PROJECT" = "SCP" ]; then |
| 138 | read -r -d '' scm_sources << EOM |
| 139 | [ |
| 140 | { |
| 141 | "type": "git", |
| 142 | "URL": "$CC_SCP_URL", |
| 143 | "COMMIT": "$CC_SCP_COMMIT", |
| 144 | "REFSPEC": "$CC_SCP_REFSPEC", |
| 145 | "LOCATION": "scp" |
| 146 | }, |
| 147 | { |
| 148 | "type": "git", |
| 149 | "URL": "$CC_CMSIS_URL", |
| 150 | "COMMIT": "$CC_CMSIS_COMMIT", |
| 151 | "REFSPEC": "$CC_CMSIS_REFSPEC", |
| 152 | "LOCATION": "scp/contrib/cmsis/git" |
| 153 | } |
| 154 | ] |
| 155 | EOM |
| 156 | elif [ "$PROJECT" = "TF-A" ]; then |
| 157 | read -r -d '' scm_sources << EOM |
| 158 | [ |
| 159 | { |
| 160 | "type": "git", |
| 161 | "URL": "$CC_TRUSTED_FIRMWARE_URL", |
| 162 | "COMMIT": "$CC_TRUSTED_FIRMWARE_COMMIT", |
| 163 | "REFSPEC": "$CC_TRUSTED_FIRMWARE_REFSPEC", |
| 164 | "LOCATION": "trusted_firmware" |
| 165 | }, |
| 166 | { |
| 167 | "type": "http", |
| 168 | "URL": "$mbedtls_archive", |
| 169 | "COMPRESSION": "xz", |
| 170 | "EXTRA_PARAMS": "--strip-components=1", |
| 171 | "LOCATION": "mbedtls" |
| 172 | } |
| 173 | ] |
| 174 | EOM |
Saul Romero | 82bcfb0 | 2023-06-27 16:24:13 +0100 | [diff] [blame] | 175 | elif [ "$PROJECT" = "HAFNIUM" ]; then |
| 176 | read -r -d '' scm_sources << EOM |
| 177 | [ |
| 178 | { |
| 179 | "type": "git", |
| 180 | "URL": "$CC_TRUSTED_FIRMWARE_URL", |
| 181 | "COMMIT": "$CC_TRUSTED_FIRMWARE_COMMIT", |
| 182 | "REFSPEC": "$CC_TRUSTED_FIRMWARE_REFSPEC", |
| 183 | "LOCATION": "trusted_firmware" |
| 184 | }, |
| 185 | { |
| 186 | "type": "git", |
| 187 | "URL": "$CC_SPM_URL", |
| 188 | "COMMIT": "$CC_SPM_COMMIT", |
| 189 | "REFSPEC": "$CC_SPM_REFSPEC", |
| 190 | "LOCATION": "spm" |
| 191 | } |
| 192 | ] |
| 193 | EOM |
Saul Romero | cacda17 | 2023-03-10 14:23:41 +0000 | [diff] [blame] | 194 | else |
| 195 | echo "SCM sources not provided for project '${PROJECT}'" |
| 196 | exit 1 |
| 197 | fi |
| 198 | local metadata="\"BUILD_CONFIG\": \"${BUILD_CONFIG}\", \"RUN_CONFIG\": \"${RUN_CONFIG}\"" |
| 199 | cat <<EOF > "${CONFIG_JSON}" |
| 200 | { |
| 201 | "configuration": |
| 202 | { |
| 203 | "remove_workspace": true, |
| 204 | "include_assembly": true |
| 205 | }, |
| 206 | "parameters": |
| 207 | { |
| 208 | "objdump": "${OBJDUMP}", |
| 209 | "readelf": "${READELF}", |
| 210 | "sources": $scm_sources, |
| 211 | "workspace": "${root_repos_foolder}", |
| 212 | "output_file": "${INTERMEDIATE_LAYER_FILE}", |
| 213 | "metadata": {$metadata} |
| 214 | }, |
| 215 | "elfs": [ |
| 216 | ${bin_section} |
| 217 | ] |
| 218 | } |
| 219 | EOF |
| 220 | |
| 221 | } |
| 222 | |
| 223 | ################################################################################ |
| 224 | # Creates intermediate layer json file with trace coverage data. |
| 225 | # |
| 226 | # Creates a configuration JSON file to be the input for the intermediate |
| 227 | # layer file creation. |
| 228 | # GLOBALS: |
| 229 | # TRACE_FILE_PREFIX, CODE_COVERAGE_FOLDER |
| 230 | # ARGUMENTS: |
| 231 | # $1 Location of trace files. |
| 232 | # $2 Location of elf/axf files. |
| 233 | # $3 List of binaries to be checked the traces. |
| 234 | # $4 Root folder name where all the repos are cloned. |
| 235 | # OUTPUTS: |
| 236 | # A configuration JSON file. |
| 237 | # An intermediate layer JSON file. |
| 238 | # RETURN: |
| 239 | # 0 if succeeds, non-zero on error. |
| 240 | ################################################################################ |
| 241 | create_intermediate_layer() { |
| 242 | local TRACE_FOLDER="$1" |
| 243 | local ELF_FOLDER="$2" |
| 244 | local LIST_OF_BINARIES="$3" |
| 245 | local root_repos_foolder="$4" |
| 246 | |
| 247 | # Copying trace files into the qa-tools executables folder |
| 248 | if [ $(ls -1 ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* 2>/dev/null | wc -l) != 0 ]; then |
| 249 | cp ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* ${CODE_COVERAGE_FOLDER}/. |
| 250 | else |
| 251 | echo "Trace files not present, aborting reports..." |
| 252 | ls -al ${TRACE_FOLDER} |
| 253 | exit -1 |
| 254 | fi |
| 255 | create_config_json "${ELF_FOLDER}" "${LIST_OF_BINARIES}" "${TRACE_FOLDER}" "$root_repos_foolder" |
| 256 | python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/intermediate_layer.py \ |
| 257 | --config-json ${CONFIG_JSON} |
| 258 | |
| 259 | } |
| 260 | |
| 261 | |
| 262 | ################################################################################ |
| 263 | # Creates LCOV coverage report. |
| 264 | # GLOBALS: |
| 265 | # CODE_COVERAGE_FOLDER, workspace, INTERMEDIATE_LAYER_FILE, INFO_FILE, |
| 266 | # REPORT_FOLDER |
| 267 | # ARGUMENTS: |
| 268 | # None |
| 269 | # OUTPUTS: |
| 270 | # A coverage info file. |
| 271 | # LCOV HTML coverage report. |
| 272 | # RETURN: |
| 273 | # 0 if succeeds, non-zero on error. |
| 274 | ################################################################################ |
| 275 | create_coverage_report() { |
| 276 | python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/generate_info_file.py \ |
| 277 | --workspace ${workspace} --json ${INTERMEDIATE_LAYER_FILE} --info ${INFO_FILE} |
| 278 | genhtml --branch-coverage ${INFO_FILE} --output-directory ${REPORT_FOLDER} |
| 279 | } |