dhgdh

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by joey shelton

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 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