blob: 87d6041edcb5d040bda6199384e48b07ba9035af [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
Kevin Pengec0e5ce2022-02-17 13:48:51 +0800306Test Partition Specific Manifest Attributes
307===========================================
308There are some test purpose attributes in Secure Partition manifests that are
309**NOT** compatible with FF-M.
310They should be used in Test Partitions only.
311
312weak_dependencies
313-----------------
314A TF-M regression test Partition calls other RoT services for test. But it
315can still run other tests if some of the RoT services are disabled.
316TF-M defines a ``"weak_dependencies"`` attribute in partition manifests of
317regression test partitions to describe test service access to other RoT
318services. It *shall* be only used for TF-M regression test services.
319
320model
321-----
322A TF-M regression test Partition may support both the SFN and IPC model.
323The actual model being used follows the SPM backend enabled.
324
325The TF-M build system supports this by allowing Secure Partitions to set
326the ``model`` attribute to ``dual``.
327The manifest tool will then change it to the corresponding value according
328to the current backend selected.
329
330The Test Partitions use the following definitions to know what model is being
331built:
332
333- ``<<partition_name>>_MODEL_IPC``, ``1`` if IPC model is used.
334- ``<<partition_name>>_MODEL_SFN``, ``1`` if SFN model is used.
335
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800336Test service implementation
337===========================
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800338
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800339Test service of individual test
340-------------------------------
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800341
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800342An individual test dedicated test service should be put under the corresponding
343test folder ``test/secure_fw/suites/<test_name>``.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800344
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800345``add_subdirectory(suites/<test_name>/<service_dir>)`` shall be added into
346``tf-m-tests/test/secure_fw/secure_tests.cmake`` to make sure that the test
347service is built with secure side configuration.
348
349Common test service
350-------------------
351
352If a new test service is required by multiple test suites, the code should be
353put under ``test/secure_fw/common_test_services``. If the new test suite relies
354on a common test service, please make sure that the build implementation of the
355test service is linked correctly, including the header files and libraries.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800356
Jianliang Shen4009df82021-09-02 14:46:23 +0800357**********************************
358Out-of-tree regression test suites
359**********************************
360
361TF-M supports out-of-tree regression test suites build, whose source code
362folders are maintained outside tf-m-tests repo. There are two configurations
363for developers to include the source code.
364
365- ``EXTRA_NS_TEST_SUITES_PATHS``
366
367 A list of the absolute directories of the out-of-tree non-secure test suites
368 source code folder(s). TF-M build system searches ``CMakeLists.txt`` of
369 non-secure test suites in the source code folder(s).
370 Use semicolons ``;`` to separate multiple out-of-tree non-secure test suites
371 directorires.
372
373- ``EXTRA_S_TEST_SUITES_PATHS``
374
375 A list of the absolute directories of the out-of-tree secure test suites
376 source code folder(s).
377
378Example usage
379=============
380
381Take non-secure test as an example in
382`tf-m-extras <https://git.trustedfirmware.org/TF-M/tf-m-extras.git/>`__.
383A single out-of-tree test suite folder can be organized as the figure below:
384
385.. code-block:: bash
386
387 extra_ns
388 ├── CMakeLists.txt
389 ├── ns_test.c
390 ├── ns_test_config.cmake
391 └── ns_test.h
392
393In the example above, ``EXTRA_NS_TEST_SUITES_PATHS`` in the build command can be
394specified as listed below.
395
396.. code-block:: bash
397
398 -DEXTRA_NS_TEST_SUITES_PATHS=<Absolute-path-extra-test-folder>
399
400Coding instructions
401===================
402
403This is a demo of source code so the structure has been simplified. Files like
404``ns_test.c`` and ``ns_test.h`` can be expanded to ``src`` and ``include``
405folders. The ``CMakeLists.txt`` is required in the root path and
406``ns_test_config.cmake`` is optional.
407
408Header Files
409------------
410
411The header file ``extra_ns_tests.h`` must be included by out-of-tree source
412code. This file contains the definition of ``struct extra_tests_t``,
413``int32_t register_extra_tests()`` and declaration of
414``int32_t extra_ns_tests_init()``.
415
416Source code
417-----------
418
419To connect the out-of-tree source code and tf-m-tests framework, the high-level
420test function must be defined first. An example format is:
421
422.. code-block:: c
423
424 int32_t ns_test(void)
425 {
426 /* Add platform specific non-secure test suites code here. */
427
428 return EXTRA_TEST_SUCCESS;
429 }
430
431This function is the main entry to test framework. All the out-of-tree's test
432cases can be added into it. The returned error code of this function is
433specified as ``int32_t``. This function shall return an expected value which is
434same as the part ``expected_ret`` set in ``plat_ns_t`` below, take the macro
435EXTRA_TEST_SUCCESS as an example.
436
437After ``ns_test()`` is defined, a structure variable need to be created like:
438
439.. code-block:: c
440
441 const struct extra_tests_t plat_ns_t = {
442 .test_entry = ns_test,
443 .expected_ret = EXTRA_TEST_SUCCESS
444 };
445
446It will be used by function ``extra_ns_tests_init()`` to register the test by
447function ``register_extra_tests()``:
448
449.. code-block:: c
450
451 int32_t extra_ns_tests_init(struct extra_tests_t *internal_test_t)
452 {
453 /* Add platform init code here. */
454
455 return register_extra_tests(internal_test_t, &plat_ns_t);
456 }
457
458The platform initialization code can be added in this function because it runs
459before ``ns_test()``.
460
461.. Note::
462 Function ``extra_ns_tests_init()`` is declared in tf-m-tests repository
463 without definition. It is supplied to out-of-tree source code and need to be
464 defined with no change of its format, like returns error code and parameter
465 name.
466
467
468CMakeLists.txt
469--------------
470
471In addition to the implementation of CMAKE target like ``example_test_ns`` of
472out-of-tree source code, the configuration below needs to be appended:
473
474.. code-block:: cmake
475
476 # Example test must link tfm_test_suite_extra_common to use related interface
477 target_link_libraries(example_test_ns
478 PRIVATE
479 tfm_test_suite_extra_common
480 )
481
482 # The example_test_ns library must be linked by tfm_test_suite_extra_common
483 target_link_libraries(tfm_test_suite_extra_ns
484 PRIVATE
485 example_test_ns
486 )
487
488To use the interfaces come from tf-m-tests repository, library
489``tfm_test_suite_extra_common`` must be linked by ``example_test_ns``.
490To add out-of-tree test into TF-M, library ``example_test_ns`` must be linked
491by ``tfm_test_suite_extra_ns``.
492
493ns_test_config.cmake
494--------------------
495
496The CMAKE configuration file is optional. If out-of-tree source already exists
497another configuration file, a new one can be ignored.
498
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800499--------------
500
Jianliang Shen53f7ecd2022-02-22 10:57:51 +0800501*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*