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