Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
utest_types.h
00001 /**************************************************************************** 00002 * Copyright (c) 2015, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 **************************************************************************** 00017 */ 00018 00019 #ifndef UTEST_TYPES_H 00020 #define UTEST_TYPES_H 00021 00022 #include <stdint.h> 00023 #include <stdbool.h> 00024 #include <stdio.h> 00025 #include "utest/utest_shim.h" 00026 #include "SingletonPtr.h" 00027 00028 namespace utest { 00029 /** \addtogroup frameworks */ 00030 /** @{*/ 00031 namespace v1 { 00032 00033 /// repeat_t 00034 enum repeat_t { 00035 REPEAT_UNDECLR = 0, 00036 REPEAT_NONE = 1, ///< continue with the next test case 00037 00038 REPEAT_ON_TIMEOUT = 2, 00039 REPEAT_ON_VALIDATE = 4, 00040 REPEAT_CASE_ONLY = 8, 00041 REPEAT_SETUP_TEARDOWN = 16, 00042 00043 REPEAT_MASK = REPEAT_ON_TIMEOUT | REPEAT_ON_VALIDATE | REPEAT_CASE_ONLY | REPEAT_SETUP_TEARDOWN, 00044 00045 REPEAT_ALL_ON_TIMEOUT = REPEAT_SETUP_TEARDOWN | REPEAT_ON_TIMEOUT, ///< repeat the handler with setup and teardown on timeout 00046 REPEAT_HANDLER_ON_TIMEOUT = REPEAT_CASE_ONLY | REPEAT_ON_TIMEOUT, ///< repeat only the handler on timeout 00047 REPEAT_ALL = REPEAT_SETUP_TEARDOWN | REPEAT_ON_VALIDATE, ///< repeat the handler with setup and teardown 00048 REPEAT_HANDLER = REPEAT_CASE_ONLY | REPEAT_ON_VALIDATE ///< repeat only the handler 00049 }; 00050 00051 /// status_t 00052 enum status_t { 00053 STATUS_CONTINUE = -1, ///< continues testing 00054 STATUS_IGNORE = -2, ///< ignores failure and continues testing 00055 STATUS_ABORT = -3 ///< stops testing 00056 }; 00057 00058 /// failure_reason_t 00059 enum failure_reason_t { 00060 REASON_NONE = 0, ///< No failure occurred 00061 00062 REASON_UNKNOWN = (1 << 0), ///< An unknown failure occurred 00063 REASON_CASES = (1 << 1), ///< A failure occurred in at least one test case 00064 REASON_EMPTY_CASE = (1 << 2), ///< The test case contains only empty handlers 00065 REASON_TIMEOUT = (1 << 3), ///< An expected asynchronous call timed out 00066 REASON_ASSERTION = (1 << 4), ///< An assertion failed 00067 00068 REASON_TEST_SETUP = (1 << 5), ///< Test setup failed 00069 REASON_TEST_TEARDOWN = (1 << 6), ///< Test teardown failed 00070 REASON_CASE_SETUP = (1 << 7), ///< Case setup failed 00071 REASON_CASE_HANDLER = (1 << 8), ///< Case handler failed 00072 REASON_CASE_TEARDOWN = (1 << 9), ///< Case teardown failed 00073 00074 REASON_CASE_INDEX = (1 << 10), ///< Case index out-of-range 00075 REASON_SCHEDULER = (1 << 11), ///< Asynchronous callback scheduling failed 00076 00077 REASON_IGNORE = 0x8000 ///< The failure may be ignored 00078 }; 00079 00080 /// location_t 00081 enum location_t { 00082 LOCATION_NONE = 0, ///< No location information 00083 LOCATION_TEST_SETUP, ///< A failure occurred in the test setup 00084 LOCATION_TEST_TEARDOWN, ///< A failure occurred in the test teardown 00085 LOCATION_CASE_SETUP, ///< A failure occurred in the case setup 00086 LOCATION_CASE_HANDLER, ///< A failure occurred in the case handler 00087 LOCATION_CASE_TEARDOWN, ///< A failure occurred in the case teardown 00088 LOCATION_UNKNOWN ///< A failure occurred in an unknown location 00089 }; 00090 00091 /// Contains the reason and location of the failure. 00092 struct failure_t { 00093 failure_t() : reason(REASON_NONE), location(LOCATION_NONE) {} 00094 failure_t(failure_reason_t reason) : reason(reason), location(LOCATION_NONE) {} 00095 failure_t(location_t location) : reason(REASON_NONE), location(location) {} 00096 failure_t(failure_reason_t reason, location_t location) : reason(reason), location(location) {} 00097 00098 /// Copy constructor 00099 failure_t(const failure_t &obj){ 00100 reason = obj.reason; 00101 location = obj.location; 00102 } 00103 00104 /// @returns a copy of the failure with the reason ignored. 00105 failure_t ignored () const { 00106 return failure_t(failure_reason_t(reason | REASON_IGNORE), location); 00107 } 00108 00109 failure_reason_t reason; 00110 location_t location; 00111 }; 00112 00113 00114 enum { 00115 TIMEOUT_NONE = uint32_t(-1), ///< Do not use a timeout 00116 TIMEOUT_UNDECLR = uint32_t(-2), ///< Timeout not explicitly specified, defaults to NONE 00117 TIMEOUT_FOREVER = uint32_t(-3) ///< Never time out 00118 }; 00119 00120 /// Stringifies a failure reason for understandable error messages. 00121 const char* stringify(failure_reason_t reason); 00122 /// Stringifies a failure for understandable error messages. 00123 const char* stringify(failure_t failure); 00124 /// Stringifies a location. 00125 const char* stringify(location_t location); 00126 /// Stringifies a status. 00127 const char* stringify(utest::v1::status_t status); 00128 00129 /** POD version of the class control_t. 00130 * It is used to instantiate const control_t objects as PODs 00131 * and prevent them to be included in the final binary. 00132 * @note: control_pod_t can be converted to control_t by copy construction. 00133 */ 00134 struct base_control_t { 00135 repeat_t repeat; 00136 uint32_t timeout; 00137 00138 repeat_t inline get_repeat() const { 00139 return repeat; 00140 } 00141 uint32_t inline get_timeout() const { 00142 return timeout; 00143 } 00144 }; 00145 00146 /** Control class for specifying test case attributes 00147 * 00148 * This class encapsulated control information about test cases which, when returned from 00149 * a test case influences the behavior of the test harness. 00150 * Instead of using this class directly it is recommended to use the aliases for clearer 00151 * semantics: 00152 * @code 00153 * control_t test_case(const size_t call_count) { 00154 * // repeat 5 times for a total of 6 calls 00155 * return (call_count < 6) ? CaseRepeatHandler : CaseNext; 00156 * } 00157 * @endcode 00158 * 00159 * This class overloads the `+` operator to implement something similiar to saturated arbitration: 00160 * - The lower timeout value "wins". 00161 * - A more involved repeat "wins" (ie. `ALL` > 'HANDLER' > 'NONE'). 00162 * - Next Case always wins. 00163 * 00164 * You may then add timeouts and repeats together: 00165 * @code 00166 * control_t test_case(const size_t call_count) { 00167 * // repeat 5 times for a total of 6 calls, each with a 500ms asynchronous timeout 00168 * return CaseTimeout(500) + ((call_count < 6) ? CaseRepeatAll : CaseNoRepeat); 00169 * } 00170 * @endcode 00171 * 00172 * In the future, more control information may be added transparently and backwards compatible. 00173 */ 00174 struct control_t : private base_control_t 00175 { 00176 control_t() : base_control_t(make_base_control_t(REPEAT_UNDECLR, TIMEOUT_UNDECLR)) {} 00177 00178 control_t(repeat_t repeat, uint32_t timeout_ms) : 00179 base_control_t(make_base_control_t(repeat, timeout_ms)) {} 00180 00181 control_t(repeat_t repeat) : 00182 base_control_t(make_base_control_t(repeat, TIMEOUT_UNDECLR)) {} 00183 00184 control_t(uint32_t timeout_ms) : 00185 base_control_t(make_base_control_t(REPEAT_UNDECLR, timeout_ms)) {} 00186 00187 control_t(const base_control_t& other) : 00188 base_control_t(other) {} 00189 00190 friend control_t operator+(const control_t& lhs, const control_t& rhs) { 00191 control_t result( 00192 repeat_t(lhs.repeat | rhs.repeat), 00193 (rhs.timeout == TIMEOUT_NONE) ? rhs.timeout : lhs.timeout); 00194 00195 if (result.timeout != TIMEOUT_NONE && result.timeout > rhs.timeout) { 00196 result.timeout = rhs.timeout; 00197 } 00198 00199 if (result.repeat & REPEAT_NONE) { 00200 result.repeat = REPEAT_NONE; 00201 } 00202 else { 00203 if (result.repeat & REPEAT_SETUP_TEARDOWN) { 00204 result.repeat = repeat_t(result.repeat & ~REPEAT_CASE_ONLY); 00205 } 00206 if (result.timeout == TIMEOUT_NONE && result.repeat & REPEAT_ON_TIMEOUT) { 00207 result.repeat = repeat_t(result.repeat & ~REPEAT_ON_TIMEOUT); 00208 } 00209 } 00210 00211 return result; 00212 } 00213 00214 repeat_t 00215 inline get_repeat() const { 00216 return repeat; 00217 } 00218 uint32_t 00219 inline get_timeout() const { 00220 return timeout; 00221 } 00222 00223 private: 00224 static base_control_t make_base_control_t(repeat_t repeat, uint32_t timeout) { 00225 base_control_t result = { 00226 repeat, 00227 timeout 00228 }; 00229 return result; 00230 } 00231 00232 friend class Harness; 00233 }; 00234 00235 /// @see operator+ in control_t 00236 inline control_t operator+ (const base_control_t& lhs, const base_control_t& rhs) { 00237 return control_t(lhs) + control_t(rhs); 00238 } 00239 00240 /// @see operator+ in control_t 00241 inline control_t operator+ (const base_control_t& lhs, const control_t& rhs) { 00242 return control_t(lhs) + rhs; 00243 } 00244 00245 /// @see operator+ in control_t 00246 inline control_t operator+ (const control_t& lhs, const base_control_t& rhs) { 00247 return lhs + control_t(rhs); 00248 } 00249 00250 /// does not repeat this test case and immediately moves on to the next one without timeout 00251 extern const base_control_t CaseNext; 00252 00253 /// does not repeat this test case, moves on to the next one 00254 extern const base_control_t CaseNoRepeat; 00255 /// repeats the test case handler with calling teardown and setup handlers 00256 extern const base_control_t CaseRepeatAll; 00257 /// repeats only the test case handler without calling teardown and setup handlers 00258 extern const base_control_t CaseRepeatHandler; 00259 00260 /// No timeout, immediately moves on to the next case, but allows repeats 00261 extern const base_control_t CaseNoTimeout; 00262 /// Awaits until the callback is validated and never times out. Use with caution! 00263 extern const base_control_t CaseAwait; 00264 /// Alias class for asynchronous timeout control in milliseconds 00265 inline control_t CaseTimeout(uint32_t ms) { return ms; } 00266 00267 /// Alias class for asynchronous timeout control in milliseconds and 00268 /// repeats the test case handler with calling teardown and setup handlers 00269 inline control_t CaseRepeatAllOnTimeout(uint32_t ms) { return control_t(REPEAT_ALL_ON_TIMEOUT, ms); } 00270 /// Alias class for asynchronous timeout control in milliseconds and 00271 /// repeats only the test case handler without calling teardown and setup handlers 00272 inline control_t CaseRepeatHandlerOnTimeout(uint32_t ms) { return control_t(REPEAT_HANDLER_ON_TIMEOUT, ms); } 00273 00274 class Case; // forward declaration 00275 00276 /** Test setup handler. 00277 * 00278 * This handler is called before execution of any test case and 00279 * allows you to initialize your common test environment. 00280 * 00281 * @param number_of_cases the total number of test cases in the test specification 00282 * 00283 * @returns 00284 * You can return `STATUS_ABORT` if you initialization failed and the test teardown handler will 00285 * then be called with the `REASON_SETUP`. 00286 */ 00287 typedef utest::v1::status_t (*test_setup_handler_t)(const size_t number_of_cases); 00288 00289 /** Test teardown handler. 00290 * 00291 * This handler is called after execution of all test case or if test execution is aborted. 00292 * You can use this handler to de-initialize your test environment and output test statistics. 00293 * The failure argument contains the immediate reason why this handler is called. 00294 * If the test completed normally without failures, this will contain `REASON_NONE`. 00295 * 00296 * After execution of this handler, the test harness will stop execution. 00297 * 00298 * @param passed the number of cases without failures 00299 * @param failed the number of cases with at least one failure 00300 * @param failure the reason why this handler was called 00301 */ 00302 typedef void (*test_teardown_handler_t)(const size_t passed, const size_t failed, const failure_t failure); 00303 00304 /** Test failure handler. 00305 * 00306 * This handler is called anytime a failure occurs during the execution of a test speficication. 00307 * The handler only allows logging of failures and cannot influence test execution. 00308 * 00309 * @param failure the reason why this handler was called 00310 */ 00311 typedef void (*test_failure_handler_t)(const failure_t reason); 00312 00313 /** Test case setup handler. 00314 * 00315 * This handler is called before execution of each test case and 00316 * allows you to modify your environment before each test case. 00317 * 00318 * @param source the test case to be setup 00319 * @param index_of_case the current index of the test case within the specification 00320 * 00321 * @returns 00322 * You can return `STATUS_ABORT` to indicate that your setup failed, which will call the case 00323 * failure handler with `REASON_SETUP` and then the case teardown handler with `REASON_SETUP`. 00324 * This gives the teardown handler a chance to clean up a failed setup. 00325 */ 00326 typedef utest::v1::status_t (*case_setup_handler_t)(const Case *const source, const size_t index_of_case); 00327 00328 /** Primitive test case handler 00329 * 00330 * This handler is called only if the case setup succeeded and is followed by the test case teardown handler. 00331 * 00332 * @note This handler is executed only once. 00333 */ 00334 typedef void (*case_handler_t)(void); 00335 00336 /** Complex test case handler 00337 * 00338 * This handler is called only if the case setup succeeded and then may be repeated or 00339 * awaiting a asynchronous callback, depending on the return modifiers. 00340 * 00341 * @returns 00342 * A combination of control modifiers. 00343 */ 00344 typedef control_t (*case_control_handler_t)(void); 00345 00346 /** Test case handler (repeatable) 00347 * 00348 * This handler is called only if the case setup succeeded and then may be repeated or 00349 * awaiting a asynchronous callback, depending on the return modifiers. 00350 * 00351 * @param call_count starting at `1`, contains the number of times this handler has been called 00352 * 00353 * @returns 00354 * A combination of control modifiers. 00355 */ 00356 typedef control_t (*case_call_count_handler_t)(const size_t call_count); 00357 00358 /** Test case teardown handler. 00359 * 00360 * This handler is called after execution of each test case or all repeated test cases and 00361 * allows you to reset your environment after each test case. 00362 * 00363 * @param source the test case to be torn down 00364 * @param passed the number of cases without failures (can be >1 for repeated test cases) 00365 * @param failed the number failures (can be larger than the number of (repeated) test cases) 00366 * @param failure the reason why this handler was called 00367 * 00368 * @returns 00369 * You can return `STATUS_ABORT` to indicate that your teardown failed, which will call the case 00370 * failure handler with `REASON_TEARDOWN`. 00371 */ 00372 typedef utest::v1::status_t (*case_teardown_handler_t)(const Case *const source, const size_t passed, const size_t failed, const failure_t reason); 00373 00374 /** Test case failure handler. 00375 * 00376 * This handler is called whenever a failure occurred during the setup, execution or teardown. 00377 * 00378 * @param source the test case in which the failure occurred 00379 * @param reason the reason why this handler was called 00380 * 00381 * @returns 00382 * You can return `STATUS_ABORT` to indicate that this failure is non-recoverable, which will call the case 00383 * teardown handler with reason. If a failure occurs during teardown, the teardown will not be called again. 00384 * You may return `STATUS_IGNORE` which will cause the harness to ignore and not count the failure. 00385 */ 00386 typedef utest::v1::status_t (*case_failure_handler_t)(const Case *const source, const failure_t reason); 00387 00388 00389 // deprecations 00390 __deprecated_message("Use CaseRepeatAll instead.") 00391 extern const base_control_t CaseRepeat; 00392 00393 __deprecated_message("Use CaseRepeatHandler instead.") 00394 extern const base_control_t CaseRepeatHandlerOnly; 00395 00396 __deprecated_message("Use REASON_NONE instead.") const failure_reason_t FAILURE_NONE = REASON_NONE; 00397 __deprecated_message("Use REASON_UNKNOWN instead.") const failure_reason_t FAILURE_UNKNOWN = REASON_UNKNOWN; 00398 __deprecated_message("Use REASON_CASES instead.") const failure_reason_t FAILURE_CASES = REASON_CASES; 00399 __deprecated_message("Use REASON_EMPTY_CASE instead.") const failure_reason_t FAILURE_EMPTY_CASE = REASON_EMPTY_CASE; 00400 __deprecated_message("Use REASON_TIMEOUT instead.") const failure_reason_t FAILURE_TIMEOUT = REASON_TIMEOUT; 00401 __deprecated_message("Use REASON_ASSERTION instead.") const failure_reason_t FAILURE_ASSERTION = REASON_ASSERTION; 00402 __deprecated_message("Use REASON_CASE_SETUP instead.") const failure_reason_t FAILURE_SETUP = REASON_CASE_SETUP; 00403 __deprecated_message("Use REASON_CASE_TEARDOWN instead.") const failure_reason_t FAILURE_TEARDOWN = REASON_CASE_TEARDOWN; 00404 __deprecated_message("Use REASON_IGNORE instead.") const failure_reason_t FAILURE_IGNORE = REASON_IGNORE; 00405 00406 00407 } // namespace v1 00408 } // namespace utest 00409 00410 #endif // UTEST_TYPES_H 00411 00412 /** @}*/
Generated on Sun Jul 17 2022 08:25:33 by 1.7.2