blob: 7557796d3de0195c37163eb72c88bd9d233764f6 [file] [log] [blame]
Jianliang Shen5f7b1b72022-05-03 19:01:27 +08001#################################
2Adding TF-M Regression Test Suite
3#################################
4
5.. contents:: Table of Contents
6
7*************************************
8Introduction of TF-M regression tests
9*************************************
10
11TF-M regression tests test whether changes to TF-M code work as expected.
12A new regression test can consist of following 3 components:
13
141. ``test suite``: A series of tests of a certain function.
152. ``test case``: A specific test instance in test suites.
163. ``test service or partition``: Optional secure services or partitions to
17 support related test suites.
18
19Source structure
20================
21
22+---------------------------------------+---------------------------------------------------------------+
23| Folder name | Description |
24+=======================================+===============================================================+
25| test/bl1 | TF-M bl1 test suites source code. |
26+---------------------------------------+---------------------------------------------------------------+
27| test/bl2 | TF-M bL2 test suites source code. |
28+---------------------------------------+---------------------------------------------------------------+
29| test/config | The CMAKE test configurations files. |
30+---------------------------------------+---------------------------------------------------------------+
31| test/framework | Source code for test framework code, managing test suites. |
32+---------------------------------------+---------------------------------------------------------------+
33| test/secure_fw/suites | Test suites divided into subdirectories. |
34+---------------------------------------+---------------------------------------------------------------+
35| test/secure_fw/suites/<suite>/service | Test service divided into corresponding suite subdirectories. |
36+---------------------------------------+---------------------------------------------------------------+
37| test/secure_fw/common_test_services | Common test services. |
38+---------------------------------------+---------------------------------------------------------------+
39
40***********************
41Adding a new test suite
42***********************
43
44This section introduces how to add a new test suite and control its compilation
David Hu945d22d2023-11-30 17:49:34 +080045with a test configuration in ``tests_reg/test`` repository.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080046
47Source code
48===========
49
50The test suite example subdirectory named ``<test_name>`` is located under the
David Hu945d22d2023-11-30 17:49:34 +080051path ``tests_reg/test/secure_fw/suites``. If the new test suite includes both
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080052non-secure and secure parts, the source code shall be divided shared code and
53specific code. An example test suite folder can be organized as the figure
54below.
55
56.. code-block:: bash
57
58 .
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080059 ├── <test_name>_tests_common.c
60 ├── non_secure
David Hu945d22d2023-11-30 17:49:34 +080061 | ├── CMakeLists.txt
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080062 ├── <test_name>_ns_interface_testsuite.c
63 └── <test_name>_ns_tests.h
64 └── secure
David Hu945d22d2023-11-30 17:49:34 +080065 ├── CMakeLists.txt
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080066 ├── <test_name>_s_interface_testsuite.c
67 └── <test_name>_s_tests.h
68
69Creating test configurations
70============================
71
72A test configuration controls whether one or multiple test suites are enabled.
Elena Uziunaite99438172023-11-13 14:39:29 +000073The doc :doc:`TF-M Build Instructions <TF-M:building/tfm_build_instruction>`.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080074shows some test configurations which are already supported in current TF-M.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080075
76Developers shall assign corresponding test configurations to control the test
77suites.
78
79Naming test configurations
80--------------------------
81
82The test configurations of example test suites are ``TEST_NS_<TEST_NAME>``
83in non-secure and ``TEST_S_<TEST_NAME>`` in secure.
84
85.. Note::
86 The test configurations must be named with the prefixes ``TEST_S_`` and
87 ``TEST_NS_``, for secure regression tests and non-secure regression tests
David Hu945d22d2023-11-30 17:49:34 +080088 respectively. Otherwise, tests_reg/test build system may not recognize it.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080089
90Setting test configurations
91---------------------------
92
David Hu945d22d2023-11-30 17:49:34 +080093When the test configurations have dependencies, the default value need to be set.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080094The setting is performed in following four steps.
95
96#. Command line input: The configuration can be enabled or disabled by the
97 command ``-DTEST_NS_<TEST_NAME>=ON/OFF -DTEST_S_<TEST_NAME>=ON/OFF``, and
98 the value cannot be changed throughout the whole compilation of TF-M tests.
99
David Hu945d22d2023-11-30 17:49:34 +0800100#. ``tests_reg/test/config/config.cmake``: The test configurations shall be
101 ``OFF`` if its dependencies are not supported. The dependencies are probably from:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800102
103 #. TF-M partitions configurations like ``TFM_PARTITION_CRYPTO``,
104 ``TFM_PARTITION_INITIAL_ATTESTATION``, etc.
Summer Qinab4e42d2022-10-09 17:36:39 +0800105 #. TF-M build mode configuration like ``CONFIG_TFM_SPM_BACKEND``.
Mark Horvath2f072582022-09-09 16:15:30 +0200106 #. TF-M other configurations like ``TFM_PARTITION_FIRMWARE_UPDATE``, etc.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800107
David Hu945d22d2023-11-30 17:49:34 +0800108#. ``tests_reg/test/config/default_ns_test_config.cmake`` or
109 ``tests_reg/test/config/default_s_test_config.cmake``: It is required to give
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800110 the default value of the new test configuration in these two files when
111 ``TEST_NS`` or ``TEST_S`` is ON. The recommended value is ON unless the
112 single test's code or data size is very large.
113
David Hu945d22d2023-11-30 17:49:34 +0800114#. ``tests_reg/test/config/default_test_config.cmake``: It is required to give the
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800115 default value of the new test configuration in the file when both
116 ``TEST_NS`` and ``TEST_S`` are OFF. The default value must be OFF.
117
118.. Note::
119 The test configurations must be set as CACHE value in CMAKE files. The CACHE
120 set cannot replace the value from command line, see
121 `Set Cache Entry <https://cmake.org/cmake/help/latest/command/set.html#set-cache-entry>`_.
122
123Checking test configurations
124----------------------------
125
126The new test configurations must be checked by function ``tfm_invalid_config()``
127if they have any dependence. The value comes from command line may be wrong when
David Hu945d22d2023-11-30 17:49:34 +0800128the dependencies are conflicting.
129
130Implement necessary checks in ``tests_reg/test/config/check_config.cmake``.
131
132Export TF-M configurations
133==========================
134
135If the new test depends on some TF-M configurations, export their value via
136``tests_reg/test/config/config_ns_tests.cmake.in``.
137TF-M secure build will install ``config_ns_tests.cmake`` and export configuration values.
138tf-m-tests non-secure build will include ``config_ns_tests.cmake`` and receive TF-M configuration
139values.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800140
BohdanHunko48eedb32022-10-19 19:01:25 +0300141Applying test configurations
142============================
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800143
144The mission of test configurations is to control the build. They are applied
145in ``test/secure_fw/suites/<test_name>/CMakeLists.txt`` like the example below.
146
147.. code-block:: cmake
148
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800149 if (NOT TEST_NS_<TEST_NAME> AND NOT TEST_S_<TEST_NAME>)
150 return()
151 endif()
152
153 ####################### Non Secure #########################################
154
155 if (TEST_NS_<TEST_NAME>)
156 add_library(tfm_test_suite_<test_name>_ns STATIC EXCLUDE_FROM_ALL)
157 # target_sources()
158 # target_include_directories()
159 target_compile_definitions(tfm_test_suite_<test_name>_ns
160 INTERFACE
161 TEST_NS_<TEST_NAME>
162 )
163 # target_link_libraries()
164 endif()
165
166 ####################### Secure #############################################
167
168 if (TEST_S_<TEST_NAME>)
169 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
170 # target_sources()
171 # target_include_directories()
172 target_compile_definitions(tfm_test_suite_<test_name>_s
173 INTERFACE
174 TEST_S_<TEST_NAME>
175 )
176 # target_link_libraries()
177 endif()
178
179The function ``target_compile_definitions`` will export the macros
180``TEST_NS_<TEST_NAME>`` or ``TEST_S_<TEST_NAME>`` into source code. and in the
David Hu945d22d2023-11-30 17:49:34 +0800181file ``tests_reg/test/framework/non_secure_suites.c`` or
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800182``tests/framework/secure_suites.c``, the definitions of these macros will be
183checked, and then the head file will be included and test cases will be
184registered if the macro is defined.
185
186.. code-block:: c
187
188 #ifdef TEST_NS_<TEST_NAME>
189 #include "<test_name>_ns_tests.h"
190 #endif
191
192 static struct test_suite_t test_suites[] = {
193 /* Non-secure example test cases */
194 // ......
195 #ifdef TEST_NS_<TEST_NAME>
196 {&register_testsuite_ns_<test_name>_interface, 0, 0, 0},
197 #endif
198 };
199
200.. code-block:: c
201
202 #ifdef TEST_S_<TEST_NAME>
203 #include "<test_name>_s_tests.h"
204 #endif
205
206 static struct test_suite_t test_suites[] = {
207 /* Secure example test cases */
208 // ......
209 #ifdef TEST_S_<TEST_NAME>
210 {&register_testsuite_s_<test_name>_interface, 0, 0, 0},
211 #endif
212 };
213
214.. Note::
215 On most platforms non-secure tests and secure tests run on the same CPU
216 core, but dual-core platform is an exception. So secure test library and
BohdanHunko48eedb32022-10-19 19:01:25 +0300217 secure services shall be linked together in the file
David Hu945d22d2023-11-30 17:49:34 +0800218 ``tests_reg/test/test/secure_fw/secure_tests.cmake``. Thus they can be built on
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800219 secure CPU core and non-secure tests library and RTOS are built on
220 non-secure CPU core.
221
222.. code-block:: cmake
223
David Huaecf9972023-04-06 17:41:16 +0800224 # ...
225 if (TEST_S_<TEST_NAME>)
226 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800227 endif()
228
229************************************
230Adding a new test case in test suite
231************************************
232
233The test cases usually express as a function in source code. They will be added
234into an array with structure type called ``test_t`` defined in
David Hu945d22d2023-11-30 17:49:34 +0800235``tests_reg/test/test/framework/test_framework.h``.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800236
237.. code-block:: c
238
239 struct test_t {
240 TEST_FUN * const test; /*!< Test function to call */
241 const char *name; /*!< Test name */
242 const char *desc; /*!< Test description */
243 };
244
245For example, a new test case called ``TFM_NS_<TEST_NAME>_TEST_1001`` is created
246and the function ``tfm_<test_name>_test_1001`` needs to be defined in file
247``<test_name>_ns_interface_testsuite.c``. Then the function shall be appended
248into the array which will be quoted in function
249``register_testsuite_ns_<test_name>_interface``. See the reference code below.
250
251.. code-block:: c
252
253 /* List of test cases */
254 static void tfm_<test_name>_test_1001(struct test_result_t *ret);
255
256 /* Append test cases */
257 static struct test_t <test_name>_tests[] = {
258 {&tfm_<test_name>_test_1001, "TFM_NS_<TEST_NAME>_TEST_1001",
259 "Example test case"},
260 };
261
262 /* Register test case into test suites */
263 void register_testsuite_ns_<test_name>_interface(struct test_suite_t *p_test_suite)
264 {
265 uint32_t list_size;
266
267 list_size = (sizeof(<test_name>_tests) / sizeof(<test_name>_tests[0]));
268
269 set_testsuite("<TEST_NAME> non-secure interface test (TFM_NS_<TEST_NAME>_TEST_1XXX)",
270 <test_name>_tests, list_size, p_test_suite);
271 }
272
273 static void tfm_<test_name>_test_1001(struct test_result_t *ret)
274 {
275 /* test case code */
276 }
277
278********************
279Adding test services
280********************
281
282Some test group may need specific test services. These test services may support
283one or more groups thus developers shall determine the proper test scope. Refer
284to
Elena Uziunaite99438172023-11-13 14:39:29 +0000285:doc:`Adding partitions for regression tests <tfm_test_partitions_addition>`
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800286to get more information.
287
288**********************************
289Out-of-tree regression test suites
290**********************************
291
292TF-M supports out-of-tree regression test suites build, whose source code
Raef Colesb52543f2024-05-03 10:38:11 +0100293folder is outside tf-m-tests repo. There are four configurations for developers
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800294to include the source code.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800295
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800296- ``EXTRA_NS_TEST_SUITE_PATH``
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800297
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800298 An absolute directory of the out-of-tree non-secure test suite
299 source code folder. TF-M build system searches ``CMakeLists.txt`` of
300 non-secure test suite in the source code folder.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800301
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800302- ``EXTRA_S_TEST_SUITE_PATH``
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800303
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800304 An absolute directory of the out-of-tree secure test suite
305 source code folder.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800306
Raef Colesb52543f2024-05-03 10:38:11 +0100307- ``EXTRA_BL1_1_TEST_SUITE_PATH``
308
309 An absolute directory of the out-of-tree BL1_1 test suite
310 source code folder.
311
312- ``EXTRA_BL1_2_TEST_SUITE_PATH``
313
314 An absolute directory of the out-of-tree BL1_2 test suite
315 source code folder.
316
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800317Example usage
318=============
319
320Take non-secure test as an example in
321`tf-m-extras <https://git.trustedfirmware.org/TF-M/tf-m-extras.git/>`_.
322A single out-of-tree test suite folder can be organized as the figure below:
323
324.. code-block:: bash
325
326 extra_ns
327 ├── CMakeLists.txt
328 ├── ns_test.c
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300329 └── ns_test_config.cmake
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800330
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800331In the example above, ``EXTRA_NS_TEST_SUITE_PATH`` in the build command can be
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800332specified as listed below.
333
334.. code-block:: bash
335
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800336 -DEXTRA_NS_TEST_SUITE_PATH=<Absolute-path-extra-test-folder>
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800337
338Coding instructions
339===================
340
341This is a demo of source code so the structure has been simplified. Files like
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300342``.c`` and ``.h`` can be expanded to ``src`` and ``include`` folders
343respectively. The ``CMakeLists.txt`` is required in the root path and
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800344``ns_test_config.cmake`` is optional.
345
346Header Files
347------------
348
349The header file ``extra_ns_tests.h`` must be included by out-of-tree source
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300350code. This file contains the declaration of
351``void register_testsuite_extra_ns_interface(struct test_suite_t *p_test_suite)``.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800352
353Source code
354-----------
355
David Hu945d22d2023-11-30 17:49:34 +0800356To connect the out-of-tree source code and regression test framework, the test case
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300357function/functions must be defined first. An example format is:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800358
359.. code-block:: c
360
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300361 void ns_test(struct test_result_t *ret)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800362 {
363 /* Add platform specific non-secure test suites code here. */
364
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300365 ret->val = TEST_PASSED;
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800366 }
367
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300368This function follows the standard TF-M test case function prototype.
369
370.. note::
371 Extra tests can have one or more test cases. This is simplified example so
372 only one test case is added.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800373
374After ``ns_test()`` is defined, a structure variable need to be created like:
375
376.. code-block:: c
377
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300378 static struct test_t plat_ns_t[] = {
379 {&ns_test, "TFM_EXTRA_TEST_1001",
380 "Extra Non-Secure test"},
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800381 };
382
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300383It will be used by function ``register_testsuite_extra_ns_interface()`` to
384register the test by calling the ``set_testsuite()`` function:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800385
386.. code-block:: c
387
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300388 void register_testsuite_extra_ns_interface(struct test_suite_t *p_test_suite)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800389 {
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300390 uint32_t list_size;
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800391
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300392 list_size = (sizeof(plat_ns_t) /
393 sizeof(plat_ns_t[0]));
394
395 set_testsuite("Extra Non-Secure interface tests"
396 "(TFM_NS_EXTRA_TEST_1XXX)",
397 plat_ns_t, list_size, p_test_suite);
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800398 }
399
400The platform initialization code can be added in this function because it runs
401before ``ns_test()``.
402
403.. Note::
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300404 Function ``register_testsuite_extra_ns_interface()`` is declared in
405 tf-m-tests repository without definition. It is supplied to out-of-tree
406 source code and need to be defined with no change of its format, like
407 returns error code and parameter name.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800408
409
410CMakeLists.txt
411--------------
412
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300413After extra test suite file were created they must be linked to
414``tfm_test_suite_extra_ns`` CMAKE target:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800415
416.. code-block:: cmake
417
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300418 target_sources(tfm_test_suite_extra_ns
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800419 PRIVATE
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300420 ${CMAKE_CURRENT_SOURCE_DIR}/ns_test.c
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800421 )
422
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800423ns_test_config.cmake
424--------------------
425
426The CMAKE configuration file is optional. If out-of-tree source already exists
427another configuration file, a new one can be ignored.
428
429--------------
430
431*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300432*Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
433or an affiliate of Cypress Semiconductor Corporation. All rights reserved.*