STM32F7 Ethernet interface for nucleo STM32F767

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers utest_types.h Source File

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 /** @}*/