• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13# Convenience functions for testing Panda.
14
15include(${CMAKE_CURRENT_LIST_DIR}/PandaCmakeFunctions.cmake)
16
17function(common_add_gtest)
18    if(NOT PANDA_WITH_TESTS)
19        return()
20    endif()
21
22    set(prefix ARG)
23    set(noValues CONTAINS_MAIN NO_CORES RAPIDCHECK_ON USE_CATCH2)
24    set(singleValues NAME OUTPUT_DIRECTORY TSAN_EXTRA_OPTIONS PANDA_STD_LIB ARK_BOOTCLASSPATH CUSTOM_PRERUN_ENVIRONMENT TEST_RUN_DIR)
25    set(multiValues SOURCES INCLUDE_DIRS LIBRARIES SANITIZERS DEPS_TARGETS)
26    set(TIMEOUT_SIGNAL USR1)
27
28    cmake_parse_arguments(${prefix}
29                          "${noValues}"
30                          "${singleValues}"
31                          "${multiValues}"
32                          ${ARGN})
33
34    if (ARG_RAPIDCHECK_ON AND DEFINED DONT_USE_RAPIDCHECK)
35      return()
36    endif()
37
38    if (NOT DEFINED ARG_OUTPUT_DIRECTORY)
39        message(FATAL_ERROR "OUTPUT_DIRECTORY is not defined")
40    endif()
41
42    if (NOT ARG_CONTAINS_MAIN)
43        if(ARG_USE_CATCH2)
44            set(ARG_SOURCES ${ARG_SOURCES} ${PANDA_THIRD_PARTY_SOURCES_DIR}/rapidcheck/test/main.cpp)
45        elseif (NOT CMAKE_CROSSCOMPILING)
46            set(ARG_SOURCES ${ARG_SOURCES} ${PANDA_ROOT}/tests/gtest_launcher/main.cpp)
47        endif()
48    endif()
49
50    if (ARG_RAPIDCHECK_ON)
51        panda_add_executable(${ARG_NAME} RAPIDCHECK_ON ${ARG_SOURCES})
52        set_target_properties(${ARG_NAME} PROPERTIES LINK_FLAGS "-frtti -fexceptions")
53        target_compile_definitions(${ARG_NAME} PRIVATE PANDA_RAPIDCHECK)
54        target_compile_options(${ARG_NAME} PRIVATE "-frtti" "-fexceptions" "-fPIC")
55        target_compile_definitions(${ARG_NAME} PUBLIC PANDA_RAPIDCHECK)
56    else()
57        panda_add_executable(${ARG_NAME} ${ARG_SOURCES})
58    endif()
59
60    if (ARG_USE_CATCH2)
61        target_compile_definitions(${ARG_NAME} PUBLIC PANDA_CATCH2)
62    else()
63        target_compile_definitions(${ARG_NAME} PUBLIC PANDA_GTEST)
64        if (NOT ARG_CONTAINS_MAIN AND NOT CMAKE_CROSSCOMPILING)
65            find_program(GDB_PATH gdb REQUIRED)
66            target_compile_definitions(${ARG_NAME} PUBLIC -DTIMEOUT_SIGNAL=SIG${TIMEOUT_SIGNAL} -DGDB_PATH=${GDB_PATH})
67        endif()
68    endif()
69
70    if(PANDA_CI_TESTING_MODE STREQUAL "Nightly")
71        target_compile_definitions(${ARG_NAME} PUBLIC PANDA_NIGHTLY_TEST_ON)
72    endif()
73    # By default tests are just built, running is available either via an
74    # umbrella target or via `ctest -R ...`. But one can always do something
75    # like this if really needed:
76    # add_custom_target(${ARG_NAME}_run
77    #                  COMMENT "Run ${ARG_NAME}"
78    #                  COMMAND ${CMAKE_CTEST_COMMAND}
79    #                  DEPENDS ${ARG_NAME})
80    if (ARG_USE_CATCH2)
81        foreach(include_dir ${ARG_INCLUDE_DIRS} ${PANDA_THIRD_PARTY_SOURCES_DIR}/rapidcheck/ext/catch/single_include)
82            target_include_directories(${ARG_NAME} PUBLIC ${include_dir})
83        endforeach()
84    else()
85        foreach(include_dir ${ARG_INCLUDE_DIRS} ${PANDA_THIRD_PARTY_SOURCES_DIR}/googletest/googlemock/include)
86            target_include_directories(${ARG_NAME} PUBLIC ${include_dir})
87        endforeach()
88    endif()
89
90    if (NOT ARG_USE_CATCH2)
91        if (CONTAINS_MAIN OR NOT CMAKE_CROSSCOMPILING)
92            target_link_libraries(${ARG_NAME} gtest)
93        else()
94            target_link_libraries(${ARG_NAME} gtest_main)
95        endif()
96    endif()
97
98    if (NOT (PANDA_TARGET_MOBILE OR PANDA_TARGET_OHOS))
99       target_link_libraries(${ARG_NAME} pthread)
100    endif()
101    target_link_libraries(${ARG_NAME} ${ARG_LIBRARIES})
102
103    add_dependencies(gtests_build ${ARG_NAME} ${ARG_DEPS_TARGETS})
104
105    if (ARG_RAPIDCHECK_ON)
106        target_link_libraries(${ARG_NAME} rapidcheck)
107        target_link_libraries(${ARG_NAME} rapidcheck_catch)
108        add_dependencies(${ARG_NAME} rapidcheck)
109    endif()
110
111    panda_add_sanitizers(TARGET ${ARG_NAME} SANITIZERS ${ARG_SANITIZERS})
112
113    set(prlimit_prefix "")
114    if (ARG_NO_CORES)
115        set(prlimit_prefix prlimit --core=0)
116    endif()
117    set_target_properties(${ARG_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${ARG_OUTPUT_DIRECTORY}")
118
119    set(tsan_options "")
120    if ("thread" IN_LIST PANDA_SANITIZERS_LIST)
121        if (DEFINED ENV{TSAN_OPTIONS})
122            set(tsan_options "TSAN_OPTIONS=$ENV{TSAN_OPTIONS},${ARG_TSAN_EXTRA_OPTIONS}")
123        endif()
124    endif()
125
126    # Yes, this is hardcoded. No, do not ask for an option. Go and fix your tests.
127    if (PANDA_CI_TESTING_MODE STREQUAL "Nightly")
128        set(timeout_prefix timeout --preserve-status --signal=${TIMEOUT_SIGNAL} --kill-after=30s 40m)
129    else ()
130        set(timeout_prefix timeout --preserve-status --signal=${TIMEOUT_SIGNAL} --kill-after=30s 20m)
131    endif()
132
133    if (ARG_RAPIDCHECK_ON)
134        add_custom_target(${ARG_NAME}_rapidcheck_tests
135                          COMMAND ${tsan_options} ${prlimit_prefix} ${timeout_prefix}
136                                  ${PANDA_RUN_PREFIX} "${ARG_OUTPUT_DIRECTORY}/${ARG_NAME}"
137                          DEPENDS ${ARG_NAME} ${ARG_DEPS_TARGETS}
138        )
139        add_dependencies(gtests ${ARG_NAME}_rapidcheck_tests)
140    else()
141        set(PANDA_STD_LIB "")
142        if (DEFINED ARG_PANDA_STD_LIB)
143            set(PANDA_STD_LIB "PANDA_STD_LIB=${ARG_PANDA_STD_LIB}")
144        endif()
145
146        set(ARK_BOOTCLASSPATH "")
147        if (DEFINED ARG_ARK_BOOTCLASSPATH)
148            set(ARK_BOOTCLASSPATH "ARK_BOOTCLASSPATH=${ARG_ARK_BOOTCLASSPATH}")
149        endif()
150
151        set(CUSTOM_PRERUN_ENVIRONMENT "")
152        if(DEFINED ARG_CUSTOM_PRERUN_ENVIRONMENT)
153            set(CUSTOM_PRERUN_ENVIRONMENT ${ARG_CUSTOM_PRERUN_ENVIRONMENT})
154        endif()
155
156        set(TEST_RUN_DIR ${CMAKE_CURRENT_BINARY_DIR})
157        if(DEFINED ARG_TEST_RUN_DIR)
158            set(TEST_RUN_DIR ${ARG_TEST_RUN_DIR})
159        endif()
160
161        set(output_file "${ARG_OUTPUT_DIRECTORY}/${ARG_NAME}_gtest_output.txt")
162        add_custom_target(${ARG_NAME}_gtests
163                          COMMAND ${PANDA_STD_LIB} ${ARK_BOOTCLASSPATH} ${CUSTOM_PRERUN_ENVIRONMENT}
164                                  ${tsan_options} ${prlimit_prefix} ${timeout_prefix}
165                                  ${PANDA_RUN_PREFIX} "${ARG_OUTPUT_DIRECTORY}/${ARG_NAME}"
166                                  --gtest_shuffle --gtest_death_test_style=threadsafe
167                                  --gtest_brief=0
168                                  >${output_file} 2>&1
169                                  || (cat ${output_file} && false)
170                          DEPENDS ${ARG_NAME} ${ARG_DEPS_TARGETS}
171                          WORKING_DIRECTORY ${TEST_RUN_DIR}
172       )
173       add_dependencies(gtests ${ARG_NAME}_gtests)
174    endif()
175endfunction()
176