blob: b27ed7437e1a9a65d5902e232cfb6c2785e9b0d5 [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
45with a test configuration in ``tf-m-tests`` repository.
46
47Source code
48===========
49
50The test suite example subdirectory named ``<test_name>`` is located under the
51path ``tf-m-tests/test/secure_fw/suites``. If the new test suite includes both
52non-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 .
59 ├── CMakeLists.txt
60 ├── <test_name>_tests_common.c
61 ├── non_secure
62 │ ├── <test_name>_ns_interface_testsuite.c
63 │ └── <test_name>_ns_tests.h
64 └── secure
65 ├── <test_name>_s_interface_testsuite.c
66 └── <test_name>_s_tests.h
67
68Creating test configurations
69============================
70
71A test configuration controls whether one or multiple test suites are enabled.
BohdanHunko48eedb32022-10-19 19:01:25 +030072The doc `TF-M Build Instructions <https://tf-m-user-guide.trustedfirmware.org/technical_references/instructions/tfm_build_instruction.html>`_.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +080073shows some test configurations which are already supported in current TF-M.
74An example usage of test configuration shows below.
75
76.. code-block:: bash
77
78 cmake -S . -B cmake_build -DTFM_PLATFORM=arm/mps2/an521 \
79 -DTFM_TOOLCHAIN_FILE=toolchain_GNUARM.cmake \
80 -DCMAKE_BUILD_TYPE=Release \
81 -DTEST_NS_ATTESTATION=ON
82
83With this command, only non-secure initial attestation test suite will be built.
84
85Developers shall assign corresponding test configurations to control the test
86suites.
87
88Naming test configurations
89--------------------------
90
91The test configurations of example test suites are ``TEST_NS_<TEST_NAME>``
92in non-secure and ``TEST_S_<TEST_NAME>`` in secure.
93
94.. Note::
95 The test configurations must be named with the prefixes ``TEST_S_`` and
96 ``TEST_NS_``, for secure regression tests and non-secure regression tests
97 respectively. Otherwise, tf-m-tests build system may not recognize it.
98
99Setting test configurations
100---------------------------
101
102When the test configurations have dependences, the default value need to be set.
103The setting is performed in following four steps.
104
105#. Command line input: The configuration can be enabled or disabled by the
106 command ``-DTEST_NS_<TEST_NAME>=ON/OFF -DTEST_S_<TEST_NAME>=ON/OFF``, and
107 the value cannot be changed throughout the whole compilation of TF-M tests.
108
109#. ``tf-m-tests/config/set_config.cmake``: The test configurations shall be
110 OFF if its dependences are not supported. The dependences are probably
111 from:
112
113 #. TF-M partitions configurations like ``TFM_PARTITION_CRYPTO``,
114 ``TFM_PARTITION_INITIAL_ATTESTATION``, etc.
Summer Qinab4e42d2022-10-09 17:36:39 +0800115 #. TF-M build mode configuration like ``CONFIG_TFM_SPM_BACKEND``.
Mark Horvath2f072582022-09-09 16:15:30 +0200116 #. TF-M other configurations like ``TFM_PARTITION_FIRMWARE_UPDATE``, etc.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800117
118#. ``tf-m-tests/config/default_ns_test_config.cmake`` or
119 ``tf-m-tests/config/default_s_test_config.cmake``: It is required to give
120 the default value of the new test configuration in these two files when
121 ``TEST_NS`` or ``TEST_S`` is ON. The recommended value is ON unless the
122 single test's code or data size is very large.
123
124#. ``tf-m-tests/config/default_test_config.cmake``: It is required to give the
125 default value of the new test configuration in the file when both
126 ``TEST_NS`` and ``TEST_S`` are OFF. The default value must be OFF.
127
128.. Note::
129 The test configurations must be set as CACHE value in CMAKE files. The CACHE
130 set cannot replace the value from command line, see
131 `Set Cache Entry <https://cmake.org/cmake/help/latest/command/set.html#set-cache-entry>`_.
132
133Checking test configurations
134----------------------------
135
136The new test configurations must be checked by function ``tfm_invalid_config()``
137if they have any dependence. The value comes from command line may be wrong when
138the dependences are conflicting. In addition to the dependences quoted in
139``tf-m-tests/config/set_config.cmake``, some other test configurations may be
140necessary.
141
BohdanHunko48eedb32022-10-19 19:01:25 +0300142Applying test configurations
143============================
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800144
145The mission of test configurations is to control the build. They are applied
146in ``test/secure_fw/suites/<test_name>/CMakeLists.txt`` like the example below.
147
148.. code-block:: cmake
149
150 cmake_policy(SET CMP0079 NEW)
151
152 if (NOT TEST_NS_<TEST_NAME> AND NOT TEST_S_<TEST_NAME>)
153 return()
154 endif()
155
156 ####################### Non Secure #########################################
157
158 if (TEST_NS_<TEST_NAME>)
159 add_library(tfm_test_suite_<test_name>_ns STATIC EXCLUDE_FROM_ALL)
160 # target_sources()
161 # target_include_directories()
162 target_compile_definitions(tfm_test_suite_<test_name>_ns
163 INTERFACE
164 TEST_NS_<TEST_NAME>
165 )
166 # target_link_libraries()
167 endif()
168
169 ####################### Secure #############################################
170
171 if (TEST_S_<TEST_NAME>)
172 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
173 # target_sources()
174 # target_include_directories()
175 target_compile_definitions(tfm_test_suite_<test_name>_s
176 INTERFACE
177 TEST_S_<TEST_NAME>
178 )
179 # target_link_libraries()
180 endif()
181
182The function ``target_compile_definitions`` will export the macros
183``TEST_NS_<TEST_NAME>`` or ``TEST_S_<TEST_NAME>`` into source code. and in the
184file ``tf-m-tests/framework/non_secure_suites.c`` or
185``tests/framework/secure_suites.c``, the definitions of these macros will be
186checked, and then the head file will be included and test cases will be
187registered if the macro is defined.
188
189.. code-block:: c
190
191 #ifdef TEST_NS_<TEST_NAME>
192 #include "<test_name>_ns_tests.h"
193 #endif
194
195 static struct test_suite_t test_suites[] = {
196 /* Non-secure example test cases */
197 // ......
198 #ifdef TEST_NS_<TEST_NAME>
199 {&register_testsuite_ns_<test_name>_interface, 0, 0, 0},
200 #endif
201 };
202
203.. code-block:: c
204
205 #ifdef TEST_S_<TEST_NAME>
206 #include "<test_name>_s_tests.h"
207 #endif
208
209 static struct test_suite_t test_suites[] = {
210 /* Secure example test cases */
211 // ......
212 #ifdef TEST_S_<TEST_NAME>
213 {&register_testsuite_s_<test_name>_interface, 0, 0, 0},
214 #endif
215 };
216
217.. Note::
218 On most platforms non-secure tests and secure tests run on the same CPU
219 core, but dual-core platform is an exception. So secure test library and
BohdanHunko48eedb32022-10-19 19:01:25 +0300220 secure services shall be linked together in the file
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800221 ``tf-m-tests/test/secure_fw/secure_tests.cmake``. Thus they can be built on
222 secure CPU core and non-secure tests library and RTOS are built on
223 non-secure CPU core.
224
225.. code-block:: cmake
226
David Huaecf9972023-04-06 17:41:16 +0800227 # ...
228 if (TEST_S_<TEST_NAME>)
229 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800230 endif()
231
232************************************
233Adding a new test case in test suite
234************************************
235
236The test cases usually express as a function in source code. They will be added
237into an array with structure type called ``test_t`` defined in
238``tf-m-tests/test/framework/test_framework.h``.
239
240.. code-block:: c
241
242 struct test_t {
243 TEST_FUN * const test; /*!< Test function to call */
244 const char *name; /*!< Test name */
245 const char *desc; /*!< Test description */
246 };
247
248For example, a new test case called ``TFM_NS_<TEST_NAME>_TEST_1001`` is created
249and the function ``tfm_<test_name>_test_1001`` needs to be defined in file
250``<test_name>_ns_interface_testsuite.c``. Then the function shall be appended
251into the array which will be quoted in function
252``register_testsuite_ns_<test_name>_interface``. See the reference code below.
253
254.. code-block:: c
255
256 /* List of test cases */
257 static void tfm_<test_name>_test_1001(struct test_result_t *ret);
258
259 /* Append test cases */
260 static struct test_t <test_name>_tests[] = {
261 {&tfm_<test_name>_test_1001, "TFM_NS_<TEST_NAME>_TEST_1001",
262 "Example test case"},
263 };
264
265 /* Register test case into test suites */
266 void register_testsuite_ns_<test_name>_interface(struct test_suite_t *p_test_suite)
267 {
268 uint32_t list_size;
269
270 list_size = (sizeof(<test_name>_tests) / sizeof(<test_name>_tests[0]));
271
272 set_testsuite("<TEST_NAME> non-secure interface test (TFM_NS_<TEST_NAME>_TEST_1XXX)",
273 <test_name>_tests, list_size, p_test_suite);
274 }
275
276 static void tfm_<test_name>_test_1001(struct test_result_t *ret)
277 {
278 /* test case code */
279 }
280
281********************
282Adding test services
283********************
284
285Some test group may need specific test services. These test services may support
286one or more groups thus developers shall determine the proper test scope. Refer
287to
288`Adding partitions for regression tests <https://git.trustedfirmware.org/TF-M/tf-m-tests.git/tree/docs/tfm_test_services_addition.rst>`_
289to get more information.
290
291**********************************
292Out-of-tree regression test suites
293**********************************
294
295TF-M supports out-of-tree regression test suites build, whose source code
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800296folder is outside tf-m-tests repo. There are two configurations for developers
297to include the source code.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800298
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800299- ``EXTRA_NS_TEST_SUITE_PATH``
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800300
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800301 An absolute directory of the out-of-tree non-secure test suite
302 source code folder. TF-M build system searches ``CMakeLists.txt`` of
303 non-secure test suite in the source code folder.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800304
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800305- ``EXTRA_S_TEST_SUITE_PATH``
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800306
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800307 An absolute directory of the out-of-tree secure test suite
308 source code folder.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800309
310Example usage
311=============
312
313Take non-secure test as an example in
314`tf-m-extras <https://git.trustedfirmware.org/TF-M/tf-m-extras.git/>`_.
315A single out-of-tree test suite folder can be organized as the figure below:
316
317.. code-block:: bash
318
319 extra_ns
320 ├── CMakeLists.txt
321 ├── ns_test.c
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300322 └── ns_test_config.cmake
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800323
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800324In the example above, ``EXTRA_NS_TEST_SUITE_PATH`` in the build command can be
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800325specified as listed below.
326
327.. code-block:: bash
328
Jianliang Shenb5fd67b2022-11-14 14:15:59 +0800329 -DEXTRA_NS_TEST_SUITE_PATH=<Absolute-path-extra-test-folder>
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800330
331Coding instructions
332===================
333
334This is a demo of source code so the structure has been simplified. Files like
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300335``.c`` and ``.h`` can be expanded to ``src`` and ``include`` folders
336respectively. The ``CMakeLists.txt`` is required in the root path and
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800337``ns_test_config.cmake`` is optional.
338
339Header Files
340------------
341
342The header file ``extra_ns_tests.h`` must be included by out-of-tree source
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300343code. This file contains the declaration of
344``void register_testsuite_extra_ns_interface(struct test_suite_t *p_test_suite)``.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800345
346Source code
347-----------
348
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300349To connect the out-of-tree source code and tf-m-tests framework, the test case
350function/functions must be defined first. An example format is:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800351
352.. code-block:: c
353
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300354 void ns_test(struct test_result_t *ret)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800355 {
356 /* Add platform specific non-secure test suites code here. */
357
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300358 ret->val = TEST_PASSED;
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800359 }
360
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300361This function follows the standard TF-M test case function prototype.
362
363.. note::
364 Extra tests can have one or more test cases. This is simplified example so
365 only one test case is added.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800366
367After ``ns_test()`` is defined, a structure variable need to be created like:
368
369.. code-block:: c
370
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300371 static struct test_t plat_ns_t[] = {
372 {&ns_test, "TFM_EXTRA_TEST_1001",
373 "Extra Non-Secure test"},
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800374 };
375
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300376It will be used by function ``register_testsuite_extra_ns_interface()`` to
377register the test by calling the ``set_testsuite()`` function:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800378
379.. code-block:: c
380
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300381 void register_testsuite_extra_ns_interface(struct test_suite_t *p_test_suite)
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800382 {
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300383 uint32_t list_size;
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800384
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300385 list_size = (sizeof(plat_ns_t) /
386 sizeof(plat_ns_t[0]));
387
388 set_testsuite("Extra Non-Secure interface tests"
389 "(TFM_NS_EXTRA_TEST_1XXX)",
390 plat_ns_t, list_size, p_test_suite);
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800391 }
392
393The platform initialization code can be added in this function because it runs
394before ``ns_test()``.
395
396.. Note::
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300397 Function ``register_testsuite_extra_ns_interface()`` is declared in
398 tf-m-tests repository without definition. It is supplied to out-of-tree
399 source code and need to be defined with no change of its format, like
400 returns error code and parameter name.
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800401
402
403CMakeLists.txt
404--------------
405
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300406After extra test suite file were created they must be linked to
407``tfm_test_suite_extra_ns`` CMAKE target:
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800408
409.. code-block:: cmake
410
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300411 target_sources(tfm_test_suite_extra_ns
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800412 PRIVATE
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300413 ${CMAKE_CURRENT_SOURCE_DIR}/ns_test.c
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800414 )
415
Jianliang Shen5f7b1b72022-05-03 19:01:27 +0800416ns_test_config.cmake
417--------------------
418
419The CMAKE configuration file is optional. If out-of-tree source already exists
420another configuration file, a new one can be ignored.
421
422--------------
423
424*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
BohdanHunkoce2e7c92022-10-21 15:42:39 +0300425*Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
426or an affiliate of Cypress Semiconductor Corporation. All rights reserved.*