From 1b686c685493a2de898d32fd593340804f1087dc Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 5 Jun 2016 14:52:30 -0500 Subject: [PATCH 1/4] Added rtos::Thread tests --- TESTS/mbedmicro-rtos-mbed/threads/main.cpp | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 TESTS/mbedmicro-rtos-mbed/threads/main.cpp diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp new file mode 100644 index 0000000000..555a2a1bfe --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -0,0 +1,110 @@ +#include "mbed.h" +#include "test_env.h" +#include "unity.h" +#include "utest.h" +#include "rtos.h" + + +using namespace utest::v1; + + +// Tasks with different functions to test on threads +void increment(const void *var) { + (*(int *)var)++; +} + +void increment_with_yield(const void *var) { + Thread::yield(); + (*(int *)var)++; +} + +void increment_with_wait(const void *var) { + Thread::wait(100); + (*(int *)var)++; +} + +void increment_with_child(const void *var) { + Thread child(increment, (void*)var); + child.join(); +} + +void increment_with_murder(const void *var) { + Thread child(increment_with_wait, (void*)var); + // Kill child before it can increment var + child.terminate(); + (*(int *)var)++; +} + + +// Tests that spawn tasks in different configurations +template +void test_single_thread() { + int var = 0; + Thread thread(F, &var); + thread.join(); + TEST_ASSERT_EQUAL(var, 1); +} + +template +void test_parallel_threads() { + int var = 0; + Thread *threads[N]; + + for (int i = 0; i < N; i++) { + threads[i] = new Thread(F, &var); + } + + for (int i = 0; i < N; i++) { + threads[i]->join(); + delete threads[i]; + } + + TEST_ASSERT_EQUAL(var, N); +} + +template +void test_serial_threads() { + int var = 0; + + for (int i = 0; i < N; i++) { + Thread thread(F, &var); + thread.join(); + } + + TEST_ASSERT_EQUAL(var, N); +} + + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(40, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +// Test cases +Case cases[] = { + Case("Testing single thread", test_single_thread), + Case("Testing parallel threads", test_parallel_threads<3, increment>), + Case("Testing serial threads", test_serial_threads<10, increment>), + + Case("Testing single thread with yield", test_single_thread), + Case("Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>), + Case("Testing serial threads with yield", test_serial_threads<10, increment_with_yield>), + + Case("Testing single thread with wait", test_single_thread), + Case("Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>), + Case("Testing serial threads with wait", test_serial_threads<10, increment_with_wait>), + + Case("Testing single thread with child", test_single_thread), + Case("Testing parallel threads with child", test_parallel_threads<3, increment_with_child>), + Case("Testing serial threads with child", test_serial_threads<10, increment_with_child>), + + Case("Testing single thread with murder", test_single_thread), + Case("Testing parallel threads with murder", test_parallel_threads<3, increment_with_murder>), + Case("Testing serial threads with murder", test_serial_threads<10, increment_with_murder>), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} From 8a90b557c94230e0fe5a59fa88e930ea49f80a23 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 5 Jun 2016 15:11:58 -0500 Subject: [PATCH 2/4] Added Callback and FunctionPointer tests --- TESTS/mbed_drivers/callback/main.cpp | 267 +++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 TESTS/mbed_drivers/callback/main.cpp diff --git a/TESTS/mbed_drivers/callback/main.cpp b/TESTS/mbed_drivers/callback/main.cpp new file mode 100644 index 0000000000..90fdd1af1c --- /dev/null +++ b/TESTS/mbed_drivers/callback/main.cpp @@ -0,0 +1,267 @@ +#include "mbed.h" +#include "test_env.h" +#include "unity.h" +#include "utest.h" + +using namespace utest::v1; + + +// static functions +template +T static_func5(T a0, T a1, T a2, T a3, T a4) { return a0 | a1 | a2 | a3 | a4; } +template +T static_func4(T a0, T a1, T a2, T a3) { return a0 | a1 | a2 | a3; } +template +T static_func3(T a0, T a1, T a2) { return a0 | a1 | a2; } +template +T static_func2(T a0, T a1) { return a0 | a1; } +template +T static_func1(T a0) { return a0; } +template +T static_func0() { return 0; } + +// class functions +template +struct Thing { + T t; + Thing() : t(0x80) {} + + T member_func5(T a0, T a1, T a2, T a3, T a4) { return t | a0 | a1 | a2 | a3 | a4; } + T member_func4(T a0, T a1, T a2, T a3) { return t | a0 | a1 | a2 | a3; } + T member_func3(T a0, T a1, T a2) { return t | a0 | a1 | a2; } + T member_func2(T a0, T a1) { return t | a0 | a1; } + T member_func1(T a0) { return t | a0; } + T member_func0() { return t; } +}; + +// bound functions +template +T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +template +T bound_func4(Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +template +T bound_func3(Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +template +T bound_func2(Thing *t, T a0, T a1) { return t->t | a0 | a1; } +template +T bound_func1(Thing *t, T a0) { return t->t | a0; } +template +T bound_func0(Thing *t) { return t->t; } + + +// function call and result verification +template +struct Verifier { + static void verify5(Callback func) { + T result = func(0x01, 0x02, 0x04, 0x08, 0x10); + TEST_ASSERT_EQUAL(result, 0x1f); + } + + template + static void verify5(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02, 0x04, 0x08, 0x10); + TEST_ASSERT_EQUAL(result, 0x9f); + } + + static void verify4(Callback func) { + T result = func(0x01, 0x02, 0x04, 0x08); + TEST_ASSERT_EQUAL(result, 0x0f); + } + + template + static void verify4(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02, 0x04, 0x08); + TEST_ASSERT_EQUAL(result, 0x8f); + } + + static void verify3(Callback func) { + T result = func(0x01, 0x02, 0x04); + TEST_ASSERT_EQUAL(result, 0x07); + } + + template + static void verify3(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02, 0x04); + TEST_ASSERT_EQUAL(result, 0x87); + } + + static void verify2(Callback func) { + T result = func(0x01, 0x02); + TEST_ASSERT_EQUAL(result, 0x03); + } + + template + static void verify2(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02); + TEST_ASSERT_EQUAL(result, 0x83); + } + + static void verify1(Callback func) { + T result = func(0x01); + TEST_ASSERT_EQUAL(result, 0x01); + } + + template + static void verify1(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01); + TEST_ASSERT_EQUAL(result, 0x81); + } + + static void verify0(Callback func) { + T result = func(); + TEST_ASSERT_EQUAL(result, 0x00); + } + + template + static void verify0(O *obj, M method) { + Callback func(obj, method); + T result = func(); + TEST_ASSERT_EQUAL(result, 0x80); + } +}; + + +// test dispatch +template +void test_dispatch5() { + Thing thing; + Verifier::verify5(static_func5); + Verifier::verify5(&thing, &Thing::member_func5); + Verifier::verify5(&thing, &bound_func5); + + Callback callback(static_func5); + Verifier::verify5(callback); + callback.attach(&thing, &bound_func5); + Verifier::verify5(&callback, &Callback::call); + Verifier::verify5((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch4() { + Thing thing; + Verifier::verify4(static_func4); + Verifier::verify4(&thing, &Thing::member_func4); + Verifier::verify4(&thing, &bound_func4); + + Callback callback(static_func4); + Verifier::verify4(callback); + callback.attach(&thing, &bound_func4); + Verifier::verify4(&callback, &Callback::call); + Verifier::verify4((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch3() { + Thing thing; + Verifier::verify3(static_func3); + Verifier::verify3(&thing, &Thing::member_func3); + Verifier::verify3(&thing, &bound_func3); + + Callback callback(static_func3); + Verifier::verify3(callback); + callback.attach(&thing, &bound_func3); + Verifier::verify3(&callback, &Callback::call); + Verifier::verify3((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch2() { + Thing thing; + Verifier::verify2(static_func2); + Verifier::verify2(&thing, &Thing::member_func2); + Verifier::verify2(&thing, &bound_func2); + + Callback callback(static_func2); + Verifier::verify2(callback); + callback.attach(&thing, &bound_func2); + Verifier::verify2(&callback, &Callback::call); + Verifier::verify2((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch1() { + Thing thing; + Verifier::verify1(static_func1); + Verifier::verify1(&thing, &Thing::member_func1); + Verifier::verify1(&thing, &bound_func1); + + Callback callback(static_func1); + Verifier::verify1(callback); + callback.attach(&thing, &bound_func1); + Verifier::verify1(&callback, &Callback::call); + Verifier::verify1((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch0() { + Thing thing; + Verifier::verify0(static_func0); + Verifier::verify0(&thing, &Thing::member_func0); + Verifier::verify0(&thing, &bound_func0); + + Callback callback(static_func0); + Verifier::verify0(callback); + callback.attach(&thing, &bound_func0); + Verifier::verify0(&callback, &Callback::call); + Verifier::verify0((void*)&callback, &Callback::thunk); +} + +template +void test_fparg1() { + Thing thing; + FunctionPointerArg1 fp(static_func1); + Verifier::verify1(fp); + Verifier::verify1(fp.get_function()); +} + +template +void test_fparg0() { + Thing thing; + FunctionPointerArg1 fp(static_func0); + Verifier::verify0(fp); + Verifier::verify0(fp.get_function()); +} + + +// Test setup +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(40, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Testing callbacks with 5 ints", test_dispatch5), + Case("Testing callbacks with 4 ints", test_dispatch4), + Case("Testing callbacks with 3 ints", test_dispatch3), + Case("Testing callbacks with 2 ints", test_dispatch2), + Case("Testing callbacks with 1 ints", test_dispatch1), + Case("Testing callbacks with 0 ints", test_dispatch0), + + Case("Testing callbacks with 5 uchars", test_dispatch5), + Case("Testing callbacks with 4 uchars", test_dispatch4), + Case("Testing callbacks with 3 uchars", test_dispatch3), + Case("Testing callbacks with 2 uchars", test_dispatch2), + Case("Testing callbacks with 1 uchars", test_dispatch1), + Case("Testing callbacks with 0 uchars", test_dispatch0), + + Case("Testing callbacks with 5 uint64s", test_dispatch5), + Case("Testing callbacks with 4 uint64s", test_dispatch4), + Case("Testing callbacks with 3 uint64s", test_dispatch3), + Case("Testing callbacks with 2 uint64s", test_dispatch2), + Case("Testing callbacks with 1 uint64s", test_dispatch1), + Case("Testing callbacks with 0 uint64s", test_dispatch0), + + Case("Testing FunctionPointerArg1 compatibility", test_fparg1), + Case("Testing FunctionPointer compatibility", test_fparg0), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} From 47e41ac321b5d3266b6e6d29f7575262dbd41ea4 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 5 Jun 2016 15:22:11 -0500 Subject: [PATCH 3/4] Added attribute tests based off tests from armmbed/compiler-polyfil --- TESTS/mbedmicro-mbed/attributes/attributes.c | 143 +++++++++++++++++++ TESTS/mbedmicro-mbed/attributes/main.cpp | 53 +++++++ TESTS/mbedmicro-mbed/attributes/weak.c | 10 ++ 3 files changed, 206 insertions(+) create mode 100644 TESTS/mbedmicro-mbed/attributes/attributes.c create mode 100644 TESTS/mbedmicro-mbed/attributes/main.cpp create mode 100644 TESTS/mbedmicro-mbed/attributes/weak.c diff --git a/TESTS/mbedmicro-mbed/attributes/attributes.c b/TESTS/mbedmicro-mbed/attributes/attributes.c new file mode 100644 index 0000000000..f8ad7f7a40 --- /dev/null +++ b/TESTS/mbedmicro-mbed/attributes/attributes.c @@ -0,0 +1,143 @@ +#include "toolchain.h" + +#include +#include + + +MBED_PACKED(struct) TestAttrPackedStruct1 { + char a; + int x; +}; + +typedef MBED_PACKED(struct) { + char a; + int x; +} TestAttrPackedStruct2; + +int testPacked() { + int failed = 0; + + if (sizeof(struct TestAttrPackedStruct1) != sizeof(int) + sizeof(char)) { + failed++; + } + + if (sizeof(TestAttrPackedStruct2) != sizeof(int) + sizeof(char)) { + failed++; + } + + return failed; +} + + +int testAlign() { + int failed = 0; + + MBED_ALIGN(8) char a; + MBED_ALIGN(8) char b; + MBED_ALIGN(16) char c; + MBED_ALIGN(8) char d; + MBED_ALIGN(16) char e; + + if(((uintptr_t)&a) & 0x7){ + failed++; + } + if(((uintptr_t)&b) & 0x7){ + failed++; + } + if(((uintptr_t)&c) & 0xf){ + failed++; + } + if(((uintptr_t)&d) & 0x7){ + failed++; + } + if(((uintptr_t)&e) & 0xf){ + failed++; + } + + return failed; +} + + +int testUnused1(MBED_UNUSED int arg) { + return 0; +} + +int testUnused() { + return testUnused1(0); +} + + +int testWeak1(); +int testWeak2(); + +MBED_WEAK int testWeak1() { + return 1; +} + +int testWeak2() { + return 0; +} + +int testWeak() { + return testWeak1() | testWeak2(); +} + + +MBED_PURE int testPure1() { + return 0; +} + +int testPure() { + return testPure1(); +} + + +MBED_FORCEINLINE int testForceInline1() { + return 0; +} + +int testForceInline() { + return testForceInline1(); +} + + +MBED_NORETURN int testNoReturn1() { + while (1) {} +} + +int testNoReturn() { + if (0) { + testNoReturn1(); + } + return 0; +} + + +int testUnreachable1(int i) { + switch (i) { + case 0: + return 0; + } + + MBED_UNREACHABLE; +} + +int testUnreachable() { + return testUnreachable1(0); +} + + +MBED_DEPRECATED("this message should not be displayed") +void testDeprecatedUnused(); +void testDeprecatedUnused() { } + +MBED_DEPRECATED("this message should be displayed") +int testDeprecatedUsed(); +int testDeprecatedUsed() { + return 0; +} + +int testDeprecated() { + return testDeprecatedUsed(); +} + diff --git a/TESTS/mbedmicro-mbed/attributes/main.cpp b/TESTS/mbedmicro-mbed/attributes/main.cpp new file mode 100644 index 0000000000..1a0feb99ae --- /dev/null +++ b/TESTS/mbedmicro-mbed/attributes/main.cpp @@ -0,0 +1,53 @@ +#include +#include + +#include "toolchain.h" +#include "test_env.h" +#include "unity.h" +#include "utest.h" + +using namespace utest::v1; + + +// Test functions declared as C functions to avoid issues with name mangling +extern "C" { + int testPacked(); + int testAlign(); + int testUnused(); + int testWeak(); + int testPure(); + int testForceInline(); + int testNoReturn(); + int testUnreachable(); + int testDeprecated(); +} + + +// Test wrapper and test cases for utest +template +void test_wrapper() { + TEST_ASSERT_UNLESS(F()); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(40, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Testing PACKED attribute", test_wrapper), + Case("Testing ALIGN attribute", test_wrapper), + Case("Testing UNUSED attribute", test_wrapper), + Case("Testing WEAK attribute", test_wrapper), + Case("Testing PURE attribute", test_wrapper), + Case("Testing FORCEINLINE attribute", test_wrapper), + Case("Testing NORETURN attribute", test_wrapper), + Case("Testing UNREACHABLE attribute", test_wrapper), + Case("Testing DEPRECATED attribute", test_wrapper), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} diff --git a/TESTS/mbedmicro-mbed/attributes/weak.c b/TESTS/mbedmicro-mbed/attributes/weak.c new file mode 100644 index 0000000000..05db78dbea --- /dev/null +++ b/TESTS/mbedmicro-mbed/attributes/weak.c @@ -0,0 +1,10 @@ +#include "toolchain.h" + +int testWeak1() { + return 0; +} + +MBED_WEAK int testWeak2() { + return 1; +} + From 2e5f3409810682716d00e195ef63f8acce39d4c9 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 6 Jun 2016 11:17:00 -0500 Subject: [PATCH 4/4] Updated pre-defork-tests with feedback --- TESTS/mbed_drivers/callback/main.cpp | 4 ++-- TESTS/mbedmicro-mbed/attributes/main.cpp | 4 ++-- TESTS/mbedmicro-rtos-mbed/threads/main.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/TESTS/mbed_drivers/callback/main.cpp b/TESTS/mbed_drivers/callback/main.cpp index 90fdd1af1c..7d229fa7a3 100644 --- a/TESTS/mbed_drivers/callback/main.cpp +++ b/TESTS/mbed_drivers/callback/main.cpp @@ -1,5 +1,5 @@ #include "mbed.h" -#include "test_env.h" +#include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" @@ -230,7 +230,7 @@ void test_fparg0() { // Test setup utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(40, "default_auto"); + GREENTEA_SETUP(5, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/TESTS/mbedmicro-mbed/attributes/main.cpp b/TESTS/mbedmicro-mbed/attributes/main.cpp index 1a0feb99ae..c006e904db 100644 --- a/TESTS/mbedmicro-mbed/attributes/main.cpp +++ b/TESTS/mbedmicro-mbed/attributes/main.cpp @@ -2,7 +2,7 @@ #include #include "toolchain.h" -#include "test_env.h" +#include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" @@ -30,7 +30,7 @@ void test_wrapper() { } utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(40, "default_auto"); + GREENTEA_SETUP(5, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index 555a2a1bfe..d3f8acc18f 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -1,5 +1,5 @@ #include "mbed.h" -#include "test_env.h" +#include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" #include "rtos.h"