mirror of https://github.com/ARMmbed/mbed-os.git
utest optimization: Allow case data structure to be put in ROM.
This patch split the Case class in two entities: Case and case_t. case_t contains the test case data structure while Case provide the interface to the test case. Unlike the class Case, case _t is a POD and can be instantiated at compile time and put in the constant data section (in ROM). The Specification class has also been modified to accept arrays of case_t.pull/4430/head
parent
a41e08c7bf
commit
5b27d65755
|
@ -21,44 +21,75 @@
|
||||||
|
|
||||||
using namespace utest::v1;
|
using namespace utest::v1;
|
||||||
|
|
||||||
|
// case_t factory used by Case contructor
|
||||||
|
static inline case_t make_case(
|
||||||
|
const char *description,
|
||||||
|
const case_handler_t handler,
|
||||||
|
const case_control_handler_t control_handler,
|
||||||
|
const case_call_count_handler_t repeat_count_handler,
|
||||||
|
const case_setup_handler_t setup_handler,
|
||||||
|
const case_teardown_handler_t teardown_handler,
|
||||||
|
const case_failure_handler_t failure_handler)
|
||||||
|
{
|
||||||
|
case_t result = {
|
||||||
|
description,
|
||||||
|
handler,
|
||||||
|
control_handler,
|
||||||
|
repeat_count_handler,
|
||||||
|
setup_handler,
|
||||||
|
teardown_handler,
|
||||||
|
failure_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// normal handler
|
// normal handler
|
||||||
Case::Case(const char *description,
|
Case::Case(const char *description,
|
||||||
const case_setup_handler_t setup_handler,
|
const case_setup_handler_t setup_handler,
|
||||||
const case_handler_t handler,
|
const case_handler_t handler,
|
||||||
const case_teardown_handler_t teardown_handler,
|
const case_teardown_handler_t teardown_handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(handler),
|
description,
|
||||||
control_handler(ignore_handler),
|
handler,
|
||||||
repeat_count_handler(ignore_handler),
|
ignore_handler,
|
||||||
setup_handler(setup_handler),
|
ignore_handler,
|
||||||
teardown_handler(teardown_handler),
|
setup_handler,
|
||||||
failure_handler(failure_handler)
|
teardown_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Case::Case(const char *description,
|
Case::Case(const char *description,
|
||||||
const case_handler_t handler,
|
const case_handler_t handler,
|
||||||
const case_teardown_handler_t teardown_handler,
|
const case_teardown_handler_t teardown_handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(handler),
|
description,
|
||||||
control_handler(ignore_handler),
|
handler,
|
||||||
repeat_count_handler(ignore_handler),
|
ignore_handler,
|
||||||
setup_handler(default_handler),
|
ignore_handler,
|
||||||
teardown_handler(teardown_handler),
|
default_handler,
|
||||||
failure_handler(failure_handler)
|
teardown_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Case::Case(const char *description,
|
Case::Case(const char *description,
|
||||||
const case_handler_t handler,
|
const case_handler_t handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(handler),
|
description,
|
||||||
control_handler(ignore_handler),
|
handler,
|
||||||
repeat_count_handler(ignore_handler),
|
ignore_handler,
|
||||||
setup_handler(default_handler),
|
ignore_handler,
|
||||||
teardown_handler(default_handler),
|
default_handler,
|
||||||
failure_handler(failure_handler)
|
default_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// control handler
|
// control handler
|
||||||
|
@ -67,38 +98,44 @@ Case::Case(const char *description,
|
||||||
const case_control_handler_t handler,
|
const case_control_handler_t handler,
|
||||||
const case_teardown_handler_t teardown_handler,
|
const case_teardown_handler_t teardown_handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(ignore_handler),
|
description,
|
||||||
control_handler(handler),
|
ignore_handler,
|
||||||
repeat_count_handler(ignore_handler),
|
handler,
|
||||||
setup_handler(setup_handler),
|
ignore_handler,
|
||||||
teardown_handler(teardown_handler),
|
setup_handler,
|
||||||
failure_handler(failure_handler)
|
teardown_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Case::Case(const char *description,
|
Case::Case(const char *description,
|
||||||
const case_control_handler_t handler,
|
const case_control_handler_t handler,
|
||||||
const case_teardown_handler_t teardown_handler,
|
const case_teardown_handler_t teardown_handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(ignore_handler),
|
description,
|
||||||
control_handler(handler),
|
ignore_handler,
|
||||||
repeat_count_handler(ignore_handler),
|
handler,
|
||||||
setup_handler(default_handler),
|
ignore_handler,
|
||||||
teardown_handler(teardown_handler),
|
default_handler,
|
||||||
failure_handler(failure_handler)
|
teardown_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Case::Case(const char *description,
|
Case::Case(const char *description,
|
||||||
const case_control_handler_t handler,
|
const case_control_handler_t handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(ignore_handler),
|
description,
|
||||||
control_handler(handler),
|
ignore_handler,
|
||||||
repeat_count_handler(ignore_handler),
|
handler,
|
||||||
setup_handler(default_handler),
|
ignore_handler,
|
||||||
teardown_handler(default_handler),
|
default_handler,
|
||||||
failure_handler(failure_handler)
|
default_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// control flow handler
|
// control flow handler
|
||||||
|
@ -107,38 +144,44 @@ Case::Case(const char *description,
|
||||||
const case_call_count_handler_t case_repeat_count_handler,
|
const case_call_count_handler_t case_repeat_count_handler,
|
||||||
const case_teardown_handler_t teardown_handler,
|
const case_teardown_handler_t teardown_handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(ignore_handler),
|
description,
|
||||||
control_handler(ignore_handler),
|
ignore_handler,
|
||||||
repeat_count_handler(case_repeat_count_handler),
|
ignore_handler,
|
||||||
setup_handler(setup_handler),
|
case_repeat_count_handler,
|
||||||
teardown_handler(teardown_handler),
|
setup_handler,
|
||||||
failure_handler(failure_handler)
|
teardown_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Case::Case(const char *description,
|
Case::Case(const char *description,
|
||||||
const case_call_count_handler_t case_repeat_count_handler,
|
const case_call_count_handler_t case_repeat_count_handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(ignore_handler),
|
description,
|
||||||
control_handler(ignore_handler),
|
ignore_handler,
|
||||||
repeat_count_handler(case_repeat_count_handler),
|
ignore_handler,
|
||||||
setup_handler(default_handler),
|
case_repeat_count_handler,
|
||||||
teardown_handler(default_handler),
|
default_handler,
|
||||||
failure_handler(failure_handler)
|
default_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Case::Case(const char *description,
|
Case::Case(const char *description,
|
||||||
const case_call_count_handler_t case_repeat_count_handler,
|
const case_call_count_handler_t case_repeat_count_handler,
|
||||||
const case_teardown_handler_t teardown_handler,
|
const case_teardown_handler_t teardown_handler,
|
||||||
const case_failure_handler_t failure_handler) :
|
const case_failure_handler_t failure_handler) :
|
||||||
description(description),
|
case_t(make_case(
|
||||||
handler(ignore_handler),
|
description,
|
||||||
control_handler(ignore_handler),
|
ignore_handler,
|
||||||
repeat_count_handler(case_repeat_count_handler),
|
ignore_handler,
|
||||||
setup_handler(default_handler),
|
case_repeat_count_handler,
|
||||||
teardown_handler(teardown_handler),
|
default_handler,
|
||||||
failure_handler(failure_handler)
|
teardown_handler,
|
||||||
|
failure_handler
|
||||||
|
))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
|
|
|
@ -30,6 +30,59 @@ namespace utest {
|
||||||
/** \addtogroup frameworks */
|
/** \addtogroup frameworks */
|
||||||
/** @{*/
|
/** @{*/
|
||||||
namespace v1 {
|
namespace v1 {
|
||||||
|
/**
|
||||||
|
* POD data structure of the Case class.
|
||||||
|
* Unlike the Case class it can be used as a POD and be put in ROM.
|
||||||
|
*
|
||||||
|
* @warning Initialization of handlers with either default_handler or
|
||||||
|
* ignore_handler helpers will prevent the object to be a POD. Prefer usage
|
||||||
|
* of NULL in favor of ignore_handler or <handler_type>(1) for default
|
||||||
|
* handler.
|
||||||
|
*
|
||||||
|
* @see Case.
|
||||||
|
*/
|
||||||
|
struct case_t
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Textual description of the test case
|
||||||
|
*/
|
||||||
|
const char *description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive test case handler
|
||||||
|
* This is called only if the case setup succeeded. It is followed by
|
||||||
|
* the test case teardown handler.
|
||||||
|
*/
|
||||||
|
const case_handler_t handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see case_control_handler_t
|
||||||
|
*/
|
||||||
|
const case_control_handler_t control_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see case_call_count_handler_t
|
||||||
|
*/
|
||||||
|
const case_call_count_handler_t repeat_count_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler called before the execution of the case handler. It sets up
|
||||||
|
* the case environment.
|
||||||
|
*/
|
||||||
|
const case_setup_handler_t setup_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler called after the execution of the case handler. It cleans up
|
||||||
|
* the case environment.
|
||||||
|
*/
|
||||||
|
const case_teardown_handler_t teardown_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler called whenever a faillure occur; at any stage of the case
|
||||||
|
* execution (including setup and teardown).
|
||||||
|
*/
|
||||||
|
const case_failure_handler_t failure_handler;
|
||||||
|
};
|
||||||
|
|
||||||
/** Test case wrapper class.
|
/** Test case wrapper class.
|
||||||
*
|
*
|
||||||
|
@ -52,7 +105,7 @@ namespace v1 {
|
||||||
* @note While you can specify an empty test case (ie. use `ignore_handler` for all callbacks),
|
* @note While you can specify an empty test case (ie. use `ignore_handler` for all callbacks),
|
||||||
* the harness will abort the test unconditionally.
|
* the harness will abort the test unconditionally.
|
||||||
*/
|
*/
|
||||||
class Case
|
class Case : private case_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// overloads for case_handler_t
|
// overloads for case_handler_t
|
||||||
|
@ -111,18 +164,9 @@ namespace v1 {
|
||||||
bool is_empty() const;
|
bool is_empty() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *description;
|
// see data member in case_t
|
||||||
|
|
||||||
const case_handler_t handler;
|
|
||||||
const case_control_handler_t control_handler;
|
|
||||||
const case_call_count_handler_t repeat_count_handler;
|
|
||||||
|
|
||||||
const case_setup_handler_t setup_handler;
|
|
||||||
const case_teardown_handler_t teardown_handler;
|
|
||||||
|
|
||||||
const case_failure_handler_t failure_handler;
|
|
||||||
|
|
||||||
friend class Harness;
|
friend class Harness;
|
||||||
|
friend class Specification;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace v1
|
} // namespace v1
|
||||||
|
|
|
@ -48,81 +48,116 @@ namespace v1 {
|
||||||
class Specification
|
class Specification
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const Case (&cases)[N],
|
Specification(const CaseType (&cases)[N],
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(default_handler), teardown_handler(default_handler), failure_handler(default_handler),
|
setup_handler(default_handler), teardown_handler(default_handler), failure_handler(default_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{
|
||||||
|
MBED_STATIC_ASSERT(
|
||||||
|
sizeof(CaseType) == sizeof(Case),
|
||||||
|
"CaseType and Case should have the same size"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const Case (&cases)[N],
|
Specification(const CaseType (&cases)[N],
|
||||||
const test_failure_handler_t failure_handler,
|
const test_failure_handler_t failure_handler,
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(default_handler), teardown_handler(default_handler), failure_handler(failure_handler),
|
setup_handler(default_handler), teardown_handler(default_handler), failure_handler(failure_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{
|
||||||
|
MBED_STATIC_ASSERT(
|
||||||
|
sizeof(CaseType) == sizeof(Case),
|
||||||
|
"CaseType and Case should have the same size"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const Case (&cases)[N],
|
Specification(const CaseType (&cases)[N],
|
||||||
const test_teardown_handler_t teardown_handler,
|
const test_teardown_handler_t teardown_handler,
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(default_handler), teardown_handler(teardown_handler), failure_handler(default_handler),
|
setup_handler(default_handler), teardown_handler(teardown_handler), failure_handler(default_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{
|
||||||
|
MBED_STATIC_ASSERT(
|
||||||
|
sizeof(CaseType) == sizeof(Case),
|
||||||
|
"CaseType and Case should have the same size"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const Case (&cases)[N],
|
Specification(const CaseType (&cases)[N],
|
||||||
const test_teardown_handler_t teardown_handler,
|
const test_teardown_handler_t teardown_handler,
|
||||||
const test_failure_handler_t failure_handler,
|
const test_failure_handler_t failure_handler,
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(default_handler), teardown_handler(teardown_handler), failure_handler(failure_handler),
|
setup_handler(default_handler), teardown_handler(teardown_handler), failure_handler(failure_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{
|
||||||
|
MBED_STATIC_ASSERT(
|
||||||
|
sizeof(CaseType) == sizeof(Case),
|
||||||
|
"CaseType and Case should have the same size"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const test_setup_handler_t setup_handler,
|
Specification(const test_setup_handler_t setup_handler,
|
||||||
const Case (&cases)[N],
|
const CaseType (&cases)[N],
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(setup_handler), teardown_handler(default_handler), failure_handler(default_handler),
|
setup_handler(setup_handler), teardown_handler(default_handler), failure_handler(default_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const test_setup_handler_t setup_handler,
|
Specification(const test_setup_handler_t setup_handler,
|
||||||
const Case (&cases)[N],
|
const CaseType (&cases)[N],
|
||||||
const test_failure_handler_t failure_handler,
|
const test_failure_handler_t failure_handler,
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(setup_handler), teardown_handler(default_handler), failure_handler(failure_handler),
|
setup_handler(setup_handler), teardown_handler(default_handler), failure_handler(failure_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{
|
||||||
|
MBED_STATIC_ASSERT(
|
||||||
|
sizeof(CaseType) == sizeof(Case),
|
||||||
|
"CaseType and Case should have the same size"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const test_setup_handler_t setup_handler,
|
Specification(const test_setup_handler_t setup_handler,
|
||||||
const Case (&cases)[N],
|
const CaseType (&cases)[N],
|
||||||
const test_teardown_handler_t teardown_handler,
|
const test_teardown_handler_t teardown_handler,
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(setup_handler), teardown_handler(teardown_handler), failure_handler(default_handler),
|
setup_handler(setup_handler), teardown_handler(teardown_handler), failure_handler(default_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{
|
||||||
|
MBED_STATIC_ASSERT(
|
||||||
|
sizeof(CaseType) == sizeof(Case),
|
||||||
|
"CaseType and Case should have the same size"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
template< size_t N >
|
template< size_t N, typename CaseType >
|
||||||
Specification(const test_setup_handler_t setup_handler,
|
Specification(const test_setup_handler_t setup_handler,
|
||||||
const Case (&cases)[N],
|
const CaseType (&cases)[N],
|
||||||
const test_teardown_handler_t teardown_handler,
|
const test_teardown_handler_t teardown_handler,
|
||||||
const test_failure_handler_t failure_handler,
|
const test_failure_handler_t failure_handler,
|
||||||
const handlers_t defaults = default_handlers) :
|
const handlers_t defaults = default_handlers) :
|
||||||
setup_handler(setup_handler), teardown_handler(teardown_handler), failure_handler(failure_handler),
|
setup_handler(setup_handler), teardown_handler(teardown_handler), failure_handler(failure_handler),
|
||||||
cases(cases), length(N),
|
cases(static_cast<const Case*>(static_cast<const CaseType*>(cases))), length(N),
|
||||||
defaults(defaults)
|
defaults(defaults)
|
||||||
{}
|
{
|
||||||
|
MBED_STATIC_ASSERT(
|
||||||
|
sizeof(CaseType) == sizeof(Case),
|
||||||
|
"CaseType and Case should have the same size"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const test_setup_handler_t setup_handler;
|
const test_setup_handler_t setup_handler;
|
||||||
|
|
Loading…
Reference in New Issue