blob: 044a0cf2e4877de7a1ded0d9bb1c8d78aec5b663 [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
149 cmake_policy(SET CMP0079 NEW)
150
151 if (NOT TEST_NS_<TEST_NAME> AND NOT TEST_S_<TEST_NAME>)
152 return()
153 endif()
154
155 ####################### Non Secure #########################################
156
157 if (TEST_NS_<TEST_NAME>)
158 add_library(tfm_test_suite_<test_name>_ns STATIC EXCLUDE_FROM_ALL)
159 # target_sources()
160 # target_include_directories()
161 target_compile_definitions(tfm_test_suite_<test_name>_ns
162 INTERFACE
163 TEST_NS_<TEST_NAME>
164 )
165 # target_link_libraries()
166 endif()
167
168 ####################### Secure #############################################
169
170 if (TEST_S_<TEST_NAME>)
171 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
172 # target_sources()
173 # target_include_directories()
174 target_compile_definitions(tfm_test_suite_<test_name>_s
175 INTERFACE
176 TEST_S_<TEST_NAME>
177 )
178 # target_link_libraries()
179 endif()
180
181The function ``target_compile_definitions`` will export the macros
182``TEST_NS_<TEST_NAME>`` or ``TEST_S_<TEST_NAME>`` into source code. and in the
David Hu945d22d2023-11-30 17:49:34 +0800183file ``tests_reg/test/framework/non_secure_suites.c`` or
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800184``tests/framework/secure_suites.c``, the definitions of these macros will be
185checked, and then the head file will be included and test cases will be
186registered if the macro is defined.
187
188.. code-block:: c
189
190 #ifdef TEST_NS_<TEST_NAME>
191 #include "<test_name>_ns_tests.h"
192 #endif
193
194 static struct test_suite_t test_suites[] = {
195 /* Non-secure example test cases */
196 // ......
197 #ifdef TEST_NS_<TEST_NAME>
198 {&register_testsuite_ns_<test_name>_interface, 0, 0, 0},
199 #endif
200 };
201
202.. code-block:: c
203
204 #ifdef TEST_S_<TEST_NAME>
205 #include "<test_name>_s_tests.h"
206 #endif
207
208 static struct test_suite_t test_suites[] = {
209 /* Secure example test cases */
210 // ......
211 #ifdef TEST_S_<TEST_NAME>
212 {&register_testsuite_s_<test_name>_interface, 0, 0, 0},
213 #endif
214 };
215
216.. Note::
217 On most platforms non-secure tests and secure tests run on the same CPU
218 core, but dual-core platform is an exception. So secure test library and
BohdanHunko48eedb32022-10-19 19:01:25 +0300219 secure services shall be linked together in the file
David Hu945d22d2023-11-30 17:49:34 +0800220 ``tests_reg/test/test/secure_fw/secure_tests.cmake``. Thus they can be built on
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800221 secure CPU core and non-secure tests library and RTOS are built on
222 non-secure CPU core.
223
224.. code-block:: cmake
225
David Huaecf9972023-04-06 17:41:16 +0800226 # ...
227 if (TEST_S_<TEST_NAME>)
228 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800229 endif()
230
231************************************
232Adding a new test case in test suite
233************************************
234
235The test cases usually express as a function in source code. They will be added
236into an array with structure type called ``test_t`` defined in
David Hu945d22d2023-11-30 17:49:34 +0800237``tests_reg/test/test/framework/test_framework.h``.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800238
239.. code-block:: c
240
241 struct test_t {
242 TEST_FUN * const test; /*!< Test function to call */
243 const char *name; /*!< Test name */
244 const char *desc; /*!< Test description */
245 };
246
247For example, a new test case called ``TFM_NS_<TEST_NAME>_TEST_1001`` is created
248and the function ``tfm_<test_name>_test_1001`` needs to be defined in file
249``<test_name>_ns_interface_testsuite.c``. Then the function shall be appended
250into the array which will be quoted in function
251``register_testsuite_ns_<test_name>_interface``. See the reference code below.
252
253.. code-block:: c
254
255 /* List of test cases */
256 static void tfm_<test_name>_test_1001(struct test_result_t *ret);
257
258 /* Append test cases */
259 static struct test_t <test_name>_tests[] = {
260 {&tfm_<test_name>_test_1001, "TFM_NS_<TEST_NAME>_TEST_1001",
261 "Example test case"},
262 };
263
264 /* Register test case into test suites */
265 void register_testsuite_ns_<test_name>_interface(struct test_suite_t *p_test_suite)
266 {
267 uint32_t list_size;
268
269 list_size = (sizeof(<test_name>_tests) / sizeof(<test_name>_tests[0]));
270
271 set_testsuite("<TEST_NAME> non-secure interface test (TFM_NS_<TEST_NAME>_TEST_1XXX)",
272 <test_name>_tests, list_size, p_test_suite);
273 }
274
275 static void tfm_<test_name>_test_1001(struct test_result_t *ret)
276 {
277 /* test case code */
278 }
279
280********************
281Adding test services
282********************
283
284Some test group may need specific test services. These test services may support
285one or more groups thus developers shall determine the proper test scope. Refer
286to
Elena Uziunaite99438172023-11-13 14:39:29 +0000287:doc:`Adding partitions for regression tests <tfm_test_partitions_addition>`
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800288to get more information.
289
290**********************************
291Out-of-tree regression test suites
292**********************************
293
294TF-M supports out-of-tree regression test suites build, whose source code
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800295folder is outside tf-m-tests repo. There are two configurations for developers
296to include the source code.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800297
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800298- ``EXTRA_NS_TEST_SUITE_PATH``
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800299
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800300 An absolute directory of the out-of-tree non-secure test suite
301 source code folder. TF-M build system searches ``CMakeLists.txt`` of
302 non-secure test suite in the source code folder.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800303
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800304- ``EXTRA_S_TEST_SUITE_PATH``
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800305
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800306 An absolute directory of the out-of-tree secure test suite
307 source code folder.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800308
309Example usage
310=============
311
312Take non-secure test as an example in
313`tf-m-extras <https://git.trustedfirmware.org/TF-M/tf-m-extras.git/>`_.
314A single out-of-tree test suite folder can be organized as the figure below:
315
316.. code-block:: bash
317
318 extra_ns
319 ├── CMakeLists.txt
320 ├── ns_test.c
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300321 └── ns_test_config.cmake
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800322
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800323In the example above, ``EXTRA_NS_TEST_SUITE_PATH`` in the build command can be
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800324specified as listed below.
325
326.. code-block:: bash
327
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800328 -DEXTRA_NS_TEST_SUITE_PATH=<Absolute-path-extra-test-folder>
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800329
330Coding instructions
331===================
332
333This is a demo of source code so the structure has been simplified. Files like
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300334``.c`` and ``.h`` can be expanded to ``src`` and ``include`` folders
335respectively. The ``CMakeLists.txt`` is required in the root path and
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800336``ns_test_config.cmake`` is optional.
337
338Header Files
339------------
340
341The header file ``extra_ns_tests.h`` must be included by out-of-tree source
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300342code. This file contains the declaration of
343``void register_testsuite_extra_ns_interface(struct test_suite_t *p_test_suite)``.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800344
345Source code
346-----------
347
David Hu945d22d2023-11-30 17:49:34 +0800348To connect the out-of-tree source code and regression test framework, the test case
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300349function/functions must be defined first. An example format is:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800350
351.. code-block:: c
352
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300353 void ns_test(struct test_result_t *ret)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800354 {
355 /* Add platform specific non-secure test suites code here. */
356
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300357 ret->val = TEST_PASSED;
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800358 }
359
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300360This function follows the standard TF-M test case function prototype.
361
362.. note::
363 Extra tests can have one or more test cases. This is simplified example so
364 only one test case is added.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800365
366After ``ns_test()`` is defined, a structure variable need to be created like:
367
368.. code-block:: c
369
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300370 static struct test_t plat_ns_t[] = {
371 {&ns_test, "TFM_EXTRA_TEST_1001",
372 "Extra Non-Secure test"},
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800373 };
374
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300375It will be used by function ``register_testsuite_extra_ns_interface()`` to
376register the test by calling the ``set_testsuite()`` function:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800377
378.. code-block:: c
379
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300380 void register_testsuite_extra_ns_interface(struct test_suite_t *p_test_suite)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800381 {
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300382 uint32_t list_size;
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800383
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300384 list_size = (sizeof(plat_ns_t) /
385 sizeof(plat_ns_t[0]));
386
387 set_testsuite("Extra Non-Secure interface tests"
388 "(TFM_NS_EXTRA_TEST_1XXX)",
389 plat_ns_t, list_size, p_test_suite);
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800390 }
391
392The platform initialization code can be added in this function because it runs
393before ``ns_test()``.
394
395.. Note::
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300396 Function ``register_testsuite_extra_ns_interface()`` is declared in
397 tf-m-tests repository without definition. It is supplied to out-of-tree
398 source code and need to be defined with no change of its format, like
399 returns error code and parameter name.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800400
401
402CMakeLists.txt
403--------------
404
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300405After extra test suite file were created they must be linked to
406``tfm_test_suite_extra_ns`` CMAKE target:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800407
408.. code-block:: cmake
409
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300410 target_sources(tfm_test_suite_extra_ns
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800411 PRIVATE
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300412 ${CMAKE_CURRENT_SOURCE_DIR}/ns_test.c
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800413 )
414
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800415ns_test_config.cmake
416--------------------
417
418The CMAKE configuration file is optional. If out-of-tree source already exists
419another configuration file, a new one can be ignored.
420
421--------------
422
423*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300424*Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
425or an affiliate of Cypress Semiconductor Corporation. All rights reserved.*