#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

# Configuration for code analysis tools.
#
# The RUNTIME_CHECK variable enables run-time checking when running
# the CTest test suite. The following tools are supported
#
# -DRUNTIME_CHECK=tsan      # turns on thread sanitizer
# -DRUNTIME_CHECK=asan      # address and undefined behavior sanitizer
# -DRUNTIME_CHECK=hwasan    # hardware-supported asan for aarch64
# -DRUNTIME_CHECK=memcheck  # valgrind memcheck (in progress)
# -DRUNTIME_CHECK=helgrind  # valgrind helgrind (in progress)
#
# This file updates the QDROUTERD_RUNNER and CMAKE_C_FLAGS
# appropriately for use when running the ctest suite.


# Valgrind configuration
#
find_program(VALGRIND_EXECUTABLE valgrind DOC "Location of the valgrind program")
set(VALGRIND_SUPPRESSIONS "${CMAKE_SOURCE_DIR}/tests/valgrind.supp" CACHE STRING "Suppressions file for valgrind")
set(VALGRIND_COMMON_ARGS "--error-exitcode=42 --xml=yes --xml-file=valgrind-%p.xml --quiet --suppressions=${VALGRIND_SUPPRESSIONS}")
mark_as_advanced(VALGRIND_EXECUTABLE VALGRIND_SUPPRESSIONS VALGRIND_COMMON_ARGS)
macro(assert_has_valgrind)
  if(NOT VALGRIND_EXECUTABLE)
    message(FATAL_ERROR "valgrind is not available")
  endif()
endmacro()

# Check for compiler's support of sanitizers.
# Currently have tested back to gcc 5.4.0 and clang 6.0.0, older
# versions may require more work
#
if((CMAKE_C_COMPILER_ID MATCHES "GNU"
      AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER 5.4
        OR CMAKE_C_COMPILER_VERSION VERSION_EQUAL 5.4))
    OR (CMAKE_C_COMPILER_ID MATCHES "Clang"
      AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER 6.0
        OR CMAKE_C_COMPILER_VERSION VERSION_EQUAL 6.0)))
  set(HAS_SANITIZERS TRUE)
endif()
macro(assert_has_sanitizers)
  if(NOT HAS_SANITIZERS)
    message(FATAL_ERROR "compiler sanitizers are not available")
  endif()
endmacro()

# Valid options for RUNTIME_CHECK
#
set(runtime_checks OFF tsan asan hwasan memcheck helgrind)

# Set RUNTIME_CHECK value and deal with the older cmake flags for
# valgrind and TSAN
#
set(RUNTIME_CHECK_DEFAULT OFF)
macro(deprecated_enable_check old new doc)
  if (${old})
    message("WARNING: option ${old} is deprecated, use -DRUNTIME_CHECK=${new} instead")
    set(RUNTIME_CHECK_DEFAULT ${new})
  endif()
  unset(${old} CACHE)
endmacro()
option(VALGRIND_XML "Write valgrind output as XML (DEPRECATED)" OFF)
deprecated_enable_check(USE_VALGRIND memcheck "Use valgrind to detect run-time problems")
deprecated_enable_check(USE_TSAN tsan "Compile with thread sanitizer (tsan)")

set(RUNTIME_CHECK ${RUNTIME_CHECK_DEFAULT} CACHE STRING "Enable runtime checks. Valid values: ${runtime_checks}")
if(CMAKE_BUILD_TYPE MATCHES "Coverage" AND RUNTIME_CHECK)
  message(FATAL_ERROR "Cannot set RUNTIME_CHECK with CMAKE_BUILD_TYPE=Coverage")
endif()

if(RUNTIME_CHECK STREQUAL "memcheck")
  assert_has_valgrind()
  message(STATUS "Runtime memory checker: valgrind memcheck")
  set(QDROUTERD_RUNNER "${VALGRIND_EXECUTABLE} --tool=memcheck --leak-check=full --show-leak-kinds=definite --errors-for-leak-kinds=definite ${VALGRIND_COMMON_ARGS}")

elseif(RUNTIME_CHECK STREQUAL "helgrind")
  assert_has_valgrind()
  message(STATUS "Runtime race checker: valgrind helgrind")
  set(QDROUTERD_RUNNER "${VALGRIND_EXECUTABLE} --tool=helgrind ${VALGRIND_COMMON_ARGS}")

elseif(RUNTIME_CHECK STREQUAL "asan" OR RUNTIME_CHECK STREQUAL "hwasan")
  assert_has_sanitizers()
  find_library(ASAN_LIBRARY NAME asan libasan)
  if(ASAN_LIBRARY-NOTFOUND)
    message(FATAL_ERROR "libasan not installed - address sanitizer not available")
  endif(ASAN_LIBRARY-NOTFOUND)
  find_library(UBSAN_LIBRARY NAME ubsan libubsan)
  if(UBSAN_LIBRARY-NOTFOUND)
    message(FATAL_ERROR "libubsan not installed - address sanitizer not available")
  endif(UBSAN_LIBRARY-NOTFOUND)
  if(RUNTIME_CHECK STREQUAL "asan")
    set(ASAN_VARIANTS "address,undefined")
  elseif(RUNTIME_CHECK STREQUAL "hwasan")
    set(ASAN_VARIANTS "hwaddress,undefined")
    # hwasan currently needs lld, otherwise binaries crash on invalid instruction
    #  https://github.com/google/sanitizers/issues/1241
    add_link_options("-fuse-ld=lld")
  endif()
  message(STATUS "Runtime memory checker: gcc/clang address sanitizers: ${ASAN_VARIANTS}")
  option(SANITIZE_3RD_PARTY "Detect leaks in 3rd party libraries used by Dispatch while running tests" OFF)
  if (SANITIZE_3RD_PARTY)
    add_custom_command(
        OUTPUT ${CMAKE_BINARY_DIR}/tests/lsan.supp
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/tests/lsan.supp ${CMAKE_BINARY_DIR}/tests/lsan.supp
        DEPENDS ${CMAKE_SOURCE_DIR}/tests/lsan.supp
        VERBATIM)
  else (SANITIZE_3RD_PARTY)
    # Append wholesale library suppressions
    #  this is necessary if target system does not have debug symbols for these libraries installed
    #  and therefore the more specific suppressions do not match
    add_custom_command(
        OUTPUT ${CMAKE_BINARY_DIR}/tests/lsan.supp
        COMMAND bash -c 'cat ${CMAKE_SOURCE_DIR}/tests/lsan.supp ${CMAKE_SOURCE_DIR}/tests/lsan_3rdparty.supp > ${CMAKE_BINARY_DIR}/tests/lsan.supp'
        DEPENDS ${CMAKE_SOURCE_DIR}/tests/lsan.supp ${CMAKE_SOURCE_DIR}/tests/lsan_3rdparty.supp)
  endif ()
  add_custom_target(generate_lsan.supp ALL
        DEPENDS ${CMAKE_BINARY_DIR}/tests/lsan.supp)
  # force QD_MEMORY_DEBUG else lsan will catch alloc_pool suppressed leaks (ok to remove this once leaks are fixed)
  set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer -fsanitize=${ASAN_VARIANTS} -DQD_MEMORY_DEBUG=1")
  # `detect_leaks=1` is set by default where it is available; better not to set it conditionally ourselves
  # https://github.com/openSUSE/systemd/blob/1270e56526cd5a3f485ae2aba975345c38860d37/docs/TESTING_WITH_SANITIZERS.md
  # TODO(DISPATCH-2148) re-enable odr violation detection when Proton linking issue in test-sender is fixed
  set(RUNTIME_ASAN_ENV_OPTIONS "detect_odr_violation=0 strict_string_checks=1 detect_stack_use_after_return=1 check_initialization_order=1 strict_init_order=1 detect_invalid_pointer_pairs=2 suppressions=${CMAKE_SOURCE_DIR}/tests/asan.supp")
  set(RUNTIME_LSAN_ENV_OPTIONS "suppressions=${CMAKE_BINARY_DIR}/tests/lsan.supp")
  set(RUNTIME_UBSAN_ENV_OPTIONS "print_stacktrace=1 print_summary=1")

elseif(RUNTIME_CHECK STREQUAL "tsan")
  assert_has_sanitizers()
  find_library(TSAN_LIBRARY NAME tsan libtsan)
  if(TSAN_LIBRARY-NOTFOUND)
    message(FATAL_ERROR "libtsan not installed - thread sanitizer not available")
  endif(TSAN_LIBRARY-NOTFOUND)
  message(STATUS "Runtime race checker: gcc/clang thread sanitizer")
  set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer -fsanitize=thread")
  set(RUNTIME_TSAN_ENV_OPTIONS "history_size=4 second_deadlock_stack=1 suppressions=${CMAKE_SOURCE_DIR}/tests/tsan.supp")

elseif(RUNTIME_CHECK)
  message(FATAL_ERROR "'RUNTIME_CHECK=${RUNTIME_CHECK}' is invalid, valid values: ${runtime_checks}")
endif()
