Use SingletonPtr for the internal variables defaults and handlers in utest_harness.

pull/2559/head
Vincent Coubard 2016-09-09 17:22:41 +01:00
parent caa4c4f2a3
commit aab107020b
1 changed files with 30 additions and 32 deletions

View File

@ -47,15 +47,13 @@ namespace
size_t case_failed = 0; size_t case_failed = 0;
size_t case_failed_before = 0; size_t case_failed_before = 0;
handlers_t& defaults() { struct DefaultHandlers : public handlers_t {
static handlers_t _handlers = default_handlers; DefaultHandlers() : handlers_t(default_handlers) { }
return _handlers; DefaultHandlers(const handlers_t& other) : handlers_t(other) { }
} };
handlers_t& handlers() { SingletonPtr<DefaultHandlers> defaults;
static handlers_t _handlers = default_handlers; SingletonPtr<DefaultHandlers> handlers;
return _handlers;
}
location_t location = LOCATION_UNKNOWN; location_t location = LOCATION_UNKNOWN;
@ -117,10 +115,10 @@ bool Harness::run(const Specification& specification)
return false; return false;
test_cases = specification.cases; test_cases = specification.cases;
test_length = specification.length; test_length = specification.length;
defaults() = specification.defaults; *defaults.get() = specification.defaults;
handlers().test_setup = defaults().get_handler(specification.setup_handler); handlers->test_setup = defaults->get_handler(specification.setup_handler);
handlers().test_teardown = defaults().get_handler(specification.teardown_handler); handlers->test_teardown = defaults->get_handler(specification.teardown_handler);
handlers().test_failure = defaults().get_handler(specification.failure_handler); handlers->test_failure = defaults->get_handler(specification.failure_handler);
test_index_of_case = 0; test_index_of_case = 0;
test_passed = 0; test_passed = 0;
@ -134,16 +132,16 @@ bool Harness::run(const Specification& specification)
int setup_status = 0; int setup_status = 0;
failure_t failure(REASON_NONE, location); failure_t failure(REASON_NONE, location);
if (handlers().test_setup) { if (handlers->test_setup) {
setup_status = handlers().test_setup(test_length); setup_status = handlers->test_setup(test_length);
if (setup_status == STATUS_CONTINUE) setup_status = 0; if (setup_status == STATUS_CONTINUE) setup_status = 0;
else if (setup_status < STATUS_CONTINUE) failure.reason = REASON_TEST_SETUP; else if (setup_status < STATUS_CONTINUE) failure.reason = REASON_TEST_SETUP;
else if (setup_status > signed(test_length)) failure.reason = REASON_CASE_INDEX; else if (setup_status > signed(test_length)) failure.reason = REASON_CASE_INDEX;
} }
if (failure.reason != REASON_NONE) { if (failure.reason != REASON_NONE) {
if (handlers().test_failure) handlers().test_failure(failure); if (handlers->test_failure) handlers->test_failure(failure);
if (handlers().test_teardown) handlers().test_teardown(0, 0, failure); if (handlers->test_teardown) handlers->test_teardown(0, 0, failure);
test_cases = NULL; test_cases = NULL;
exit(1); exit(1);
return true; return true;
@ -157,8 +155,8 @@ bool Harness::run(const Specification& specification)
scheduler.post(run_next_case, 0); scheduler.post(run_next_case, 0);
if (scheduler.run() != 0) { if (scheduler.run() != 0) {
failure.reason = REASON_SCHEDULER; failure.reason = REASON_SCHEDULER;
if (handlers().test_failure) handlers().test_failure(failure); if (handlers->test_failure) handlers->test_failure(failure);
if (handlers().test_teardown) handlers().test_teardown(0, 0, failure); if (handlers->test_teardown) handlers->test_teardown(0, 0, failure);
test_cases = NULL; test_cases = NULL;
exit(1); exit(1);
return true; return true;
@ -174,8 +172,8 @@ void Harness::raise_failure(const failure_reason_t reason)
if (test_cases == NULL) return; if (test_cases == NULL) return;
utest::v1::status_t fail_status = STATUS_ABORT; utest::v1::status_t fail_status = STATUS_ABORT;
if (handlers().test_failure) handlers().test_failure(failure_t(reason, location)); if (handlers->test_failure) handlers->test_failure(failure_t(reason, location));
if (handlers().case_failure) fail_status = handlers().case_failure(case_current, failure_t(reason, location)); if (handlers->case_failure) fail_status = handlers->case_failure(case_current, failure_t(reason, location));
{ {
UTEST_ENTER_CRITICAL_SECTION; UTEST_ENTER_CRITICAL_SECTION;
@ -191,25 +189,25 @@ void Harness::raise_failure(const failure_reason_t reason)
} }
if (fail_status == STATUS_ABORT || reason & REASON_CASE_SETUP) { if (fail_status == STATUS_ABORT || reason & REASON_CASE_SETUP) {
if (handlers().case_teardown && location != LOCATION_CASE_TEARDOWN) { if (handlers->case_teardown && location != LOCATION_CASE_TEARDOWN) {
location_t fail_loc(location); location_t fail_loc(location);
location = LOCATION_CASE_TEARDOWN; location = LOCATION_CASE_TEARDOWN;
utest::v1::status_t teardown_status = handlers().case_teardown(case_current, case_passed, case_failed, failure_t(reason, fail_loc)); utest::v1::status_t teardown_status = handlers->case_teardown(case_current, case_passed, case_failed, failure_t(reason, fail_loc));
if (teardown_status < STATUS_CONTINUE) raise_failure(REASON_CASE_TEARDOWN); if (teardown_status < STATUS_CONTINUE) raise_failure(REASON_CASE_TEARDOWN);
else if (teardown_status > signed(test_length)) raise_failure(REASON_CASE_INDEX); else if (teardown_status > signed(test_length)) raise_failure(REASON_CASE_INDEX);
else if (teardown_status >= 0) case_index = teardown_status - 1; else if (teardown_status >= 0) case_index = teardown_status - 1;
// Restore case failure location once we have dealt with case teardown // Restore case failure location once we have dealt with case teardown
location = fail_loc; location = fail_loc;
handlers().case_teardown = NULL; handlers->case_teardown = NULL;
} }
} }
if (fail_status == STATUS_ABORT) { if (fail_status == STATUS_ABORT) {
test_failed++; test_failed++;
failure_t fail(reason, location); failure_t fail(reason, location);
location = LOCATION_TEST_TEARDOWN; location = LOCATION_TEST_TEARDOWN;
if (handlers().test_teardown) handlers().test_teardown(test_passed, test_failed, fail); if (handlers->test_teardown) handlers->test_teardown(test_passed, test_failed, fail);
exit(test_failed); exit(test_failed);
die(); die();
} }
@ -225,8 +223,8 @@ void Harness::schedule_next_case()
if (case_control.repeat & REPEAT_SETUP_TEARDOWN || !(case_control.repeat & (REPEAT_ON_TIMEOUT | REPEAT_ON_VALIDATE))) { if (case_control.repeat & REPEAT_SETUP_TEARDOWN || !(case_control.repeat & (REPEAT_ON_TIMEOUT | REPEAT_ON_VALIDATE))) {
location = LOCATION_CASE_TEARDOWN; location = LOCATION_CASE_TEARDOWN;
if (handlers().case_teardown) { if (handlers->case_teardown) {
utest::v1::status_t status = handlers().case_teardown(case_current, case_passed, case_failed, utest::v1::status_t status = handlers->case_teardown(case_current, case_passed, case_failed,
case_failed ? failure_t(REASON_CASES, LOCATION_UNKNOWN) : failure_t(REASON_NONE)); case_failed ? failure_t(REASON_CASES, LOCATION_UNKNOWN) : failure_t(REASON_NONE));
if (status < STATUS_CONTINUE) raise_failure(REASON_CASE_TEARDOWN); if (status < STATUS_CONTINUE) raise_failure(REASON_CASE_TEARDOWN);
else if (status > signed(test_length)) raise_failure(REASON_CASE_INDEX); else if (status > signed(test_length)) raise_failure(REASON_CASE_INDEX);
@ -305,9 +303,9 @@ void Harness::run_next_case()
UTEST_LOG_FUNCTION(); UTEST_LOG_FUNCTION();
if(case_current < (test_cases + test_length)) if(case_current < (test_cases + test_length))
{ {
handlers().case_setup = defaults().get_handler(case_current->setup_handler); handlers->case_setup = defaults->get_handler(case_current->setup_handler);
handlers().case_teardown = defaults().get_handler(case_current->teardown_handler); handlers->case_teardown = defaults->get_handler(case_current->teardown_handler);
handlers().case_failure = defaults().get_handler(case_current->failure_handler); handlers->case_failure = defaults->get_handler(case_current->failure_handler);
if (case_current->is_empty()) { if (case_current->is_empty()) {
location = LOCATION_UNKNOWN; location = LOCATION_UNKNOWN;
@ -328,7 +326,7 @@ void Harness::run_next_case()
if (setup_repeat & REPEAT_SETUP_TEARDOWN) { if (setup_repeat & REPEAT_SETUP_TEARDOWN) {
location = LOCATION_CASE_SETUP; location = LOCATION_CASE_SETUP;
if (handlers().case_setup && (handlers().case_setup(case_current, test_index_of_case) != STATUS_CONTINUE)) { if (handlers->case_setup && (handlers->case_setup(case_current, test_index_of_case) != STATUS_CONTINUE)) {
raise_failure(REASON_CASE_SETUP); raise_failure(REASON_CASE_SETUP);
schedule_next_case(); schedule_next_case();
return; return;
@ -368,9 +366,9 @@ void Harness::run_next_case()
UTEST_LEAVE_CRITICAL_SECTION; UTEST_LEAVE_CRITICAL_SECTION;
} }
} }
else if (handlers().test_teardown) { else if (handlers->test_teardown) {
location = LOCATION_TEST_TEARDOWN; location = LOCATION_TEST_TEARDOWN;
handlers().test_teardown(test_passed, test_failed, test_failed ? failure_t(REASON_CASES, LOCATION_UNKNOWN) : failure_t(REASON_NONE)); handlers->test_teardown(test_passed, test_failed, test_failed ? failure_t(REASON_CASES, LOCATION_UNKNOWN) : failure_t(REASON_NONE));
test_cases = NULL; test_cases = NULL;
exit(test_failed); exit(test_failed);
} else { } else {