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