blob: e3802f4e97fce24af8aaac003412afa8c8380373 [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
11TF-M regression tests test whether changes to TF-M features work as expected.
12This documentation focus on three parts in TF-M regression tests:
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``: 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
25+----------------+-------------------------------------------------------------+
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/suites | Test suites divided into subdirectories. |
33+----------------+-------------------------------------------------------------+
34| test/services | Test services divided into subdirectories. |
35+----------------+-------------------------------------------------------------+
36
37Test configuration
38==================
39
40A test configuration controls whether one or multiple test suites are enabled.
41The doc :doc:`TF-M Build Instructions </docs/technical_references/instructions/tfm_build_instruction>`
42shows some test configurations which are already supported in current TF-M.
43An example usage of test configuration shows below.
44
45.. code-block:: bash
46
47 cmake -S . -B cmake_build -DTFM_PLATFORM=arm/mps2/an521 \
48 -DTFM_TOOLCHAIN_FILE=toolchain_GNUARM.cmake \
49 -DCMAKE_BUILD_TYPE=Release \
Jianliang Shenbde10ed2021-08-25 13:48:00 +080050 -DTEST_NS_ATTESTATION=ON
51
52With this command, only non-secure initial attestation test suite will be built.
53
54***********************
55Adding a new test suite
56***********************
57
58This section introduces how to add a new test suite and control its compilation
59with a test configuration in ``tf-m-tests`` repository.
60
61Source code
62===========
63
64The test suite example subdirectory named ``<test_name>`` is located under the path
65``tf-m-tests/test/suites``. If the new test suite includes both non-secure and
66secure parts, the source code shall be divided shared code and specific code.
67An example test suite folder can be organized as the figure below.
68
69.. code-block:: bash
70
71 .
72 ├── CMakeLists.txt
73 ├── <test_name>_tests_common.c
74 ├── non_secure
75 ├── <test_name>_ns_interface_testsuite.c
76 └── <test_name>_ns_tests.h
77 └── secure
78 ├── <test_name>_s_interface_testsuite.c
79 └── <test_name>_s_tests.h
80
81Creating test configurations
82============================
83
84Developers shall assign corresponding test configurations to control the test
85suites.
86
87Naming test configurations
88--------------------------
89
90The test configurations of example test suites are ``TEST_NS_<TEST_NAME>``
91in non-secure and ``TEST_S_<TEST_NAME>`` in secure.
92
93.. Note::
94 The test configurations must be named with the prefixes ``TEST_S_`` and
95 ``TEST_NS_``, for secure regression tests and non-secure regression tests
96 respectively. Otherwise, tf-m-tests build system may not recognize it.
97
98Setting test configurations
99---------------------------
100
101When the test configurations have dependences, the default value need to be set.
102The setting is performed in following four steps.
103
104#. Command line input: The configuration can be enabled or disabled by the
105 command ``-DTEST_NS_<TEST_NAME>=ON/OFF -DTEST_S_<TEST_NAME>=ON/OFF``, and
106 the value cannot be changed throughout the whole compilation of TF-M tests.
107
108#. ``tf-m-tests/config/set_config.cmake``: The test configurations shall be
109 OFF if its dependences are not supported. The dependences are probably
110 from:
111
112 #. TF-M partitions configurations like ``TFM_PARTITION_CRYPTO``,
113 ``TFM_PARTITION_INITIAL_ATTESTATION``, etc.
Kevin Peng23a583c2021-09-08 22:33:33 +0800114 #. TF-M build mode configuration like ``TFM_LIB_MODEL``.
Jianliang Shenbde10ed2021-08-25 13:48:00 +0800115 #. TF-M other configurations like ``TFM_PARTITION_FIRMWARE_UPDATE``,
116 ``FORWARD_PROT_MSG``, etc.
117
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
142Applicating test configurations
143===============================
144
145The mission of test configurations is to control the build. They are applied
146in ``test/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
220 secure sevices shall be linked together in the file
221 ``tf-m-tests/test/test_services/CMakeLists.txt``. 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
227 if (TEST_FRAMEWORK_S)
228 # ...
229 if (TEST_S_<TEST_NAME>)
230 add_library(tfm_test_suite_<test_name>_s STATIC EXCLUDE_FROM_ALL)
231 endif()
232 endif()
233
234************************************
235Adding a new test case in test suite
236************************************
237
238The test cases usually express as a function in source code. They will be added
239into an array with structure type called ``test_t`` defined in
240``tf-m-tests/test/framework/test_framework.h``.
241
242.. code-block:: c
243
244 struct test_t {
245 TEST_FUN * const test; /*!< Test function to call */
246 const char *name; /*!< Test name */
247 const char *desc; /*!< Test description */
248 struct test_result_t ret; /*!< Test result */
249 };
250
251For example, a new test case called ``TFM_NS_<TEST_NAME>_TEST_1001`` is created
252and the function ``tfm_<test_name>_test_1001`` needs to be defined in file
253``<test_name>_ns_interface_testsuite.c``. Then the function shall be appended
254into the array which will be quoted in function
255``register_testsuite_ns_<test_name>_interface``. See the reference code below.
256
257.. code-block:: c
258
259 /* List of test cases */
260 static void tfm_<test_name>_test_1001(struct test_result_t *ret);
261
262 /* Append test cases */
263 static struct test_t <test_name>_tests[] = {
264 {&tfm_<test_name>_test_1001, "TFM_NS_<TEST_NAME>_TEST_1001",
265 "Example test case", {TEST_PASSED}},
266 };
267
268 /* Register test case into test suites */
269 void register_testsuite_ns_<test_name>_interface(struct test_suite_t *p_test_suite)
270 {
271 uint32_t list_size;
272
273 list_size = (sizeof(<test_name>_tests) / sizeof(<test_name>_tests[0]));
274
275 set_testsuite("<TEST_NAME> non-secure interface test (TFM_NS_<TEST_NAME>_TEST_1XXX)",
276 <test_name>_tests, list_size, p_test_suite);
277 }
278
279 static void tfm_<test_name>_test_1001(struct test_result_t *ret)
280 {
281 /* test case code */
282 }
283
284********************
285Adding test services
286********************
287
288Some test group may need specific test services. These test services may support
289one or more groups thus developers shall determine the proper test scope.
290
291Steps
292=====
293
294Adding a test service is same as adding a secure partition, generally the
295process can be referenced from the document
296:doc:`Adding Secure Partition </docs/integration_guide/services/tfm_secure_partition_addition>`
297
298.. Note::
299 Each test service must have resource requirements declared in a manifest
300 file, the contents of test services are the same as secure partitions,but
301 their locations are different. Test service manifests shall be set in
302 ``tf-m-tests/test/test_services/tfm_test_manifest_list.yaml``.
303
304Configuration
305=============
306
307If the new test service names ``tfm_<test_name>_test_service`` only supports for the
308example test, the configuration in
309``tf-m-tests/test/test_services/CMakeLists.txt`` forms like below.
310
311.. code-block:: cmake
312
313 if (TEST_S_<TEST_NAME> OR TEST_NS_<TEST_NAME>)
314 add_subdirectory(tfm_<test_name>_test_service)
315 endif()
316
317--------------
318
319*Copyright (c) 2021, Arm Limited. All rights reserved.*