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