blob: a6457f78128c736b8c061598928dd44c2f95ca2d [file] [log] [blame]
Javier Almansa Sobrinoc4ad5b02022-07-05 19:05:14 +01001#
2# SPDX-License-Identifier: BSD-3-Clause
3# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4#
5
6#[=======================================================================[.rst:
7rmm_build_unittest
8------------------
9
10.. default-domain:: unit tests
11
12.. command:: rmm_build_unittest
13
14Build a unit test group for a given target
15
16.. code:: cmake
17
18 rmm_build_unittest(NAME <name> TARGET <target> SOURCES <sources>
19 [RUN_ISOLATED_TESTS <LIST of tests to run>]
20 [LIBRARIES <libraries_to_link>]
21 [ITERATIONS <iterations>])
22
23This helper function simplifies the mechanics to setup and enable an unit test.
24
25Basics
26^^^^^^
27
28Every unit test configuration has the following parameters (defined as
29strings):
30
31- ``NAME`` Name of the test. It must match the name of the CppUtest test group.
32- ``TARGET`` Target where the tests will be linked against.
33- ``SOURCES`` Source files for the tests. This is usually a single C++ file.
34- ``RUN_ISOLATED_TESTS`` Optional parameter that specifies a list of tests
35 implemented within ``SOURCES`` to be run. When this
36 list is specified, the binary is re-spawned for each
37 test and only executed once (``ITERATIONS`` is
38 ignored). Any test not included on the list will be
39 ignored.
40 If this parameter is not used, all the tests included
41 in the group will be run automatically by CppUTest,
42 the number of times specified by ``ITERATIONS``
43- ``LIBRARIES`` Optional parameter to define libraries to link against
44 the tests.
45- ``ITERATIONS`` Optional parameter that defines how many times the test will
46 run. By default it is 1 times.
47 This option is ignored when using ``RUN_ISOLATED_TESTS``
48
49#]=======================================================================]
50
51if(RMM_UNITTESTS)
52 include("${CMAKE_SOURCE_DIR}/cmake/BuildCppUTest.cmake")
53
54 # Clean ${IMPORT_TEST_GROUPS}, used to generate test_groups.h later.
55 SET(IMPORT_TEST_GROUPS "" CACHE INTERNAL "IMPORT_TEST_GROUP List")
56
57 # Generate an empty test_groups.h, needed if we don't have unittests
58 configure_file(${CMAKE_SOURCE_DIR}/plat/host/host_test/src/test_groups.h.in
59 ${CMAKE_BINARY_DIR}/plat/host/host_test/src/test_groups.h
60 @ONLY)
61
62 # Include CTest for unittests
63 include(CTest)
64
Javier Almansa Sobrino9f3f9032022-12-08 14:53:14 +000065 set(CMAKE_CTEST_ARGUMENTS "--verbose")
66
Javier Almansa Sobrinoc4ad5b02022-07-05 19:05:14 +010067 # Custom target to run the unit tests
68 add_custom_target(run-unittests
69 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
Javier Almansa Sobrino9f3f9032022-12-08 14:53:14 +000070 COMMAND ctest "${CMAKE_CTEST_ARGUMENTS}" -C "$<CONFIG>"
Mate Toth-Palbbb816d2024-08-01 10:41:35 +020071 DEPENDS rmm_core.elf rmm_core.map
Javier Almansa Sobrinoc4ad5b02022-07-05 19:05:14 +010072 )
73endif()
74
75function(rmm_build_unittest)
76 if(RMM_UNITTESTS)
77 set(_options "")
78 set(_multi_args "SOURCES;LIBRARIES;RUN_ISOLATED_TESTS")
79 set(_single_args "NAME;TARGET;ITERATIONS")
80
81 cmake_parse_arguments(
82 arg "${_options}" "${_single_args}" "${_multi_args}" ${ARGN})
83
84 if("NAME" IN_LIST arg_KEYWORDS_MISSING_VALUES OR
85 NOT DEFINED arg_NAME)
86 message(FATAL_ERROR "Missing unit test name")
87 endif()
88
89 if("TARGET" IN_LIST arg_KEYWORDS_MISSING_VALUES OR
90 NOT DEFINED arg_TARGET)
91 message(FATAL_ERROR "Missing test target")
92 endif()
93
94 if("SOURCES" IN_LIST arg_KEYWORDS_MISSING_VALUES OR
95 NOT DEFINED arg_SOURCES)
96 message(FATAL_ERROR "Missing test sources")
97 endif()
98
99 if("ITERATIONS" IN_LIST arg_KEYWORDS_MISSING_VALUES OR
Javier Almansa Sobrinoe9621b82023-01-12 09:54:41 +0000100 NOT DEFINED arg_ITERATIONS OR
101 RMM_UNITTESTS_RUN_ONCE)
Javier Almansa Sobrinoc4ad5b02022-07-05 19:05:14 +0100102 set(arg_ITERATIONS "1")
103 endif()
104
105 target_sources("${arg_TARGET}"
106 PRIVATE ${arg_SOURCES})
107
108 target_link_libraries("${arg_TARGET}"
109 PRIVATE CppUTest ${arg_LIBRARIES})
110
111 # Add the test to the CMake test builder, so we can automate
112 # the test run process.
113 if("RUN_ISOLATED_TESTS" IN_LIST arg_KEYWORDS_MISSING_VALUES OR
114 NOT DEFINED arg_RUN_ISOLATED_TESTS)
115 # Run all tests at once
116 add_test(NAME "${arg_NAME}"
Arunachalam Ganapathy098836d2024-04-18 18:17:54 +0100117 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
Mate Toth-Palbbb816d2024-08-01 10:41:35 +0200118 COMMAND ${CMAKE_BINARY_DIR}/$<CONFIG>/rmm_core.elf
Javier Almansa Sobrinoc4ad5b02022-07-05 19:05:14 +0100119 -g${arg_NAME}
120 -r${arg_ITERATIONS})
121 else()
122 # Register a test for each test case, so each one on them can
123 # run on isolation.
124 foreach(TEST IN LISTS arg_RUN_ISOLATED_TESTS)
125 add_test(NAME "${arg_NAME}::${TEST}"
Arunachalam Ganapathy098836d2024-04-18 18:17:54 +0100126 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
Mate Toth-Palbbb816d2024-08-01 10:41:35 +0200127 COMMAND ${CMAKE_BINARY_DIR}/$<CONFIG>/rmm_core.elf
Javier Almansa Sobrinoc4ad5b02022-07-05 19:05:14 +0100128 -sg${arg_NAME}
129 -sn${TEST})
130 endforeach()
131 endif()
132
133 # Use CppUtest IMPORT_TEST_GROUP macro to explicitly include the new test
134 # group. This is needed as otherwise the linker will ignore the test code.
135 SET(IMPORT_TEST_GROUPS "${IMPORT_TEST_GROUPS} IMPORT_TEST_GROUP(${arg_NAME});"
136 CACHE INTERNAL "IMPORT_TEST_GROUP List")
137
138 # Generate the test_groups.h
139 configure_file(${CMAKE_SOURCE_DIR}/plat/host/host_test/src/test_groups.h.in
140 ${CMAKE_BINARY_DIR}/plat/host/host_test/src/test_groups.h
141 @ONLY)
142 endif()
143endfunction()