run-ci 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #! /bin/bash
  2. #
  3. # © 2018 Ansgar Burchardt <ansgar@debian.org>
  4. # © 2020 Ivo De Decker <ivodd@debian.org>
  5. # License: GPL-2+
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  19. # start/end collapsible sections in GitLab's CI
  20. # Reference: https://docs.gitlab.com/ee/ci/pipelines/#custom-collapsible-sections
  21. section_start() {
  22. local name header
  23. name="${1:?}"
  24. header="${2:-}"
  25. echo -e "section_start:$(date +%s):${name}\r\e[0K\e[36;1m${header}\e[0;m"
  26. }
  27. section_end() {
  28. local name
  29. name="${1:?}"
  30. echo -e "section_end:$(date +%s):${name}\r\e[0K"
  31. }
  32. run_apt-get() {
  33. if [ "$UID" = 0 ]
  34. then
  35. apt-get $@
  36. else
  37. echo not running apt-get $@
  38. fi
  39. }
  40. # salsa ci total number of parallel jobs
  41. if [[ ! -v CI_NODE_TOTAL ]]; then
  42. export CI_NODE_TOTAL=1
  43. fi
  44. # salsa ci number for this specific job (from 1 to $CI_NODE_TOTAL)
  45. if [[ ! -v CI_NODE_INDEX ]]; then
  46. export CI_NODE_INDEX=1
  47. fi
  48. if [[ ! -v CI ]]; then
  49. CI=false
  50. fi
  51. MY_CI_COUNTER=0
  52. run_this_test() {
  53. MY_MODULO=$(( $MY_CI_COUNTER % $CI_NODE_TOTAL + 1 ))
  54. echo "run_this_test: $MY_MODULO $MY_CI_COUNTER"
  55. MY_CI_COUNTER=$(( MY_CI_COUNTER + 1 ))
  56. [[ $MY_MODULO = $CI_NODE_INDEX ]]
  57. }
  58. if [ "x$1" = "x--with-coverage" ]; then
  59. RUN_COVERAGE=y
  60. PYTEST_COV_OPTIONS=" --cov-branch --cov --cov-report= "
  61. shift
  62. else
  63. RUN_COVERAGE=
  64. PYTEST_COV_OPTIONS=""
  65. fi
  66. export RUN_COVERAGE
  67. copy_coverage_data() {
  68. t="$1"
  69. if [ "$RUN_COVERAGE" = "y" ]; then
  70. TESTNAME=${t##*/}
  71. DESTDIR=${DAK_CI_OUTPUT_DIR}/coveragedata/data_${TESTNAME}
  72. echo copy coverage data for $TESTNAME to $DESTDIR
  73. mkdir -p $DESTDIR
  74. [ -e .coverage ] && cp .coverage $DESTDIR/.coverage.data.${TESTNAME/}
  75. cp .coverage.* $DESTDIR || true
  76. fi
  77. }
  78. set -eu
  79. if [ ! -f dak/dak.py ]; then
  80. echo >&2 "E: run-ci must be invoked in the root directory of dak"
  81. exit 1
  82. fi
  83. export BASEDIR="$(cd $(dirname "${BASH_SOURCE}")/..; pwd)"
  84. export DAK_ROOT=$BASEDIR
  85. export DAK_CI_OUTPUT_DIR=${BASEDIR}/output
  86. mkdir -p ${DAK_CI_OUTPUT_DIR}
  87. LOGFILE=${DAK_CI_OUTPUT_DIR}/log_job${CI_NODE_INDEX}.txt
  88. section_start "install_dep[collapsed=true]" "Install Dependencies"
  89. echo `date` installing packages | tee -a $LOGFILE
  90. run_apt-get update
  91. run_apt-get install -y build-essential
  92. run_apt-get build-dep -y .
  93. if [ "${CI_JOB_IMAGE:-}" = "debian:buster" ]; then
  94. patch -d /usr/bin -p1 < debian/ci-buster-pg-virtualenv.patch || :
  95. fi
  96. section_end install_dep
  97. mkdir -p $DAK_ROOT/test-gnupghome
  98. export GNUPGHOME=${DAK_ROOT}/test-gnupghome
  99. cd ${DAK_ROOT}
  100. section_start unit_tests "Unit Tests"
  101. if run_this_test; then
  102. echo `date` running unit tests | tee -a $LOGFILE
  103. py.test-3 -v ${PYTEST_COV_OPTIONS} daklib tests
  104. copy_coverage_data "unit_tests"
  105. echo `date` unit tests done | tee -a $LOGFILE
  106. else
  107. echo "not running unit tests in this job ($CI_NODE_INDEX/$CI_NODE_TOTAL)"
  108. fi
  109. section_end unit_tests
  110. section_start "fixtures[collapsed=true]" "Creating Fixtures"
  111. echo `date` making fixtures | tee -a $LOGFILE
  112. make -C tests/fixtures/packages
  113. echo `date` making fixtures done | tee -a $LOGFILE
  114. section_end fixtures
  115. section_start integration_tests "Integration Tests"
  116. TESTS="${DAK_ROOT}/integration-tests/tests/[0-9]*[^~] \
  117. ${DAK_ROOT}/tests/run-dbtests"
  118. for t in $TESTS
  119. do
  120. if run_this_test; then
  121. section_start "${t}" "Running test ${t}"
  122. echo `date` running $t | tee -a $LOGFILE
  123. ./integration-tests/run-tests $t
  124. copy_coverage_data $t
  125. echo `date` running $t done | tee -a $LOGFILE
  126. section_end "${t}"
  127. else
  128. echo "not running test $t in this job ($CI_NODE_INDEX/$CI_NODE_TOTAL)"
  129. fi
  130. done
  131. section_end integration_tests
  132. # On the gitlab CI, there is a separate job for generating the
  133. # coverage report. That provides the total coverage. Unfortunately,
  134. # these partial coverage reports causes Gitlab to compute an average
  135. # of all totals, which gives a weird coverage percentage that does not
  136. # reflect the true coverage rating.
  137. if [ "$RUN_COVERAGE" = "y" ] && [ "${CI}" = "false" ]; then
  138. section_start coverage "Coverage Report"
  139. python3-coverage combine --append
  140. python3-coverage report -m
  141. echo
  142. python3-coverage html -d ${BASEDIR}/coverage
  143. python3-coverage annotate -d ${BASEDIR}/coverage/annotated
  144. section_end coverage
  145. fi
  146. echo `date` all done | tee -a $LOGFILE