diff --git a/.bazelrc b/.bazelrc index e138b84b9..d2f644b34 100644 --- a/.bazelrc +++ b/.bazelrc @@ -4,10 +4,6 @@ build --define=grpc_no_ares=true build --cxxopt='-std=c++17' -# Required by envoy and grpc-echo -build --incompatible_disable_deprecated_attr_params=false -query --incompatible_disable_deprecated_attr_params=false - # Compile a Position Independent Executable # Ref: github.com/envoyproxy/envoy#8792 build --copt=-fPIC @@ -100,8 +96,9 @@ build:asan-fuzzer --test_env=UBSAN_OPTIONS=print_stacktrace=1 # Coverage coverage --config=coverage +coverage --build_tests_only build:coverage --action_env=BAZEL_USE_LLVM_NATIVE_COVERAGE=1 -build:coverage --action_env=GCOV=llvm-profdata +build:coverage --action_env=GCOV=llvm-profdata-10 build:coverage --action_env=CC=clang-10 build:coverage --action_env=CXX=clang++-10 build:coverage --copt=-DNDEBUG diff --git a/.bazelversion b/.bazelversion index 4a36342fc..47b322c97 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -3.0.0 +3.4.1 diff --git a/DEVELOPER.md b/DEVELOPER.md index 87d49cc3c..de37bdb3b 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -91,4 +91,4 @@ make integration-test ``` make test-envoy-asan/tsan make integration-test-asan/tsan -``` +``` \ No newline at end of file diff --git a/WORKSPACE b/WORKSPACE index 170c4850c..b4ecbaacd 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -90,9 +90,9 @@ load("//bazel:repositories.bzl", "service_control_repositories") service_control_repositories() -load("@io_bazel_rules_python//python:pip.bzl", "pip_import") +load("@io_bazel_rules_python//python:pip.bzl", "pip_install") -pip_import( +pip_install( name = "grpc_python_dependencies", requirements = "@com_github_grpc_grpc//:requirements.bazel.txt", ) diff --git a/bazel/bazel_rules_python.bzl b/bazel/bazel_rules_python.bzl index 67aec0936..deab62645 100644 --- a/bazel/bazel_rules_python.bzl +++ b/bazel/bazel_rules_python.bzl @@ -12,15 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -load( - "@bazel_tools//tools/build_defs/repo:git.bzl", - "git_repository", -) +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") def bazel_rules_python_repositories(load_repo = True): if load_repo: - git_repository( + http_archive( name = "io_bazel_rules_python", - commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", - remote = "https://github.com/bazelbuild/rules_python.git", + url = "https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz", + sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0", ) diff --git a/docker/Dockerfile-prow-env b/docker/Dockerfile-prow-env index fe98a3f1e..d14f4f89e 100644 --- a/docker/Dockerfile-prow-env +++ b/docker/Dockerfile-prow-env @@ -41,13 +41,6 @@ RUN INSTALLER="bazel-0.28.1-installer-linux-x86_64.sh"; \ RUN wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/download/v0.0.8/bazelisk-linux-amd64 && \ chmod +x /usr/local/bin/bazel -# install clang-8 and associated tools (old envoy) -RUN wget -O- https://apt.llvm.org/llvm-snapshot.gpg.key| apt-key add - && \ - echo "deb https://apt.llvm.org/buster/ llvm-toolchain-buster-8 main" >> /etc/apt/sources.list && \ - apt-get update && \ - apt-get install -y llvm-8 llvm-8-dev libclang-8-dev clang-8 \ - lld lld-8 clang-tools-7 clang-format-7 libc++-dev xz-utils - # install clang-10 and associated tools (new envoy) RUN wget -O- https://apt.llvm.org/llvm-snapshot.gpg.key| apt-key add - && \ echo "deb https://apt.llvm.org/buster/ llvm-toolchain-buster-10 main" >> /etc/apt/sources.list && \ @@ -55,10 +48,14 @@ RUN wget -O- https://apt.llvm.org/llvm-snapshot.gpg.key| apt-key add - && \ apt-get install -y llvm-10 llvm-10-dev libclang-10-dev clang-10 \ lld-10 clang-tools-10 clang-format-10 libc++-dev xz-utils +# Install lcov-1.14 (apt only has 1.13 for buster) +RUN wget https://github.com/linux-test-project/lcov/releases/download/v1.14/lcov-1.14.tar.gz && \ + tar -xvzf lcov-1.14.tar.gz && \ + make -C lcov-1.14 install + ENV CC clang-10 ENV CXX clang++-10 - # install golang and setup Go standard envs ENV GOPATH /go ENV PATH /usr/local/go/bin:$PATH diff --git a/prow/gcpproxy-coverage.sh b/prow/gcpproxy-coverage.sh index 98423b46b..f5a9f1899 100755 --- a/prow/gcpproxy-coverage.sh +++ b/prow/gcpproxy-coverage.sh @@ -19,51 +19,37 @@ # Fail on any error. set -eo pipefail -gcloud config set core/project cloudesf-testing -gcloud auth activate-service-account \ - --key-file="${GOOGLE_APPLICATION_CREDENTIALS}" - ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" . ${ROOT}/scripts/all-utilities.sh || { echo 'Cannot load Bash utilities'; exit 1; } - -# https://github.com/bazelbuild/bazel/issues/7247 -# TODO(nareddyt): See if there are workarounds. -case "${JOB_TYPE}" in - "presubmit") - echo "Coverage job is disabled for presubmits due to a bug with remote caching." - echo "Otherwise, presubmits would take too long to complete." - echo "If you need to see coverage for your commit, please run this script locally." - echo "Coverage job will still run periodically on the master branch." - exit 0 - ;; -esac -#echo '=======================================================' -#echo '===================== Setup Cache =====================' -#echo '=======================================================' -#try_setup_bazel_remote_cache "${PROW_JOB_ID}" "${IMAGE}" "${ROOT}" "${JOB_TYPE}-coverage" - -echo '=======================================================' -echo '==================== C++ Coverage =====================' -echo '=======================================================' -. ${ROOT}/third_party/tools/coverage/cpp_unit.sh - -echo '=======================================================' -echo '=================== Upload Coverage ===================' -echo '=======================================================' +PUBLIC_DIRECTORY="" # Note that JOB_TYPE is set by Prow. # https://github.com/kubernetes/test-infra/blob/master/prow/jobs.md#job-environment-variables -PUBLIC_DIRECTORY="" case "${JOB_TYPE}" in "presubmit") # Store in directory with the SHA for each presubmit run. PUBLIC_DIRECTORY=$(get_tag_name) + + gcloud config set core/project cloudesf-testing + gcloud auth activate-service-account \ + --key-file="${GOOGLE_APPLICATION_CREDENTIALS}" + + # https://github.com/bazelbuild/bazel/issues/7247 + echo "Coverage job is disabled for presubmits due to a bug with remote caching." + echo "Otherwise, presubmits would take too long to complete." + echo "If you need to see coverage for your commit, please run this script locally." + echo "Coverage job will still run periodically on the master branch." + # exit 0 ;; "periodic") # Overwrite global directory with latest coverage for all continuous runs. PUBLIC_DIRECTORY="latest" + + gcloud config set core/project cloudesf-testing + gcloud auth activate-service-account \ + --key-file="${GOOGLE_APPLICATION_CREDENTIALS}" ;; *) # If running locally, just upload to special-case folder. @@ -72,6 +58,15 @@ case "${JOB_TYPE}" in ;; esac +echo '=======================================================' +echo '==================== C++ Coverage =====================' +echo '=======================================================' +. ${ROOT}/third_party/tools/coverage/cpp_unit.sh + +echo '=======================================================' +echo '=================== Upload Coverage ===================' +echo '=======================================================' + # Upload folder. gsutil -m rsync -r -d "${ROOT}/generated" "gs://esp-v2-coverage/${PUBLIC_DIRECTORY}" @@ -82,4 +77,4 @@ echo '=======================================================' echo '==================== View Coverage ====================' echo '=======================================================' echo "C++ Unit test coverage is viewable at the URL below" -echo "https://storage.googleapis.com/esp-v2-coverage/${PUBLIC_DIRECTORY}/third_party/tools/coverage/coverage_tests/index.html" +echo "https://storage.googleapis.com/esp-v2-coverage/${PUBLIC_DIRECTORY}/coverage/index.html" diff --git a/third_party/tools/coverage/README.md b/third_party/tools/coverage/README.md index 2270b99a3..df6b78790 100644 --- a/third_party/tools/coverage/README.md +++ b/third_party/tools/coverage/README.md @@ -1,19 +1,9 @@ The code in this directory is copied from Envoy's [tools/](https://github.com/envoyproxy/envoy/tree/master/tools) directory. -### C++ Fuzz Test Coverage - -Written by asraa@ - -Example usage: - -```shell script -./third_party/tools/coverage/cpp_fuzz.sh //src/envoy/utils:json_struct_fuzz_test -``` - ### C++ Unit Test Coverage -Example usage: +Run coverage tests and upload report to GCS with this script: ```shell script -./third_party/tools/coverage/cpp_unit.sh +./prow/gcpproxy-coverage.sh ``` \ No newline at end of file diff --git a/third_party/tools/coverage/cpp_fuzz.sh b/third_party/tools/coverage/cpp_fuzz.sh deleted file mode 100755 index d63975d15..000000000 --- a/third_party/tools/coverage/cpp_fuzz.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -set -e - -[[ -z "${SRCDIR}" ]] && SRCDIR="${PWD}" - -echo "Starting coverage/cpp_fuzz.sh..." -echo " PWD=$(pwd)" -echo " SRCDIR=${SRCDIR}" - -echo $(bazel --version) -# This is the fuzz target that will be run to generate coverage data. -if [[ $# -gt 0 ]]; then - TARGET=$* -else - TARGET=//src/envoy/utils:json_struct_fuzz_test -fi - -TARGET_PATH=${TARGET:2} -TARGET_PATH=${TARGET_PATH//://} -echo ${TARGET_PATH} - -# Create a temp directory for the corpus the fuzzer will generate -CORPUS_DIR=$(mktemp -d) - -# Get the original corpus directory for the fuzz target. -# Assumes all fuzz targets follow the same directory layouts. -ORIGINAL_CORPUS=$(bazel query "labels(srcs, ${TARGET}_corpus_tar)" | head -1) -ORIGINAL_CORPUS=${ORIGINAL_CORPUS/://} -ORIGINAL_CORPUS="${ORIGINAL_CORPUS%"_corpus"}/" -echo ${ORIGINAL_CORPUS} - -echo "RUNNING FUZZER" -# Run the fuzzer for one minute: -bazel run --config=asan-fuzzer ${TARGET}_with_libfuzzer -- -max_total_time=60 $(pwd)${ORIGINAL_CORPUS:1} - -SCRIPT_DIR="$(realpath "$(dirname "$0")")" -. "${SCRIPT_DIR}"/gen_coverage.sh \ No newline at end of file diff --git a/third_party/tools/coverage/cpp_unit.sh b/third_party/tools/coverage/cpp_unit.sh index 30ef6bca4..76a19f3e7 100755 --- a/third_party/tools/coverage/cpp_unit.sh +++ b/third_party/tools/coverage/cpp_unit.sh @@ -1,13 +1,11 @@ #!/bin/bash - -set -e +set -x # Copied from here # https://github.com/envoyproxy/envoy/blob/master/test/run_envoy_bazel_coverage.sh [[ -z "${SRCDIR}" ]] && SRCDIR="${PWD}" -[[ -z "${VALIDATE_COVERAGE}" ]] && VALIDATE_COVERAGE=true -[[ -z "${FUZZ_COVERAGE}" ]] && FUZZ_COVERAGE=false +[[ -z "${VALIDATE_COVERAGE}" ]] && VALIDATE_COVERAGE=false echo "Starting run_envoy_bazel_coverage.sh..." echo " PWD=$(pwd)" @@ -22,16 +20,10 @@ if [[ $# -gt 0 ]]; then elif [[ -n "${COVERAGE_TARGET}" ]]; then COVERAGE_TARGETS=${COVERAGE_TARGET} else - # For fuzz builds, this overrides to just fuzz targets. - COVERAGE_TARGETS=//src/... && [[ ${FUZZ_COVERAGE} == "true" ]] && - COVERAGE_TARGETS="$(bazel query 'attr("tags", "fuzzer", //src/...)')" + COVERAGE_TARGETS=//src/... fi -if [[ "${FUZZ_COVERAGE}" == "true" ]]; then - BAZEL_BUILD_OPTIONS+=" --config=fuzz-coverage --test_tag_filters=-nocoverage" -else - BAZEL_BUILD_OPTIONS+=" --config=test-coverage --test_tag_filters=-nocoverage,-fuzz_target" -fi +BAZEL_BUILD_OPTIONS+=" --config=test-coverage --test_tag_filters=-nocoverage,-fuzz_target" bazel coverage ${BAZEL_BUILD_OPTIONS} ${COVERAGE_TARGETS} @@ -49,11 +41,7 @@ COVERAGE_VALUE=${COVERAGE_VALUE%?} [[ -z "${ENVOY_COVERAGE_DIR}" ]] || rsync -av "${COVERAGE_DIR}"/ "${ENVOY_COVERAGE_DIR}" if [[ "$VALIDATE_COVERAGE" == "true" ]]; then - if [[ "${FUZZ_COVERAGE}" == "true" ]]; then - COVERAGE_THRESHOLD=27.0 - else - COVERAGE_THRESHOLD=97.0 - fi + COVERAGE_THRESHOLD=97.0 COVERAGE_FAILED=$(echo "${COVERAGE_VALUE}<${COVERAGE_THRESHOLD}" | bc) if test ${COVERAGE_FAILED} -eq 1; then echo Code coverage ${COVERAGE_VALUE} is lower than limit of ${COVERAGE_THRESHOLD} diff --git a/third_party/tools/coverage/gen_coverage.sh b/third_party/tools/coverage/gen_coverage.sh deleted file mode 100755 index 9cfb4bf25..000000000 --- a/third_party/tools/coverage/gen_coverage.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -set -e - -# Using GTEST_SHUFFLE here to workaround https://github.com/envoyproxy/envoy/issues/10108 -BAZEL_USE_LLVM_NATIVE_COVERAGE=1 GCOV=llvm-profdata-8 CC=clang-8 CXX=clang++-8 \ - bazel coverage ${BAZEL_BUILD_OPTIONS} \ - -c fastbuild --copt=-DNDEBUG --instrumentation_filter="//src/..." \ - --test_timeout=2000 --cxxopt="-DENVOY_CONFIG_COVERAGE=1" --test_output=errors \ - --test_arg="--log-path /dev/null" --test_arg="-l trace" --test_env=HEAPCHECK= \ - --test_env=GTEST_SHUFFLE=1 --flaky_test_attempts=5 ${TARGET} - -COVERAGE_DIR="${SRCDIR}"/generated/${TARGET_PATH} -mkdir -p "${COVERAGE_DIR}" - -COVERAGE_IGNORE_REGEX="(/external/|pb\.(validate\.)?(h|cc)|/chromium_url/|/test/|/tmp|/source/extensions/quic_listeners/quiche/)" -COVERAGE_BINARY="bazel-bin/${TARGET_PATH}" -COVERAGE_DATA="${COVERAGE_DIR}/coverage.dat" - -echo "Merging coverage data..." -llvm-profdata-8 merge -sparse -o ${COVERAGE_DATA} $(find -L bazel-out/k8-fastbuild/testlogs/${TARGET_PATH} -name coverage.dat) - -echo "Generating report..." -llvm-cov-8 show "${COVERAGE_BINARY}" -instr-profile="${COVERAGE_DATA}" -Xdemangler=c++filt \ - -ignore-filename-regex="${COVERAGE_IGNORE_REGEX}" -output-dir=${COVERAGE_DIR} -format=html -sed -i -e 's|>proc/self/cwd/|>|g' "${COVERAGE_DIR}/index.html" -sed -i -e 's|>bazel-out/[^/]*/bin/\([^/]*\)/[^<]*/_virtual_includes/[^/]*|>\1|g' "${COVERAGE_DIR}/index.html" - -COVERAGE_VALUE=$(llvm-cov-8 export "${COVERAGE_BINARY}" -instr-profile="${COVERAGE_DATA}" \ - -ignore-filename-regex="${COVERAGE_IGNORE_REGEX}" -summary-only | \ - python3 -c "import sys, json; print(json.load(sys.stdin)['data'][0]['totals']['lines']['percent'])") -echo "Covered lines percentage: ${COVERAGE_VALUE}" - -echo "HTML coverage report is in ${COVERAGE_DIR}/index.html" \ No newline at end of file