github.com/nilium/gitlab-runner@v12.5.0+incompatible/scripts/go_test_with_coverage_report (about) 1 #!/usr/bin/env bash 2 3 set -eo pipefail 4 5 testsDefinitions="testsdefinitions.txt" 6 7 TESTFLAGS=${TESTFLAGS:-"-cover"} 8 PARALLEL_TESTS_LIMIT=${PARALLEL_TESTS_LIMIT:-10} 9 10 CI_NODE_TOTAL=${CI_NODE_TOTAL:-1} 11 CI_NODE_INDEX=${CI_NODE_INDEX:-0} 12 13 output="regular" 14 coverMode="count" 15 16 if [[ ${TESTFLAGS} = *"-race"* ]]; then 17 output="race" 18 coverMode="atomic" 19 fi 20 21 printMessage() { 22 echo -e "\\033[1m${*}\\033[0m" 23 } 24 25 joinBy() { 26 local IFS="${1}" 27 shift 28 echo "${*}" 29 } 30 31 prepareTestCommands() { 32 local definitions 33 34 [[ ! -f ${testsDefinitions} ]] || rm ${testsDefinitions} 35 36 for pkg in ${OUR_PACKAGES}; do 37 local testIndex=0 38 local runTests=() 39 40 echo "Listing tests for ${pkg} package" 41 42 local tempFile 43 tempFile=$(mktemp) 44 local exitCode=0 45 46 go test -list "Test.*" "${pkg}" > "${tempFile}" || exitCode=1 47 48 local tests 49 tests=$(grep "^Test" "${tempFile}" || true) 50 51 rm "${tempFile}" 52 53 if [[ ${exitCode} -ne 0 ]]; then 54 exit ${exitCode} 55 fi 56 57 if [[ -z "${tests}" ]]; then 58 continue 59 fi 60 61 local counter=0 62 for test in ${tests}; do 63 counter=$((counter+1)) 64 runTests+=("${test}") 65 66 if [[ ${counter} -ge ${PARALLEL_TESTS_LIMIT} ]]; then 67 if [[ ${#runTests[@]} -gt 0 ]]; then 68 definitions=$(joinBy "|" "${runTests[@]}") 69 echo "${pkg} ${testIndex} ${definitions}" | tee -a ${testsDefinitions} 70 fi 71 72 counter=0 73 runTests=() 74 75 testIndex=$((testIndex+1)) 76 fi 77 done 78 79 if [[ ${#runTests[@]} -gt 0 ]]; then 80 definitions=$(joinBy "|" "${runTests[@]}") 81 echo "${pkg} ${testIndex} ${definitions}" | tee -a ${testsDefinitions} 82 fi 83 done 84 } 85 86 executeTestCommand() { 87 local pkg=${1} 88 local index=${2} 89 local runTestsList=${3} 90 91 local options="" 92 93 local pkgSlug 94 pkgSlug=$(echo "${pkg}" | tr "/" "-") 95 96 if [[ ${TESTFLAGS} = *"-cover"* ]]; then 97 mkdir -p ".cover" 98 mkdir -p ".testoutput" 99 100 printMessage "\\n\\n--- Starting part ${index} of go tests of '${pkg}' package with coverprofile in '${coverMode}' mode:\\n" 101 102 local profileFile=".cover/${pkgSlug}.${index}.${coverMode}.cover.txt" 103 options="-covermode=${coverMode} -coverprofile=${profileFile}" 104 else 105 echo "Starting go test" 106 fi 107 108 local testOutputFile=".testoutput/${pkgSlug}.${index}.${output}.output.txt" 109 110 local exitCode=0 111 # shellcheck disable=SC2086 112 go test ${options} ${TESTFLAGS} -v "${pkg}" -run "${runTestsList}" 2>&1 | tee "${testOutputFile}" || exitCode=1 113 114 return ${exitCode} 115 } 116 117 executeTestPart() { 118 rm -rf ".cover/" 119 rm -rf ".testoutput/" 120 121 local numberOfDefinitions 122 numberOfDefinitions=$(< "${testsDefinitions}" wc -l) 123 local executionSize 124 executionSize=$((numberOfDefinitions/CI_NODE_TOTAL+1)) 125 local nodeIndex=$((CI_NODE_INDEX-1)) 126 local executionOffset 127 executionOffset=$((nodeIndex*executionSize+1)) 128 129 printMessage "Number of definitions: ${numberOfDefinitions}" 130 printMessage "Suite size: ${CI_NODE_TOTAL}" 131 printMessage "Suite index: ${CI_NODE_INDEX}" 132 133 printMessage "Execution size: ${executionSize}" 134 printMessage "Execution offset: ${executionOffset}" 135 136 local exitCode=0 137 while read -r pkg index tests; do 138 executeTestCommand "${pkg}" "${index}" "${tests}" || exitCode=1 139 done < <(tail -n +${executionOffset} ${testsDefinitions} | head -n ${executionSize}) 140 141 exit ${exitCode} 142 } 143 144 computeCoverageReport() { 145 local reportDirectory="out/coverage" 146 local sourceFile="${reportDirectory}/coverprofile.${output}.source.txt" 147 local htmlReportFile="${reportDirectory}/coverprofile.${output}.html" 148 local textReportFile="${reportDirectory}/coverprofile.${output}.txt" 149 150 mkdir -p "${reportDirectory}" 151 152 echo "mode: ${coverMode}" > ${sourceFile} 153 grep -h -v -E -e "^mode:" -e "\/mock_[^\.]+\.go" .cover/*.${coverMode}.cover.txt >> ${sourceFile} 154 155 printMessage "Generating HTML coverage report" 156 go tool cover -o ${htmlReportFile} -html=${sourceFile} 157 printMessage "Generating TXT coverage report" 158 go tool cover -o ${textReportFile} -func=${sourceFile} 159 160 printMessage "General coverage percentage:" 161 local total 162 total=$(grep "total" "${textReportFile}" || echo "") 163 164 if [[ -n "${total}" ]]; then 165 echo "${output} ${total}" 166 fi 167 } 168 169 computeJUnitReport() { 170 local reportDirectory="out/junit" 171 local concatenatedOutputFile="/tmp/test-output.txt" 172 173 mkdir -p "${reportDirectory}" 174 175 cat .testoutput/*.${output}.output.txt > "${concatenatedOutputFile}" 176 177 go-junit-report < "${concatenatedOutputFile}" > "${reportDirectory}/report.xml" 178 } 179 180 case "$1" in 181 prepare) 182 prepareTestCommands 183 ;; 184 execute) 185 executeTestPart 186 ;; 187 coverage) 188 computeCoverageReport 189 ;; 190 junit) 191 computeJUnitReport 192 ;; 193 esac