#!/bin/bash set -e set -u DIR="$(cd "$(dirname "$0")" && pwd)" coverage_setup() { local build_dir="$1" # Zero coverage for any file, e.g. previous tests lcov -q --directory "${build_dir}" --no-external --zerocounters # Create a baseline by capturing any file used for compilation, no execution yet lcov -q --rc lcov_branch_coverage=1 --directory "${build_dir}" --base-directory="${KLEE_SRC}" --no-external --capture --initial --output-file coverage_base.info lcov -q --rc lcov_branch_coverage=1 --remove coverage_base.info 'test/*' --output-file coverage_base.info lcov -q --rc lcov_branch_coverage=1 --remove coverage_base.info 'unittests/*' --output-file coverage_base.info } coverage_update() { tags="$2" codecov_suffix=(${tags// /}) build_dir="$1" # Create report # (NOTE: "--rc lcov_branch_coverage=1" needs to be added in all calls, otherwise branch coverage gets dropped) lcov -q --rc lcov_branch_coverage=1 --directory "${build_dir}" --base-directory="${KLEE_SRC}" --no-external --capture --output-file coverage.info # Exclude uninteresting coverage goals (LLVM, googletest, and KLEE system and unit tests) lcov -q --rc lcov_branch_coverage=1 --remove coverage.info 'test/*' --output-file coverage.info lcov -q --rc lcov_branch_coverage=1 --remove coverage.info 'unittests/*' --output-file coverage.info # Combine baseline and measured coverage lcov -q --rc lcov_branch_coverage=1 -a coverage_base.info -a coverage.info -o coverage_all.info."${codecov_suffix}" # Debug info lcov -q --rc lcov_branch_coverage=1 --list coverage_all.info."${codecov_suffix}" } run_tests() { build_dir="$1" KLEE_SRC="$(cd "${DIR}"/../../ && pwd)" # TODO change to pinpoint specific directory cd "${build_dir}" # Remove klee from PATH export PATH=${PATH/":/home/klee/klee_build/bin"/} if which klee; then return 1 # should not happen fi ############################################################################### # Unit tests ############################################################################### # Prepare coverage information if COVERAGE is set if [ "${COVERAGE}" -eq 1 ]; then coverage_setup "${build_dir}" fi make unittests # Generate and upload coverage if COVERAGE is set if [ "${COVERAGE}" -eq 1 ]; then coverage_update "${build_dir}" "unittests" fi ############################################################################### # lit tests ############################################################################### if [ "${COVERAGE}" -eq 1 ]; then coverage_setup "${build_dir}" fi make systemtests || return 1 # If metaSMT is the only solver, then rerun lit tests with non-default metaSMT backends if [ "X${SOLVERS}" == "XmetaSMT" ]; then base_path="$(python3 -m site --user-base)" export PATH="$PATH:${base_path}/bin" available_metasmt_backends="btor stp z3 yices2 cvc4" for backend in $available_metasmt_backends; do if [ "X${METASMT_DEFAULT}" != "X$backend" ]; then lit -v --param klee_opts=-metasmt-backend="$backend" --param kleaver_opts=-metasmt-backend="$backend" test/ fi done fi # Generate and upload coverage if COVERAGE is set if [ "${COVERAGE}" -eq 1 ]; then coverage_update "${build_dir}" "systemtests" fi } function upload_coverage() { file="$1" tags="$2" cd /home/klee/klee_src bash <(curl -s https://codecov.io/bash) -X gcov -R /tmp/klee_src/ -f /home/klee/klee_build/coverage_all.info."${file}" -F "$tags" } function run_docker() { docker_arguments=(docker run -u root --cap-add SYS_PTRACE -t -e SOLVERS -e METASMT_DEFAULT) script_arguments=("--debug" '"/tmp/klee_build"*') if [[ "${COVERAGE}" -eq 1 ]]; then script_arguments+=("--coverage") fi if [[ "${UPLOAD_COVERAGE}" -eq 1 ]]; then docker_arguments+=($(bash <(curl -s https://codecov.io/env))) script_arguments+=("--upload-coverage") fi # Run the image that was build last with extended capabilities to allow tracing tests "${docker_arguments[@]}" "$(docker images -q | head -n 1)" /bin/bash -i -c "ulimit -s 16384; source /home/klee/.bashrc; export; /tmp/klee_src/scripts/build/run-tests.sh ${script_arguments[*]}" } main() { local NAME NAME=$(basename "${0}") local RUN_DOCKER=0 local COVERAGE=0 local UPLOAD_COVERAGE=0 local directory="" for i in "$@" ;do case $i in --debug) set -x ;; --run-docker) RUN_DOCKER=1 ;; --coverage) COVERAGE=1 ;; --upload-coverage) UPLOAD_COVERAGE=1 ;; -*) echo "${NAME}: unknown argument: $i" exit 1 ;; *) directory="${i}" ;; esac done if [[ "${RUN_DOCKER}" -eq 1 ]]; then run_docker "${COVERAGE}" return 0 fi run_tests "${directory}" # FIXME Enable separated coverage tags again if [[ "${UPLOAD_COVERAGE}" -eq 1 ]]; then upload_coverage systemtests systemtests_unittests upload_coverage unittests systemtests_unittests fi } main "$@"