mbed-os for GR-LYCHEE

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:f782d9c66c49 1 /****************************************************************************
dkato 0:f782d9c66c49 2 * Copyright (c) 2015, ARM Limited, All Rights Reserved
dkato 0:f782d9c66c49 3 * SPDX-License-Identifier: Apache-2.0
dkato 0:f782d9c66c49 4 *
dkato 0:f782d9c66c49 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
dkato 0:f782d9c66c49 6 * not use this file except in compliance with the License.
dkato 0:f782d9c66c49 7 * You may obtain a copy of the License at
dkato 0:f782d9c66c49 8 *
dkato 0:f782d9c66c49 9 * http://www.apache.org/licenses/LICENSE-2.0
dkato 0:f782d9c66c49 10 *
dkato 0:f782d9c66c49 11 * Unless required by applicable law or agreed to in writing, software
dkato 0:f782d9c66c49 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
dkato 0:f782d9c66c49 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dkato 0:f782d9c66c49 14 * See the License for the specific language governing permissions and
dkato 0:f782d9c66c49 15 * limitations under the License.
dkato 0:f782d9c66c49 16 ****************************************************************************
dkato 0:f782d9c66c49 17 */
dkato 0:f782d9c66c49 18
dkato 0:f782d9c66c49 19 #include "utest/utest_harness.h"
dkato 0:f782d9c66c49 20 #include "utest/utest_stack_trace.h"
dkato 0:f782d9c66c49 21 #include "utest/utest_serial.h"
dkato 0:f782d9c66c49 22
dkato 0:f782d9c66c49 23 #include <stdlib.h>
dkato 0:f782d9c66c49 24
dkato 0:f782d9c66c49 25 using namespace utest::v1;
dkato 0:f782d9c66c49 26
dkato 0:f782d9c66c49 27 namespace
dkato 0:f782d9c66c49 28 {
dkato 0:f782d9c66c49 29 const Case *test_cases = NULL;
dkato 0:f782d9c66c49 30 size_t test_length = 0;
dkato 0:f782d9c66c49 31
dkato 0:f782d9c66c49 32 size_t test_index_of_case = 0;
dkato 0:f782d9c66c49 33
dkato 0:f782d9c66c49 34 size_t test_passed = 0;
dkato 0:f782d9c66c49 35 size_t test_failed = 0;
dkato 0:f782d9c66c49 36
dkato 0:f782d9c66c49 37 const Case *case_current = NULL;
dkato 0:f782d9c66c49 38 size_t case_index = 0;
dkato 0:f782d9c66c49 39 base_control_t case_control = { REPEAT_SETUP_TEARDOWN, TIMEOUT_UNDECLR };
dkato 0:f782d9c66c49 40 size_t case_repeat_count = 1;
dkato 0:f782d9c66c49 41
dkato 0:f782d9c66c49 42 void *case_timeout_handle = NULL;
dkato 0:f782d9c66c49 43 size_t case_validation_count = 0;
dkato 0:f782d9c66c49 44 bool case_timeout_occurred = false;
dkato 0:f782d9c66c49 45
dkato 0:f782d9c66c49 46 size_t case_passed = 0;
dkato 0:f782d9c66c49 47 size_t case_failed = 0;
dkato 0:f782d9c66c49 48 size_t case_failed_before = 0;
dkato 0:f782d9c66c49 49
dkato 0:f782d9c66c49 50 struct DefaultHandlers : public handlers_t {
dkato 0:f782d9c66c49 51 DefaultHandlers() : handlers_t(default_handlers) { }
dkato 0:f782d9c66c49 52 DefaultHandlers(const handlers_t& other) : handlers_t(other) { }
dkato 0:f782d9c66c49 53 };
dkato 0:f782d9c66c49 54
dkato 0:f782d9c66c49 55 SingletonPtr<DefaultHandlers> defaults;
dkato 0:f782d9c66c49 56 SingletonPtr<DefaultHandlers> handlers;
dkato 0:f782d9c66c49 57
dkato 0:f782d9c66c49 58 location_t location = LOCATION_UNKNOWN;
dkato 0:f782d9c66c49 59
dkato 0:f782d9c66c49 60 utest_v1_scheduler_t scheduler = {NULL, NULL, NULL, NULL};
dkato 0:f782d9c66c49 61 }
dkato 0:f782d9c66c49 62
dkato 0:f782d9c66c49 63 static void die() {
dkato 0:f782d9c66c49 64 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 65 while(1) ;
dkato 0:f782d9c66c49 66 }
dkato 0:f782d9c66c49 67
dkato 0:f782d9c66c49 68 static bool is_scheduler_valid(const utest_v1_scheduler_t scheduler)
dkato 0:f782d9c66c49 69 {
dkato 0:f782d9c66c49 70 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 71 return (scheduler.init && scheduler.post && scheduler.cancel && scheduler.run);
dkato 0:f782d9c66c49 72 }
dkato 0:f782d9c66c49 73
dkato 0:f782d9c66c49 74 bool Harness::set_scheduler(const utest_v1_scheduler_t scheduler)
dkato 0:f782d9c66c49 75 {
dkato 0:f782d9c66c49 76 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 77 if (is_scheduler_valid(scheduler)) {
dkato 0:f782d9c66c49 78 ::scheduler = scheduler;
dkato 0:f782d9c66c49 79 return true;
dkato 0:f782d9c66c49 80 }
dkato 0:f782d9c66c49 81 return false;
dkato 0:f782d9c66c49 82 }
dkato 0:f782d9c66c49 83
dkato 0:f782d9c66c49 84
dkato 0:f782d9c66c49 85 void Harness::notify_testcases()
dkato 0:f782d9c66c49 86 {
dkato 0:f782d9c66c49 87 for(unsigned i = 0; i < test_length; i++) {
dkato 0:f782d9c66c49 88 utest::v1::greentea_testcase_notification_handler(test_cases[i].get_description());
dkato 0:f782d9c66c49 89 }
dkato 0:f782d9c66c49 90 }
dkato 0:f782d9c66c49 91
dkato 0:f782d9c66c49 92 bool Harness::run(const Specification& specification, size_t)
dkato 0:f782d9c66c49 93 {
dkato 0:f782d9c66c49 94 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 95 return run(specification);
dkato 0:f782d9c66c49 96 }
dkato 0:f782d9c66c49 97
dkato 0:f782d9c66c49 98 bool Harness::run(const Specification& specification)
dkato 0:f782d9c66c49 99 {
dkato 0:f782d9c66c49 100 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 101 // check if a specification is currently running
dkato 0:f782d9c66c49 102 if (is_busy())
dkato 0:f782d9c66c49 103 return false;
dkato 0:f782d9c66c49 104
dkato 0:f782d9c66c49 105 // if the scheduler is invalid, this is the first time we are calling
dkato 0:f782d9c66c49 106 if (!is_scheduler_valid(scheduler))
dkato 0:f782d9c66c49 107 scheduler = utest_v1_get_scheduler();
dkato 0:f782d9c66c49 108
dkato 0:f782d9c66c49 109 // if the scheduler is still invalid, abort
dkato 0:f782d9c66c49 110 if (!is_scheduler_valid(scheduler))
dkato 0:f782d9c66c49 111 return false;
dkato 0:f782d9c66c49 112
dkato 0:f782d9c66c49 113 // if the scheduler failed to initialize, abort
dkato 0:f782d9c66c49 114 if (scheduler.init() != 0)
dkato 0:f782d9c66c49 115 return false;
dkato 0:f782d9c66c49 116 test_cases = specification.cases;
dkato 0:f782d9c66c49 117 test_length = specification.length;
dkato 0:f782d9c66c49 118 *defaults.get() = specification.defaults;
dkato 0:f782d9c66c49 119 handlers->test_setup = defaults->get_handler(specification.setup_handler);
dkato 0:f782d9c66c49 120 handlers->test_teardown = defaults->get_handler(specification.teardown_handler);
dkato 0:f782d9c66c49 121 handlers->test_failure = defaults->get_handler(specification.failure_handler);
dkato 0:f782d9c66c49 122
dkato 0:f782d9c66c49 123 test_index_of_case = 0;
dkato 0:f782d9c66c49 124 test_passed = 0;
dkato 0:f782d9c66c49 125 test_failed = 0;
dkato 0:f782d9c66c49 126
dkato 0:f782d9c66c49 127 case_passed = 0;
dkato 0:f782d9c66c49 128 case_failed = 0;
dkato 0:f782d9c66c49 129 case_failed_before = 0;
dkato 0:f782d9c66c49 130
dkato 0:f782d9c66c49 131 location = LOCATION_TEST_SETUP;
dkato 0:f782d9c66c49 132 int setup_status = 0;
dkato 0:f782d9c66c49 133 failure_t failure(REASON_NONE, location);
dkato 0:f782d9c66c49 134
dkato 0:f782d9c66c49 135 if (handlers->test_setup) {
dkato 0:f782d9c66c49 136 setup_status = handlers->test_setup(test_length);
dkato 0:f782d9c66c49 137 if (setup_status == STATUS_CONTINUE) setup_status = 0;
dkato 0:f782d9c66c49 138 else if (setup_status < STATUS_CONTINUE) failure.reason = REASON_TEST_SETUP;
dkato 0:f782d9c66c49 139 else if (setup_status > signed(test_length)) failure.reason = REASON_CASE_INDEX;
dkato 0:f782d9c66c49 140 }
dkato 0:f782d9c66c49 141
dkato 0:f782d9c66c49 142 if (failure.reason != REASON_NONE) {
dkato 0:f782d9c66c49 143 if (handlers->test_failure) handlers->test_failure(failure);
dkato 0:f782d9c66c49 144 if (handlers->test_teardown) handlers->test_teardown(0, 0, failure);
dkato 0:f782d9c66c49 145 test_cases = NULL;
dkato 0:f782d9c66c49 146 exit(1);
dkato 0:f782d9c66c49 147 }
dkato 0:f782d9c66c49 148
dkato 0:f782d9c66c49 149 notify_testcases();
dkato 0:f782d9c66c49 150
dkato 0:f782d9c66c49 151 case_index = setup_status;
dkato 0:f782d9c66c49 152 case_current = &test_cases[case_index];
dkato 0:f782d9c66c49 153
dkato 0:f782d9c66c49 154 scheduler.post(run_next_case, 0);
dkato 0:f782d9c66c49 155 if (scheduler.run() != 0) {
dkato 0:f782d9c66c49 156 failure.reason = REASON_SCHEDULER;
dkato 0:f782d9c66c49 157 if (handlers->test_failure) handlers->test_failure(failure);
dkato 0:f782d9c66c49 158 if (handlers->test_teardown) handlers->test_teardown(0, 0, failure);
dkato 0:f782d9c66c49 159 test_cases = NULL;
dkato 0:f782d9c66c49 160 exit(1);
dkato 0:f782d9c66c49 161 }
dkato 0:f782d9c66c49 162 return true;
dkato 0:f782d9c66c49 163 }
dkato 0:f782d9c66c49 164
dkato 0:f782d9c66c49 165 void Harness::raise_failure(const failure_reason_t reason)
dkato 0:f782d9c66c49 166 {
dkato 0:f782d9c66c49 167 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 168 // ignore a failure, if the Harness has not been initialized.
dkato 0:f782d9c66c49 169 // this allows using unity assertion macros without setting up utest.
dkato 0:f782d9c66c49 170 if (test_cases == NULL) return;
dkato 0:f782d9c66c49 171
dkato 0:f782d9c66c49 172 utest::v1::status_t fail_status = STATUS_ABORT;
dkato 0:f782d9c66c49 173 if (handlers->test_failure) handlers->test_failure(failure_t(reason, location));
dkato 0:f782d9c66c49 174 if (handlers->case_failure) fail_status = handlers->case_failure(case_current, failure_t(reason, location));
dkato 0:f782d9c66c49 175
dkato 0:f782d9c66c49 176 {
dkato 0:f782d9c66c49 177 UTEST_ENTER_CRITICAL_SECTION;
dkato 0:f782d9c66c49 178
dkato 0:f782d9c66c49 179 if (fail_status != STATUS_IGNORE) case_failed++;
dkato 0:f782d9c66c49 180
dkato 0:f782d9c66c49 181 if ((fail_status == STATUS_ABORT) && case_timeout_handle)
dkato 0:f782d9c66c49 182 {
dkato 0:f782d9c66c49 183 scheduler.cancel(case_timeout_handle);
dkato 0:f782d9c66c49 184 case_timeout_handle = NULL;
dkato 0:f782d9c66c49 185 }
dkato 0:f782d9c66c49 186 UTEST_LEAVE_CRITICAL_SECTION;
dkato 0:f782d9c66c49 187 }
dkato 0:f782d9c66c49 188
dkato 0:f782d9c66c49 189 if (fail_status == STATUS_ABORT || reason & REASON_CASE_SETUP) {
dkato 0:f782d9c66c49 190 if (handlers->case_teardown && location != LOCATION_CASE_TEARDOWN) {
dkato 0:f782d9c66c49 191 location_t fail_loc(location);
dkato 0:f782d9c66c49 192 location = LOCATION_CASE_TEARDOWN;
dkato 0:f782d9c66c49 193
dkato 0:f782d9c66c49 194 utest::v1::status_t teardown_status = handlers->case_teardown(case_current, case_passed, case_failed, failure_t(reason, fail_loc));
dkato 0:f782d9c66c49 195 if (teardown_status < STATUS_CONTINUE) raise_failure(REASON_CASE_TEARDOWN);
dkato 0:f782d9c66c49 196 else if (teardown_status > signed(test_length)) raise_failure(REASON_CASE_INDEX);
dkato 0:f782d9c66c49 197 else if (teardown_status >= 0) case_index = teardown_status - 1;
dkato 0:f782d9c66c49 198
dkato 0:f782d9c66c49 199 // Restore case failure location once we have dealt with case teardown
dkato 0:f782d9c66c49 200 location = fail_loc;
dkato 0:f782d9c66c49 201 handlers->case_teardown = NULL;
dkato 0:f782d9c66c49 202 }
dkato 0:f782d9c66c49 203 }
dkato 0:f782d9c66c49 204 if (fail_status == STATUS_ABORT) {
dkato 0:f782d9c66c49 205 test_failed++;
dkato 0:f782d9c66c49 206 failure_t fail(reason, location);
dkato 0:f782d9c66c49 207 location = LOCATION_TEST_TEARDOWN;
dkato 0:f782d9c66c49 208 if (handlers->test_teardown) handlers->test_teardown(test_passed, test_failed, fail);
dkato 0:f782d9c66c49 209 exit(test_failed);
dkato 0:f782d9c66c49 210 die();
dkato 0:f782d9c66c49 211 }
dkato 0:f782d9c66c49 212 }
dkato 0:f782d9c66c49 213
dkato 0:f782d9c66c49 214 void Harness::schedule_next_case()
dkato 0:f782d9c66c49 215 {
dkato 0:f782d9c66c49 216 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 217 if (!case_timeout_occurred && case_failed_before == case_failed) {
dkato 0:f782d9c66c49 218 case_passed++;
dkato 0:f782d9c66c49 219 }
dkato 0:f782d9c66c49 220
dkato 0:f782d9c66c49 221 if (case_control.repeat & REPEAT_SETUP_TEARDOWN || !(case_control.repeat & (REPEAT_ON_TIMEOUT | REPEAT_ON_VALIDATE))) {
dkato 0:f782d9c66c49 222 location = LOCATION_CASE_TEARDOWN;
dkato 0:f782d9c66c49 223
dkato 0:f782d9c66c49 224 if (handlers->case_teardown) {
dkato 0:f782d9c66c49 225 utest::v1::status_t status = handlers->case_teardown(case_current, case_passed, case_failed,
dkato 0:f782d9c66c49 226 case_failed ? failure_t(REASON_CASES, LOCATION_UNKNOWN) : failure_t(REASON_NONE));
dkato 0:f782d9c66c49 227 if (status < STATUS_CONTINUE) raise_failure(REASON_CASE_TEARDOWN);
dkato 0:f782d9c66c49 228 else if (status > signed(test_length)) raise_failure(REASON_CASE_INDEX);
dkato 0:f782d9c66c49 229 else if (status >= 0) case_index = status - 1;
dkato 0:f782d9c66c49 230 }
dkato 0:f782d9c66c49 231 }
dkato 0:f782d9c66c49 232
dkato 0:f782d9c66c49 233 if (!(case_control.repeat & (REPEAT_ON_TIMEOUT | REPEAT_ON_VALIDATE))) {
dkato 0:f782d9c66c49 234 if (case_failed > 0) test_failed++;
dkato 0:f782d9c66c49 235 else test_passed++;
dkato 0:f782d9c66c49 236
dkato 0:f782d9c66c49 237 case_control = control_t(REPEAT_SETUP_TEARDOWN);
dkato 0:f782d9c66c49 238 case_index++;
dkato 0:f782d9c66c49 239 case_current = &test_cases[case_index];
dkato 0:f782d9c66c49 240 case_passed = 0;
dkato 0:f782d9c66c49 241 case_failed = 0;
dkato 0:f782d9c66c49 242 case_failed_before = 0;
dkato 0:f782d9c66c49 243 case_repeat_count = 1;
dkato 0:f782d9c66c49 244 test_index_of_case++;
dkato 0:f782d9c66c49 245 }
dkato 0:f782d9c66c49 246 scheduler.post(run_next_case, 0);
dkato 0:f782d9c66c49 247 }
dkato 0:f782d9c66c49 248
dkato 0:f782d9c66c49 249 void Harness::handle_timeout()
dkato 0:f782d9c66c49 250 {
dkato 0:f782d9c66c49 251 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 252 {
dkato 0:f782d9c66c49 253 UTEST_ENTER_CRITICAL_SECTION;
dkato 0:f782d9c66c49 254
dkato 0:f782d9c66c49 255 if (case_timeout_handle != NULL) {
dkato 0:f782d9c66c49 256 case_timeout_handle = NULL;
dkato 0:f782d9c66c49 257 case_timeout_occurred = true;
dkato 0:f782d9c66c49 258 }
dkato 0:f782d9c66c49 259 UTEST_LEAVE_CRITICAL_SECTION;
dkato 0:f782d9c66c49 260 }
dkato 0:f782d9c66c49 261 if (case_timeout_occurred) {
dkato 0:f782d9c66c49 262 raise_failure(failure_reason_t(REASON_TIMEOUT | ((case_control.repeat & REPEAT_ON_TIMEOUT) ? REASON_IGNORE : 0)));
dkato 0:f782d9c66c49 263 scheduler.post(schedule_next_case, 0);
dkato 0:f782d9c66c49 264 }
dkato 0:f782d9c66c49 265 }
dkato 0:f782d9c66c49 266
dkato 0:f782d9c66c49 267 void Harness::validate_callback(const control_t control)
dkato 0:f782d9c66c49 268 {
dkato 0:f782d9c66c49 269 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 270 UTEST_ENTER_CRITICAL_SECTION;
dkato 0:f782d9c66c49 271 case_validation_count++;
dkato 0:f782d9c66c49 272
dkato 0:f782d9c66c49 273 if (case_timeout_handle != NULL || case_control.timeout == TIMEOUT_FOREVER)
dkato 0:f782d9c66c49 274 {
dkato 0:f782d9c66c49 275 scheduler.cancel(case_timeout_handle);
dkato 0:f782d9c66c49 276 case_timeout_handle = NULL;
dkato 0:f782d9c66c49 277 control_t merged_control = case_control + control;
dkato 0:f782d9c66c49 278 case_control.repeat = repeat_t(merged_control.repeat & ~REPEAT_ON_TIMEOUT);
dkato 0:f782d9c66c49 279 case_control.timeout = TIMEOUT_NONE;
dkato 0:f782d9c66c49 280 scheduler.post(schedule_next_case, 0);
dkato 0:f782d9c66c49 281 }
dkato 0:f782d9c66c49 282 UTEST_LEAVE_CRITICAL_SECTION;
dkato 0:f782d9c66c49 283 }
dkato 0:f782d9c66c49 284
dkato 0:f782d9c66c49 285 bool Harness::is_busy()
dkato 0:f782d9c66c49 286 {
dkato 0:f782d9c66c49 287 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 288 UTEST_ENTER_CRITICAL_SECTION;
dkato 0:f782d9c66c49 289 bool res = false;
dkato 0:f782d9c66c49 290
dkato 0:f782d9c66c49 291 if (test_cases && case_current) {
dkato 0:f782d9c66c49 292 res = (case_current < (test_cases + test_length));
dkato 0:f782d9c66c49 293 }
dkato 0:f782d9c66c49 294
dkato 0:f782d9c66c49 295 UTEST_LEAVE_CRITICAL_SECTION;
dkato 0:f782d9c66c49 296 return res;
dkato 0:f782d9c66c49 297 }
dkato 0:f782d9c66c49 298
dkato 0:f782d9c66c49 299 void Harness::run_next_case()
dkato 0:f782d9c66c49 300 {
dkato 0:f782d9c66c49 301 UTEST_LOG_FUNCTION();
dkato 0:f782d9c66c49 302 if(case_current < (test_cases + test_length))
dkato 0:f782d9c66c49 303 {
dkato 0:f782d9c66c49 304 handlers->case_setup = defaults->get_handler(case_current->setup_handler);
dkato 0:f782d9c66c49 305 handlers->case_teardown = defaults->get_handler(case_current->teardown_handler);
dkato 0:f782d9c66c49 306 handlers->case_failure = defaults->get_handler(case_current->failure_handler);
dkato 0:f782d9c66c49 307
dkato 0:f782d9c66c49 308 if (case_current->is_empty()) {
dkato 0:f782d9c66c49 309 location = LOCATION_UNKNOWN;
dkato 0:f782d9c66c49 310 raise_failure(REASON_EMPTY_CASE);
dkato 0:f782d9c66c49 311 schedule_next_case();
dkato 0:f782d9c66c49 312 return;
dkato 0:f782d9c66c49 313 }
dkato 0:f782d9c66c49 314
dkato 0:f782d9c66c49 315 repeat_t setup_repeat;
dkato 0:f782d9c66c49 316 {
dkato 0:f782d9c66c49 317 UTEST_ENTER_CRITICAL_SECTION;
dkato 0:f782d9c66c49 318 case_validation_count = 0;
dkato 0:f782d9c66c49 319 case_timeout_occurred = false;
dkato 0:f782d9c66c49 320 setup_repeat = case_control.repeat;
dkato 0:f782d9c66c49 321 case_control = control_t();
dkato 0:f782d9c66c49 322 UTEST_LEAVE_CRITICAL_SECTION;
dkato 0:f782d9c66c49 323 }
dkato 0:f782d9c66c49 324
dkato 0:f782d9c66c49 325 if (setup_repeat & REPEAT_SETUP_TEARDOWN) {
dkato 0:f782d9c66c49 326 location = LOCATION_CASE_SETUP;
dkato 0:f782d9c66c49 327 if (handlers->case_setup && (handlers->case_setup(case_current, test_index_of_case) != STATUS_CONTINUE)) {
dkato 0:f782d9c66c49 328 raise_failure(REASON_CASE_SETUP);
dkato 0:f782d9c66c49 329 schedule_next_case();
dkato 0:f782d9c66c49 330 return;
dkato 0:f782d9c66c49 331 }
dkato 0:f782d9c66c49 332 }
dkato 0:f782d9c66c49 333
dkato 0:f782d9c66c49 334 case_failed_before = case_failed;
dkato 0:f782d9c66c49 335 location = LOCATION_CASE_HANDLER;
dkato 0:f782d9c66c49 336
dkato 0:f782d9c66c49 337 if (case_current->handler) {
dkato 0:f782d9c66c49 338 case_current->handler();
dkato 0:f782d9c66c49 339 } else if (case_current->control_handler) {
dkato 0:f782d9c66c49 340 case_control = case_control + case_current->control_handler();
dkato 0:f782d9c66c49 341 } else if (case_current->repeat_count_handler) {
dkato 0:f782d9c66c49 342 case_control = case_control + case_current->repeat_count_handler(case_repeat_count);
dkato 0:f782d9c66c49 343 }
dkato 0:f782d9c66c49 344 case_repeat_count++;
dkato 0:f782d9c66c49 345
dkato 0:f782d9c66c49 346 {
dkato 0:f782d9c66c49 347 UTEST_ENTER_CRITICAL_SECTION;
dkato 0:f782d9c66c49 348 if (case_validation_count) case_control.repeat = repeat_t(case_control.repeat & ~REPEAT_ON_TIMEOUT);
dkato 0:f782d9c66c49 349
dkato 0:f782d9c66c49 350 // if timeout valid
dkato 0:f782d9c66c49 351 if (case_control.timeout < TIMEOUT_UNDECLR && case_validation_count == 0) {
dkato 0:f782d9c66c49 352 // if await validation _with_ timeout
dkato 0:f782d9c66c49 353 if (case_control.timeout < TIMEOUT_FOREVER) {
dkato 0:f782d9c66c49 354 case_timeout_handle = scheduler.post(handle_timeout, case_control.timeout);
dkato 0:f782d9c66c49 355 if (case_timeout_handle == NULL) {
dkato 0:f782d9c66c49 356 raise_failure(REASON_SCHEDULER);
dkato 0:f782d9c66c49 357 schedule_next_case();
dkato 0:f782d9c66c49 358 }
dkato 0:f782d9c66c49 359 }
dkato 0:f782d9c66c49 360 }
dkato 0:f782d9c66c49 361 else {
dkato 0:f782d9c66c49 362 scheduler.post(schedule_next_case, 0);
dkato 0:f782d9c66c49 363 }
dkato 0:f782d9c66c49 364 UTEST_LEAVE_CRITICAL_SECTION;
dkato 0:f782d9c66c49 365 }
dkato 0:f782d9c66c49 366 }
dkato 0:f782d9c66c49 367 else if (handlers->test_teardown) {
dkato 0:f782d9c66c49 368 location = LOCATION_TEST_TEARDOWN;
dkato 0:f782d9c66c49 369 handlers->test_teardown(test_passed, test_failed, test_failed ? failure_t(REASON_CASES, LOCATION_UNKNOWN) : failure_t(REASON_NONE));
dkato 0:f782d9c66c49 370 test_cases = NULL;
dkato 0:f782d9c66c49 371 exit(test_failed);
dkato 0:f782d9c66c49 372 } else {
dkato 0:f782d9c66c49 373 exit(test_failed);
dkato 0:f782d9c66c49 374 }
dkato 0:f782d9c66c49 375 }