blob: ccab71419333c70ebafd77b3f1efd5361b7f1d0c [file] [log] [blame]
Jianliang Shenbde10ed2021-08-25 13:48:00 +08001#################################
2Adding TF-M Regression Test Suite
3#################################
4
5.. contents:: Table of Contents
6
7*************************************
8Introduction of TF-M regression tests
9*************************************
10
Jianliang Shen4009df82021-09-02 14:46:23 +080011TF-M regression tests test whether changes to TF-M code work as expected.
12This documentation focuses on three parts in TF-M regression tests:
Jianliang Shenbde10ed2021-08-25 13:48:00 +080013
141. ``test suite``: A series of tests of a certain function.
152. ``test case``: A specific test instance in test suites.
163. ``test service``: An extra module works like secure partitions to support
17 related test suites.
18
19Source structure
20================
21
22TF-M tests source code are located in
23`tf-m-tests <https://git.trustedfirmware.org/TF-M/tf-m-tests.git/>`__.
24
Jianliang Shen53f7ecd2022-02-22 10:57:51 +080025+---------------------------------------+---------------------------------------------------------------+
26| Folder name | Description |
27+=======================================+===============================================================+
28| test/config | The CMAKE test configurations files. |
29+---------------------------------------+---------------------------------------------------------------+
30| test/framework | Source code for test framework code, managing test suites. |
31+---------------------------------------+---------------------------------------------------------------+
32| test/secure_fw/suites | Test suites divided into subdirectories. |
33+---------------------------------------+---------------------------------------------------------------+
34| test/secure_fw/suites/<suite>/service | Test service divided into corresponding suite subdirectories. |
35+---------------------------------------+---------------------------------------------------------------+
36| test/secure_fw/common_test_services | Common test services. |
37+---------------------------------------+---------------------------------------------------------------+
Jianliang Shenbde10ed2021-08-25 13:48:00 +080038
39Test configuration
40==================
41
42A test configuration controls whether one or multiple test suites are enabled.
43The doc :doc:`TF-M Build Instructions </docs/technical_references/instructions/tfm_build_instruction>`
44shows some test configurations which are already supported in current TF-M.
45An example usage of test configuration shows below.
46
47.. code-block:: bash
48
49 cmake -S . -B cmake_build -DTFM_PLATFORM=arm/mps2/an521 \
50 -DTFM_TOOLCHAIN_FILE=toolchain_GNUARM.cmake \
51 -DCMAKE_BUILD_TYPE=Release \
Jianliang Shenbde10ed2021-08-25 13:48:00 +080052 -DTEST_NS_ATTESTATION=ON
53
54With this command, only non-secure initial attestation test suite will be built.
55
56***********************
57Adding a new test suite
58***********************
59
60This section introduces how to add a new test suite and control its compilation
61with a test configuration in ``tf-m-tests`` repository.
62
63Source code
64===========
65
Jianliang Shen53f7ecd2022-02-22 10:57:51 +080066The test suite example subdirectory named ``<test_name>`` is located under the
67path ``tf-m-tests/test/secure_fw/suites``. If the new test suite includes both
68non-secure and secure parts, the source code shall be divided shared code and
69specific code. An example test suite folder can be organized as the figure
70below.
Jianliang Shenbde10ed2021-08-25 13:48:00 +080071
72.. code-block:: bash
73
74 .
75 ├── CMakeLists.txt
76 ├── <test_name>_tests_common.c
77 ├── non_secure
78 ├── <test_name>_ns_interface_testsuite.c
79 └── <test_name>_ns_tests.h
80 └── secure
81 ├── <test_name>_s_interface_testsuite.c
82 └── <test_name>_s_tests.h
83
84Creating test configurations
85============================
86
87Developers shall assign corresponding test configurations to control the test
88suites.
89
90Naming test configurations
91--------------------------
92
93The test configurations of example test suites are ``TEST_NS_<TEST_NAME>``
94in non-secure and ``TEST_S_<TEST_NAME>`` in secure.
95
96.. Note::
97 The test configurations must be named with the prefixes ``TEST_S_`` and
98 ``TEST_NS_``, for secure regression tests and non-secure regression tests
99 respectively. Otherwise, tf-m-tests build system may not recognize it.
100
101Setting test configurations
102---------------------------
103
104When the test configurations have dependences, the default value need to be set.
105The setting is performed in following four steps.
106
107#. Command line input: The configuration can be enabled or disabled by the
108 command ``-DTEST_NS_<TEST_NAME>=ON/OFF -DTEST_S_<TEST_NAME>=ON/OFF``, and
109 the value cannot be changed throughout the whole compilation of TF-M tests.
110
111#. ``tf-m-tests/config/set_config.cmake``: The test configurations shall be
112 OFF if its dependences are not supported. The dependences are probably
113 from:
114
115 #. TF-M partitions configurations like ``TFM_PARTITION_CRYPTO``,
116 ``TFM_PARTITION_INITIAL_ATTESTATION``, etc.
Kevin Peng23a583c2021-09-08 22:33:33 +0800117 #. TF-M build mode configuration like ``TFM_LIB_MODEL``.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800118 #. TF-M other configurations like ``TFM_PARTITION_FIRMWARE_UPDATE``,
119 ``FORWARD_PROT_MSG``, etc.
120
121#. ``tf-m-tests/config/default_ns_test_config.cmake`` or
122 ``tf-m-tests/config/default_s_test_config.cmake``: It is required to give
123 the default value of the new test configuration in these two files when
124 ``TEST_NS`` or ``TEST_S`` is ON. The recommended value is ON unless the
125 single test's code or data size is very large.
126
127#. ``tf-m-tests/config/default_test_config.cmake``: It is required to give the
128 default value of the new test configuration in the file when both
129 ``TEST_NS`` and ``TEST_S`` are OFF. The default value must be OFF.
130
131.. Note::
132 The test configurations must be set as CACHE value in CMAKE files. The CACHE
133 set cannot replace the value from command line, see
134 `Set Cache Entry <https://cmake.org/cmake/help/latest/command/set.html#set-cache-entry>`__.
135
136Checking test configurations
137----------------------------
138
139The new test configurations must be checked by function ``tfm_invalid_config()``
140if they have any dependence. The value comes from command line may be wrong when
141the dependences are conflicting. In addition to the dependences quoted in
142``tf-m-tests/config/set_config.cmake``, some other test configurations may be
143necessary.
144
145Applicating test configurations
146===============================
147
148The mission of test configurations is to control the build. They are applied
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800149in ``test/secure_fw/suites/<test_name>/CMakeLists.txt`` like the example below.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800150
151.. code-block:: cmake
152
153 cmake_policy(SET CMP0079 NEW)
154
155 if (NOT TEST_NS_<TEST_NAME> AND NOT TEST_S_<TEST_NAME>)
156 return()
157 endif()
158
159 ####################### Non Secure #########################################
160
161 if (TEST_NS_<TEST_NAME>)
162 add_library(tfm_test_suite_<test_name>_ns STATIC EXCLUDE_FROM_ALL)
163 # target_sources()
164 # target_include_directories()
165 target_compile_definitions(tfm_test_suite_<test_name>_ns
166 INTERFACE
167 TEST_NS_<TEST_NAME>
168 )
169 # target_link_libraries()
170 endif()
171
172 ####################### Secure #############################################
173
174 if (TEST_S_<TEST_NAME>)
175 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
176 # target_sources()
177 # target_include_directories()
178 target_compile_definitions(tfm_test_suite_<test_name>_s
179 INTERFACE
180 TEST_S_<TEST_NAME>
181 )
182 # target_link_libraries()
183 endif()
184
185The function ``target_compile_definitions`` will export the macros
186``TEST_NS_<TEST_NAME>`` or ``TEST_S_<TEST_NAME>`` into source code. and in the
187file ``tf-m-tests/framework/non_secure_suites.c`` or
188``tests/framework/secure_suites.c``, the definitions of these macros will be
189checked, and then the head file will be included and test cases will be
190registered if the macro is defined.
191
192.. code-block:: c
193
194 #ifdef TEST_NS_<TEST_NAME>
195 #include "<test_name>_ns_tests.h"
196 #endif
197
198 static struct test_suite_t test_suites[] = {
199 /* Non-secure example test cases */
200 // ......
201 #ifdef TEST_NS_<TEST_NAME>
202 {&register_testsuite_ns_<test_name>_interface, 0, 0, 0},
203 #endif
204 };
205
206.. code-block:: c
207
208 #ifdef TEST_S_<TEST_NAME>
209 #include "<test_name>_s_tests.h"
210 #endif
211
212 static struct test_suite_t test_suites[] = {
213 /* Secure example test cases */
214 // ......
215 #ifdef TEST_S_<TEST_NAME>
216 {&register_testsuite_s_<test_name>_interface, 0, 0, 0},
217 #endif
218 };
219
220.. Note::
221 On most platforms non-secure tests and secure tests run on the same CPU
222 core, but dual-core platform is an exception. So secure test library and
223 secure sevices shall be linked together in the file
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800224 ``tf-m-tests/test/secure_fw/secure_tests.cmake``. Thus they can be built on
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800225 secure CPU core and non-secure tests library and RTOS are built on
226 non-secure CPU core.
227
228.. code-block:: cmake
229
230 if (TEST_FRAMEWORK_S)
231 # ...
232 if (TEST_S_<TEST_NAME>)
233 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
234 endif()
235 endif()
236
237************************************
238Adding a new test case in test suite
239************************************
240
241The test cases usually express as a function in source code. They will be added
242into an array with structure type called ``test_t`` defined in
243``tf-m-tests/test/framework/test_framework.h``.
244
245.. code-block:: c
246
247 struct test_t {
248 TEST_FUN * const test; /*!< Test function to call */
249 const char *name; /*!< Test name */
250 const char *desc; /*!< Test description */
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800251 };
252
253For example, a new test case called ``TFM_NS_<TEST_NAME>_TEST_1001`` is created
254and the function ``tfm_<test_name>_test_1001`` needs to be defined in file
255``<test_name>_ns_interface_testsuite.c``. Then the function shall be appended
256into the array which will be quoted in function
257``register_testsuite_ns_<test_name>_interface``. See the reference code below.
258
259.. code-block:: c
260
261 /* List of test cases */
262 static void tfm_<test_name>_test_1001(struct test_result_t *ret);
263
264 /* Append test cases */
265 static struct test_t <test_name>_tests[] = {
266 {&tfm_<test_name>_test_1001, "TFM_NS_<TEST_NAME>_TEST_1001",
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800267 "Example test case"},
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800268 };
269
270 /* Register test case into test suites */
271 void register_testsuite_ns_<test_name>_interface(struct test_suite_t *p_test_suite)
272 {
273 uint32_t list_size;
274
275 list_size = (sizeof(<test_name>_tests) / sizeof(<test_name>_tests[0]));
276
277 set_testsuite("<TEST_NAME> non-secure interface test (TFM_NS_<TEST_NAME>_TEST_1XXX)",
278 <test_name>_tests, list_size, p_test_suite);
279 }
280
281 static void tfm_<test_name>_test_1001(struct test_result_t *ret)
282 {
283 /* test case code */
284 }
285
286********************
287Adding test services
288********************
289
290Some test group may need specific test services. These test services may support
291one or more groups thus developers shall determine the proper test scope.
292
293Steps
294=====
295
296Adding a test service is same as adding a secure partition, generally the
297process can be referenced from the document
298:doc:`Adding Secure Partition </docs/integration_guide/services/tfm_secure_partition_addition>`
299
300.. Note::
301 Each test service must have resource requirements declared in a manifest
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800302 file, the contents of test services are the same as secure partitions, but
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800303 their locations are different. Test service manifests shall be set in
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800304 ``tf-m-tests/test/secure_fw/tfm_test_manifest_list.yaml``.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800305
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800306Test service implementation
307===========================
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800308
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800309Test service of individual test
310-------------------------------
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800311
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800312An individual test dedicated test service should be put under the corresponding
313test folder ``test/secure_fw/suites/<test_name>``.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800314
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800315``add_subdirectory(suites/<test_name>/<service_dir>)`` shall be added into
316``tf-m-tests/test/secure_fw/secure_tests.cmake`` to make sure that the test
317service is built with secure side configuration.
318
319Common test service
320-------------------
321
322If a new test service is required by multiple test suites, the code should be
323put under ``test/secure_fw/common_test_services``. If the new test suite relies
324on a common test service, please make sure that the build implementation of the
325test service is linked correctly, including the header files and libraries.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800326
Jianliang Shen4009df82021-09-02 14:46:23 +0800327**********************************
328Out-of-tree regression test suites
329**********************************
330
331TF-M supports out-of-tree regression test suites build, whose source code
332folders are maintained outside tf-m-tests repo. There are two configurations
333for developers to include the source code.
334
335- ``EXTRA_NS_TEST_SUITES_PATHS``
336
337 A list of the absolute directories of the out-of-tree non-secure test suites
338 source code folder(s). TF-M build system searches ``CMakeLists.txt`` of
339 non-secure test suites in the source code folder(s).
340 Use semicolons ``;`` to separate multiple out-of-tree non-secure test suites
341 directorires.
342
343- ``EXTRA_S_TEST_SUITES_PATHS``
344
345 A list of the absolute directories of the out-of-tree secure test suites
346 source code folder(s).
347
348Example usage
349=============
350
351Take non-secure test as an example in
352`tf-m-extras <https://git.trustedfirmware.org/TF-M/tf-m-extras.git/>`__.
353A single out-of-tree test suite folder can be organized as the figure below:
354
355.. code-block:: bash
356
357 extra_ns
358 ├── CMakeLists.txt
359 ├── ns_test.c
360 ├── ns_test_config.cmake
361 └── ns_test.h
362
363In the example above, ``EXTRA_NS_TEST_SUITES_PATHS`` in the build command can be
364specified as listed below.
365
366.. code-block:: bash
367
368 -DEXTRA_NS_TEST_SUITES_PATHS=<Absolute-path-extra-test-folder>
369
370Coding instructions
371===================
372
373This is a demo of source code so the structure has been simplified. Files like
374``ns_test.c`` and ``ns_test.h`` can be expanded to ``src`` and ``include``
375folders. The ``CMakeLists.txt`` is required in the root path and
376``ns_test_config.cmake`` is optional.
377
378Header Files
379------------
380
381The header file ``extra_ns_tests.h`` must be included by out-of-tree source
382code. This file contains the definition of ``struct extra_tests_t``,
383``int32_t register_extra_tests()`` and declaration of
384``int32_t extra_ns_tests_init()``.
385
386Source code
387-----------
388
389To connect the out-of-tree source code and tf-m-tests framework, the high-level
390test function must be defined first. An example format is:
391
392.. code-block:: c
393
394 int32_t ns_test(void)
395 {
396 /* Add platform specific non-secure test suites code here. */
397
398 return EXTRA_TEST_SUCCESS;
399 }
400
401This function is the main entry to test framework. All the out-of-tree's test
402cases can be added into it. The returned error code of this function is
403specified as ``int32_t``. This function shall return an expected value which is
404same as the part ``expected_ret`` set in ``plat_ns_t`` below, take the macro
405EXTRA_TEST_SUCCESS as an example.
406
407After ``ns_test()`` is defined, a structure variable need to be created like:
408
409.. code-block:: c
410
411 const struct extra_tests_t plat_ns_t = {
412 .test_entry = ns_test,
413 .expected_ret = EXTRA_TEST_SUCCESS
414 };
415
416It will be used by function ``extra_ns_tests_init()`` to register the test by
417function ``register_extra_tests()``:
418
419.. code-block:: c
420
421 int32_t extra_ns_tests_init(struct extra_tests_t *internal_test_t)
422 {
423 /* Add platform init code here. */
424
425 return register_extra_tests(internal_test_t, &plat_ns_t);
426 }
427
428The platform initialization code can be added in this function because it runs
429before ``ns_test()``.
430
431.. Note::
432 Function ``extra_ns_tests_init()`` is declared in tf-m-tests repository
433 without definition. It is supplied to out-of-tree source code and need to be
434 defined with no change of its format, like returns error code and parameter
435 name.
436
437
438CMakeLists.txt
439--------------
440
441In addition to the implementation of CMAKE target like ``example_test_ns`` of
442out-of-tree source code, the configuration below needs to be appended:
443
444.. code-block:: cmake
445
446 # Example test must link tfm_test_suite_extra_common to use related interface
447 target_link_libraries(example_test_ns
448 PRIVATE
449 tfm_test_suite_extra_common
450 )
451
452 # The example_test_ns library must be linked by tfm_test_suite_extra_common
453 target_link_libraries(tfm_test_suite_extra_ns
454 PRIVATE
455 example_test_ns
456 )
457
458To use the interfaces come from tf-m-tests repository, library
459``tfm_test_suite_extra_common`` must be linked by ``example_test_ns``.
460To add out-of-tree test into TF-M, library ``example_test_ns`` must be linked
461by ``tfm_test_suite_extra_ns``.
462
463ns_test_config.cmake
464--------------------
465
466The CMAKE configuration file is optional. If out-of-tree source already exists
467another configuration file, a new one can be ignored.
468
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800469--------------
470
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800471*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*