Paul Beesley | 5c92895 | 2019-10-24 11:57:00 +0000 | [diff] [blame^] | 1 | Implementing Tests |
| 2 | ================== |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 3 | |
| 4 | This document aims at providing some pointers to help implementing new tests in |
| 5 | the TFTF image. |
| 6 | |
| 7 | Structure of a test |
| 8 | ------------------- |
| 9 | |
| 10 | A test might be divided into 3 logical parts, detailed in the following |
| 11 | sections. |
| 12 | |
| 13 | Prologue |
| 14 | '''''''' |
| 15 | |
| 16 | A test has a main entry point function, whose type is: |
| 17 | |
| 18 | :: |
| 19 | |
| 20 | typedef test_result_t (*test_function_t)(void); |
| 21 | |
| 22 | See `tftf/framework/include/tftf.h`_. |
| 23 | |
| 24 | Only the primary CPU enters this function, while other CPUs are powered down. |
| 25 | |
| 26 | First of all, the test function should check whether this test is applicable to |
| 27 | this platform and environment. Some tests rely on specific hardware features or |
| 28 | firmware capabilities to be present. If these are not available, the test should |
| 29 | be skipped. For example, a multi-core test requires at least 2 CPUs to |
| 30 | run. Macros and functions are provided in `include/common/test_helpers.h`_ to |
| 31 | help test code verify that their requirements are met. |
| 32 | |
| 33 | Core |
| 34 | '''' |
| 35 | |
| 36 | This is completely dependent on the purpose of the test. The paragraphs below |
| 37 | just provide some useful, general information. |
| 38 | |
| 39 | The primary CPU may power on other CPUs by calling the function |
| 40 | ``tftf_cpu_on()``. It provides an address to which secondary CPUs should jump |
| 41 | to once they have been initialized by the test framework. This address should be |
| 42 | different from the primary CPU test function. |
| 43 | |
| 44 | Synchronization primitives are provided in `include/lib/events.h`_ in case CPUs' |
| 45 | execution threads need to be synchronized. Most multi-processing tests will need |
| 46 | some synchronisation points that all/some CPUs need to reach before test |
| 47 | execution may continue. |
| 48 | |
| 49 | Any CPU that is involved in a test must return from its test function. Failure |
| 50 | to do so will put the framework in an unrecoverable state, see the `TFTF known |
| 51 | limitations`_. The return code indicates the test result from the point of view |
| 52 | of this CPU. At the end of the test, individual CPU results are aggregated and |
| 53 | the overall test result is derived from that. A test is considered as passed if |
| 54 | all involved CPUs reported a success status code. |
| 55 | |
| 56 | Epilogue |
| 57 | '''''''' |
| 58 | |
| 59 | Each test is responsible for releasing any allocated resources and putting the |
| 60 | system back in a clean state when it finishes. Any change to the system |
| 61 | configuration (e.g. MMU setup, GIC configuration, system registers, ...) must be |
| 62 | undone and the original configuration must be restored. This guarantees that the |
| 63 | next test is not affected by the actions of the previous one. |
| 64 | |
| 65 | One exception to this rule is that CPUs powered on as part of a test must not be |
| 66 | powered down. As already stated above, as soon as a CPU enters the test, the |
| 67 | framework expects it to return from the test. |
| 68 | |
| 69 | Template test code |
| 70 | ------------------ |
| 71 | |
| 72 | Some template test code is provided in `tftf/tests/template_tests`_. It can be |
| 73 | used as a starting point for developing new tests. Template code for both |
| 74 | single-core and multi-core tests is provided. |
| 75 | |
| 76 | Plugging the test into the build system |
| 77 | --------------------------------------- |
| 78 | |
| 79 | All test code is located under the `tftf/tests`_ directory. Tests are usually |
| 80 | divided into categories represented as sub-directories under ``tftf/tests/``. |
| 81 | |
| 82 | The source file implementing the new test code should be added to the |
| 83 | appropriate tests makefile, see `.*mk` files under `tftf/tests`_. |
| 84 | |
| 85 | The new test code should also appear in a tests manifest, see ``*.xml`` files |
| 86 | under `tftf/tests`_. A unique name and test function must be provided. An |
| 87 | optional description may be provided as well. |
| 88 | |
| 89 | For example, to create a test case named "``Foo test case``", whose test |
| 90 | function is ``foo()``, add the following line in the tests manifest: |
| 91 | |
| 92 | :: |
| 93 | |
| 94 | <testcase name="Foo test case" function="foo" /> |
| 95 | |
| 96 | A testcase must be part of a testsuite. The ``testcase`` XML node above must be |
| 97 | inside a ``testsuite`` XML node. A unique name and a description must be |
| 98 | provided for the testsuite. |
| 99 | |
| 100 | For example, to create a test suite named "``Bar test suite``", whose |
| 101 | description is: "``An example test suite``", add the following 2 lines: |
| 102 | |
| 103 | :: |
| 104 | |
| 105 | <testsuite name="Bar test suite" description="An example test suite"> |
| 106 | </testsuite> |
| 107 | |
| 108 | See the template test manifest for reference: `tftf/tests/tests-template.xml`_. |
| 109 | |
| 110 | -------------- |
| 111 | |
Paul Beesley | 5c92895 | 2019-10-24 11:57:00 +0000 | [diff] [blame^] | 112 | *Copyright (c) 2018-2019, Arm Limited. All rights reserved.* |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 113 | |
| 114 | .. _SMC Calling Convention: SMCCC_ |
| 115 | .. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf |
| 116 | |
| 117 | .. _TFTF known limitations: change-log.rst#test-framework |
| 118 | .. _tftf/framework/include/tftf.h: ../tftf/framework/include/tftf.h |
| 119 | .. _tftf/tests: ../tftf/tests |
| 120 | .. _tftf/tests/template_tests: ../tftf/tests/template_tests |
| 121 | .. _tftf/tests/tests-template.xml: ../tftf/tests/tests-template.xml |
| 122 | .. _include/common/test_helpers.h: ../include/common/test_helpers.h |
| 123 | .. _include/lib/events.h: ../include/lib/events.h |